mercury-api (empty) → 0.1.0.0
raw patch · 98 files changed
+38192/−0 lines, 98 filesdep +HUnitdep +ansi-terminaldep +basesetup-changed
Dependencies added: HUnit, ansi-terminal, base, bytestring, clock, directory, hashable, mercury-api, optparse-applicative, text, unordered-containers
Files
- ChangeLog.md +5/−0
- LICENSE +45/−0
- README.md +55/−0
- Setup.hs +2/−0
- UPGRADING.md +30/−0
- cbits/api/hex_bytes.c +151/−0
- cbits/api/llrp_reader_imp.h +293/−0
- cbits/api/osdep.h +96/−0
- cbits/api/osdep_posix.c +97/−0
- cbits/api/osdep_win32.c +86/−0
- cbits/api/patches/README.md +23/−0
- cbits/api/patches/config.patch +23/−0
- cbits/api/patches/eintr.patch +30/−0
- cbits/api/patches/extern.patch +28/−0
- cbits/api/patches/host-c-library.patch +33/−0
- cbits/api/patches/infinite-loop.patch +13/−0
- cbits/api/patches/metadataflag-size.patch +13/−0
- cbits/api/patches/mingw-dword-pointer.patch +13/−0
- cbits/api/patches/mingw-snprintf.patch +13/−0
- cbits/api/patches/typos.patch +884/−0
- cbits/api/patches/windows-time.patch +55/−0
- cbits/api/serial_reader.c +6169/−0
- cbits/api/serial_reader_imp.h +1011/−0
- cbits/api/serial_reader_l3.c +7295/−0
- cbits/api/serial_transport_posix.c +307/−0
- cbits/api/serial_transport_win32.c +234/−0
- cbits/api/tm_config.h +263/−0
- cbits/api/tm_reader.c +3680/−0
- cbits/api/tm_reader.h +1289/−0
- cbits/api/tm_reader_async.c +1599/−0
- cbits/api/tmr_filter.h +102/−0
- cbits/api/tmr_gen2.h +537/−0
- cbits/api/tmr_gpio.h +55/−0
- cbits/api/tmr_ipx.h +41/−0
- cbits/api/tmr_iso180006b.h +108/−0
- cbits/api/tmr_llrp_reader.h +278/−0
- cbits/api/tmr_param.c +152/−0
- cbits/api/tmr_params.h +224/−0
- cbits/api/tmr_read_plan.h +211/−0
- cbits/api/tmr_region.h +75/−0
- cbits/api/tmr_serial_reader.h +473/−0
- cbits/api/tmr_serial_transport.h +232/−0
- cbits/api/tmr_status.h +238/−0
- cbits/api/tmr_strerror.c +296/−0
- cbits/api/tmr_tag_auth.h +79/−0
- cbits/api/tmr_tag_data.h +186/−0
- cbits/api/tmr_tag_lock_action.h +77/−0
- cbits/api/tmr_tag_protocol.h +70/−0
- cbits/api/tmr_tagop.h +1734/−0
- cbits/api/tmr_types.h +121/−0
- cbits/api/tmr_utils.c +233/−0
- cbits/api/tmr_utils.h +156/−0
- cbits/glue/glue.c +340/−0
- cbits/glue/glue.h +141/−0
- examples/ExampleUtil.hs +122/−0
- examples/LICENSE-FOR-EXAMPLES +121/−0
- examples/tmr-firmware.hs +65/−0
- examples/tmr-gpio.hs +81/−0
- examples/tmr-lock.hs +96/−0
- examples/tmr-params.hs +79/−0
- examples/tmr-read.hs +99/−0
- examples/tmr-write.hs +100/−0
- mercury-api.cabal +270/−0
- src/System/Hardware/MercuryApi.hs +1048/−0
- src/System/Hardware/MercuryApi/Enums.hsc +967/−0
- src/System/Hardware/MercuryApi/ParamValue.hs +145/−0
- src/System/Hardware/MercuryApi/Params.hs +613/−0
- src/System/Hardware/MercuryApi/Records.hsc +828/−0
- src/System/Hardware/MercuryApi/Testing.hsc +320/−0
- tests/blockErase.result +5/−0
- tests/blockErase.transport +118/−0
- tests/blockPermalockRead.result +3/−0
- tests/blockPermalockRead.transport +86/−0
- tests/blockPermalockWrite.result +38/−0
- tests/blockPermalockWrite.transport +284/−0
- tests/blockWrite.result +5/−0
- tests/blockWrite.transport +118/−0
- tests/gpi.result +1/−0
- tests/gpi.transport +58/−0
- tests/gpo.result +0/−0
- tests/gpo.transport +117/−0
- tests/kill.result +5/−0
- tests/kill.transport +111/−0
- tests/lock.result +7/−0
- tests/lock.transport +109/−0
- tests/param-test.hs +832/−0
- tests/params.result +77/−0
- tests/params.transport +205/−0
- tests/read.result +17/−0
- tests/read.transport +119/−0
- tests/readUser.result +3/−0
- tests/readUser.transport +95/−0
- tests/replay.hs +496/−0
- tests/unit.hs +82/−0
- tests/write.result +5/−0
- tests/write.transport +118/−0
- tests/writeEpc.result +6/−0
- tests/writeEpc.transport +124/−0
+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for mercury-api++## 0.1.0.0 -- 2017-06-05++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,45 @@+Copyright (c) 2017 Patrick Pelletier++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.++----------------------------------------------------------------------++ThingMagic Mercury API Software License++Copyright (c) 2009 - 2012 Trimble Navigation Limited++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.
+ README.md view
@@ -0,0 +1,55 @@+Latest:+[](https://hackage.haskell.org/package/hs-mercury-api)+Linux:+[](https://travis-ci.org/ppelleti/hs-mercury-api)+Windows:+[](https://ci.appveyor.com/project/ppelleti/hs-mercury-api/branch/master)++This package is a Haskell binding to the [Mercury API][5] C API for+[ThingMagic][6] RFID readers. It is especially geared toward+the [SparkFun Simultaneous RFID Reader][1], which uses ThingMagic's+[M6e Nano][7] module, but it should work with other ThingMagic+readers. (Though currently, only support for serial readers is+compiled in.) Most of the function and type names are the same as+their counterparts in the C API, with the `TMR_` prefix dropped. For+more in-depth, language-independent documentation of Mercury API, see+[Mercury API Programmers Guide][2].++This package includes a copy of the Mercury API C library, so no+external libraries are necessary. Several small bug fixes have been+applied to the included version of the library. (I have submitted+these patches upstream, but I don't know if or when they will be+included in the official version.) If you need to upgrade to a newer+version of Mercury API than the included one, see [UPGRADING.md][9].++The Haskell binding doesn't support background reads. I recommend+that you just spawn a new Haskell thread and do foreground reads+instead.++Currently, only support for the serial reader is compiled in, but it+probably wouldn't be too hard to enable LLRP support. (I don't have+any way to test LLRP, however, as the M6e Nano doesn't support it.)++On Mac OS X, be sure to use the serial device that starts with+`/dev/cu.`, not the serial device that starts with `/dev/tty.`.++Only some parameters and some tagops are currently supported in the+Haskell binding. (There are a lot of them, and I only implemented the+ones I needed.) If you need support for additional parameters or+tagops, please file an issue in GitHub and I will add them.++Additional resources:++* [RFID Basics][8]+* [SparkFun Simultaneous RFID Reader hookup guide][3]+* [ThingMagic manuals and firmware][4]++[1]: https://www.sparkfun.com/products/14066+[2]: http://www.thingmagic.com/images/Downloads/Docs/MercuryAPI_ProgrammerGuide_for_v1.27.3.pdf+[3]: https://learn.sparkfun.com/tutorials/simultaneous-rfid-tag-reader-hookup-guide+[4]: http://www.thingmagic.com/index.php/manuals-firmware+[5]: http://www.thingmagic.com/index.php/manuals-firmware#Mercury_API+[6]: http://www.thingmagic.com/+[7]: http://www.thingmagic.com/index.php/embedded-rfid-readers/thingmagic-nano-module+[8]: https://learn.sparkfun.com/tutorials/rfid-basics+[9]: https://github.com/ppelleti/hs-mercury-api/blob/master/UPGRADING.md
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ UPGRADING.md view
@@ -0,0 +1,30 @@+Hopefully I will keep this package up-to-date with the latest version+of Mercury API. But if you're in the position of needing to update+Mercury API, follow these instructions:++* Unzip the Mercury API zipfile.++* Copy the files from `c/src/api/` in the Mercury API distribution to+ `cbits/api/` in this package.++* Run `dos2unix` on the files you copied, to normalize the line+ endings. (In the Mercury API distribution, they are a random+ combination of DOS and Unix line endings, often in the same file.)++* Apply the patches from the `cbits/api/patches/` directory.++* Update `mercury-api.cabal` with any additional C files that were+ added in the new release. Note that not all C files are needed; in+ particular, `serial_transport_tcp_posix.c` and+ `tmr_loadsave_configuration.c` are not needed. Also, note that the+ files are supposed to be listed in [dependency order][1]. (And+ sadly, to get them in the right order, we have to list all the files+ for both Windows and POSIX, because the files end up in the wrong+ order if some are conditional and some are unconditional. Yuck!)++* Run `util/generate-tmr-hsc.pl` (no arguments needed), which will+ update the generated files `Enums.hsc` and `Params.hs` based on the+ new `.h` and `.c` files. (In particular, this will automatically+ pick up new status codes and new parameters.)++[1]: https://ghc.haskell.org/trac/ghc/ticket/13786#comment:3
+ cbits/api/hex_bytes.c view
@@ -0,0 +1,151 @@+/**+ * @file hex_bytes.c+ * @brief Routines for converting between byte arrays and hex strings+ * @author Nathan Williams+ * @date 10/23/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 "tm_reader.h"+#include "serial_reader_imp.h"++static char hexchars[] = "0123456789ABCDEF";+++TMR_Status+TMR_hexToBytes(const char *hex, uint8_t *bytes, uint32_t size,+ uint32_t *convertLen)+{+ char c;+ int i, len;+ uint8_t val[2];++ if (hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X'))+ {+ hex += 2;+ }++ len = 0;+ while (size > 0 && *hex != '\0')+ {+ for (i = 0; i < 2; i++)+ {+ c = *hex++;+ if (c >= '0' && c <= '9')+ val[i] = c - '0';+ else if (c >= 'a' && c <= 'f')+ val[i] = 10 + c - 'a';+ else if (c >= 'A' && c <= 'F')+ val[i] = 10 + c - 'A';+ else+ return TMR_ERROR_INVALID;+ }+ *bytes = (val[0] << 4) | val[1];++ len++;+ bytes++;+ size--;+ }++ if (convertLen != NULL)+ {+ *convertLen = len;+ }++ return TMR_SUCCESS;+}++void+TMR_bytesToHex(const uint8_t *bytes, uint32_t size, char *hex)+{++ while (size--)+ {+ *hex++ = hexchars[*bytes >> 4];+ *hex++ = hexchars[*bytes & 15];+ bytes++;+ }+ *hex = '\0';+}++/**+ * Convert a four-byte array into a null-terminated string+ * with the format %02X.%02X.%02X.%02X (AA.BB.CC.DD).+ *+ * @param bytes The array of four bytes to convert+ * @param buf The string to write to. Must be at least 12 bytes.+ */+void+TMR_hexDottedQuad(const uint8_t bytes[4], char buf[12])+{+ int i;++ for (i = 0; i < 4 ; i++)+ {+ *buf++ = hexchars[*bytes >> 4];+ *buf++ = hexchars[*bytes & 15];+ *buf++ = '.';+ bytes++;+ }+ *--buf = '\0';+}++/**+ * Convert a 12-byte null-terminated string hexDottedQuad into a uint32_t+ *+ * @param bytes The array of twelve bytes to convert+ * @param result The resulting uint32_t+ * @return uint32_t represented but the 12 bytes+ */+TMR_Status+TMR_hexDottedQuadToUint32(const char bytes[12], uint32_t *result)+{+ TMR_Status retVal;+ uint32_t tmpResult;+ uint8_t byteVal;+ int i,j;++ tmpResult=0;+ for (i = 0, j = 0; i < 12 ; i+=3,++j)+ {+ retVal = TMR_hexToBytes(&bytes[i], &byteVal, 1, NULL);+ if (TMR_SUCCESS == retVal)+ {+ tmpResult |= (byteVal << (8 * (3-j)));+ }+ else+ {+ return retVal;+ }+ }++ if (NULL != result)+ {+ *result = tmpResult;+ }+ return retVal;+}
+ cbits/api/llrp_reader_imp.h view
@@ -0,0 +1,293 @@+#ifndef _LLRP_READER_IMP_H+#define _LLRP_READER_IMP_H++/**+ * @file llrp_reader_imp.h+ * @brief LLRP reader internal implementation header+ * @author Somu+ * @date 05/25/2011+ */++/*+ * Copyright (c) 2011 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 <time.h>+#include "tm_reader.h"+#include "tmr_status.h"+#include "ltkc.h"++#ifdef __cplusplus+extern "C" {+#endif++/**+ * Magic Number to reboot the Thingmagic LLRP+ * fixed reader.+ **/+#define TMR_POWER_CYCLE_MAGIC_NUMBER 0x20000920 ++/**+ * LLRP specific AccessCommandOpSpecResult parameter typenums+ **/+#define TMR_LLRP_C1G2READOPSPECRESULT 349+#define TMR_LLRP_C1G2WRITEOPSPECRESULT 350+#define TMR_LLRP_C1G2KILLOPSPECRESULT 351+#define TMR_LLRP_C1G2LOCKOPSPECRESULT 352+#define TMR_LLRP_C1G2BLOCKERASEOPSPECRESULT 353+#define TMR_LLRP_C1G2BLOCKWRITEOPSPECRESULT 354+#define TMR_LLRP_CUSTOM_BLOCKPERMALOCKOPSPECRESULT 22+#define TMR_LLRP_CUSTOM_HIGGS2PARTIALLOADIMAGEOPSPECRESULT 24+#define TMR_LLRP_CUSTOM_HIGGS2FULLLOADIMAGEOPSPECRESULT 26+#define TMR_LLRP_CUSTOM_HIGGS3FASTLOADIMAGEOPSPECRESULT 28+#define TMR_LLRP_CUSTOM_HIGGS3LOADIMAGEOPSPECRESULT 30+#define TMR_LLRP_CUSTOM_HIGGS3BLOCKREADLOCKOPSPECRESULT 32+#define TMR_LLRP_CUSTOM_G2ISETREADPROTECTOPSPECRESULT 34 +#define TMR_LLRP_CUSTOM_G2XSETREADPROTECTOPSPECRESULT 36 +#define TMR_LLRP_CUSTOM_G2IRESETREADPROTECTOPSPECRESULT 38 +#define TMR_LLRP_CUSTOM_G2XRESETREADPROTECTOPSPECRESULT 40 +#define TMR_LLRP_CUSTOM_G2ICHANGEEASOPSPECRESULT 42 +#define TMR_LLRP_CUSTOM_G2XCHANGEEASOPSPECRESULT 44 +#define TMR_LLRP_CUSTOM_G2IEASALARMOPSPECRESULT 46 +#define TMR_LLRP_CUSTOM_G2XEASALARMOPSPECRESULT 48 +#define TMR_LLRP_CUSTOM_G2ICALIBRATEOPSPECRESULT 50 +#define TMR_LLRP_CUSTOM_G2XCALIBRATEOPSPECRESULT 52 +#define TMR_LLRP_CUSTOM_G2ICHANGECONFIGOPSPECRESULT 54 +#define TMR_LLRP_CUSTOM_MONZA4QTREADWRITEOPSPECRESULT 57+#define TMR_LLRP_CUSTOM_IDS_SETSFEPARAMETERSOPSPECRESULT 99+#define TMR_LLRP_CUSTOM_IDS_GETMEASUREMENTSETUPOPSPECRESULT 93+#define TMR_LLRP_CUSTOM_IDS_GETBATTERYLEVELOPSPECRESULT 103+#define TMR_LLRP_CUSTOM_IDS_SETLOGLIMITSOPSPECRESULT 116+#define TMR_LLRP_CUSTOM_IDS_SETSHELFLIFEOPSPECRESULT 124+#define TMR_LLRP_CUSTOM_IDS_SETPASSWORDOPSPECRESULT 118+#define TMR_LLRP_CUSTOM_WRITETAGOPSPECRESULT 61+#define TMR_LLRP_CUSTOM_IDS_GETSENSORVALUEOPSPECRESULT 77+#define TMR_LLRP_CUSTOM_IDS_SETLOGMODEOPSPECRESULT 85+#define TMR_LLRP_CUSTOM_IDS_STARTLOGMODEOPSPECRESULT 87+#define TMR_LLRP_CUSTOM_IDS_GETLOGSTATEOPSPECRESULT 79+#define TMR_LLRP_CUSTOM_IDS_ENDLOGOPSPECRESULT 89+#define TMR_LLRP_CUSTOM_IDS_INITIALIZEOPSPECRESULT 91+#define TMR_LLRP_CUSTOM_IDS_ACCESSFIFOSTATUSOPSPECRESULT 101+#define TMR_LLRP_CUSTOM_IDS_ACCESSFIFOWRITEOPSPECRESULT 114+#define TMR_LLRP_CUSTOM_IDS_ACCESSFIFOREADOPSPECRESULT 112+#define TMR_LLRP_CUSTOM_IDS_GETCALIBRATIONDATAOPSPECRESULT 95+#define TMR_LLRP_CUSTOM_IDS_SETCALIBRATIONDATAOPSPECRESULT 97+#define TMR_LLRP_CUSTOM_DENATRAN_IAV_ACTIVATESECUREMODEOPSPECRESULT 127+#define TMR_LLRP_CUSTOM_DENATRAN_IAV_AUTHENTICATEOBUOPSPECRESULT 129+#define TMR_LLRP_CUSTOM_DENATRAN_IAV_ACTIVATESINIAVMODEOPSPECRESULT 131+#define TMR_LLRP_CUSTOM_DENATRAN_IAV_AUTHENTICATEIDOPSPECRESULT 133+#define TMR_LLRP_CUSTOM_DENATRAN_IAV_AUTHENTICATEFULLPASS1OPSPECRESULT 135+#define TMR_LLRP_CUSTOM_DENATRAN_IAV_AUTHENTICATEFULLPASS2OPSPECRESULT 137+#define TMR_LLRP_CUSTOM_DENATRAN_IAV_OBUREADFROMMEMMAPOPSPECRESULT 139+#define TMR_LLRP_CUSTOM_DENATRAN_IAV_OBUWRITETOMEMMAPOPSPECRESULT 141++#ifdef TMR_ENABLE_ISO180006B+#define TMR_LLRP_CUSTOM_ISO_READDATAOPSPECRESULT 65+#define TMR_LLRP_CUSTOM_ISO_WRITEDATAOPSPECRESULT 68+#define TMR_LLRP_CUSTOM_ISO_LOCKOPSPECRESULT 70+#endif /* TMR_ENABLE_ISO180006B */++/**+ * Maximum number of ROSpecs supported by reader.+ **/+#define TMR_LLRP_MAX_ROSPECS 32+/**+ * Maximum milliseconds required for reader to stop an ongoing search+ **/+#define TMR_LLRP_STOP_TIMEOUT 5000++/**+ * This structure is returned from TMR_LLRP_cmdAntennaDetect.+ **/+typedef struct TMR_LLRP_PortDetect+{+ /** The port number. */+ uint16_t port;+ /** Whether the antenna is connected? */+ bool connected;+ /** Antenna gain */+ int16_t gain;+}TMR_LLRP_PortDetect;++/**+ * This struture is returned from ThingMagicDeDuplication+ **/+typedef struct TMR_LLRP_TMDeDuplication+{+ /** Record Highest RSSI */+ llrp_u1_t highestRSSI;++ /** Unique By Antenna */+ llrp_u1_t uniquebyAntenna;++ /** Unique By Data */+ llrp_u1_t uniquebyData;+}TMR_LLRP_TMDeDuplication;+ +/**+ * This structure is returned from cmdGetThingmagicReaderConfiguration+ **/+typedef struct TMR_LLRP_TMReaderConfiguration+{+ /** Reader description */+ llrp_utf8v_t description;+ /** Reader Role */+ llrp_utf8v_t role;+ /** Reader host name */+ llrp_utf8v_t hostName;+} TMR_LLRP_TMReaderConfiguration;++/**+ * This value is returned from TMR_LLRP_cmdVersionModel.+ **/+# define TMR_LLRP_MODEL_M6 0x06+# define TMR_LLRP_MODEL_ASTRA_EX 0x30+# define TMR_LLRP_MODEL_SARGAS 0x3430++TMR_Status TMR_LLRP_notifyTransportListener(TMR_Reader *reader, LLRP_tSMessage *pMsg, bool tx, int timeout);+TMR_Status TMR_LLRP_sendMessage(TMR_Reader *reader, LLRP_tSMessage *pMsg, int timeoutMs);+TMR_Status TMR_LLRP_receiveMessage(TMR_Reader *reader, LLRP_tSMessage **pMsg, int timeoutMs);+TMR_Status TMR_LLRP_sendTimeout(TMR_Reader *reader, LLRP_tSMessage *pMsg, LLRP_tSMessage **pRsp, int timeoutMs);+TMR_Status TMR_LLRP_send(TMR_Reader *reader, LLRP_tSMessage *pMsg, LLRP_tSMessage **pRsp);+void TMR_LLRP_freeMessage(LLRP_tSMessage *pMsg);+TMR_Status TMR_LLRP_checkLLRPStatus(LLRP_tSLLRPStatus *pLLRPStatus);++TMR_Status TMR_LLRP_cmdGetRegion(TMR_Reader *reader, TMR_Region *region);+TMR_Status TMR_LLRP_cmdAntennaDetect(TMR_Reader *reader, uint8_t *count, TMR_LLRP_PortDetect *ports);+TMR_Status TMR_LLRP_cmdGetTMAsyncOffTime(TMR_Reader *reader, uint32_t *offtime);++TMR_Status TMR_LLRP_cmdGetGPIState(TMR_Reader *reader, uint8_t *count, TMR_GpioPin state[]);+TMR_Status TMR_LLRP_cmdSetGPOState(TMR_Reader *reader, uint8_t count, const TMR_GpioPin state[]);++TMR_Status TMR_LLRP_cmdGetReaderCapabilities(TMR_Reader *reader, TMR_LLRP_ReaderCapabilities *capabilities);++TMR_Status TMR_LLRP_cmdGetReadTransmitPowerList(TMR_Reader *reader, TMR_PortValueList *pPortValueList);+TMR_Status TMR_LLRP_cmdSetReadTransmitPowerList(TMR_Reader *reader, TMR_PortValueList *pPortValueList);++TMR_Status TMR_LLRP_cmdGetWriteTransmitPowerList(TMR_Reader *reader, TMR_PortValueList *pPortValueList);+TMR_Status TMR_LLRP_cmdSetWriteTransmitPowerList(TMR_Reader *reader, TMR_PortValueList *pPortValueList);+TMR_Status TMR_LLRP_cmdGetTMDeviceInformationCapabilities(TMR_Reader *reader, int param, TMR_String *version);+TMR_Status TMR_LLRP_cmdGetActiveRFControl(TMR_Reader *reader, TMR_LLRP_RFControl *rfControl);+TMR_Status TMR_LLRP_cmdSetActiveRFControl(TMR_Reader *reader, TMR_LLRP_RFControl *rfControl);+TMR_Status TMR_LLRP_cmdGetGen2Session(TMR_Reader *reader, TMR_GEN2_Session *session);+TMR_Status TMR_LLRP_cmdSetGen2Session(TMR_Reader *reader, TMR_GEN2_Session *session);+TMR_Status TMR_LLRP_cmdSetTMAsyncOffTime(TMR_Reader *reader, uint32_t offtime);++/*ThingMagic Licensed Features*/+TMR_Status TMR_LLRP_cmdGetLicensedFeatures(TMR_Reader *reader, TMR_uint8List *features);++/*ThingMagic Selected Protocols*/+TMR_Status TMR_LLRP_cmdGetSelectedProtocols(TMR_Reader *reader, TMR_TagProtocolList *protocolList);++/* ThingMagic DeDuplication */+TMR_Status TMR_LLRP_cmdGetThingMagicDeDuplication(TMR_Reader *reader, TMR_LLRP_TMDeDuplication *duplication);+TMR_Status TMR_LLRP_cmdSetThingMagicDeDuplication(TMR_Reader *reader, TMR_LLRP_TMDeDuplication *duplication);++/* Thingmagic Reader configuration */+TMR_Status TMR_LLRP_cmdGetThingmagicReaderConfiguration(TMR_Reader *reader, TMR_LLRP_TMReaderConfiguration *config);+TMR_Status TMR_LLRP_cmdSetThingmagicReaderConfiguration(TMR_Reader *reader, TMR_LLRP_TMReaderConfiguration *config);+void TMR_LLRP_freeTMReaderConfiguration(TMR_LLRP_TMReaderConfiguration *config);++/* Thingmagic Current Time */+TMR_Status TMR_LLRP_cmdGetThingMagicCurrentTime(TMR_Reader *reader, struct tm *curTime);++/* Thingmagic Reader Module Temperature */+TMR_Status TMR_LLRP_cmdGetThingMagicReaderModuleTemperature(TMR_Reader *reader, uint8_t *temp);++/* Thingmagic protocol configuration: Gen2 Q */+TMR_Status TMR_LLRP_cmdSetGen2Q(TMR_Reader *reader, TMR_GEN2_Q *q);+TMR_Status TMR_LLRP_cmdGetGen2Q(TMR_Reader *reader, TMR_GEN2_Q *q);++/* Thingmagic Protocol configuration:Gen2 Target */+TMR_Status TMR_LLRP_cmdSetGen2Target(TMR_Reader *reader, TMR_GEN2_Target *target);+TMR_Status TMR_LLRP_cmdGetGen2Target(TMR_Reader *reader, TMR_GEN2_Target *target);++/* Thingmagic LicenseKey */+TMR_Status TMR_LLRP_cmdSetTMLicenseKey(TMR_Reader *reader, TMR_uint8List *license);++/* Thingmagic ISO 18K6B Delimiter */+TMR_Status TMR_LLRP_cmdSetISO18K6BDelimiter(TMR_Reader *reader, TMR_ISO180006B_Delimiter *delimiter);+TMR_Status TMR_LLRP_cmdGetISO18K6BDelimiter(TMR_Reader *reader, TMR_ISO180006B_Delimiter *delimiter);++/* Thingmagic ISO 18K6B Modulation Depth */+TMR_Status TMR_LLRP_cmdSetISO18K6BModDepth(TMR_Reader *reader, TMR_ISO180006B_ModulationDepth *modDepth);+TMR_Status TMR_LLRP_cmdGetISO18K6BModDepth(TMR_Reader *reader, TMR_ISO180006B_ModulationDepth *modDepth);++/* Thingmagic ISO 1806B Link Frequency */+TMR_Status TMR_LLRP_cmdSetISO18K6BLinkFrequency(TMR_Reader *reader, TMR_ISO180006B_LinkFrequency *linkFreq);+TMR_Status TMR_LLRP_cmdGetISO18K6BLinkFrequency(TMR_Reader *reader, TMR_ISO180006B_LinkFrequency *linkFreq);++/* Thingmagic Device Protocol Capabilities */+TMR_Status TMR_LLRP_cmdGetTMDeviceProtocolCapabilities(TMR_Reader *reader, TMR_TagProtocolList * protocol);++/* Thingmagic Device Antenna Detection */+TMR_Status TMR_LLRP_cmdGetThingMagicAntennaDetection(TMR_Reader *reader, bool *antennaport);+TMR_Status TMR_LLRP_cmdSetThingMagicAntennaDetection(TMR_Reader *reader, bool *antennaport);++/* Read */+TMR_Status TMR_LLRP_cmdPrepareROSpec(TMR_Reader *reader, uint16_t timeout, TMR_uint8List *antennaList,+ const TMR_TagFilter *filter, TMR_TagProtocol protocol);+TMR_Status TMR_LLRP_cmdAddROSpec(TMR_Reader *reader, uint16_t readDuration, TMR_uint8List *antennaList,+ const TMR_TagFilter *filter, TMR_TagProtocol protocol);+TMR_Status TMR_LLRP_cmdEnableROSpec(TMR_Reader *reader);+TMR_Status TMR_LLRP_cmdDisableROSpec(TMR_Reader *reader);+TMR_Status TMR_LLRP_cmdStartROSpec(TMR_Reader *reader, llrp_u32_t roSpecId);+TMR_Status TMR_LLRP_cmdStopROSpec(TMR_Reader *reader, bool receiveResponse);+TMR_Status TMR_LLRP_cmdDeleteAllROSpecs(TMR_Reader *reader, bool receiveResponse);+TMR_Status TMR_LLRP_parseMetadataFromMessage(TMR_Reader *reader, TMR_TagReadData *data, LLRP_tSTagReportData *msg);+TMR_Status TMR_LLRP_verifyReadOperation(TMR_Reader *reader, int32_t *tagCount);+TMR_Status TMR_LLRP_cmdStopReading(struct TMR_Reader *reader);++TMR_Status TMR_LLRP_cmdGetVersionSerial(TMR_Reader *reader, TMR_String *version);+TMR_Status TMR_LLRP_cmdrebootReader(TMR_Reader *reader);++/* Reset Reader */+TMR_Status TMR_LLRP_stopActiveROSpecs(TMR_Reader *reader);++/* Reports, Notifications and Keepalives */+TMR_Status TMR_LLRP_setKeepAlive(TMR_Reader *reader);+TMR_Status TMR_LLRP_enableEventsAndReports(TMR_Reader *reader);+TMR_Status TMR_LLRP_setHoldEventsAndReportsStatus(TMR_Reader *reader, llrp_u1_t status);+TMR_Status TMR_LLRP_handleKeepAlive(TMR_Reader *reader, LLRP_tSMessage *pMsg);+TMR_Status TMR_LLRP_startBackgroundReceiver(TMR_Reader *reader);+TMR_Status TMR_LLRP_cmdSetEventNotificationSpec(TMR_Reader *reader, bool state);+TMR_Status TMR_LLRP_handleReaderEvents(TMR_Reader *reader, LLRP_tSMessage *pMsg);+TMR_Status TMR_LLRP_processReceivedMessage(TMR_Reader *reader, LLRP_tSMessage *pMsg);+void TMR_LLRP_setBackgroundReceiverState(TMR_Reader *reader, bool state);++/* Access Spec */+TMR_Status TMR_LLRP_cmdEnableAccessSpec(TMR_Reader *reader, llrp_u32_t accessSpecId);+TMR_Status TMR_LLRP_msgPrepareAccessCommand(TMR_Reader *reader, LLRP_tSAccessCommand *pAccessCommand,+ TMR_TagFilter *filter, TMR_TagOp *tagop);+TMR_Status TMR_LLRP_cmdAddAccessSpec(TMR_Reader *reader, TMR_TagProtocol protocol, TMR_TagFilter *filter,+ llrp_u32_t roSpecId, TMR_TagOp *tagop, bool isStandalone);+TMR_Status TMR_LLRP_verifyOpSpecResultStatus(TMR_Reader *reader, LLRP_tSParameter *pParameter);+TMR_Status TMR_LLRP_cmdDeleteAllAccessSpecs(TMR_Reader *reader);++TMR_Status TMR_LLRP_parseCustomTagOpSpecResultType(LLRP_tEThingMagicCustomTagOpSpecResultType status);+void TMR_LLRP_parseTagOpSpecData(LLRP_tSParameter *pParameter, TMR_uint8List *data);++TMR_Status TMR_LLRP_cmdGetReport(TMR_Reader *reader);+#ifdef __cplusplus+}+#endif++#endif /* _LLRP_READER_IMP_H */
+ cbits/api/osdep.h view
@@ -0,0 +1,96 @@+#ifndef _OSDEP_H+#define _OSDEP_H++/**+ * @file osdep.h+ * @brief Mercury API - OS dependencies+ * @author Nathan Williams+ * @date 2/24/2010+ */++/*+ * Copyright (c) 2010 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.+ */++#ifdef WINCE+#include <stdint_win32.h>+#else+#include <stdint.h>+#endif++#ifdef __cplusplus+extern "C" {+#endif++/* These are functions that must be provided for the library to operate */++ /*+ * Thing magic reader time objeect to reprejent the time stamp+ */+ typedef struct TMR_TimeStructure+ {+ uint32_t tm_sec;+ uint32_t tm_min;+ uint32_t tm_hour;+ uint32_t tm_mday;+ uint32_t tm_mon;+ uint32_t tm_year;+ }TMR_TimeStructure;++/*+ * The time function used to return the current time in+ * thing magic time structure.+ */+TMR_TimeStructure tmr_gettimestructure(void);++uint64_t tmr_gettime(void);++/* The time functions collectively return a 64-bit counter in units of+ * milliseconds. Both methods are used when timestamping events such+ * as tag reads. For controlling elapsed time, only the lower one is+ * used, so If your platform does not support more than 32 bits of+ * millisecond counting, returning 0 from the high method will not+ * cause problems internal to the library.+ */++/**+ * Return the low 32-bits of a system millisecond counter. This is+ * used internally for operation timing and to timestamp tag reads.+ */+uint32_t tmr_gettime_low(void);++/**+ * Return the high 32-bits of a system millisecond counter. This is+ * used to timestamp tag reads.+ */+uint32_t tmr_gettime_high(void);++/**+ * Suspend operation for a given duration.+ * @param sleepms The number of milliseconds to sleep for.+ */+void tmr_sleep(uint32_t sleepms);++#ifdef __cplusplus+}+#endif++#endif /* _OSDEP_H */
+ cbits/api/osdep_posix.c view
@@ -0,0 +1,97 @@++/**+ * @file osdep_posix.c+ * @brief Mercury API - POSIX platform implementation of OS dependencies+ * @author Nathan Williams+ * @date 2/24/2010+ */++/*+ * Copyright (c) 2010 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 <time.h>+#include <sys/time.h>++#include "osdep.h"++uint64_t+tmr_gettime()+{+ struct timeval tv;+ uint64_t totalms;++ gettimeofday(&tv, NULL);+ totalms = (((uint64_t)tv.tv_sec) * 1000) + ((uint64_t) tv.tv_usec) / 1000;++ return totalms;+}++uint32_t+tmr_gettime_low()+{++ return (tmr_gettime() >> 0) & 0xffffffff;+}++uint32_t+tmr_gettime_high()+{++ return (tmr_gettime() >> 32) & 0xffffffff;+}+++void+tmr_sleep(uint32_t sleepms)+{+ struct timespec sleep, rem;++ sleep.tv_sec = sleepms / 1000;+ sleep.tv_nsec = (sleepms % 1000) * 1000000L;++ /* Sleep until the proper time has elapsed, and re-sleep if interrupted. */+ while (-1 == nanosleep(&sleep, &rem))+ {+ sleep = rem;+ }+}++TMR_TimeStructure +tmr_gettimestructure()+{+ time_t now;+ uint64_t temp;+ struct tm *timestamp;+ TMR_TimeStructure timestructure;++ temp = tmr_gettime();+ now = (time_t)(temp/1000);+ timestamp = localtime(&now);++ timestructure.tm_year = (uint32_t)(1900 + timestamp->tm_year);+ timestructure.tm_mon = (uint32_t)(1 + timestamp->tm_mon);+ timestructure.tm_mday = (uint32_t)timestamp->tm_mday;+ timestructure.tm_hour = (uint32_t)timestamp->tm_hour;+ timestructure.tm_min = (uint32_t)timestamp->tm_min;+ timestructure.tm_sec = (uint32_t)timestamp->tm_sec;+ return timestructure; +}
+ cbits/api/osdep_win32.c view
@@ -0,0 +1,86 @@+/**+ * @file osdep_win32.c+ * @brief Mercury API - Windows platform implementation of OS dependencies+*/++/*+ * Copyright (c) 2010 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.+ */++#if !defined(_WINSOCK2API_) && !defined(_WINSOCKAPI_)+#include <winsock2.h>+#endif+#include <time.h>+#include "osdep.h"++// https://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux+#define SEC_TO_UNIX_EPOCH 11644473600LL++uint64_t+tmr_gettime()+{+ uint64_t totalms;+ SYSTEMTIME st;+ FILETIME ft;+ LARGE_INTEGER li; + GetSystemTime(&st);+ SystemTimeToFileTime(&st, &ft);+ li.LowPart = ft.dwLowDateTime;+ li.HighPart = ft.dwHighDateTime;+ totalms=(((uint64_t)li.LowPart) | ((uint64_t)li.HighPart)<<32)/10000;+ totalms -= SEC_TO_UNIX_EPOCH * 1000;+ return totalms;+}++uint32_t+tmr_gettime_low()+{+ return (uint32_t) tmr_gettime();+}++uint32_t+tmr_gettime_high()+{+ return (uint32_t) (tmr_gettime() >> 32);+}++void+tmr_sleep(uint32_t sleepms)+{+ Sleep(sleepms);+}++TMR_TimeStructure +tmr_gettimestructure()+{ + SYSTEMTIME st;+ TMR_TimeStructure timestructure;++ GetSystemTime(&st);++ timestructure.tm_year = (uint32_t)st.wYear;+ timestructure.tm_mon = (uint32_t)st.wMonth;+ timestructure.tm_mday = (uint32_t)st.wDay;+ timestructure.tm_hour = (uint32_t)st.wHour;+ timestructure.tm_min = (uint32_t)st.wMinute;+ timestructure.tm_sec = (uint32_t)st.wSecond;+ return timestructure; +}
+ cbits/api/patches/README.md view
@@ -0,0 +1,23 @@+These are patches to be applied to Mercury API to fix various bugs.+I've submitted all of them (except `config.patch`) to ThingMagic for+possible inclusion in a future release.++`config.patch` - This increases the maximum length of URIs from 64 bytes to 256 bytes. Unlike all the other patches, this is a configuration change, not a bug fix, so it has not been submitted upstream.++`eintr.patch` - This retries the `select()` operation when it returns `EINTR`. This is always good practice, but it seemed to be necessary in my situation to avoid failing with a timeout. There are probably plenty of other places in the API where this should be done, too.++`extern.patch` - This fixes a problem I ran into with `isSecureAccessEnabled` being multiply defined, when compiling with cabal. (Strangely, doesn't happen when using ThingMagic's Makefile.)++`host-c-library.patch` - The build failed when `TMR_USE_HOST_C_LIBRARY` was defined. This fixes that.++`infinite-loop.patch` - This avoids an infinite loop that I ran into, when somehow `readOffSet` was 142, and `dataLength` was 128. Not sure how that happened, and it probably indicates another bug, but at least this fix prevents going into an infinite loop in that situation.++`metadataflag-size.patch` - `paramSet()` treated `TMR_PARAM_METADATAFLAG` as `TMR_TRD_MetadataFlag`, while `paramGet()` treated `TMR_PARAM_METADATAFLAG` as `uint16_t`. Since `sizeof(TMR_TRD_MetadataFlag)` is 4 but `sizeof(uint16_t)` is 2, the sizes didn't match. This patch fixes `paramGet()` to also treat it as `TMR_TRD_MetadataFlag`.++`mingw-dword-pointer.patch` - Fixes a compiler warning about `warning: passing argument 4 of 'ReadFile' from incompatible pointer type [-Wincompatible-pointer-types]`. Somehow the warning was getting treated as an error on Appveyor.++`mingw-snprintf.patch` - Fixes a problem I ran into on MinGW, where `sprintf_s()` doesn't seem to work properly, but `snprintf()` does work properly.++`typos.patch` - This just fixes a bunch of small typos I found.++`windows-time.patch` - On Windows, `tmr_gettime_low()` and `tmr_gettime_high()` were returning the number of 100-nanosecond units since 1/1/1601, rather than the number of milliseconds since 1/1/1970. This caused the `timestampLow` and `timestampHigh` fields of `TMR_TagReadData` to be populated incorrectly. This patch fixes that problem.
+ cbits/api/patches/config.patch view
@@ -0,0 +1,23 @@+commit 092146c3eb431d9358135e5a2919f5a9a6f4c0db+Author: Patrick Pelletier <code@funwithsoftware.org>+Date: Thu May 25 15:55:39 2017 -0700++ increase the maximum length of a reader URI+ + This is necessary because in the case of test:// URIs, we are passing+ an arbitrary filename. Even 256 is fairly arbitrary, but it seems+ like enough for most cases, while 64 seemed tight.++diff --git a/tm_config.h b/tm_config.h+index a749b26..ea5892e 100644+--- a/tm_config.h++++ b/tm_config.h+@@ -56,7 +56,7 @@ extern "C" {+ /**+ * The longest possible name for a reader.+ */+-#define TMR_MAX_READER_NAME_LENGTH 64++#define TMR_MAX_READER_NAME_LENGTH 256+ + /**+ * The maximum number of protocols supported in a multiprotocol search command
+ cbits/api/patches/eintr.patch view
@@ -0,0 +1,30 @@+diff --git a/serial_transport_posix.c b/serial_transport_posix.c+index 9146589..4127ee3 100644+--- a/serial_transport_posix.c++++ b/serial_transport_posix.c+@@ -127,12 +127,19 @@ s_receiveBytes(TMR_SR_SerialTransport *this, uint32_t length,+ + do+ {+- FD_ZERO(&set);+- FD_SET(c->handle, &set);+- tv.tv_sec = timeoutMs / 1000;+- tv.tv_usec = (timeoutMs % 1000) * 1000;+- /* Ideally should reset this timeout value every time through */+- ret = select(c->handle + 1, &set, NULL, NULL, &tv);++ do++ {++ FD_ZERO(&set);++ FD_SET(c->handle, &set);++ tv.tv_sec = timeoutMs / 1000;++ tv.tv_usec = (timeoutMs % 1000) * 1000;++ /* Ideally should reset this timeout value every time through */++ ret = select(c->handle + 1, &set, NULL, NULL, &tv);++ } while (ret == -1 && errno == EINTR);++ if (ret == -1)++ {++ return TMR_ERROR_COMM_ERRNO(errno);++ }+ if (ret < 1)+ {+ return TMR_ERROR_TIMEOUT;
+ cbits/api/patches/extern.patch view
@@ -0,0 +1,28 @@+diff --git a/serial_reader_imp.h b/serial_reader_imp.h+index 9f5fd54..16e30b1 100644+--- a/serial_reader_imp.h++++ b/serial_reader_imp.h+@@ -40,7 +40,7 @@ extern "C" {+ /* This is used to enable the Gen2 secure readdata option */+ + #ifndef BARE_METAL+- bool isSecureAccessEnabled ;++ extern bool isSecureAccessEnabled ;+ #else+ static bool isSecureAccessEnabled; + #endif+diff --git a/serial_reader_l3.c b/serial_reader_l3.c+index 99986bf..71c4192 100644+--- a/serial_reader_l3.c++++ b/serial_reader_l3.c+@@ -36,6 +36,10 @@+ #include "serial_reader_imp.h"+ #include "tmr_utils.h"+ ++#ifndef BARE_METAL++bool isSecureAccessEnabled;++#endif+++ void+ notify_read_listeners(TMR_Reader *reader, TMR_TagReadData *trd);+ #ifdef TMR_ENABLE_SERIAL_READER
+ cbits/api/patches/host-c-library.patch view
@@ -0,0 +1,33 @@+diff --git a/tm_reader_async.c b/tm_reader_async.c+index 4bcec6f..a464c5f 100644+--- a/tm_reader_async.c++++ b/tm_reader_async.c+@@ -40,6 +40,7 @@ TMR_Status restart_reading(struct TMR_Reader *reader);+ #include <semaphore.h>+ #include <time.h>+ #include <stdio.h>++#include <string.h>+ + #ifndef WIN32+ #include <sys/time.h>+diff --git a/tmr_utils.c b/tmr_utils.c+index 194a63a..80c7ce9 100644+--- a/tmr_utils.c++++ b/tmr_utils.c+@@ -28,6 +28,7 @@+ */+ + #include <stddef.h>++#include <string.h>+ + #include "osdep.h"+ #include "tmr_types.h"+@@ -171,7 +172,7 @@ TMR_stringCopy(TMR_String *dest, const char *src, int len)+ }+ if (dest->max > 0)+ {+- tm_memcpy(dest->value, src, len);++ memcpy(dest->value, src, len);+ dest->value[len] = '\0';+ }+ }
+ cbits/api/patches/infinite-loop.patch view
@@ -0,0 +1,13 @@+diff --git a/serial_reader_l3.c b/serial_reader_l3.c+index 99986bf..458740e 100644+--- a/serial_reader_l3.c++++ b/serial_reader_l3.c+@@ -1767,7 +1767,7 @@ TMR_SR_parseMetadataFromMessage(TMR_Reader *reader, TMR_TagReadData *read, uint1+ uint16_t epcDataLength;+ while (dataLength != 0)+ {+- if (readOffSet == dataLength)++ if (readOffSet >= dataLength)+ break;+ bank = ((read->data.list[readOffSet] >> 4) & 0x1F);+ epcDataLength = (read->data.list[readOffSet + 1] * 2);
+ cbits/api/patches/metadataflag-size.patch view
@@ -0,0 +1,13 @@+diff --git a/serial_reader.c b/serial_reader.c+index 7001ab1..c711aac 100644+--- a/serial_reader.c++++ b/serial_reader.c+@@ -4178,7 +4178,7 @@ TMR_SR_paramGet(struct TMR_Reader *reader, TMR_Param key, void *value)+ break;+ case TMR_PARAM_METADATAFLAG:+ {+- *(uint16_t *)value = reader->userMetadataFlag;++ *(TMR_TRD_MetadataFlag *)value = reader->userMetadataFlag;+ break;+ }+
+ cbits/api/patches/mingw-dword-pointer.patch view
@@ -0,0 +1,13 @@+diff --git a/serial_transport_win32.c b/serial_transport_win32.c+index ce4cc46..ff007b6 100644+--- a/serial_transport_win32.c++++ b/serial_transport_win32.c+@@ -126,7 +126,7 @@ s_receiveBytes(TMR_SR_SerialTransport *this, uint32_t length,+ uint32_t* messageLength, uint8_t* message, const uint32_t+ timeoutMs)+ {+- uint32_t readLength;++ DWORD readLength;+ DWORD errorFlags;+ COMSTAT comStat;+ TMR_SR_SerialPortNativeContext *c;
+ cbits/api/patches/mingw-snprintf.patch view
@@ -0,0 +1,13 @@+diff --git a/serial_transport_win32.c b/serial_transport_win32.c+index ce4cc46..e8e27cb 100644+--- a/serial_transport_win32.c++++ b/serial_transport_win32.c+@@ -39,7 +39,7 @@+ + # if defined(WINCE)+ # define snprintf _snprintf+-# else++# elif !defined(__GNUC__)+ # define snprintf sprintf_s+ # endif+
+ cbits/api/patches/typos.patch view
@@ -0,0 +1,884 @@+diff --git a/llrp_reader_l3.c b/llrp_reader_l3.c+index 555fe0a..de3fe19 100644+--- a/llrp_reader_l3.c++++ b/llrp_reader_l3.c+@@ -9691,7 +9691,7 @@ TMR_LLRP_verifyOpSpecResultStatus(TMR_Reader *reader,+ + case LLRP_C1G2ReadResultType_Memory_Locked_Error:+ {+- ret = TMR_ERROR_GEN2_PROCOCOL_MEMORY_LOCKED;++ ret = TMR_ERROR_GEN2_PROTOCOL_MEMORY_LOCKED;+ break;+ }+ +@@ -9725,7 +9725,7 @@ TMR_LLRP_verifyOpSpecResultStatus(TMR_Reader *reader,+ + case LLRP_C1G2WriteResultType_Tag_Memory_Locked_Error:+ {+- ret = TMR_ERROR_GEN2_PROCOCOL_MEMORY_LOCKED;++ ret = TMR_ERROR_GEN2_PROTOCOL_MEMORY_LOCKED;+ break;+ }+ +@@ -9881,7 +9881,7 @@ TMR_LLRP_verifyOpSpecResultStatus(TMR_Reader *reader,+ + case LLRP_C1G2BlockEraseResultType_Tag_Memory_Locked_Error:+ {+- ret = TMR_ERROR_GEN2_PROCOCOL_MEMORY_LOCKED;++ ret = TMR_ERROR_GEN2_PROTOCOL_MEMORY_LOCKED;+ break;+ }+ +@@ -9939,7 +9939,7 @@ TMR_LLRP_verifyOpSpecResultStatus(TMR_Reader *reader,+ + case LLRP_C1G2BlockWriteResultType_Tag_Memory_Locked_Error:+ {+- ret = TMR_ERROR_GEN2_PROCOCOL_MEMORY_LOCKED;++ ret = TMR_ERROR_GEN2_PROTOCOL_MEMORY_LOCKED;+ break;+ }+ +diff --git a/osdep.h b/osdep.h+index d9661ac..126e3b9 100644+--- a/osdep.h++++ b/osdep.h+@@ -56,7 +56,7 @@ extern "C" {+ }TMR_TimeStructure;+ + /*+- * The time funcution used to return the current time in++ * The time function used to return the current time in+ * thing magic time structure.+ */+ TMR_TimeStructure tmr_gettimestructure(void);+diff --git a/serial_reader.c b/serial_reader.c+index 7001ab1..1d017b1 100644+--- a/serial_reader.c++++ b/serial_reader.c+@@ -228,7 +228,7 @@ TMR_SR_boot(TMR_Reader *reader, uint32_t currentBaudRate)+ }+ + /**+- * In case for M6E and it's varient check for CRC++ * 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]) ||+@@ -426,7 +426,7 @@ TMR_SR_boot(TMR_Reader *reader, uint32_t currentBaudRate)+ {+ /*+ * Modules with firmware older than wilder will throw 0x105 error, as it was not +- * implemented. Catch this error and but do not return.++ * implemented. Catch this error but do not return.+ */+ sr->productId = 0xFFFF;+ }+@@ -497,7 +497,7 @@ TMR_SR_boot(TMR_Reader *reader, uint32_t currentBaudRate)+ + /**+ * Enable the extended EPC flag in case+- * of M5E and its varients++ * of M5E and its variants+ */+ if ((TMR_SR_MODEL_M6E != sr->versionInfo.hardware[0]) &&+ (TMR_SR_MODEL_MICRO != sr->versionInfo.hardware[0]) &&+@@ -4020,7 +4020,7 @@ TMR_SR_paramGet(struct TMR_Reader *reader, TMR_Param key, void *value)+ case TMR_SR_MODEL_MICRO:+ {+ /**+- * Micro has following varients.++ * Micro has following variants.+ **/+ switch (sr->versionInfo.hardware[3])+ {+@@ -4751,7 +4751,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_GetSensorValue op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4773,7 +4773,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_GetMeasurementSetup op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4795,7 +4795,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_GetCalibrationData op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4817,7 +4817,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_SetCalibrationData op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4839,7 +4839,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_SetSfeParameters op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4862,7 +4862,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_GetLogState op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4884,7 +4884,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_SetLogMode op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4907,7 +4907,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_Initialize op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4930,7 +4930,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_EndLog op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4952,7 +4952,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_SetPassword op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4974,7 +4974,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_AccessFifoStatus op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -4995,7 +4995,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_AccessFifoRead op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -5016,7 +5016,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_AccessFifoWrite op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -5037,7 +5037,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_StartLog op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -5059,7 +5059,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_GetBatteryLevel op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -5081,7 +5081,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_SetLogLimits op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+@@ -5103,7 +5103,7 @@ TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *+ {+ TMR_TagOp_GEN2_IDS_SL900A_SetShelfLife op;+ +- /* Set the protocol for tag opearation */++ /* Set the protocol for tag operation */+ ret = setProtocol(reader, TMR_TAG_PROTOCOL_GEN2);+ if (TMR_SUCCESS != ret)+ {+diff --git a/serial_reader_imp.h b/serial_reader_imp.h+index 9f5fd54..a96405f 100644+--- a/serial_reader_imp.h++++ b/serial_reader_imp.h+@@ -467,7 +467,7 @@ typedef struct TMR_SR_Gen2ReaderWriteTimeOut+ /* Status of reader timeout */+ bool earlyexit;+ +- /* Timeout value used for write opearation */++ /* Timeout value used for write operation */+ uint16_t writetimeout;+ }TMR_SR_Gen2ReaderWriteTimeOut;+ /**+@@ -677,11 +677,11 @@ TMR_Status TMR_SR_cmdSL900aGetBatteryLevel(TMR_Reader *reader, uint16_t timeout,+ uint8_t CommandCode, uint32_t password, PasswordLevel level,BatteryType type,+ TMR_uint8List *data, TMR_TagFilter* target);+ TMR_Status TMR_SR_cmdSL900aAccessFifoStatus(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+- uint32_t password, PasswordLevel level, AccessFifoOperation opearation, TMR_uint8List * data, TMR_TagFilter* target);++ uint32_t password, PasswordLevel level, AccessFifoOperation operation, TMR_uint8List * data, TMR_TagFilter* target);+ TMR_Status TMR_SR_cmdSL900aAccessFifoRead(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+- uint32_t password, PasswordLevel level, AccessFifoOperation opearation, uint8_t length,TMR_uint8List * data, TMR_TagFilter* target);++ uint32_t password, PasswordLevel level, AccessFifoOperation operation, uint8_t length,TMR_uint8List * data, TMR_TagFilter* target);+ TMR_Status TMR_SR_cmdSL900aAccessFifoWrite(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+- uint32_t password, PasswordLevel level, AccessFifoOperation opearation, TMR_uint8List *payLoad, TMR_uint8List * data, TMR_TagFilter* target);++ uint32_t password, PasswordLevel level, AccessFifoOperation operation, TMR_uint8List *payLoad, TMR_uint8List * data, TMR_TagFilter* target);+ TMR_Status TMR_SR_cmdHibikiReadLock(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, uint16_t mask, uint16_t action);+ TMR_Status TMR_SR_cmdHibikiGetSystemInformation(TMR_Reader *reader, uint16_t timeout,+@@ -945,7 +945,7 @@ TMR_SR_msgAddIdsSL900aSetPassword(uint8_t *msg, uint8_t *i, uint16_t timeout, TM+ PasswordLevel newPasswordLevel, TMR_TagFilter* target);+ void + TMR_SR_msgAddIdsSL900aAccessFifoStatus(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+- uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation opearation,++ uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation operation,+ TMR_TagFilter* target);+ void + TMR_SR_msgAddIdsSL900aGetBatteryLevel(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+@@ -953,11 +953,11 @@ TMR_SR_msgAddIdsSL900aGetBatteryLevel(uint8_t *msg, uint8_t *i, uint16_t timeout+ TMR_TagFilter* target);+ void + TMR_SR_msgAddIdsSL900aAccessFifoRead(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+- uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation opearation,++ uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation operation,+ uint8_t length, TMR_TagFilter* target);+ void + TMR_SR_msgAddIdsSL900aAccessFifoWrite(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+- uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation opearation,++ uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation operation,+ TMR_uint8List *payLoad, TMR_TagFilter* target);+ void + TMR_SR_msgAddIdsSL900aStartLog(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+diff --git a/serial_reader_l3.c b/serial_reader_l3.c+index 99986bf..c20af74 100644+--- a/serial_reader_l3.c++++ b/serial_reader_l3.c+@@ -360,7 +360,7 @@ retryHeader:+ }+ + /* We got a response for a different command than the one we+- * sent. This usually means we recieved the boot-time message from++ * sent. This usually means we received the boot-time message from+ * a M6e, and thus that the device was rebooted somewhere between+ * the previous command and this one. Report this as a problem.+ */+@@ -1756,7 +1756,7 @@ TMR_SR_parseMetadataFromMessage(TMR_Reader *reader, TMR_TagReadData *read, uint1+ }+ + /**+- * if the gen2AllMemoryBankEnabled is enbled,++ * if the gen2AllMemoryBankEnabled is enabled,+ * extract the values+ **/+ if (reader->u.serialReader.gen2AllMemoryBankEnabled)+@@ -3778,7 +3778,7 @@ TMR_SR_msgSetupMultipleProtocolSearch(TMR_Reader *reader, uint8_t *msg, TMR_SR_O+ case TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE:+ {+ /**+- * simple read plan uses this funcution, only when tagop is NULL,++ * simple read plan uses this function, only when tagop is NULL,+ * s0, need to check for simple read plan tagop.+ **/+ if (TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type)+@@ -5162,7 +5162,7 @@ void TMR_SR_msgAddIdsSL900aGetBatteryLevel(uint8_t *msg, uint8_t *i, uint16_t ti+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -5234,7 +5234,7 @@ void TMR_SR_msgAddIdsSL900aGetSensorValue(uint8_t *msg, uint8_t *i, uint16_t tim+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -5304,7 +5304,7 @@ void TMR_SR_msgAddIdsSL900aGetMeasurementSetup(uint8_t *msg, uint8_t *i, uint16_+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -5374,7 +5374,7 @@ void TMR_SR_msgAddIdsSL900aGetLogState(uint8_t *msg, uint8_t *i, uint16_t timeou+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param to specify SL900A sensor type+ * @param data If the operation is success, this data contains the requested value+@@ -5459,7 +5459,7 @@ void TMR_SR_msgAddIdsSL900aSetLogMode(uint8_t *msg, uint8_t *i, uint16_t timeout+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param level IDS password level+ * @param form IDS logging form+@@ -5518,7 +5518,7 @@ void TMR_SR_msgAddIdsSL900aInitialize(uint8_t *msg, uint8_t *i, uint16_t timeout+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param delayTime to secify delayTime+ * @param applicatioData to specify applicationData+@@ -5569,7 +5569,7 @@ void TMR_SR_msgAddIdsSL900aEndLog(uint8_t *msg, uint8_t *i, uint16_t timeout, TM+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -5589,7 +5589,7 @@ TMR_SR_cmdSL900aEndLog(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password a+ }+ + /**+- * Helper funcution to form the IDS SL900A SetPassword command++ * Helper function to form the IDS SL900A SetPassword command+ */ + void TMR_SR_msgAddIdsSL900aSetPassword(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t newPassword,+@@ -5619,7 +5619,7 @@ void TMR_SR_msgAddIdsSL900aSetPassword(uint8_t *msg, uint8_t *i, uint16_t timeou+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -5669,7 +5669,7 @@ void TMR_SR_msgAddIdsSL900aAccessFifoStatus(uint8_t *msg, uint8_t *i, uint16_t t+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -5740,7 +5740,7 @@ void TMR_SR_msgAddIdsSL900aAccessFifoRead(uint8_t *msg, uint8_t *i, uint16_t tim+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -5814,7 +5814,7 @@ void TMR_SR_msgAddIdsSL900aAccessFifoWrite(uint8_t *msg, uint8_t *i, uint16_t ti+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -5885,7 +5885,7 @@ void TMR_SR_msgAddIdsSL900aStartLog(uint8_t *msg, uint8_t *i, uint16_t timeout,+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param startTime to specify count start time+ * @param target Filter to be applied.+@@ -5932,7 +5932,7 @@ void TMR_SR_msgAddIdsSL900aGetCalibrationData(uint8_t *msg, uint8_t *i, uint16_t+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -6017,7 +6017,7 @@ void TMR_SR_msgAddIdsSL900aSetCalibrationData(uint8_t *msg, uint8_t *i, uint16_t+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param calibration to spcify the calibration data+ * @param target Filter to be applied.+@@ -6067,7 +6067,7 @@ void TMR_SR_msgAddIdsSL900aSetSfeParameters(uint8_t *msg, uint8_t *i, uint16_t t+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param sfe to spcify the sfe parameters+ * @param target Filter to be applied.+@@ -6184,7 +6184,7 @@ void TMR_SR_msgAddIdsSL900aSetShelfLife(uint8_t *msg, uint8_t *i, uint16_t timeo+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+- * @param commandcode to specify the opearation++ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+@@ -6809,7 +6809,7 @@ TMR_SR_cmdResetReaderStatistics(TMR_Reader *reader, TMR_SR_ReaderStatisticsFlag+ + + /**+- * Helper funcution to be used in GetReaderStats++ * Helper function to be used in GetReaderStats+ */ + TMR_Status+ TMR_fillReaderStats(TMR_Reader *reader, TMR_Reader_StatsValues* stats, uint16_t flag, uint8_t* msg, uint8_t offset)+diff --git a/tm_config.h b/tm_config.h+index 989fa86..691b095 100644+--- a/tm_config.h++++ b/tm_config.h+@@ -153,14 +153,14 @@ Note:To run readsync_baremetal codelet you have to+ + /**+ * Enabling this option will enable the support for the parameters defined +- * in stdio.h header file like FILE *. This check is required as stdio.h doese not++ * in stdio.h header file like FILE *. This check is required as stdio.h does not+ * exist in some of the embedded architectures.+ */+ #define TMR_ENABLE_STDIO+ + /**+ * Enabling this option will enable the support for the parameters defined +- * in string.h header file like sterror(). This check is required as string.h doese not++ * in string.h header file like strerror(). This check is required as string.h does not+ * exist in some of the embedded architectures.+ */+ #define TMR_USE_STRERROR+@@ -214,14 +214,14 @@ Note:To run readsync_baremetal codelet you have to+ + /**+ * Enabling this option will enable the support for the parameters defined +- * in stdio.h header file like FILE *. This check is required as stdio.h doese not++ * in stdio.h header file like FILE *. This check is required as stdio.h does not+ * exist in some of the embedded architectures.+ */+ #undef TMR_ENABLE_STDIO+ + /**+ * Enabling this option will enable the support for the parameters defined +- * in string.h header file like sterror(). This check is required as string.h doese not++ * in string.h header file like strerror(). This check is required as string.h does not+ * exist in some of the embedded architectures.+ */+ #undef TMR_USE_STRERROR+diff --git a/tm_reader.c b/tm_reader.c+index 5ba8edf..1b71dec 100644+--- a/tm_reader.c++++ b/tm_reader.c+@@ -3058,7 +3058,7 @@ TMR_init_GEN2_Impinj_Monza4_Payload(TMR_Monza4_Payload *payload)+ }+ + /**+- * Helper funcution to update or modifying the sfe parameters++ * Helper function to update or modifying the sfe parameters+ */+ TMR_Status+ TMR_update_GEN2_IDS_SL900A_SfeParameters(TMR_TagOp_GEN2_IDS_SL900A_SfeParameters *sfe)+@@ -3122,7 +3122,7 @@ TMR_update_GEN2_IDS_SL900A_SfeParameters(TMR_TagOp_GEN2_IDS_SL900A_SfeParameters+ }+ + /**+- * Helper funcution to update or modifying the calibration Data++ * Helper function to update or modifying the calibration Data+ */+ TMR_Status+ TMR_update_GEN2_IDS_SL900A_CalibrationData(TMR_TagOp_GEN2_IDS_SL900A_CalibrationData *cal)+@@ -3219,7 +3219,7 @@ TMR_update_GEN2_IDS_SL900A_CalibrationData(TMR_TagOp_GEN2_IDS_SL900A_Calibration+ }+ + /**+- * Helper funcution to set the calibration Data++ * Helper function to set the calibration Data+ */+ TMR_Status+ TMR_init_GEN2_IDS_SL900A_CalibrationData(uint8_t byte[7], TMR_TagOp_GEN2_IDS_SL900A_CalibrationData *cal)+@@ -3249,7 +3249,7 @@ TMR_init_GEN2_IDS_SL900A_CalibrationData(uint8_t byte[7], TMR_TagOp_GEN2_IDS_SL9+ }+ + /**+- * Helper funcution to set the sfe parameters++ * Helper function to set the sfe parameters+ */+ TMR_Status+ TMR_init_GEN2_IDS_SL900A_SfeParameters(uint8_t byte[2], TMR_TagOp_GEN2_IDS_SL900A_SfeParameters *sfe)+diff --git a/tm_reader.h b/tm_reader.h+index 559c0c5..49630cf 100644+--- a/tm_reader.h++++ b/tm_reader.h+@@ -130,9 +130,9 @@ typedef enum TMR_Reader_StatsFlag+ TMR_READER_STATS_FLAG_RF_ON_TIME = (1 << 0),+ /** Noise floor with the TX on for the antennas were last configured for searching */+ TMR_READER_STATS_FLAG_NOISE_FLOOR_SEARCH_RX_TX_WITH_TX_ON = (1 << 6),+- /** Current frequency in uints of Khz */++ /** Current frequency in units of Khz */+ TMR_READER_STATS_FLAG_FREQUENCY = (1 << 7),+- /** Current temperature of the device in units of Celcius */++ /** Current temperature of the device in units of Celsius */+ TMR_READER_STATS_FLAG_TEMPERATURE = (1 << 8),+ /** Current antenna */+ TMR_READER_STATS_FLAG_ANTENNA_PORTS = (1 << 9),+@@ -381,7 +381,7 @@ struct TMR_Reader+ bool isStopNTags;+ /* Param wait indicator for Reader and protocol param control during continuous read */+ bool paramWait;+- /* Param responsefor Reader and protocol param control during continuous read */++ /* Param response for Reader and protocol param control during continuous read */+ uint8_t paramMessage[256];+ /* True Continuous Read Start indicator */+ bool hasContinuousReadStarted;+@@ -1013,7 +1013,7 @@ TMR_Param TMR_paramID(const char *name);+ * @ingroup reader+ * + * Add a listener to the list of functions that will be called for+- * each message sent to or recieved from the reader.++ * each message sent to or received from the reader.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+@@ -1027,7 +1027,7 @@ TMR_Status TMR_addTransportListener(TMR_Reader *reader, TMR_TransportListenerBlo+ * @ingroup reader+ * + * Remove a listener from the list of functions that will be called+- * for each message sent to or recieved from the reader.++ * for each message sent to or received from the reader.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+@@ -1179,9 +1179,9 @@ TMR_Status TMR_stopReading(struct TMR_Reader *reader);+ + /**+ * @ingroup reader+- * Stores the transport init function againest the provided scheme.++ * Stores the transport init function against the provided scheme.+ *+- * @param scheme the transport schme name.++ * @param scheme the transport scheme name.+ * @param nativeInit reference to the init function.+ */ + TMR_Status TMR_setSerialTransport(char* scheme, TMR_TransportNativeInit nativeInit);+@@ -1197,14 +1197,14 @@ const char *TMR_strerr(TMR_Reader *reader, TMR_Status status);+ + /**+ * @ingroup reader+- * This funcution will initialize the++ * This function will initialize the+ * TMR_StatValues structure with the default values+ */+ TMR_Status TMR_STATS_init(TMR_Reader_StatsValues *stats);+ + /**+ * @ingroup reader+- * This funcution loads the reader configuration parameters from file and applies to module.++ * This function loads the reader configuration parameters from file and applies to module.+ *+ * @param reader The reader to operate on.+ * @param filePath load reader configurations from filepath.+@@ -1213,7 +1213,7 @@ TMR_Status TMR_loadConfig(struct TMR_Reader *reader, char *filePath);+ + /**+ * @ingroup reader+- * This funcution saves the current reader configuration parameters and its values to a file.++ * This function saves the current reader configuration parameters and its values to a file.+ *+ * @param reader The reader to operate on.+ * @param filePath save reader configurations from filepath.+diff --git a/tmr_gen2.h b/tmr_gen2.h+index 311ad27..9696f61 100644+--- a/tmr_gen2.h++++ b/tmr_gen2.h+@@ -135,7 +135,7 @@ typedef struct TMR_GEN2_Select+ bool invert;+ /** The memory bank in which to compare the mask */+ TMR_GEN2_Bank bank;+- /** The location (in bits) at which t to begin comparing the mask */++ /** The location (in bits) at which to begin comparing the mask */+ uint32_t bitPointer;+ /** The length (in bits) of the mask */+ uint16_t maskBitLength;+diff --git a/tmr_params.h b/tmr_params.h+index 581c5d2..d48c9bc 100644+--- a/tmr_params.h++++ b/tmr_params.h+@@ -67,7 +67,7 @@ typedef enum TMR_Param+ TMR_PARAM_ANTENNA_PORTSWITCHGPOS,+ /** "/reader/antenna/settlingTimeList", TMR_PortValueList */+ TMR_PARAM_ANTENNA_SETTLINGTIMELIST,+- /** "reader/antenna/returnLoss", TMR_PortValueList */++ /** "/reader/antenna/returnLoss", TMR_PortValueList */+ TMR_PARAM_ANTENNA_RETURNLOSS,+ /** "/reader/antenna/txRxMap", TMR_AntennaMapList */+ TMR_PARAM_ANTENNA_TXRXMAP,+@@ -85,15 +85,15 @@ typedef enum TMR_Param+ TMR_PARAM_GEN2_SESSION,+ /** "/reader/gen2/target", TMR_GEN2_Target */+ TMR_PARAM_GEN2_TARGET,+- /** "/reader/gen2/BLF", TMR_Gen2_LinkFrequency */++ /** "/reader/gen2/BLF", TMR_GEN2_LinkFrequency */+ TMR_PARAM_GEN2_BLF,+- /** "/reader/gen2/tari", TMR_Gen2_Tari */++ /** "/reader/gen2/tari", TMR_GEN2_Tari */+ TMR_PARAM_GEN2_TARI,+- /**"/reader/gen2/writeMode", TMR_Gen2_WriteMode*/++ /**"/reader/gen2/writeMode", TMR_GEN2_WriteMode */+ TMR_PARAM_GEN2_WRITEMODE,+- /** "/reader/gen2/bap", TMR_Gen2_Bap */++ /** "/reader/gen2/bap", TMR_GEN2_Bap */+ TMR_PARAM_GEN2_BAP,+- /** "/reader/gen2/protocolExtension", TMR_PARAM_GEN2_PROTOCOLEXTENSION */++ /** "/reader/gen2/protocolExtension", TMR_GEN2_ProtocolExtension */+ TMR_PARAM_GEN2_PROTOCOLEXTENSION,+ /** "/reader/iso180006b/BLF", TMR_ISO180006B_LinkFrequency */+ TMR_PARAM_ISO180006B_BLF,+@@ -107,7 +107,7 @@ typedef enum TMR_Param+ TMR_PARAM_READ_ASYNCONTIME,+ /** "/reader/read/plan", TMR_ReadPlan */+ TMR_PARAM_READ_PLAN,+- /** "/reader/radio/enablePowerSave, bool **/++ /** "/reader/radio/enablePowerSave", bool **/+ TMR_PARAM_RADIO_ENABLEPOWERSAVE,+ /** "/reader/radio/powerMax", int16_t */+ TMR_PARAM_RADIO_POWERMAX,+@@ -165,7 +165,7 @@ typedef enum TMR_Param+ TMR_PARAM_EXTENDEDEPC,+ /** "/reader/statistics", TMR_SR_ReaderStatistics */+ TMR_PARAM_READER_STATISTICS,+- /** "/reader/stats", TMR_ */++ /** "/reader/stats", TMR_Reader_StatsValues */+ TMR_PARAM_READER_STATS,+ /** "/reader/uri", TMR_String */+ TMR_PARAM_URI,+@@ -193,7 +193,7 @@ typedef enum TMR_Param+ TMR_PARAM_TAGREADDATA_UNIQUEBYPROTOCOL,+ /** "/reader/description", TMR_String */+ TMR_PARAM_READER_DESCRIPTION,+- /** "reader/hostname", TMR_String */++ /** "/reader/hostname", TMR_String */+ TMR_PARAM_READER_HOSTNAME,+ /** "/reader/currentTime", struct tm */+ TMR_PARAM_CURRENTTIME,+@@ -201,12 +201,13 @@ typedef enum TMR_Param+ TMR_PARAM_READER_WRITE_REPLY_TIMEOUT,+ /** "/reader/gen2/writeEarlyExit", bool */+ TMR_PARAM_READER_WRITE_EARLY_EXIT,+- /** "reader/stats/enable", TMR_StatsEnable */++ /** "/reader/stats/enable", TMR_StatsEnable */+ TMR_PARAM_READER_STATS_ENABLE,+ /** "/reader/trigger/read/Gpi", TMR_uint8List */+ TMR_PARAM_TRIGGER_READ_GPI,+ /** "/reader/metadataflags", TMR_TRD_MetadataFlag*/+ TMR_PARAM_METADATAFLAG,++ /** "/reader/licensedFeatures", TMR_uint8List */+ TMR_PARAM_LICENSED_FEATURES,+ TMR_PARAM_SELECTED_PROTOCOLS,+ TMR_PARAM_END,+diff --git a/tmr_serial_reader.h b/tmr_serial_reader.h+index b246277..bca3fe9 100644+--- a/tmr_serial_reader.h++++ b/tmr_serial_reader.h+@@ -169,7 +169,7 @@ typedef struct TMR_SR_GEN2_Q+ } TMR_SR_GEN2_Q;+ + +-/** An antenna port with an associated uint16_t value. */++/** An antenna port with an associated int32_t value. */+ typedef struct TMR_PortValue+ {+ /** The port number */+@@ -309,7 +309,7 @@ typedef struct TM_SR_SerialReader+ int tagsRemaining;+ /* Buffer tag records fetched from module but not yet passed to caller. */+ uint8_t bufResponse[TMR_SR_MAX_PACKET_SIZE];+- /* bufResopnse read index */++ /* bufResponse read index */+ uint8_t bufPointer;+ /* Number of tag records in buffer but not yet passed to caller */+ uint8_t tagsRemainingInBuffer;+diff --git a/tmr_serial_transport.h b/tmr_serial_transport.h+index c618d1e..290cf23 100644+--- a/tmr_serial_transport.h++++ b/tmr_serial_transport.h+@@ -80,7 +80,7 @@ struct TMR_SR_SerialTransport+ /**+ * This callback causes the communication interface to be opened but+ * does not transmit any serial-layer data. This should perform+- * actionms such as opening a serial port device or establishing a++ * actions such as opening a serial port device or establishing a+ * network connection within a wrapper protocol.+ *+ * @param this The TMR_SR_SerialTransport structure.+@@ -109,7 +109,7 @@ struct TMR_SR_SerialTransport+ * @param this The TMR_SR_SerialTransport structure.+ * @param length The number of bytes to receive.+ * @param[out] messageLength The number of bytes received.+- * @param[out] message Pointer to the location to store recieved bytes.++ * @param[out] message Pointer to the location to store received bytes.+ * @param timeoutMs The duration for the operation to complete.+ */+ TMR_Status (*receiveBytes)(TMR_SR_SerialTransport *, uint32_t length,+diff --git a/tmr_status.h b/tmr_status.h+index 50ccc16..2832184 100644+--- a/tmr_status.h++++ b/tmr_status.h+@@ -78,7 +78,7 @@ typedef uint32_t TMR_Status;+ #define TMR_ERROR_INVALID_BAUD_RATE TMR_ERROR_CODE(0x10a)+ /**Region is not supported. */+ #define TMR_ERROR_INVALID_REGION TMR_ERROR_CODE(0x10b)+-/** License key code in invalid */++/** License key code is invalid */+ #define TMR_ERROR_INVALID_LICENSE_KEY TMR_ERROR_CODE(0x10c)+ /**Firmware is corrupt: Checksum doesn't match content. */+ #define TMR_ERROR_BL_INVALID_IMAGE_CRC TMR_ERROR_CODE(0x200)+@@ -137,10 +137,10 @@ typedef uint32_t TMR_Status;+ /**Internal reader error. Contact support. */+ #define TMR_ERROR_GEN2_PROTOCOL_MEMORY_OVERRUN_BAD_PC TMR_ERROR_CODE(0x423)+ /**Internal reader error. Contact support. */+-#define TMR_ERROR_GEN2_PROCOCOL_MEMORY_LOCKED TMR_ERROR_CODE(0x424)++#define TMR_ERROR_GEN2_PROTOCOL_MEMORY_LOCKED TMR_ERROR_CODE(0x424)+ /**Authentication failed with specified key. */+ #define TMR_ERROR_GEN2_PROTOCOL_V2_AUTHEN_FAILED TMR_ERROR_CODE(0x425)+-/** Untrace opearation failed. */++/** Untrace operation failed. */+ #define TMR_ERROR_GEN2_PROTOCOL_V2_UNTRACE_FAILED TMR_ERROR_CODE(0x426)+ /**Internal reader error. Contact support. */+ #define TMR_ERROR_GEN2_PROTOCOL_INSUFFICIENT_POWER TMR_ERROR_CODE(0x42b)+diff --git a/tmr_strerror.c b/tmr_strerror.c+index 211695c..4540a5a 100644+--- a/tmr_strerror.c++++ b/tmr_strerror.c+@@ -174,7 +174,7 @@ TMR_strerr(TMR_Reader *reader, TMR_Status status)+ return "Other Gen2 error";+ case TMR_ERROR_GEN2_PROTOCOL_MEMORY_OVERRUN_BAD_PC:+ return "Gen2 memory overrun - bad PC";+- case TMR_ERROR_GEN2_PROCOCOL_MEMORY_LOCKED:\++ case TMR_ERROR_GEN2_PROTOCOL_MEMORY_LOCKED:+ return "Gen2 memory locked";+ case TMR_ERROR_GEN2_PROTOCOL_INSUFFICIENT_POWER:+ return "Gen2 tag has insufficent power for operation";+@@ -185,7 +185,7 @@ TMR_strerr(TMR_Reader *reader, TMR_Status status)+ case TMR_ERROR_GEN2_PROTOCOL_V2_AUTHEN_FAILED:+ return "Authentication failed with specified key.";+ case TMR_ERROR_GEN2_PROTOCOL_V2_UNTRACE_FAILED:+- return "Untrace opearation failed.";++ return "Untrace operation failed.";+ case TMR_ERROR_AHAL_INVALID_FREQ:+ return "Invalid frequency";+ case TMR_ERROR_AHAL_CHANNEL_OCCUPIED:+diff --git a/tmr_tag_data.h b/tmr_tag_data.h+index 2f1ad8e..be42c53 100644+--- a/tmr_tag_data.h++++ b/tmr_tag_data.h+@@ -140,7 +140,7 @@ typedef struct TMR_TagReadData+ uint8_t gpioCount;+ /** Number of times the tag was read */+ uint32_t readCount;+- /** Strength of the signal recieved from the tag */++ /** Strength of the signal received from the tag */+ int32_t rssi;+ /** RF carrier frequency the tag was read with */+ uint32_t frequency;+diff --git a/tmr_tag_protocol.h b/tmr_tag_protocol.h+index 1c47fce..da5b267 100644+--- a/tmr_tag_protocol.h++++ b/tmr_tag_protocol.h+@@ -67,4 +67,4 @@ typedef struct TMR_TagProtocolList+ #endif+ + +-#endif /* _TMR_TAG_PROTOCL_H_ */++#endif /* _TMR_TAG_PROTOCOL_H_ */+diff --git a/tmr_tagop.h b/tmr_tagop.h+index eb92f85..7b22248 100644+--- a/tmr_tagop.h++++ b/tmr_tagop.h+@@ -363,7 +363,7 @@ typedef struct SecurePasswordLookup+ + typedef struct TMR_TagOp_GEN2_SecureReadData+ {+- /** Gen2 read opearation */++ /** Gen2 read operation */+ TMR_TagOp_GEN2_ReadData readData;+ + /** type of Gen2 Secure operation*/+@@ -1291,7 +1291,7 @@ typedef struct TMR_TagOp_GEN2_IDS_SL900A_Initialize+ Delay delayTime;+ }TMR_TagOp_GEN2_IDS_SL900A_Initialize;+ +-/** Sub-Class for specifying AccessFifo opearation */++/** Sub-Class for specifying AccessFifo operation */+ typedef enum AccessFifoOperation+ {+ /* Read from FIFO */+@@ -1312,7 +1312,7 @@ typedef struct TMR_TagOp_GEN2_IDS_SL900A_AccessFifo+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+- /* specify the opearationn do be done on fifo */++ /* specify the operation do be done on fifo */+ AccessFifoOperation operation;+ }TMR_TagOp_GEN2_IDS_SL900A_AccessFifo;+
+ cbits/api/patches/windows-time.patch view
@@ -0,0 +1,55 @@+diff --git a/osdep_win32.c b/osdep_win32.c+index ba65bfa..4ea7603 100644+--- a/osdep_win32.c++++ b/osdep_win32.c+@@ -31,8 +31,8 @@+ #include <time.h>+ #include "osdep.h"+ +-/* FILETIME of Jan 1 1970 00:00:00. */+-static const unsigned __int64 epoch = ((unsigned __int64) 116444736000000000ULL);++// https://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux++#define SEC_TO_UNIX_EPOCH 11644473600LL+ + uint64_t+ tmr_gettime()+@@ -41,35 +41,25 @@ tmr_gettime()+ SYSTEMTIME st;+ FILETIME ft;+ LARGE_INTEGER li; +- struct timeval tv;+ GetSystemTime(&st);+ SystemTimeToFileTime(&st, &ft);+ li.LowPart = ft.dwLowDateTime;+ li.HighPart = ft.dwHighDateTime;+- tv.tv_sec = (long) ((li.QuadPart - epoch) / 10000000L);+- tv.tv_usec =(long) (st.wMilliseconds * 1000);+- totalms = (((uint64_t)tv.tv_sec) * 1000) + ((uint64_t) tv.tv_usec) / 1000;++ totalms=(((uint64_t)li.LowPart) | ((uint64_t)li.HighPart)<<32)/10000;++ totalms -= SEC_TO_UNIX_EPOCH * 1000;+ return totalms;+ }+ + uint32_t+ tmr_gettime_low()+ {+- SYSTEMTIME st;+- FILETIME ft;+- GetSystemTime(&st);+- SystemTimeToFileTime(&st, &ft);+- return ft.dwLowDateTime;++ return (uint32_t) tmr_gettime();+ }+ + uint32_t+ tmr_gettime_high()+ {+- SYSTEMTIME st;+- FILETIME ft;+- GetSystemTime(&st);+- SystemTimeToFileTime(&st, &ft);+- return ft.dwHighDateTime;++ return (uint32_t) (tmr_gettime() >> 32);+ }+ + void
+ cbits/api/serial_reader.c view
@@ -0,0 +1,6169 @@+/**+ * @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 */
+ cbits/api/serial_reader_imp.h view
@@ -0,0 +1,1011 @@+#ifndef _SERIAL_READER_IMP_H+#define _SERIAL_READER_IMP_H++/**+ * @file serial_reader_imp.h+ * @brief Serial reader internal implementation header+ * @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 "tm_reader.h"+#include "tmr_status.h"++#ifdef __cplusplus+extern "C" {+#endif++ +/* This is used to enable the Gen2 secure readdata option */++#ifndef BARE_METAL+ extern bool isSecureAccessEnabled ;+#else+ static bool isSecureAccessEnabled; +#endif++typedef enum TMR_SR_OpCode+{+ TMR_SR_OPCODE_WRITE_FLASH = 0x01,+ TMR_SR_OPCODE_READ_FLASH = 0x02,+ TMR_SR_OPCODE_VERSION = 0x03,+ TMR_SR_OPCODE_BOOT_FIRMWARE = 0x04,+ TMR_SR_OPCODE_SET_BAUD_RATE = 0x06,+ TMR_SR_OPCODE_ERASE_FLASH = 0x07,+ TMR_SR_OPCODE_VERIFY_IMAGE_CRC = 0x08,+ TMR_SR_OPCODE_BOOT_BOOTLOADER = 0x09,+ TMR_SR_OPCODE_HW_VERSION = 0x10,+ TMR_SR_OPCODE_MODIFY_FLASH = 0x0A,+ TMR_SR_OPCODE_GET_DSP_SILICON_ID = 0x0B,+ TMR_SR_OPCODE_GET_CURRENT_PROGRAM = 0x0C,+ TMR_SR_OPCODE_WRITE_FLASH_SECTOR = 0x0D,+ TMR_SR_OPCODE_GET_SECTOR_SIZE = 0x0E,+ TMR_SR_OPCODE_MODIFY_FLASH_SECTOR = 0x0F,+ TMR_SR_OPCODE_READ_TAG_ID_SINGLE = 0x21,+ TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE = 0x22,+ TMR_SR_OPCODE_WRITE_TAG_ID = 0x23,+ TMR_SR_OPCODE_WRITE_TAG_DATA = 0x24,+ TMR_SR_OPCODE_LOCK_TAG = 0x25,+ TMR_SR_OPCODE_KILL_TAG = 0x26,+ TMR_SR_OPCODE_READ_TAG_DATA = 0x28,+ TMR_SR_OPCODE_GET_TAG_ID_BUFFER = 0x29,+ TMR_SR_OPCODE_CLEAR_TAG_ID_BUFFER = 0x2A,+ TMR_SR_OPCODE_WRITE_TAG_SPECIFIC = 0x2D,+ TMR_SR_OPCODE_ERASE_BLOCK_TAG_SPECIFIC= 0x2E,+ TMR_SR_OPCODE_MULTI_PROTOCOL_TAG_OP = 0x2F,+ TMR_SR_OPCODE_GET_ANTENNA_PORT = 0x61,+ TMR_SR_OPCODE_GET_READ_TX_POWER = 0x62,+ TMR_SR_OPCODE_GET_TAG_PROTOCOL = 0x63,+ TMR_SR_OPCODE_GET_WRITE_TX_POWER = 0x64,+ TMR_SR_OPCODE_GET_FREQ_HOP_TABLE = 0x65,+ TMR_SR_OPCODE_GET_USER_GPIO_INPUTS = 0x66,+ TMR_SR_OPCODE_GET_REGION = 0x67,+ TMR_SR_OPCODE_GET_POWER_MODE = 0x68,+ TMR_SR_OPCODE_GET_USER_MODE = 0x69,+ TMR_SR_OPCODE_GET_READER_OPTIONAL_PARAMS=0x6A,+ TMR_SR_OPCODE_GET_PROTOCOL_PARAM = 0x6B,+ TMR_SR_OPCODE_GET_READER_STATS = 0x6C,+ TMR_SR_OPCODE_GET_USER_PROFILE = 0x6D,+ TMR_SR_OPCODE_GET_AVAILABLE_PROTOCOLS = 0x70,+ TMR_SR_OPCODE_GET_AVAILABLE_REGIONS = 0x71,+ TMR_SR_OPCODE_GET_TEMPERATURE = 0x72,+ TMR_SR_OPCODE_SET_ANTENNA_PORT = 0x91,+ TMR_SR_OPCODE_SET_READ_TX_POWER = 0x92,+ TMR_SR_OPCODE_SET_TAG_PROTOCOL = 0x93,+ TMR_SR_OPCODE_SET_WRITE_TX_POWER = 0x94,+ TMR_SR_OPCODE_SET_FREQ_HOP_TABLE = 0x95,+ TMR_SR_OPCODE_SET_USER_GPIO_OUTPUTS = 0x96,+ TMR_SR_OPCODE_SET_REGION = 0x97,+ TMR_SR_OPCODE_SET_POWER_MODE = 0x98,+ TMR_SR_OPCODE_SET_USER_MODE = 0x99,+ TMR_SR_OPCODE_SET_READER_OPTIONAL_PARAMS=0x9a,+ TMR_SR_OPCODE_SET_PROTOCOL_PARAM = 0x9B,+ TMR_SR_OPCODE_SET_USER_PROFILE = 0x9D,+ TMR_SR_OPCODE_SET_PROTOCOL_LICENSEKEY = 0x9E,+ TMR_SR_OPCODE_SET_OPERATING_FREQ = 0xC1,+ TMR_SR_OPCODE_TX_CW_SIGNAL = 0xC3,+}TMR_SR_OpCode;++typedef enum TMR_SR_Gen2SingulationOptions+{+ TMR_SR_GEN2_SINGULATION_OPTION_SELECT_DISABLED = 0x00,+ TMR_SR_GEN2_SINGULATION_OPTION_SELECT_ON_EPC = 0x01,+ TMR_SR_GEN2_SINGULATION_OPTION_SELECT_ON_TID = 0x02,+ TMR_SR_GEN2_SINGULATION_OPTION_SELECT_ON_USER_MEM = 0x03,+ TMR_SR_GEN2_SINGULATION_OPTION_SELECT_ON_ADDRESSED_EPC = 0x04,+ TMR_SR_GEN2_SINGULATION_OPTION_USE_PASSWORD = 0x05,+ TMR_SR_GEN2_SINGULATION_OPTION_SELECT_ON_LENGTH_OF_EPC = 0x06,+ TMR_SR_GEN2_SINGULATION_OPTION_SELECT_GEN2TRUNCATE = 0x07,+ TMR_SR_GEN2_SINGULATION_OPTION_INVERSE_SELECT_BIT = 0x08,+ TMR_SR_GEN2_SINGULATION_OPTION_FLAG_METADATA = 0x10,+ TMR_SR_GEN2_SINGULATION_OPTION_EXTENDED_DATA_LENGTH = 0x20,+ TMR_SR_GEN2_SINGULATION_OPTION_SECURE_READ_DATA = 0x40+}TMR_SR_Gen2SingulationOptions;++typedef enum TMR_SR_TagidOption+{+ TMR_SR_TAG_ID_OPTION_NONE = 0x00,+ TMR_SR_TAG_ID_OPTION_REWIND = 0x01+}TMR_SR_TagidOption;++typedef enum TMR_SR_ModelHardwareID+{+ TMR_SR_MODEL_M5E = 0x00,+ TMR_SR_MODEL_M5E_COMPACT = 0x01,+ TMR_SR_MODEL_M5E_I = 0x02,+ TMR_SR_MODEL_M4E = 0x03,+ TMR_SR_MODEL_M6E = 0x18,+ TMR_SR_MODEL_M6E_I = 0x19,+ TMR_SR_MODEL_MICRO = 0x20,+ TMR_SR_MODEL_M6E_NANO = 0x30,+ TMR_SR_MODEL_UNKNOWN = 0xFF,+} TMR_SR_ModelHardwareID;++typedef enum TMR_SR_ModelMicro+{+ TMR_SR_MODEL_M6E_MICRO = 0x01,+ TMR_SR_MODEL_M6E_MICRO_USB = 0x02,+ TMR_SR_MODEL_M6E_MICRO_USB_PRO = 0x03,+}TMR_SR_ModelMicro;++typedef enum TMR_SR_ModelM6E_I+{+ TMR_SR_MODEL_M6E_I_REV1 = 0x01,+ TMR_SR_MODEL_M6E_I_PRC = 0x02,+ TMR_SR_MODEL_M6E_I_JIC = 0x03,+}TMR_SR_ModelM6E_I;++typedef enum TMR_SR_ModelM5EInternational+{+ TMR_SR_MODEL_M5E_I_REV_EU = 0x01,+ TMR_SR_MODEL_M5E_I_REV_NA = 0x02,+ TMR_SR_MODEL_M5E_I_REV_JP = 0x03,+ TMR_SR_MODEL_M5E_I_REV_PRC = 0x04,+}TMR_SR_ModelM5EInternational;++typedef enum TMR_SR_ProductGroupID+{+ TMR_SR_PRODUCT_MODULE = 0,+ TMR_SR_PRODUCT_RUGGEDIZED_READER = 1,+ TMR_SR_PRODUCT_USB_READER = 2,+ TMR_SR_PRODUCT_INVALID = 0xFFFF,+}TMR_SR_ProductGroupID;++TMR_Status TMR_SR_sendTimeout(TMR_Reader *reader, uint8_t *data,+ uint32_t timeoutMs);+TMR_Status TMR_SR_send(TMR_Reader *reader, uint8_t *data);+TMR_Status TMR_SR_sendMessage(TMR_Reader *reader, uint8_t *data,+ uint8_t *opcode, uint32_t timeoutMs);+TMR_Status TMR_SR_receiveMessage(TMR_Reader *reader, uint8_t *data,+ uint8_t opcode, uint32_t timeoutMs);+TMR_Status TMR_SR_receiveAutonomousReading(struct TMR_Reader *reader, TMR_TagReadData *trd, TMR_Reader_StatsValues *stats);++void TMR_SR_parseMetadataFromMessage(TMR_Reader *reader, TMR_TagReadData *read, uint16_t flags,+ uint8_t *i, uint8_t msg[]);++void+TMR_SR_parseMetadataOnly(TMR_Reader *reader, TMR_TagReadData *read, uint16_t flags,+ uint8_t *i, uint8_t msg[]);+void TMR_SR_postprocessReaderSpecificMetadata(TMR_TagReadData *read,+ TMR_SR_SerialReader *sr);+bool isContinuousReadParamSupported(TMR_Reader *reader);++/**+ * This structure is returned from read tag multiple embedded commands.+ */+typedef struct TMR_SR_MultipleStatus+{+ /** The number of tags found during the read. */+ uint16_t tagsFound;+ /** The number of tags for which the embedded operation succeeded. */+ uint16_t successCount;+ /** The number of tags for which the embedded operation failed. */+ uint16_t failureCount;+}TMR_SR_MultipleStatus;++/**+ * This structure is returned from TMR_SR_cmdGetTxRxPorts and+ * TMR_SR_cmdGetAntennaSearchList, and passed as a parameter to+ * TMR_SR_cmdSetAntennaSearchList.+ */+typedef struct TMR_SR_PortPair+{+ /** The transmit port. */+ uint8_t txPort;+ /** The receive port. */+ uint8_t rxPort;+}TMR_SR_PortPair;++/**+ * This structure is returned from TMR_SR_cmdAntennaDetect.+ */+typedef struct TMR_SR_PortDetect+{+ /** The port number. */+ uint8_t port;+ /** Whether an antenna was detected on the port. */+ bool detected;+}TMR_SR_PortDetect;++/**+ * Reader statistics options enum+ */ +typedef enum TMR_SR_ReaderStatsOption+{+ /* Get statistics specified by the statistics flag */+ TMR_SR_READER_STATS_OPTION_GET= 0x00,+ /* Reset the specified statistic */+ TMR_SR_READER_STATS_OPTION_RESET= 0x01,+ /* Get the per-port statistics specified by the statistics flag*/+ TMR_SR_READER_STATS_OPTION_GET_PER_PORT = 0x02,+}TMR_SR_ReaderStatsOption;+ ++/**+ * Reader Statistics Flag Enum+ */+typedef enum TMR_SR_ReaderStatisticsFlag+{+ /* Total time the port has been transmitting, in milliseconds. Resettable */+ TMR_SR_READER_STATS_FLAG_RF_ON_TIME = (1<<0),+ /* Detected noise floor with transmitter off. Recomputed when requested, not resettable.*/+ TMR_SR_READER_STATS_FLAG_NOISE_FLOOR = (1<<1),+ /* Detected noise floor with transmitter on. Recomputed when requested, not resettable. */+ TMR_SR_READER_STATS_FLAG_NOISE_FLOOR_TX_ON = (1<<3),+ /* ALL */+ TMR_SR_READER_STATS_ALL = (TMR_SR_READER_STATS_FLAG_RF_ON_TIME | + TMR_SR_READER_STATS_FLAG_NOISE_FLOOR |+ TMR_SR_READER_STATS_FLAG_NOISE_FLOOR_TX_ON),+}TMR_SR_ReaderStatisticsFlag;++/**+ * Antenna Configuration. Returned by TMR_SR_cmdGetAntennaConfiguration.+ */+typedef struct TMR_SR_AntennaPort+{+ /** The number of physical antenna ports. */+ uint8_t numPorts;+ /** The current logical Transmit port. */+ uint8_t txPort;+ /** The current logical Recieve port. */+ uint8_t rxPort;+ /** List specifying what ports are terminated. */+ TMR_uint8List portTerminatedList;+}TMR_SR_AntennaPort;++/** Per-port power levels. Used by TMR_SR_cmd{Get,Set}AntennaPortPowers */+typedef struct TMR_SR_PortPower+{+ /** The port number. */+ uint8_t port;+ /** The power level to use for read operations, in centidBm. */+ uint16_t readPower;+ /** The power level to use for write operations, in centidBm. */+ uint16_t writePower;+} TMR_SR_PortPower;++/**+ * Per-port power levels and settling times. Used by+ * TMR_SR_cmd{Get,Set}AntennaPortPowersAndSettlingTime.+ */+typedef struct TMR_SR_PortPowerAndSettlingTime+{+ /** The port number. */+ uint8_t port;+ /** The power level to use for read operations, in centidBm. */+ int16_t readPower;+ /** The power level to use for write operations, in centidBm. */+ int16_t writePower;+ /** The duration to wait after switching to this port, in microseconds. */+ uint16_t settlingTime;+} TMR_SR_PortPowerAndSettlingTime;++/** The current power level and the bounds of the power level range. */+typedef struct TMR_SR_PowerWithLimits+{+ /** The current power level, in centidBm. */+ uint16_t setPower;+ /** The maximum power level, in centidBm. */+ uint16_t maxPower;+ /** The minimum power level, in centidBm. */+ uint16_t minPower;+} TMR_SR_PowerWithLimits;+++void TMR_hexDottedQuad(const uint8_t bytes[4], char buf[12]);+TMR_Status TMR_hexDottedQuadToUint32(const char bytes[12], uint32_t *result);+++/**+ * This type enumerates the serial reader configuration parameters for+ * TMR_SR_cmdSetReaderConfiguration and+ * TMR_SR_cmdGetReaderConfiguration. Each value is+ * associated with a particular data type for the setting.+ */+typedef enum TMR_SR_Configuration+{+ /**+ * Key tag buffer records off of antenna ID as well as EPC;+ * i.e., keep separate records for the same EPC read on different antennas+ * 0: Disable -- Different antenna overwrites previous record.+ * 1: Enable -- Different Antenna creates a new record.+ */+ TMR_SR_CONFIGURATION_UNIQUE_BY_ANTENNA = 0,+ /**+ * Run transmitter in lower-performance, power-saving mode.+ * 0: Disable -- Higher transmitter bias for improved reader sensitivity+ * 1: Enable -- Lower transmitter bias sacrifices sensitivity for power consumption+ */+ TMR_SR_CONFIGURATION_TRANSMIT_POWER_SAVE = 1,+ /**+ * Support 496-bit EPCs (vs normal max 96 bits)+ * 0: Disable (max max EPC length = 96)+ * 1: Enable 496-bit EPCs+ */+ TMR_SR_CONFIGURATION_EXTENDED_EPC = 2,+ /**+ * Configure GPOs to drive antenna switch.+ * 0: No switch+ * 1: Switch on GPO1+ * 2: Switch on GPO2+ * 3: Switch on GPO1,GPO2+ */+ TMR_SR_CONFIGURATION_ANTENNA_CONTROL_GPIO = 3,+ /**+ * Refuse to transmit if antenna is not detected+ */+ TMR_SR_CONFIGURATION_SAFETY_ANTENNA_CHECK = 4,+ /**+ * Refuse to transmit if overtemperature condition detected+ */+ TMR_SR_CONFIGURATION_SAFETY_TEMPERATURE_CHECK = 5,+ /**+ * If tag read duplicates an existing tag buffer record (key is the same),+ * update the record's timestamp if incoming read has higher RSSI reading.+ * 0: Keep timestamp of record's first read+ * 1: Keep timestamp of read with highest RSSI+ */+ TMR_SR_CONFIGURATION_RECORD_HIGHEST_RSSI = 6,+ /**+ * Key tag buffer records off tag data as well as EPC;+ * i.e., keep separate records for the same EPC read with different data+ * 0: Disable -- Different data overwrites previous record.+ * 1: Enable -- Different data creates new record.+ */+ TMR_SR_CONFIGURATION_UNIQUE_BY_DATA = 8,+ /**+ * Whether RSSI values are reported in dBm, as opposed to+ * arbitrary uncalibrated units.+ */+ TMR_SR_CONFIGURATION_RSSI_IN_DBM = 9,+ /**+ * Self jammer cancellation+ * User can enable/disable through level2 API+ */+ TMR_SR_CONFIGURATION_SELF_JAMMER_CANCELLATION = 0x0A,+ /**+ * Key tag buffer records off of protocol as well as EPC;+ * i.e., keep separate records for the same EPC read on different protocols+ * 0: Disable -- Different protocol overwrites previous record.+ * 1: Enable -- Different protocol creates a new record.+ */+ TMR_SR_CONFIGURATION_UNIQUE_BY_PROTOCOL = 0x0B,+ /**+ * Enable read filtering+ */+ TMR_SR_CONFIGURATION_ENABLE_READ_FILTER = 0x0C,+ /**+ * Tag buffer entry timeout+ */+ TMR_SR_CONFIGURATION_READ_FILTER_TIMEOUT = 0x0D,+ /**+ * Transport (bus) type+ **/ + TMR_SR_CONFIGURATION_CURRENT_MSG_TRANSPORT = 0x0E,+ /**+ * Enable the CRC calculation+ */+ TMR_SR_CONFIGURATION_SEND_CRC = 0x1B,+ /**+ * General category of finished reader into which module is integrated; e.g.,+ * 0: bare module+ * 1: In-vehicle Reader (e.g., Tool Link, Vega)+ * 2: USB Reader+ */+ TMR_SR_CONFIGURATION_PRODUCT_GROUP_ID = 0x12,+ /**+ * Product ID (Group ID 0x0002 ) information+ * 0x0001 :M5e-C USB reader+ * 0x0002 :Backback NA antenna+ * 0x0003 :Backback EU antenna+ **/+ TMR_SR_CONFIGURATION_PRODUCT_ID = 0x13,+ /**+ * Configure GPIs to drive trigger read.+ * 0: No switch+ * 1: Switch on GPI1+ * 2: Switch on GPI2+ * 3: Switch on GPI3 (if supported)+ * 4: Switch on GOI4 (if supported)+ */+ TMR_SR_CONFIGURATION_TRIGGER_READ_GPIO = 0x1E,+} TMR_SR_Configuration;+++/**+ * This type enumerates the region configuration parameters for+ * the TMR_SR_cmdGetRegionConfiguration() command.+ */+typedef enum TMR_SR_RegionConfiguration+{+ TMR_SR_REGION_CONFIGURATION_LBT_ENABLED = 0x40,+} TMR_SR_RegionConfiguration;++/**+ * This is the enumeration of Gen2-specific configuration values. Each+ * enumerated value is associated with a particular data type for the+ * setting value.+ */+typedef enum TMR_SR_Gen2Configuration+{+ TMR_SR_GEN2_CONFIGURATION_SESSION = 0x00,+ TMR_SR_GEN2_CONFIGURATION_TARGET = 0x01,+ TMR_SR_GEN2_CONFIGURATION_TAGENCODING = 0x02,+ TMR_SR_GEN2_CONFIGURATION_LINKFREQUENCY = 0x10,+ TMR_SR_GEN2_CONFIGURATION_TARI = 0x11,+ TMR_SR_GEN2_CONFIGURATION_Q = 0x12,+ TMR_SR_GEN2_CONFIGURATION_BAP = 0x13,+ TMR_SR_GEN2_CONFIGURATION_PROTCOLEXTENSION = 0x14+} TMR_SR_Gen2Configuration;++/**+ * This struture is retuned from TMR_SR_Gen2ReaderResponseTimeOut+ */+typedef struct TMR_SR_Gen2ReaderWriteTimeOut+{+ /* Status of reader timeout */+ bool earlyexit;++ /* Timeout value used for write operation */+ uint16_t writetimeout;+}TMR_SR_Gen2ReaderWriteTimeOut;+/**+ * This is the enumeration of ISO 18000-6B-specific configuration+ * values. Each enumerated value is associated with a particular data+ * type for the setting value.+ */+typedef enum TMR_SR_Iso180006bConfiguration+{+ TMR_SR_ISO180006B_CONFIGURATION_LINKFREQUENCY = 0x10,+ TMR_SR_ISO180006B_CONFIGURATION_MODULATION_DEPTH = 0x11,+ TMR_SR_ISO180006B_CONFIGURATION_DELIMITER = 0x12+} TMR_SR_Iso180006bConfiguration;++/**+ * This is the enumeration of iPx-specific configuration+ * values. Each enumerated value is associated with a particular data+ * type for the setting value.+ */+typedef enum TMR_SR_iPxConfiguration+{+ TMR_SR_IPX_CONFIGURATION_LINKFREQUENCY = 0x10+} TMR_SR_iPxConfiguration;+++/**+ * This type selects the protocol configuration option for+ * TMR_SR_cmdSetProtocolConfiguration() and+ * TMR_SR_cmdGetProtocolConfiguration(). Each value is associated+ * with a particular data type for the setting.+ */+typedef struct TMR_SR_ProtocolConfiguration+{+ /** The protocol to configure. Determines which union member is valid. */+ TMR_TagProtocol protocol;+ union+ {+ /** The configuration key for a Gen2 option. */+ TMR_SR_Gen2Configuration gen2;+ /** The configuration key for an ISO18000-6B option. */+ TMR_SR_Iso180006bConfiguration iso180006b;+ TMR_SR_iPxConfiguration ipx;+ }u;+} TMR_SR_ProtocolConfiguration;+++/**+ * Defines the values for search flags for TMR_SR_cmdReadTagMultiple.+ */+typedef enum TMR_SR_SearchFlag+{+ TMR_SR_SEARCH_FLAG_CONFIGURED_ANTENNA = 0,+ TMR_SR_SEARCH_FLAG_ANTENNA_1_THEN_2 = 1,+ TMR_SR_SEARCH_FLAG_ANTENNA_2_THEN_1 = 2,+ TMR_SR_SEARCH_FLAG_CONFIGURED_LIST = 3,+ TMR_SR_SEARCH_FLAG_ANTENNA_MASK = 3,+ TMR_SR_SEARCH_FLAG_EMBEDDED_COMMAND = 4,+ TMR_SR_SEARCH_FLAG_TAG_STREAMING = 8,+ TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT = 16,+ TMR_SR_SEARCH_FLAG_STATUS_REPORT_STREAMING = 32,+ TMR_SR_SEARCH_FLAG_RETURN_ON_N_TAGS = 64,+ TMR_SR_SEARCH_FLAG_READ_MULTIPLE_FAST_SEARCH = 128,+ TMR_SR_SEARCH_FLAG_STATS_REPORT_STREAMING = 256,+ TMR_SR_SEARCH_FLAG_GPI_TRIGGER_READ = 512,+ TMR_SR_SEARCH_FLAG_DUTY_CYCLE_CONTROL = 1024,+}TMR_SR_SearchFlag;++typedef enum TMR_SR_ISO180006BCommands+{+ TMR_SR_ISO180006B_COMMAND_DATA_READ = 0x0B,+ TMR_SR_ISO180006B_COMMAND_READ = 0x0C,+ TMR_SR_ISO180006B_COMMAND_WRITE = 0x0D,+ TMR_SR_ISO180006B_COMMAND_WRITE_MULTIPLE = 0x0E,+ TMR_SR_ISO180006B_COMMAND_WRITE4BYTE = 0x1B,+ TMR_SR_ISO180006B_COMMAND_WRITE4BYTE_MULTIPLE = 0x1C,+} TMR_SR_ISO180006BCommands;++typedef enum TMR_SR_ISO180006BCommandOptions+{+ TMR_SR_ISO180006B_WRITE_OPTION_READ_AFTER = 0x00,+ TMR_SR_ISO180006B_WRITE_OPTION_NO_VERIFY = 0x01,+ TMR_SR_ISO180006B_WRITE_OPTION_READ_VERIFY_AFTER = 0x02,+ TMR_SR_ISO180006B_WRITE_OPTION_GROUP_SELECT = 0x03,+ TMR_SR_ISO180006B_WRITE_OPTION_COUNT_PROVIDED = 0x08,+ TMR_SR_ISO180006B_WRITE_LOCK_NO = 0x00,+ TMR_SR_ISO180006B_WRITE_LOCK_YES = 0x01,+ TMR_SR_ISO180006B_LOCK_OPTION_TYPE_FOLLOWS = 0x01,+ TMR_SR_ISO180006B_LOCK_TYPE_QUERYLOCK_THEN_LOCK = 0x01,+} TMR_SR_ISO180006BCommandOptions;++TMR_Status TMR_SR_cmdRaw(TMR_Reader *reader, uint32_t timeout, uint8_t msgLen,+ uint8_t msg[]);+TMR_Status TMR_SR_setSerialBaudRate(TMR_Reader *reader, uint32_t rate);+TMR_Status TMR_SR_cmdVersion(TMR_Reader *reader, TMR_SR_VersionInfo *info);+TMR_Status TMR_SR_cmdBootFirmware(TMR_Reader *reader);+TMR_Status TMR_SR_cmdSetBaudRate(TMR_Reader *reader, uint32_t rate);+TMR_Status TMR_SR_cmdVerifyImage(TMR_Reader *reader, bool *status);+TMR_Status TMR_SR_cmdEraseFlash(TMR_Reader *reader, uint8_t sector, + uint32_t password);+TMR_Status TMR_SR_cmdWriteFlashSector(TMR_Reader *reader, uint8_t sector, + uint32_t address, uint32_t password, uint8_t length,+ const uint8_t data[], uint32_t offset);+TMR_Status TMR_SR_cmdGetSectorSize(TMR_Reader *reader, uint8_t sector,+ uint32_t *size);+TMR_Status TMR_SR_cmdModifyFlashSector(TMR_Reader *reader, uint8_t sector, + uint32_t address, uint32_t password, uint8_t length,+ const uint8_t data[], uint32_t offset);+TMR_Status TMR_SR_cmdBootBootloader(TMR_Reader *reader);+TMR_Status TMR_SR_cmdGetHardwareVersion(TMR_Reader *reader, uint8_t option,+ uint8_t flags, uint8_t* count, uint8_t data[]);+TMR_Status TMR_SR_cmdGetCurrentProgram(TMR_Reader *reader, uint8_t *program);+TMR_Status TMR_SR_cmdReadTagSingle(TMR_Reader *reader, uint16_t timeout, + uint16_t metadataFlags, const TMR_TagFilter *filter, + TMR_TagProtocol protocol, TMR_TagReadData *tagData);+TMR_Status TMR_SR_cmdReadTagMultiple(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_SearchFlag flags, const TMR_TagFilter *filter,+ TMR_TagProtocol protocol, uint32_t *tagCount);+TMR_Status TMR_SR_cmdWriteGen2TagEpc(TMR_Reader *reader, const TMR_TagFilter *filter, TMR_GEN2_Password accessPassword,+ uint16_t timeout, uint8_t count, const uint8_t *id, bool lock);+TMR_Status TMR_SR_cmdGEN2WriteTagData(TMR_Reader *reader,+ uint16_t timeout, TMR_GEN2_Bank bank, uint32_t address,+ uint8_t count, const uint8_t data[],+ TMR_GEN2_Password accessPassword, const TMR_TagFilter *filter);+TMR_Status TMR_SR_cmdGEN2LockTag(TMR_Reader *reader, uint16_t timeout, + uint16_t mask, uint16_t action, TMR_GEN2_Password accessPassword, + const TMR_TagFilter *filter);+TMR_Status TMR_SR_cmdKillTag(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password killPassword, const TMR_TagFilter *filter);+TMR_Status TMR_SR_cmdGEN2ReadTagData(TMR_Reader *reader,+ uint16_t timeout, TMR_GEN2_Bank bank,+ uint32_t address, uint8_t length, uint32_t accessPassword,+ const TMR_TagFilter *filter, TMR_TagReadData *data);+TMR_Status TMR_SR_cmdGetTagsRemaining(TMR_Reader *reader, uint16_t *remaining);+TMR_Status TMR_SR_cmdGetTagBuffer(TMR_Reader *reader, uint16_t count, bool epc496,+ TMR_TagProtocol protocol, TMR_TagData tagData[]);+TMR_Status TMR_SR_cmdClearTagBuffer(TMR_Reader *reader);+TMR_Status TMR_SR_cmdHiggs2PartialLoadImage(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, + uint8_t len, const uint8_t epc[], TMR_TagFilter* target);+TMR_Status TMR_SR_cmdHiggs2FullLoadImage(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword,+ uint16_t lockBits, uint16_t pcWord, uint8_t count,+ const uint8_t epc[], TMR_TagFilter* target);+TMR_Status TMR_SR_cmdHiggs3FastLoadImage(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password currentAccessPassword, + TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword,+ uint16_t pcWord, uint8_t count, const uint8_t epc[], TMR_TagFilter* target);+TMR_Status TMR_SR_cmdHiggs3LoadImage(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword,+ uint16_t pcWord, uint8_t len, const uint8_t epcAndUserData[], TMR_TagFilter* target);+TMR_Status TMR_SR_cmdHiggs3BlockReadLock(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, uint8_t lockBits, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdNxpSetReadProtect(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdNxpResetReadProtect(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdNxpChangeEas(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, bool reset, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdNxpEasAlarm(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_DivideRatio dr, TMR_GEN2_TagEncoding m, TMR_GEN2_TrExt trExt,+ TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdNxpCalibrate(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdNxpChangeConfig(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_NXP_ConfigWord configWord, TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdGen2v2NXPUntraceable(TMR_Reader *reader, uint16_t timeout,TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, uint16_t configWord,+ TMR_TagOp_GEN2_NXP_Untraceable op,TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdGen2v2NXPAuthenticate(TMR_Reader *reader, uint16_t timeout,TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword, TMR_TagOp_GEN2_NXP_Authenticate op, TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdGen2v2NXPReadBuffer(TMR_Reader *reader, uint16_t timeout,TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword, TMR_TagOp_GEN2_NXP_Readbuffer op, TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdMonza4QTReadWrite(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ TMR_Monza4_ControlByte controlByte, TMR_Monza4_Payload payload, TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aGetSensorValue(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, Sensor sensortype, TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aGetMeasurementSetup(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level,TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aGetCalibrationData(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aSetCalibrationData(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint64_t calibration, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aSetSfeParameters(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t sfe, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aGetLogState(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aSetLogMode(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, LoggingForm form, StorageRule rule, bool Ext1Enable,+ bool Ext2Enable, bool TempEnable, bool BattEnable, uint16_t LogInterval, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aSetLogLimit(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t exLower,+ uint16_t lower, uint16_t upper, uint16_t exUpper, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aSetShelfLife(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t block0, uint32_t block1,+ TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aInitialize(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t delayTime,+ uint16_t applicatioData, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aStartLog(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+ uint32_t password, PasswordLevel level, uint32_t time, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aEndLog(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aSetPassword(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t newPassword,+ PasswordLevel newPasswordLevel, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aGetBatteryLevel(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level,BatteryType type,+ TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aAccessFifoStatus(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+ uint32_t password, PasswordLevel level, AccessFifoOperation operation, TMR_uint8List * data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aAccessFifoRead(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+ uint32_t password, PasswordLevel level, AccessFifoOperation operation, uint8_t length,TMR_uint8List * data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdSL900aAccessFifoWrite(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+ uint32_t password, PasswordLevel level, AccessFifoOperation operation, TMR_uint8List *payLoad, TMR_uint8List * data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdHibikiReadLock(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, uint16_t mask, uint16_t action);+TMR_Status TMR_SR_cmdHibikiGetSystemInformation(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword,+ TMR_GEN2_HibikiSystemInformation *info);+TMR_Status TMR_SR_cmdHibikiSetAttenuate(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, uint8_t level, bool lock);+TMR_Status TMR_SR_cmdHibikiBlockLock(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, uint8_t block,+ TMR_GEN2_Password blockPassword, uint8_t mask, uint8_t action);+TMR_Status TMR_SR_cmdHibikiBlockReadLock(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, uint8_t block,+ TMR_GEN2_Password blockPassword, uint8_t mask, uint8_t action);+TMR_Status TMR_SR_cmdHibikiWriteMultipleWords(TMR_Reader *reader,+ uint16_t timeout, TMR_GEN2_Password accessPassword,+ TMR_GEN2_Bank bank, uint32_t wordOffset, uint8_t count,+ const uint8_t data[]);+TMR_Status TMR_SR_cmdEraseBlockTagSpecific(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Bank bank, uint32_t address, uint8_t count);+TMR_Status TMR_SR_cmdGetTxRxPorts(TMR_Reader *reader, TMR_SR_PortPair *ant);+TMR_Status TMR_SR_cmdGetAntennaConfiguration(TMR_Reader *reader,+ TMR_SR_AntennaPort *config);+TMR_Status TMR_SR_cmdGetAntennaSearchList(TMR_Reader *reader, uint8_t *count,+ TMR_SR_PortPair *ants);+TMR_Status TMR_SR_cmdGetAntennaPortPowers(TMR_Reader *reader, uint8_t *count,+ TMR_SR_PortPower *ports);+TMR_Status TMR_SR_cmdGetAntennaPortPowersAndSettlingTime(TMR_Reader *reader,+ uint8_t *count, TMR_SR_PortPowerAndSettlingTime *ports);+TMR_Status TMR_SR_cmdGetAntennaReturnLoss(TMR_Reader *reader, TMR_PortValueList *ports);+TMR_Status TMR_SR_cmdAntennaDetect(TMR_Reader *reader, uint8_t *count,+ TMR_SR_PortDetect *ports);+TMR_Status TMR_SR_cmdGetReadTxPower(TMR_Reader *reader, int32_t *power);+TMR_Status TMR_SR_cmdGetReadTxPowerWithLimits(TMR_Reader *reader,+ TMR_SR_PowerWithLimits *power);+TMR_Status TMR_SR_cmdGetWriteTxPower(TMR_Reader *reader, int32_t *power);+TMR_Status TMR_SR_cmdGetWriteTxPowerWithLimits(TMR_Reader *reader,+ TMR_SR_PowerWithLimits *power);+TMR_Status TMR_SR_cmdGetCurrentProtocol(TMR_Reader *reader,+ TMR_TagProtocol *protocol);+TMR_Status TMR_SR_cmdMultipleProtocolSearch(TMR_Reader *reader,TMR_SR_OpCode op,TMR_TagProtocolList *protocols, TMR_TRD_MetadataFlag metadataFlags,TMR_SR_SearchFlag antennas, TMR_TagFilter **filter, uint16_t timeout, uint32_t *tagsFound);+TMR_Status TMR_SR_cmdGetFrequencyHopTable(TMR_Reader *reader, uint8_t *count,+ uint32_t *hopTable);+TMR_Status TMR_SR_cmdGetFrequencyHopTime(TMR_Reader *reader, uint32_t *hopTime);+TMR_Status TMR_SR_cmdGetGPIO(TMR_Reader *reader, uint8_t *count, TMR_GpioPin *state);+TMR_Status TMR_SR_cmdGetGPIODirection(TMR_Reader *reader, uint8_t pin,+ bool *out);+TMR_Status TMR_SR_cmdGetRegion(TMR_Reader *reader, TMR_Region *region);+TMR_Status TMR_SR_cmdGetRegionConfiguration(TMR_Reader *reader,+ TMR_SR_RegionConfiguration key, void *value);+TMR_Status TMR_SR_cmdGetPowerMode(TMR_Reader *reader, TMR_SR_PowerMode *mode);+TMR_Status TMR_SR_cmdGetUserMode(TMR_Reader *reader, TMR_SR_UserMode *mode);+TMR_Status TMR_SR_cmdGetReaderConfiguration(TMR_Reader *reader,+ TMR_SR_Configuration key, void *value);+TMR_Status TMR_SR_cmdIAVDenatranCustomOp(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t rfu,+ TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdIAVDenatranCustomActivateSiniavMode(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, bool tokenDesc, uint8_t *token);+TMR_Status TMR_SR_cmdIAVDenatranCustomReadFromMemMap(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, uint16_t wordAddress);+TMR_Status TMR_SR_cmdIAVDenatranCustomWriteToMemMap(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, uint16_t wordPtr, uint16_t wordData, uint8_t* tagId, uint8_t* dataBuf);+TMR_Status TMR_SR_cmdIAVDenatranCustomWriteSec(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, uint8_t* dataWords, uint8_t* dataBuf);+TMR_Status TMR_SR_cmdIAVDenatranCustomGetTokenId(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode,+ TMR_uint8List *data, TMR_TagFilter* target);+TMR_Status TMR_SR_cmdIAVDenatranCustomReadSec(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, uint16_t wordAddress);+TMR_Status TMR_SR_cmdGetProtocolConfiguration(TMR_Reader *reader, TMR_TagProtocol protocol,+ TMR_SR_ProtocolConfiguration key, void *value);+TMR_Status TMR_SR_cmdGetReaderStats(TMR_Reader *reader,+ TMR_Reader_StatsFlag statFlags,+ TMR_Reader_StatsValues *stats);+TMR_Status TMR_SR_cmdGetReaderStatistics(TMR_Reader *reader,+ TMR_SR_ReaderStatisticsFlag statFlags,+ TMR_SR_ReaderStatistics *stats);+TMR_Status TMR_SR_cmdGetAvailableProtocols(TMR_Reader *reader,+ TMR_TagProtocolList *protocols);+TMR_Status TMR_SR_cmdGetAvailableRegions(TMR_Reader *reader,+ TMR_RegionList *regions);+TMR_Status TMR_SR_cmdGetTemperature(TMR_Reader *reader, int8_t *temp);+TMR_Status TMR_SR_cmdSetTxRxPorts(TMR_Reader *reader, uint8_t txPrt,+ uint8_t rxPort);+TMR_Status TMR_SR_cmdSetAntennaSearchList(TMR_Reader *reader,+ uint8_t count, const TMR_SR_PortPair *ports);+TMR_Status TMR_SR_cmdSetAntennaPortPowers(TMR_Reader *reader,+ uint8_t count, const TMR_SR_PortPower *ports);+TMR_Status TMR_SR_cmdSetAntennaPortPowersAndSettlingTime(TMR_Reader *reader,+ uint8_t count, const TMR_SR_PortPowerAndSettlingTime *ports);+TMR_Status TMR_SR_cmdSetReadTxPower(TMR_Reader *reader, int32_t power);+TMR_Status TMR_SR_cmdSetWriteTxPower(TMR_Reader *reader, int32_t power);+TMR_Status TMR_SR_cmdSetProtocol(TMR_Reader *reader, TMR_TagProtocol protocol);+TMR_Status TMR_SR_cmdSetFrequencyHopTable(TMR_Reader *reader, uint8_t count,+ const uint32_t *table);+TMR_Status TMR_SR_cmdSetFrequencyHopTime(TMR_Reader *reader, uint32_t hopTime);+TMR_Status TMR_SR_cmdSetGPIO(TMR_Reader *reader, uint8_t gpio, bool high);+TMR_Status TMR_SR_cmdSetGPIODirection(TMR_Reader *reader, uint8_t pin,+ bool out);+TMR_Status TMR_SR_cmdSetRegion(TMR_Reader *reader, TMR_Region region);+TMR_Status TMR_SR_cmdSetRegionLbt(TMR_Reader *reader, TMR_Region region, bool lbt);+TMR_Status TMR_SR_cmdSetPowerMode(TMR_Reader *reader, TMR_SR_PowerMode mode);+TMR_Status TMR_SR_cmdSetUserMode(TMR_Reader *reader, TMR_SR_UserMode mode);+TMR_Status TMR_SR_cmdSetReaderConfiguration(TMR_Reader *reader, + TMR_SR_Configuration key, const void *value);+TMR_Status TMR_SR_cmdSetProtocolLicenseKey(TMR_Reader *reader, TMR_SR_SetProtocolLicenseOption option, uint8_t key[], int key_len,uint32_t *retData);+TMR_Status TMR_SR_cmdSetProtocolConfiguration(TMR_Reader *reader,+ TMR_TagProtocol protocol, TMR_SR_ProtocolConfiguration key,+ const void *value);+TMR_Status TMR_SR_cmdResetReaderStats(TMR_Reader *reader,+ TMR_Reader_StatsFlag statFlags);+TMR_Status TMR_SR_cmdResetReaderStatistics(TMR_Reader *reader,+ TMR_SR_ReaderStatisticsFlag statFlags);+TMR_Status TMR_SR_cmdTestSetFrequency(TMR_Reader *reader, uint32_t frequency);+TMR_Status TMR_SR_cmdTestSendCw(TMR_Reader *reader, bool on);+TMR_Status TMR_SR_cmdTestSendPrbs(TMR_Reader *reader, uint16_t duration);+TMR_Status TMR_SR_cmdSetUserProfile(TMR_Reader *reader,+ TMR_SR_UserConfigOperation op,TMR_SR_UserConfigCategory category, TMR_SR_UserConfigType type);+TMR_Status TMR_SR_cmdGetUserProfile(TMR_Reader *reader, + uint8_t byte[], uint8_t length, uint8_t response[], uint8_t* response_length);+TMR_Status TMR_SR_cmdBlockWrite(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Bank bank, uint32_t wordPtr, + uint32_t wordCount, const uint16_t* data, uint32_t accessPassword, const TMR_TagFilter* target);+TMR_Status TMR_SR_cmdBlockErase(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Bank bank, uint32_t wordPtr,+ uint8_t wordCount, uint32_t accessPassword, TMR_TagFilter *target);+TMR_Status TMR_SR_cmdBlockPermaLock(TMR_Reader *reader, uint16_t timeout,uint32_t readLock, TMR_GEN2_Bank bank, + uint32_t blockPtr, uint32_t blockRange, uint16_t* mask, uint32_t accessPassword, TMR_TagFilter* target, TMR_uint8List *data);+TMR_Status TMR_SR_msgSetupReadTagMultiple(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);++TMR_Status+TMR_SR_msgSetupReadTagMultipleWithMetadata(TMR_Reader *reader, uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_SR_SearchFlag searchFlag,+ TMR_TRD_MetadataFlag metadataFlag,+ const TMR_TagFilter *filter,+ TMR_TagProtocol protocol,+ TMR_GEN2_Password accessPassword);++TMR_Status TMR_SR_msgSetupReadTagSingle(uint8_t *msg, uint8_t *i, TMR_TagProtocol protocol,TMR_TRD_MetadataFlag metadataFlags, const TMR_TagFilter *filter,uint16_t timeout);+void TMR_SR_msgAddGEN2WriteTagEPC(uint8_t *msg, uint8_t *i, uint16_t timeout, uint8_t *epc, uint8_t count);+void TMR_SR_msgAddGEN2DataRead(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Bank bank, uint32_t wordAddress, uint8_t len, uint8_t option, bool withMetaData);+void TMR_SR_msgAddGEN2DataWrite(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Bank bank, uint32_t address);+void TMR_SR_msgAddGEN2LockTag(uint8_t *msg, uint8_t *i, uint16_t timeout,+ uint16_t mask, uint16_t action, TMR_GEN2_Password password);+void TMR_SR_msgAddGEN2KillTag(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Password password);+void+TMR_SR_msgAddGEN2BlockWrite(uint8_t *msg, uint8_t *i, uint16_t timeout,TMR_GEN2_Bank bank, uint32_t wordPtr, uint32_t wordCount, uint16_t* data, uint32_t accessPassword,TMR_TagFilter* target);++void+TMR_SR_msgAddGEN2BlockPermaLock(uint8_t *msg, uint8_t *i, uint16_t timeout, uint32_t readLock, TMR_GEN2_Bank bank, uint32_t blockPtr, uint32_t blockRange, uint16_t* mask, uint32_t accessPassword,TMR_TagFilter* target);++void+TMR_SR_msgAddGEN2BlockErase(uint8_t *msg, uint8_t *i, uint16_t timeout, uint32_t wordPtr, TMR_GEN2_Bank bank,+ uint8_t wordCount, uint32_t accessPassword, TMR_TagFilter* target);++void +TMR_SR_msgAddHiggs2PartialLoadImage(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword, + TMR_GEN2_Password killPassword, uint8_t len, const uint8_t *epc, TMR_TagFilter* target);+void +TMR_SR_msgAddHiggs2FullLoadImage(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, uint16_t lockBits, uint16_t pcWord, uint8_t len, const uint8_t *epc, TMR_TagFilter* target);+void +TMR_SR_msgAddHiggs3FastLoadImage(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, uint16_t pcWord, uint8_t len, const uint8_t *epc, TMR_TagFilter* target);+void +TMR_SR_msgAddHiggs3LoadImage(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, uint16_t pcWord, uint8_t len, const uint8_t *epcAndUserData, TMR_TagFilter* target);++void +TMR_SR_msgAddHiggs3BlockReadLock(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t lockBits, TMR_TagFilter* target);++void +TMR_SR_msgAddNXPSetReadProtect(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword, TMR_TagFilter* target);+void +TMR_SR_msgAddNXPResetReadProtect(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword, TMR_TagFilter* target);+void+TMR_SR_msgAddNXPChangeEAS(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword, bool reset, TMR_TagFilter* target);+void +TMR_SR_msgAddNXPEASAlarm(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_DivideRatio dr, TMR_GEN2_TagEncoding m, TMR_GEN2_TrExt trExt, TMR_TagFilter* target);+void+TMR_SR_msgAddIAVDenatranCustomOp(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t rfu, TMR_TagFilter* target);+void +TMR_SR_msgAddIAVDenatranCustomActivateSiniavMode(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, bool tokenDesc, uint8_t *token);+void +TMR_SR_msgAddIAVDenatranCustomReadFromMemMap(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, uint16_t wordAddress);+void +TMR_SR_msgAddIAVDenatranCustomWriteToMemMap(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, uint16_t wordPtr, uint16_t wordData, uint8_t* tagId, uint8_t* dataBuf);+void+TMR_SR_msgAddIAVDenatranCustomWriteSec(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, uint8_t* data, uint8_t* dataBuf);+void +TMR_SR_msgAddIAVDenatranCustomGetTokenId(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Password accessPassword, uint8_t mode, TMR_TagFilter* target);+void +TMR_SR_msgAddIAVDenatranCustomReadSec(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, uint16_t wordAddress);+void +TMR_SR_msgAddNXPCalibrate(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword, TMR_TagFilter* target);+void +TMR_SR_msgAddNXPChangeConfig(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_NXP_ConfigWord configword, TMR_TagFilter* target);+void +TMR_SR_msgAddMonza4QTReadWrite(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ TMR_Monza4_ControlByte controlByte, TMR_Monza4_Payload payload, TMR_TagFilter* target);++void +TMR_SR_msgAddIdsSL900aGetSensorValue(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, Sensor sensortype,+ TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aGetMeasurementSetup(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target);++void +TMR_SR_msgAddIdsSL900aGetCalibrationData(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aSetCalibrationData(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint64_t calibration, TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aSetSfeParameters(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t sfe,+ TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aGetLogState(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target);+void+TMR_SR_msgAddIdsSL900aSetLogMode(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, LoggingForm form,+ StorageRule rule, bool Ext1Enable, bool Ext2Enable, bool TempEnable, bool BattEnable,+ uint16_t LogInterval, TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aSetLogLimit(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t exLower,+ uint16_t lower, uint16_t upper, uint16_t exUpper, TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aSetShelfLife(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t block0, uint32_t block1,+ TMR_TagFilter* target);+void+TMR_SR_msgAddIdsSL900aInitialize(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t delayTime,+ uint16_t applicatioData, TMR_TagFilter* target);+void+TMR_SR_msgAddIdsSL900aEndLog(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target);+void+TMR_SR_msgAddIdsSL900aSetPassword(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t newPassword,+ PasswordLevel newPasswordLevel, TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aAccessFifoStatus(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation operation,+ TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aGetBatteryLevel(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, BatteryType batteryType,+ TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aAccessFifoRead(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation operation,+ uint8_t length, TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aAccessFifoWrite(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation operation,+ TMR_uint8List *payLoad, TMR_TagFilter* target);+void +TMR_SR_msgAddIdsSL900aStartLog(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t time, TMR_TagFilter* target);++TMR_Status TMR_SR_executeEmbeddedRead(TMR_Reader *reader, uint8_t *msg,+ uint16_t timeout, TMR_SR_MultipleStatus *status);++TMR_Status TMR_SR_cmdISO180006BWriteTagData(TMR_Reader *reader,+ uint16_t timeout, uint8_t address, uint8_t count, const uint8_t data[],+ const TMR_TagFilter *filter);+TMR_Status TMR_SR_cmdISO180006BReadTagData(TMR_Reader *reader,+ uint16_t timeout, uint8_t address, uint8_t length,+ const TMR_TagFilter *filter, TMR_TagReadData *read);+TMR_Status TMR_SR_cmdISO180006BLockTag(TMR_Reader *reader, uint16_t timeout,+ uint8_t address, const TMR_TagFilter *filter);+TMR_Status TMR_iso18000BBLFValToInt(int val, void *lf);+TMR_Status TMR_SR_cmdStopReading(struct TMR_Reader *reader);+TMR_Status TMR_SR_cmdGetReaderWriteTimeOut (struct TMR_Reader *reader, TMR_TagProtocol protocol,+ TMR_SR_Gen2ReaderWriteTimeOut *value);+TMR_Status TMR_SR_cmdSetReaderWriteTimeOut (struct TMR_Reader *reader, TMR_TagProtocol protocol,+ TMR_SR_Gen2ReaderWriteTimeOut *value);+TMR_Status TMR_SR_cmdAuthReqResponse(struct TMR_Reader *reader, TMR_TagAuthentication *auth);++TMR_Status TMR_SR_addTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop,TMR_ReadPlan *rp, uint8_t *msg, uint8_t *i, uint32_t readTimeMs, uint8_t *lenbyte);++TMR_Status+TMR_fillReaderStats(TMR_Reader *reader, TMR_Reader_StatsValues* stats, uint16_t flag, uint8_t* msg, uint8_t offset);+bool compareAntennas(TMR_MultiReadPlan *multi);+bool compareVersion(TMR_Reader *reader, uint8_t firstByte, uint8_t secondByte, uint8_t thirdByte, uint8_t fourthByte);+TMR_Status+TMR_SR_cmdrebootReader(TMR_Reader *reader);+TMR_Status+prepForSearch(TMR_Reader *reader, TMR_uint8List *antennaList);+TMR_Status +TMR_SR_msgSetupMultipleProtocolSearch(TMR_Reader *reader, uint8_t *msg, TMR_SR_OpCode op, TMR_TagProtocolList *protocols, TMR_TRD_MetadataFlag metadataFlags, TMR_SR_SearchFlag antennas, TMR_TagFilter **filter, uint16_t timeout);+TMR_Status TMR_SR_cmdProbeBaudRate(TMR_Reader *reader, uint32_t *currentBaudRate);+void TMR_SR_updateBaseTimeStamp(TMR_Reader *reader);+TMR_Status verifySearchStatus(TMR_Reader *reader);+++#ifdef TMR_ENABLE_BACKGROUND_READS+void notify_authreq_listeners(TMR_Reader *reader, TMR_TagReadData *trd, TMR_TagAuthentication *auth);+#endif+++#ifdef __cplusplus+}+#endif++#endif /* _SERIAL_READER_IMP_H */
+ cbits/api/serial_reader_l3.c view
@@ -0,0 +1,7295 @@+/**+ * @file serial_reader_l3.c+ * @brief Mercury API - serial reader low level implementation+ * @author Nathan Williams+ * @date 11/2/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 <inttypes.h>+#include <stdio.h>+#include <stdlib.h>+#include <string.h>++#include "tm_reader.h"+#include "serial_reader_imp.h"+#include "tmr_utils.h"++#ifndef BARE_METAL+bool isSecureAccessEnabled;+#endif++void+notify_read_listeners(TMR_Reader *reader, TMR_TagReadData *trd);+#ifdef TMR_ENABLE_SERIAL_READER++static TMR_Status filterbytes(TMR_TagProtocol protocol,+ const TMR_TagFilter *filter, + uint8_t *option, uint8_t *i, uint8_t *msg,+ uint32_t accessPassword, bool usePassword);+TMR_Status+TMR_SR_sendBytes(TMR_Reader *reader, uint8_t len, uint8_t *data, uint32_t timeoutMs);++/*+ * ThingMagic-mutated CRC used for messages.+ * Notably, not a CCITT CRC-16, though it looks close.+ */+static uint16_t crctable[] = +{+ 0x0000, 0x1021, 0x2042, 0x3063,+ 0x4084, 0x50a5, 0x60c6, 0x70e7,+ 0x8108, 0x9129, 0xa14a, 0xb16b,+ 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,+};++static uint16_t+tm_crc(uint8_t *u8Buf, uint8_t len)+{+ uint16_t crc;+ int i;++ crc = 0xffff;++ for (i = 0; i < len ; i++)+ {+ crc = ((crc << 4) | (u8Buf[i] >> 4)) ^ crctable[crc >> 12];+ crc = ((crc << 4) | (u8Buf[i] & 0xf)) ^ crctable[crc >> 12];+ }++ return crc;+}+++/**+ * Send a byte string+ *+ * @param reader The reader+ * @param[in] len Number of bytes to send+ * @param[in] data Bytes to send, with length in byte 1. Byte 0 is reserved for the SOF character, and two characters at the end are reserved for the CRC.+ * @param timeoutMs Timeout value.+ */+TMR_Status+TMR_SR_sendBytes(TMR_Reader *reader, uint8_t len, uint8_t *data, uint32_t timeoutMs)+{+ TMR_SR_SerialTransport *transport;+ TMR_Status ret;++ transport = &reader->u.serialReader.transport;++ if (NULL != reader->transportListeners)+ {+ TMR__notifyTransportListeners(reader, true, len, data, timeoutMs);+ }++ ret = transport->sendBytes(transport, len, data, timeoutMs);+ return ret;+}++/**+ * Send a message to the reader+ *+ * @param reader The reader+ * @param[in] data Message to send, with length in byte 1. Byte 0 is reserved for the SOF character, and two characters at the end are reserved for the CRC.+ * @param[out] opcode Opcode sent with message (pass this value to receiveMessage to match against response)+ * @param timeoutMs Timeout value.+ */+TMR_Status+TMR_SR_sendMessage(TMR_Reader *reader, uint8_t *data, uint8_t *opcode, uint32_t timeoutMs)+{+ TMR_SR_SerialReader *sr;+ TMR_Status ret;+ uint16_t crc;+ uint8_t len;+ uint8_t j;+ //uint8_t byteLen;++ sr = &reader->u.serialReader;+ timeoutMs += sr->transportTimeout;+/* if (reader->u.serialReader.crcEnabled)+ {+ byteLen = 5;+ }+ else+ {+ byteLen = 3;+ }*/++ /* Wake up processor from deep sleep. Tickle the RS-232 line, then+ * wait a fixed delay while the processor spins up communications again. */+ if (sr->supportsPreamble && ((sr->powerMode == TMR_SR_POWER_MODE_INVALID) ||+ (sr->powerMode == TMR_SR_POWER_MODE_SLEEP)) )+ {+ uint8_t flushBytes[] = {+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF+ };++ TMR_SR_sendBytes(reader, sizeof(flushBytes)/sizeof(uint8_t), flushBytes, timeoutMs);+ {+ uint32_t bytesper100ms;+ uint32_t bytesSent;++ /* Calculate fixed delay in terms of byte-lengths at current speed */+ /* @todo Optimize delay length. This value (100 bytes at 9600bps) is taken+ * directly from arbser, which was itself using a hastily-chosen value. */+ bytesper100ms = sr->baudRate / 50;+ for (bytesSent=0; bytesSent<bytesper100ms;+ bytesSent += (sizeof(flushBytes)/sizeof(uint8_t)))+ {+ TMR_SR_sendBytes(reader, sizeof(flushBytes)/sizeof(uint8_t), flushBytes, timeoutMs);+ }+ }+ } ++ /* Layout of message in data array: + * [0] [1] [2] [3] [4] ... [LEN+2] [LEN+3] [LEN+4]+ * FF LEN OP xx xx ... xx CRCHI CRCLO+ */+ data[0] = 0xff;+ len = data[1];+ *opcode = data[2];++ if (isContinuousReadParamSupported(reader))+ {+ for (j = 0; j <= len; j++)+ {+ reader->paramMessage[j] = data[2 + j];+ }+ data[1] = 5 + len;+ data[2] = 0x2f;+ data[3] = 0x00;+ data[4] = 0x00;+ data[5] = 0x04;+ data[6] = len;+ for (j = 0; j <= len ; j++)+ {+ data[7 + j] = reader->paramMessage[j];+ }+ len = data[1];+ reader->paramWait = true;+ }++ // if (reader->u.serialReader.crcEnabled)+ {+ crc = tm_crc(&data[1], len + 2);+ data[len + 3] = crc >> 8;+ data[len + 4] = crc & 0xff;+ }+ + ret = TMR_SR_sendBytes(reader, len+5, data, timeoutMs);+ return ret;+}+++bool+isContinuousReadParamSupported(TMR_Reader *reader)+{+ uint16_t i; + uint8_t *readerVersion = reader->u.serialReader.versionInfo.fwVersion ;+ uint8_t checkVersion[4];++ if (reader->hasContinuousReadStarted == false || reader->continuousReading == false)+ return false;++ switch (reader->u.serialReader.versionInfo.hardware[0])+ {+ case TMR_SR_MODEL_M6E:+ case TMR_SR_MODEL_M6E_I:+ checkVersion[0] = 0x01; checkVersion[1] = 0x21; checkVersion[2] = 0x01; checkVersion[3] = 0x19;+ break;+ case TMR_SR_MODEL_MICRO:+ checkVersion[0] = 0x01; checkVersion[1] = 0x09; checkVersion[2] = 0x00; checkVersion[3] = 0x14;+ break;+ case TMR_SR_MODEL_M6E_NANO:+ checkVersion[0] = 0x01; checkVersion[1] = 0x07; checkVersion[2] = 0x00; checkVersion[3] = 0x0E;+ break;+ default:+ checkVersion[0] = 0xFF; checkVersion[1] = 0xFF; checkVersion[2] = 0xFF; checkVersion[3] = 0xFF;+ }+ for (i = 0; i < 4; i++)+ {+ if (readerVersion[i] < checkVersion[i])+ {+ return false;+ }+ }+ return true;+}++/**+ * Receive a response.+ *+ * @param reader The reader+ * @param[in] data Message to send, with length in byte 1. Byte 0 is reserved for the SOF character, and two characters at the end are reserved for the CRC.+ * @param[out] data Message received.+ * @param opcode Opcode that was sent with message that elicited this response, to be matched against incoming response opcode.+ * @param timeoutMs Timeout value.+ */+TMR_Status+TMR_SR_receiveMessage(TMR_Reader *reader, uint8_t *data, uint8_t opcode, uint32_t timeoutMs)+{+ TMR_Status ret;+ uint16_t crc, status;+ uint8_t len,headerOffset;+ uint8_t receiveBytesLen;+ uint32_t inlen;+ int i;+ TMR_SR_SerialTransport *transport;+ uint8_t retryCount = 0;++ transport = &reader->u.serialReader.transport;+ timeoutMs += reader->u.serialReader.transportTimeout;++ /**+ * Initialize the receive bytes length based on+ * sr->expectCRC option+ **/+ if (reader->u.serialReader.crcEnabled)+ {+ receiveBytesLen = 7;+ }+ else+ {+ receiveBytesLen = 5;+ }++ headerOffset = 0;+retryHeader:+ inlen = 0;+ retryCount++;+ ret = transport->receiveBytes(transport, receiveBytesLen - headerOffset, &inlen, data + headerOffset, timeoutMs);+ if (TMR_SUCCESS != ret)+ {+ /* @todo Figure out how many bytes were actually obtained in a failed receive */+ TMR__notifyTransportListeners(reader, false, inlen, data, timeoutMs);+ return ret;+ }++ if (data[0] != (uint8_t)0xFF)+ {+ for (i = 1; i < receiveBytesLen; i++) + {+ if (data[i] == 0xFF)+ {+ /* An SOH has been found, so we won't enter the "NO SOH" section of code again */+ headerOffset = receiveBytesLen - i;+ memmove(data, data + i, headerOffset);+ goto retryHeader;+ }+ }+ if (retryCount < 20)+ {+ /* Retry to get SOH */+ goto retryHeader;+ }+ return TMR_ERROR_TIMEOUT;+ }++ /* After this point, we have the the bare minimum (5 or 7) of bytes in the buffer */++ /* Layout of response in data array: + * [0] [1] [2] [3] [4] [5] [6] ... [LEN+4] [LEN+5] [LEN+6]+ * FF LEN OP STATUSHI STATUSLO xx xx ... xx CRCHI CRCLO+ */+ len = data[1];++ if (0 == len)+ {+ inlen = 0;+ }+ else if ((TMR_SR_MAX_PACKET_SIZE - receiveBytesLen) < len)+ {+ /**+ * packet data size is overflowing the buffer size. This could be a+ * corrupted packet. Discard it and move on. Return back with TMR_ERROR_TOO_BIG+ * error.+ **/+ return TMR_ERROR_TOO_BIG;+ }+ else+ {+ ret = transport->receiveBytes(transport, len, &inlen, data + receiveBytesLen, timeoutMs);+ }++ if (NULL != reader->transportListeners)+ {+ TMR__notifyTransportListeners(reader, false, inlen + receiveBytesLen, data, timeoutMs);+ }++ if (TMR_SUCCESS != ret)+ {+ /* before we can actually process the message, we have to properly receive the message */+ return ret;+ }++ /**+ * Calculate the CRC only if expectCRC option+ * is enabled+ **/+ if (reader->u.serialReader.crcEnabled)+ {+ crc = tm_crc(&data[1], len + 4);+ if ((data[len + 5] != (crc >> 8)) ||+ (data[len + 6] != (crc & 0xff)))+ {+ return TMR_ERROR_CRC_ERROR;+ }+ }++ if ((data[2] != opcode) && ((data[2] != 0x2F) || (!reader->continuousReading)))+ {+ if(data[2] == 0x9D)+ {+ return TMR_ERROR_AUTOREAD_ENABLED;+ }++ /* We got a response for a different command than the one we+ * sent. This usually means we received the boot-time message from+ * a M6e, and thus that the device was rebooted somewhere between+ * the previous command and this one. Report this as a problem.+ */+ return TMR_ERROR_DEVICE_RESET;+ }++ status = GETU16AT(data, 3);+ if (status != 0)+ {+ ret = TMR_ERROR_CODE(status);+ if (ret == TMR_ERROR_TM_ASSERT_FAILED)+ {+ uint32_t line;+ uint8_t *assert = (uint8_t *) (data + 5);++ memset(reader->u.serialReader.errMsg, 0 ,TMR_SR_MAX_PACKET_SIZE);+ line = GETU32AT(assert, 0);+ sprintf(reader->u.serialReader.errMsg, "Assertion failed at line %"PRId32" in file ", line);+ memcpy(reader->u.serialReader.errMsg + strlen(reader->u.serialReader.errMsg), assert + 4, len - 4);+ }+ } + return ret;+}++/**+ * Send a message and receive a response.+ *+ * @param reader The reader+ * @param[in] data Message to send, with length in byte 1. Byte 0 is reserved for the SOF character, and two characters at the end are reserved for the CRC.+ * @param[out] data Message received.+ * @param timeoutMs Timeout value.+ */+TMR_Status+TMR_SR_sendTimeout(TMR_Reader *reader, uint8_t *data, uint32_t timeoutMs)+{+ TMR_Status ret;+ uint8_t opcode;+ ret = TMR_SR_sendMessage(reader, data, &opcode, timeoutMs);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ if (isContinuousReadParamSupported(reader))+ {+ while(reader->paramWait)+ {+#ifdef SINGLE_THREAD_ASYNC_READ+ TMR_TagReadData trd;+ ret = TMR_hasMoreTags(reader);+ if (TMR_SUCCESS == ret)+ {+ TMR_getNextTag(reader, &trd);+ notify_read_listeners(reader, &trd);+ }+#endif+ }++ reader->paramWait = false; + memcpy(data , &reader->paramMessage[5], reader->paramMessage[1] * sizeof(uint8_t));+ data[0] = 0xFF;+ ret = (TMR_Status) GETU16AT(&reader->paramMessage[0], 3);+ if (TMR_SUCCESS != ret)+ {+ return TMR_ERROR_CODE(ret);+ }+ ret = (TMR_Status) GETU16AT(data, 3);+ if (TMR_SUCCESS != ret)+ {+ return TMR_ERROR_CODE(ret);+ }+ }+ else+ {+ ret = TMR_SR_receiveMessage(reader, data, opcode, timeoutMs);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ }+ return ret;+}+++TMR_Status+TMR_SR_send(TMR_Reader *reader, uint8_t *data)+{+ return TMR_SR_sendTimeout(reader, data,+ reader->u.serialReader.commandTimeout);+}++/**+ * Set the operating frequency of the device.+ * Testing command.+ *+ * @param reader The reader+ * @param frequency the frequency to set, in kHz+ */ +TMR_Status +TMR_SR_cmdTestSetFrequency(TMR_Reader *reader, uint32_t frequency)+{+ + uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;+ SETU8(msg, i,TMR_SR_OPCODE_SET_OPERATING_FREQ);+ SETU32(msg, i, frequency);+ msg[1] = i - 3; /* Install length */+ return TMR_SR_send(reader, msg);+}++/**+ * Turn CW transmission on or off.+ * Testing command.+ *+ * @param reader The reader+ * @param on whether to turn CW on or off+ */ +TMR_Status +TMR_SR_cmdTestSendCw(TMR_Reader *reader, bool on)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;+ SETU8(msg, i,TMR_SR_OPCODE_TX_CW_SIGNAL);+ if(on)+ SETU8(msg, i,1);+ else+ SETU8(msg, i,0);+ msg[1] = i - 3; /* Install length */+ return TMR_SR_send(reader, msg);+}++/**+ * Turn on pseudo-random bit stream transmission for a particular+ * duration. + * Testing command.+ *+ * @param reader The reader+ * @param duration the duration to transmit the PRBS signal.+ */ +TMR_Status +TMR_SR_cmdTestSendPrbs(TMR_Reader *reader, uint16_t duration)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;+ SETU8(msg, i,TMR_SR_OPCODE_TX_CW_SIGNAL);+ SETU8(msg, i,2);+ SETU16(msg, i,duration);+ msg[1] = i - 3; /* Install length */+ return TMR_SR_send(reader, msg);+}++/**+ * Setting user profile on the basis of operation, category and type parameter+ *+ * @param reader The reader+ * @param op operation to be performed on configuration (Save,restore,verify and reset)+ * @param category Which category of configuration to operate on -- only TMR_SR_ALL is currently supported+ * @param type Type of configuration value to use (default, custom...)+ */++TMR_Status +TMR_SR_cmdSetUserProfile(TMR_Reader *reader,TMR_SR_UserConfigOperation op,TMR_SR_UserConfigCategory category, TMR_SR_UserConfigType type)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ TMR_Status ret;+ TMR_Status ret1;+ uint16_t readTime = 250;+ TMR_SR_SerialReader *sr;+ TMR_SR_SerialTransport *transport;++ sr = &reader->u.serialReader;+ transport = &reader->u.serialReader.transport;++ i = 2;+ SETU8(msg,i,TMR_SR_OPCODE_SET_USER_PROFILE);+ SETU8(msg,i,op);+ SETU8(msg,i,category);+ SETU8(msg,i,type);++#ifdef TMR_ENABLE_BACKGROUND_READS+ readTime = (uint16_t)reader->readParams.asyncOnTime; +#endif++ if (op == TMR_USERCONFIG_CLEAR)+ {+ /* Resrt the Autonomous option if enabled */+ sr->enableAutonomousRead = false;+ }++ if (op == TMR_USERCONFIG_SAVE_WITH_READPLAN)+ {+ /** + * extract the read plan configuration form API read plan object, frame+ * the serial command for read by using existing parser methods in read+ * operation and append that to save configuration command.+ **/+ TMR_uint8List *antennaList = NULL;+ TMR_ReadPlan *rp;+ uint8_t tempMsg[TMR_SR_MAX_PACKET_SIZE];++ rp = reader->readParams.readPlan; ++ /**+ * Currently Mercury API supports only true continuous read as a part of+ * save configuration with read plan.+ * TODO: Add support for other read types as well if needed in future.+ **/++ /* Add the Autonomous read option */+ sr->enableAutonomousRead = rp->enableAutonomousRead;+ SETU8(msg,i,rp->enableAutonomousRead);++ if (TMR_READ_PLAN_TYPE_MULTI == rp->type)+ {+ /* The Multi read plan */+ uint8_t 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_SearchFlag antennas = TMR_SR_SEARCH_FLAG_CONFIGURED_LIST;++ reader->continuousReading = true;+ 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;+ }++ if (reader->continuousReading)+ {+ bool value = false;+ ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_ENABLE_READ_FILTER, &value);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ }+ + /* Call the helper function to frame the multi protocol read command */+ ret = TMR_SR_msgSetupMultipleProtocolSearch(reader, tempMsg, TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE, protocolList,+ reader->userMetadataFlag, antennas, filters, (uint16_t)readTime);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ }+ else+ {+ /**+ * Coming here means the requested read plan is not for true continuous read.+ * Throw error back to user.+ * TODO:Remove this validation, if we need to support for other type of read+ * operation in future.+ */+ return TMR_ERROR_UNSUPPORTED;+ }+ }+ else+ {+ /* The Simple Read Plan */+ 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;++ antennaList = &rp->u.simple.antennas;+ reader->continuousReading = true;+ reader->fastSearch = rp->u.simple.useFastSearch;+ reader->triggerRead = rp->u.simple.triggerRead.enable;+ protocolList->len = 1;+ protocolList->max = 1;+ protocolList->list = protocols;++ ret = prepForSearch(reader, antennaList);+ 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;+ }+ }++ 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_msgSetupMultipleProtocolSearch(reader, tempMsg, TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE, protocolList,+ reader->userMetadataFlag, antennas, filters, (uint16_t)readTime);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ } + }++ /* Append the serial read command to save configuration command */+ memcpy((msg + i), tempMsg+1, tempMsg[1]+2);+ /* Add two bytes for Opcode and header */+ i = (i + tempMsg[1] + 2); + reader->continuousReading = false;+ }++ msg[1] = i - 3; /* Install length */+ ret1 = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret1)+ {+ return ret1;+ }++ /* If Autonomous read is enabled skip this */+ if (!sr->enableAutonomousRead)+ {+ if ((op == TMR_USERCONFIG_RESTORE)||(op == TMR_USERCONFIG_CLEAR)) //reprobe the baudrate+ {+ uint32_t rate;+ if (reader->connected == false)+ {+ ret = transport->open(transport);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ }++ ret = TMR_SR_cmdProbeBaudRate(reader, &rate);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ reader->connected = true;+ }++ /* Restore the region and protocol*/+ if ((op == TMR_USERCONFIG_RESTORE) || (op == TMR_USERCONFIG_CLEAR))+ {+ ret = TMR_SR_cmdGetRegion(reader, &sr->regionId);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ ret = TMR_SR_cmdGetCurrentProtocol(reader, &reader->tagOpParams.protocol);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ sr->currentProtocol = reader->tagOpParams.protocol;+ }+ }+ return ret1;+}++/**+ * Get Save/Restore Configuration + *+ * @param reader The reader+ * @param byte array consists of a opcode option(s)+ * @param length Length of byte array+ * @param response Response of the operation+ * @param response_length Length of response array+ */++TMR_Status TMR_SR_cmdGetUserProfile(TMR_Reader *reader, uint8_t byte[], uint8_t length, uint8_t response[], uint8_t* response_length)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i,j;+ i = 2;+ SETU8(msg,i,TMR_SR_OPCODE_GET_USER_PROFILE);+ for(j=0;j<length;j++)+ {+ SETU8(msg,i,byte[j]);+ }+ msg[1] = i - 3;+ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ for(j=0;j<msg[1];j++)+ {+ response[j]=msg[5+j];+ }+ *response_length=msg[1];+ return ret;+}++TMR_Status TMR_SR_cmdBlockWrite(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Bank bank, uint32_t wordPtr, + uint32_t wordCount, const uint16_t* data, uint32_t accessPassword, const TMR_TagFilter* target)+ { + uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, option=0,rec;+ i = 2; + SETU8(msg,i,TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, i,timeout);+ SETU8(msg,i,0x00);//chip type+ rec=i;+ SETU8(msg,i,0x40);//option+ SETU8(msg,i,0x00);+ SETU8(msg,i,0xC7);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, &i, msg,accessPassword,true);+ msg[rec]=msg[rec]|option;+ SETU8(msg,i,0x00);+ SETU8(msg,i,bank);+ SETU32(msg,i,wordPtr);+ SETU8(msg,i,(uint8_t)wordCount);+ {+ uint32_t iWord;+ for (iWord = 0; iWord < wordCount; iWord++)+ {+ SETU8(msg, i, ((data[iWord]>>8)&0xFF));+ SETU8(msg, i, ((data[iWord]>>0)&0xFF));+ }+ }+ msg[1] = i - 3;+ return TMR_SR_send(reader, msg);+ }++TMR_Status +TMR_SR_cmdBlockErase(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Bank bank, uint32_t wordPtr,+ uint8_t wordCount, uint32_t accessPassword,+ TMR_TagFilter *target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddGEN2BlockErase(msg, &i, timeout, wordPtr, bank, wordCount, accessPassword, target);++ msg[1] = i - 3;+ return TMR_SR_send(reader, msg);+}++TMR_Status+TMR_SR_cmdBlockPermaLock(TMR_Reader *reader, uint16_t timeout,uint32_t readLock, TMR_GEN2_Bank bank, uint32_t blockPtr, uint32_t blockRange, uint16_t* mask, uint32_t accessPassword, TMR_TagFilter* target, TMR_uint8List* data)+ { + TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, option=0,rec;+ unsigned int j;+ i = 2; + SETU8(msg,i,TMR_SR_OPCODE_ERASE_BLOCK_TAG_SPECIFIC);+ SETU16(msg,i,timeout);+ SETU8(msg,i,0x00);+ rec=i;+ SETU8(msg,i,0x40);+ SETU8(msg,i,0x01);+ filterbytes(TMR_TAG_PROTOCOL_GEN2,target, &option, &i, msg,accessPassword,true);+ msg[rec]=msg[rec]|option;+ SETU8(msg,i,0x00);+ SETU8(msg,i,(uint8_t)readLock);+ + SETU8(msg,i,bank);+ SETU32(msg,i,blockPtr);+ SETU8(msg,i,(uint8_t)blockRange);+ + if (readLock==0x01)+ {+ for(j=0;j<blockRange;j++)+ {+ SETU8(msg,i,(mask[j]>>8)&(0xff));+ SETU8(msg,i,(mask[j]>>0) & (0xff));+ }+ }+ msg[1] = i - 3;+ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ if ((0 == readLock) && (NULL != data))+ {+ data->len = msg[1]-2;+ if (data->len > data->max)+ {+ data->len = data->max;+ }+ memcpy(data->list, msg+7, data->len);+ }+ return ret;+ } +TMR_Status+TMR_SR_cmdVersion(TMR_Reader *reader, TMR_SR_VersionInfo *info)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, j;+ uint32_t tTimeout = 0;++ tTimeout = reader->u.serialReader.transportTimeout;++ /**+ * If user not set any trasportTimeout value.+ * Use the default value.+ */+ if (false == reader->u.serialReader.usrTimeoutEnable)+ {+ reader->u.serialReader.transportTimeout = 100;+ }++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_VERSION);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, 0);+ if (TMR_SUCCESS != ret)+ {+ reader->u.serialReader.transportTimeout = tTimeout;+ return ret; + }+ if (NULL != info)+ {+ i = 5;+ for (j = 0; j < 4 ; j++)+ {+ info->bootloader[j] = GETU8(msg, i);+ }+ for (j = 0; j < 4 ; j++)+ {+ info->hardware[j] = GETU8(msg, i);+ }+ for (j = 0; j < 4 ; j++)+ {+ info->fwDate[j] = GETU8(msg, i);+ }+ for (j = 0; j < 4 ; j++)+ {+ info->fwVersion[j] = GETU8(msg, i);+ }+ info->protocols = GETU32(msg, i);+ }++ reader->u.serialReader.transportTimeout = tTimeout;+ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdBootFirmware(TMR_Reader *reader)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, j;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_BOOT_FIRMWARE);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, 1000);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ i = 5;+ for (j = 0; j < 4 ; j++)+ {+ reader->u.serialReader.versionInfo.bootloader[j] = GETU8(msg, i);+ }+ for (j = 0; j < 4 ; j++)+ {+ reader->u.serialReader.versionInfo.hardware[j] = GETU8(msg, i);+ }+ for (j = 0; j < 4 ; j++)+ {+ reader->u.serialReader.versionInfo.fwDate[j] = GETU8(msg, i);+ }+ for (j = 0; j < 4 ; j++)+ {+ reader->u.serialReader.versionInfo.fwVersion[j] = GETU8(msg, i);+ }+ reader->u.serialReader.versionInfo.protocols = GETU32(msg, i);++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdSetBaudRate(TMR_Reader *reader, uint32_t rate)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_BAUD_RATE);+ SETU32(msg, i, rate);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdEraseFlash(TMR_Reader *reader, uint8_t sector, uint32_t password)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_ERASE_FLASH);+ SETU32(msg, i, password);+ SETU8(msg, i, sector);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, 30000);+}+++TMR_Status+TMR_SR_cmdWriteFlashSector(TMR_Reader *reader, uint8_t sector, uint32_t address,+ uint32_t password, uint8_t length, const uint8_t data[],+ uint32_t offset)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_WRITE_FLASH_SECTOR);+ SETU32(msg, i, password);+ SETU32(msg, i, address);+ SETU8(msg, i, sector);+ memcpy(&msg[i], data + offset, length);+ i += length;+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, 3000);+}++++TMR_Status+TMR_SR_cmdModifyFlashSector(TMR_Reader *reader, uint8_t sector, uint32_t address,+ uint32_t password, uint8_t length, const uint8_t data[],+ uint32_t offset)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_MODIFY_FLASH_SECTOR);+ SETU32(msg, i, password);+ SETU32(msg, i, address);+ SETU8(msg, i, sector);+ memcpy(&msg[i], data + offset, length);+ i += length;+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, 3000);+}++TMR_Status+TMR_SR_cmdBootBootloader(TMR_Reader *reader)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_BOOT_BOOTLOADER);+ msg[1] = i - 3; /* Install length */++ reader->u.serialReader.crcEnabled = true;+ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdGetHardwareVersion(TMR_Reader *reader, uint8_t option, uint8_t flags,+ uint8_t* count, uint8_t data[])+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_HW_VERSION);+ SETU8(msg, i, option);+ SETU8(msg, i, flags);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ for (i = 0 ; i < msg[1] && i < *count; i++)+ {+ data[i] = msg[5 + i];+ }++ *count = msg[1];++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetCurrentProgram(TMR_Reader *reader, uint8_t *program)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_CURRENT_PROGRAM);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ *program = msg[5];++ return ret;+}++TMR_Status TMR_SR_msgSetupReadTagSingle(uint8_t *msg, uint8_t *i, TMR_TagProtocol protocol,TMR_TRD_MetadataFlag metadataFlags, const TMR_TagFilter *filter,uint16_t timeout)+{+ uint8_t optbyte;++ SETU8(msg, *i, TMR_SR_OPCODE_READ_TAG_ID_SINGLE);+ SETU16(msg, *i, timeout);+ optbyte = *i;+ SETU8(msg, *i, 0); /* Initialize option byte */+ msg[optbyte] |= TMR_SR_GEN2_SINGULATION_OPTION_FLAG_METADATA;+ SETU16(msg,*i, metadataFlags);+ filterbytes(protocol, filter, &msg[optbyte], i, msg,0, true);+ msg[optbyte] |= TMR_SR_GEN2_SINGULATION_OPTION_FLAG_METADATA;+ return TMR_SUCCESS;++}++TMR_Status+TMR_SR_msgSetupReadTagMultiple(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)+{+ return TMR_SR_msgSetupReadTagMultipleWithMetadata(reader, msg, i, timeout,+ searchFlag, reader->userMetadataFlag, filter, protocol,accessPassword);+}+++TMR_Status+TMR_SR_msgSetupReadTagMultipleWithMetadata(TMR_Reader *reader, uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_SR_SearchFlag searchFlag,+ TMR_TRD_MetadataFlag metadataFlag,+ const TMR_TagFilter *filter,+ TMR_TagProtocol protocol,+ TMR_GEN2_Password accessPassword)+{+ TMR_Status ret;+ TMR_SR_SerialReader *sr;+ uint8_t optbyte;+ + sr = &reader->u.serialReader;+ sr->opCode = TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE;+ ret = TMR_SUCCESS;++ SETU8(msg, *i, TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE);++ /**+ * we need to add the option for bap parameters if enabled+ * + * for adding the bap parameter option, and EBV technique is used+ * raising the lowest order bit of the high opder byte signals the+ * use of new Gen2 Bap support parameters.+ **/+ if (sr->isBapEnabled)+ {+ SETU8(msg,*i,0x81);+ }++ optbyte = *i;+ SETU8(msg, *i, 0); /* Initialize option byte */++ /* add the large tag population support */+ searchFlag= (TMR_SR_SearchFlag)(searchFlag | TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT);++ if (reader->continuousReading)+ {+ msg[optbyte] |= TMR_SR_GEN2_SINGULATION_OPTION_FLAG_METADATA;+ searchFlag = (TMR_SR_SearchFlag)(searchFlag+ | TMR_SR_SEARCH_FLAG_TAG_STREAMING);++ /**+ * We need to send a different flag for the new reader stats,+ * Both these options are mutually exclusive in nature,+ * Hence can not be raised at once.+ **/+ if (TMR_SR_STATUS_NONE != reader->streamStats)+ {+ searchFlag |= TMR_SR_SEARCH_FLAG_STATUS_REPORT_STREAMING;+ }+ else+ {+ if (TMR_READER_STATS_FLAG_NONE != reader->statsFlag)+ {+ searchFlag |= TMR_SR_SEARCH_FLAG_STATS_REPORT_STREAMING;+ }+ }+ }++ /**+ * Add the fast search flag depending on the user choice+ */+ if (reader->fastSearch)+ {+ searchFlag = (TMR_SR_SearchFlag)(searchFlag+ |TMR_SR_SEARCH_FLAG_READ_MULTIPLE_FAST_SEARCH);+ reader->fastSearch = false;+ }++ /**+ * Add the trigger read flag depending on the user choice+ */+ if (reader->triggerRead)+ {+ searchFlag = (TMR_SR_SearchFlag)(searchFlag+ |TMR_SR_SEARCH_FLAG_GPI_TRIGGER_READ);+ reader->triggerRead = false;+ }++ /**+ * Add the duty cycle flag depending on the user choice+ */+ if (reader->dutyCycle)+ {+ searchFlag = (TMR_SR_SearchFlag)(searchFlag+ |TMR_SR_SEARCH_FLAG_DUTY_CYCLE_CONTROL);+ }++ if (reader->isStopNTags && !reader->continuousReading)+ {+ /**+ * Currently stop N Trigger is only supported for+ * sync read.+ **/ + searchFlag = (TMR_SR_SearchFlag)(searchFlag+ |TMR_SR_SEARCH_FLAG_RETURN_ON_N_TAGS);+ }++ SETU16(msg, *i, searchFlag);+ SETU16(msg, *i, timeout);+ if(reader->dutyCycle)+ {+ uint32_t offtime;+ ret = TMR_paramGet(reader,TMR_PARAM_READ_ASYNCOFFTIME,&offtime);+ SETU16(msg, *i, (uint16_t)offtime);+ }+ reader->dutyCycle = false;+ if (reader->continuousReading)+ {+ SETU16(msg, *i, metadataFlag);++ if (TMR_READER_STATS_FLAG_NONE != reader->statsFlag)+ {+ /**+ * To extend the flag byte, an EBV technique is to be used.+ * When the highest order bit of the flag byte is used,+ * it signals the reader’s parser, that another flag byte is to follow+ */+ if ((0x80) > reader->statsFlag)+ {+ SETU16(msg, *i, (uint16_t)reader->statsFlag);+ }+ else+ {+ SETU16(msg, *i, ((uint16_t)reader->statsFlag));+ }+ }+ else+ {+ if (TMR_SR_STATUS_NONE != reader->streamStats)+ {+ /* Add status report flags, so that the status stream responses are received */+ SETU16(msg, *i, (uint16_t)reader->streamStats);+ }+ }+ }++ /**+ * Add the no of tags to be read requested by user+ * in stop N tag reads.Currently only supported for+ * sync read.+ **/+ if (reader->isStopNTags && !reader->continuousReading)+ {+ SETU32(msg ,*i, (uint32_t)reader->numberOfTagsToRead);+ }++ /*+ * Earlier, this filter bytes were skipped for a null filter and gen2 0 access password.+ * as the filterbytes it self has the checks internally, these were removed.+ * for some protocols (such as ISO180006B) the "null" filter is not zero-length, but we don't need to send+ * that with this command.+ */+ if (TMR_TAG_PROTOCOL_ISO180006B == protocol && NULL == filter)+ {+ /* ISO18000-6B should not include any filter arg bytes if null */+ }+ else+ {+ ret = filterbytes(protocol, filter, &msg[optbyte], i, msg,+ accessPassword, true);+ }++ if (reader->continuousReading)+ {+ msg[optbyte] |= TMR_SR_GEN2_SINGULATION_OPTION_FLAG_METADATA;+ }+ if (isSecureAccessEnabled)+ {+ msg[optbyte] |= TMR_SR_GEN2_SINGULATION_OPTION_SECURE_READ_DATA;+ }++ return ret;+}++TMR_Status+TMR_SR_cmdReadTagMultiple(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_SearchFlag searchFlag,+ const TMR_TagFilter *filter, TMR_TagProtocol protocol,+ uint32_t *tagCount)+{+ TMR_Status ret;+ TMR_SR_SerialReader *sr;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ ret = TMR_SR_msgSetupReadTagMultiple(reader, msg, &i, timeout, searchFlag,+ filter, protocol, 0);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ msg[1] = i - 3; /* Install length */++ sr = &reader->u.serialReader;+ sr->opCode = TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE;+ if (reader->continuousReading)+ {+ uint8_t opcode;+ ret = TMR_SR_sendMessage(reader, msg, &opcode, timeout);+ *tagCount = (uint32_t)0;+ return ret;+ }+ else+ {+ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ if (NULL != tagCount)+ {+ if (4 == msg[1])+ {+ /* Plain 1-byte count: Reader without large-tag-population support */+ *tagCount = GETU8AT(msg, 8);+ }+ else if (5 == msg[1])+ {+ /* Later 1-byte count: ISO18k select option included in reply */+ *tagCount = GETU8AT(msg, 9);+ }+ else if (7 == msg[1])+ {+ /* Plain 4-byte count: Reader with large-tag-population support */+ *tagCount = GETU32AT(msg, 8);+ }+ else if (8 == msg[1])+ {+ /* Later 4-byte count: Large-tag-population support and ISO18k+ * select option included in reply.+ */+ *tagCount = GETU32AT(msg, 9);+ }+ else+ {+ return TMR_ERROR_PARSE;+ }+ }++ return TMR_SUCCESS;+ }+}+++TMR_Status+TMR_SR_executeEmbeddedRead(TMR_Reader *reader, uint8_t *msg, uint16_t timeout,+ TMR_SR_MultipleStatus *status)+{+ TMR_Status ret;+ uint8_t i, len, index;+ uint8_t newMsg[TMR_SR_MAX_PACKET_SIZE];+ + if (reader->continuousReading)+ {+ uint8_t opcode = TMR_SR_OPCODE_MULTI_PROTOCOL_TAG_OP;+ i = 2;+ SETU8(newMsg, i, opcode); /* Opcode */+ + /* Timeout should be zero for true continuous reading */+ SETU16(newMsg, i, 0);+ SETU8(newMsg, i, (uint8_t)0x1); /* TM Option 1, for continuous reading */+ SETU8(newMsg, i, (uint8_t)TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE); /* sub command opcode */+ SETU16(newMsg, i, (uint16_t)0x0000); /* search flags, only 0x0001 is supported */+ SETU8(newMsg, i, (uint8_t)TMR_TAG_PROTOCOL_GEN2); /* protocol ID */++ len = msg[1];+ index = i;+ SETU8(newMsg, i, 0); /* Protocol command length (initialize to 0)*/++ /* Copy the protocol command including the command opcode (len + 1)*/+ memcpy(&newMsg[i], &msg[2], (size_t)(len + 1));+ i += len + 1;++ /* Insert the exact protocol command length */+ newMsg[index] = i - index - 2;++ /* Install the total packet length*/+ newMsg[1]=i - 3; ++ ret = TMR_SR_sendMessage(reader, newMsg, &opcode, timeout);+ status->tagsFound = status->successCount = status->failureCount = 0;++ return ret;+ }+ else+ {+ uint16_t searchFlags = GETU16AT(msg, 4);++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ if (NULL != status)+ {+ int readIdx = 8;+ if ((TMR_SR_SEARCH_FLAG_LARGE_TAG_POPULATION_SUPPORT & searchFlags) &&+ ((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])))+ {+ /* Only in case of M6e, the tag length will be 4 bytes */+ status->tagsFound = (uint16_t)GETU32AT(msg, readIdx);+ readIdx += 4;+ }+ else+ {+ status->tagsFound = GETU8AT(msg, readIdx);+ readIdx += 1;+ }+ readIdx += 2;+ status->successCount = GETU16AT(msg, readIdx);+ readIdx += 2;+ status->failureCount = GETU16AT(msg, readIdx);+ readIdx += 2;+ }+ }++ return TMR_SUCCESS;+}++void+TMR_SR_msgAddGEN2WriteTagEPC(uint8_t *msg, uint8_t *i, uint16_t timeout, uint8_t *epc, uint8_t count)+{+ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_ID);+ SETU16(msg, *i, timeout); /* timeout */+ SETU16(msg, *i, 0); /* RFU 2 bytes */+ memcpy(&msg[*i], epc, count);+ *i += count;+}++void+TMR_SR_msgAddGEN2DataRead(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Bank bank, uint32_t wordAddress, uint8_t len, uint8_t option, bool withMetaData)+{++ SETU8(msg, *i, TMR_SR_OPCODE_READ_TAG_DATA);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, option); /* Options - initialize */+ if (withMetaData)+ {+ SETU16(msg, *i, 0x0000); /* metadata flags - initialize */+ }+ SETU8(msg, *i, bank);+ SETU32(msg, *i, wordAddress);+ SETU8(msg, *i, len);+}+++void+TMR_SR_msgAddGEN2DataWrite(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Bank bank, uint32_t address)+{++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_DATA);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, 0); /* Option - initialize */+ SETU32(msg, *i, address);+ SETU8(msg, *i, bank);+}+++void+TMR_SR_msgAddGEN2LockTag(uint8_t *msg, uint8_t *i, uint16_t timeout, uint16_t mask,+ uint16_t action, TMR_GEN2_Password accessPassword)+{++ SETU8(msg, *i, TMR_SR_OPCODE_LOCK_TAG);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, 0); /* Option - initialize */+ SETU32(msg, *i, accessPassword);+ SETU16(msg, *i, mask);+ SETU16(msg, *i, action);+}+++void+TMR_SR_msgAddGEN2KillTag(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Password password)+{++ SETU8(msg, *i, TMR_SR_OPCODE_KILL_TAG);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, 0); /* Option - initialize */+ SETU32(msg, *i, password);+ SETU8(msg, *i, 0); /* RFU */+}++void+TMR_SR_msgAddGEN2BlockWrite(uint8_t *msg, uint8_t *i, uint16_t timeout,TMR_GEN2_Bank bank, uint32_t wordPtr, uint32_t wordCount, uint16_t* data, uint32_t accessPassword, TMR_TagFilter* target)+{+ uint8_t option=0,rec; + SETU8(msg,*i,TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i,timeout);+ SETU8(msg,*i,0x00);//chip type+ rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg,*i,0x00);+ SETU8(msg,*i,0xC7);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg,accessPassword,true);+ msg[rec]=msg[rec]|option;+ SETU8(msg,*i,0x00);+ SETU8(msg,*i,bank);+ SETU32(msg,*i,wordPtr);+ SETU8(msg,*i,(uint8_t)wordCount);+ {+ uint32_t iWord;+ for (iWord=0; iWord<wordCount; iWord++)+ {+ SETU8(msg, *i, ((data[iWord]>>8)&0xFF));+ SETU8(msg, *i, ((data[iWord]>>0)&0xFF));+ }+ }+}++void+TMR_SR_msgAddGEN2BlockPermaLock(uint8_t *msg, uint8_t *i, uint16_t timeout, uint32_t readLock, TMR_GEN2_Bank bank, uint32_t blockPtr, uint32_t blockRange, uint16_t* mask, uint32_t accessPassword,TMR_TagFilter* target)+{+ uint8_t option=0,rec; + SETU8(msg,*i,TMR_SR_OPCODE_ERASE_BLOCK_TAG_SPECIFIC);+ SETU16(msg,*i,timeout);+ SETU8(msg,*i,0x00);+ rec=*i;+ SETU8(msg,*i,0x40);+ SETU8(msg,*i,0x01);+ filterbytes(TMR_TAG_PROTOCOL_GEN2,target, &option, i, msg,accessPassword,true);+ msg[rec]=msg[rec]|option;+ SETU8(msg,*i,0x00);+ SETU8(msg,*i,(uint8_t)readLock);++ SETU8(msg,*i,bank);+ SETU32(msg,*i,blockPtr);+ SETU8(msg,*i,(uint8_t)blockRange);+ if (readLock==0x01)+ {+ SETU16(msg, *i, *mask);+ }++}++void+TMR_SR_msgAddGEN2BlockErase(uint8_t *msg, uint8_t *i, uint16_t timeout,+ uint32_t wordPtr, TMR_GEN2_Bank bank, uint8_t wordCount,+ uint32_t accessPassword, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_ERASE_BLOCK_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, 0x00);++ rec = *i;+ SETU8(msg, *i, 0x40);+ SETU8(msg, *i, 0x00); /* Block erase */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec] = msg[rec] | option;++ SETU32(msg, *i, wordPtr);+ SETU8(msg, *i, bank);+ SETU8(msg,*i, wordCount);+}++TMR_Status+TMR_SR_cmdWriteGen2TagEpc(TMR_Reader *reader, const TMR_TagFilter *filter, TMR_GEN2_Password accessPassword, + uint16_t timeout, uint8_t count, const uint8_t *id, bool lock)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, optbyte;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_WRITE_TAG_ID);+ SETU16(msg, i, timeout);+ optbyte = i;+ SETU8(msg, i, 0);+ ++ ret = filterbytes(TMR_TAG_PROTOCOL_GEN2, filter, &msg[optbyte], &i, msg,+ accessPassword, true);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ if (0 == msg[optbyte])+ {+ SETU8(msg, i, 0); // Initialize second RFU byte to zero+ }++ if (i + count + 1 > TMR_SR_MAX_PACKET_SIZE)+ {+ return TMR_ERROR_TOO_BIG;+ }++ memcpy(&msg[i], id, count);+ i += count;+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}+++TMR_Status+TMR_SR_cmdClearTagBuffer(TMR_Reader *reader)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_CLEAR_TAG_ID_BUFFER);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}++TMR_Status TMR_SR_cmdGetTagsRemaining(TMR_Reader *reader, uint16_t *tagCount)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ TMR_Status ret;+ + i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_TAG_ID_BUFFER);+ msg[1] = i-3; /* Install length */+ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ + *tagCount = GETU16AT(msg, 7) - GETU16AT(msg, 5);+ return TMR_SUCCESS;+}++void+TMR_SR_parseMetadataFromMessage(TMR_Reader *reader, TMR_TagReadData *read, uint16_t flags,+ uint8_t *i, uint8_t msg[])+{+ int msgEpcLen;++ read->metadataFlags = flags;+ read->tag.protocol = TMR_TAG_PROTOCOL_NONE;+ read->readCount = 0;+ read->rssi = 0;+ read->antenna = 0;+ read->phase = 0;+ read->frequency = 0;+ read->dspMicros = 0;+ read->timestampLow = 0;+ read->timestampHigh = 0;+ read->isAsyncRead = false;++ switch(reader->u.serialReader.versionInfo.hardware[0])+ {+ case TMR_SR_MODEL_M5E:+ read->gpioCount = 2;+ break;+ case TMR_SR_MODEL_M6E:+ read->gpioCount = 4;+ break;+ default:+ read->gpioCount = 4;+ break;+ }+ ++ /* Fill in tag data from response */+ if (flags & TMR_TRD_METADATA_FLAG_READCOUNT)+ {+ read->readCount = GETU8(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_RSSI)+ {+ read->rssi = (int8_t)GETU8(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_ANTENNAID)+ {+ read->antenna = GETU8(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_FREQUENCY)+ {+ read->frequency = GETU24(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_TIMESTAMP)+ {+ read->dspMicros = GETU32(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_PHASE)+ {+ read->phase = GETU16(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_PROTOCOL)+ {+ read->tag.protocol = (TMR_TagProtocol)GETU8(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_DATA)+ {+ int msgDataLen, copyLen;+ + msgDataLen = tm_u8s_per_bits(GETU16(msg, *i));+ read->data.len = msgDataLen;+ copyLen = msgDataLen;+ if (copyLen > read->data.max)+ {+ copyLen = read->data.max;+ }+ if (NULL != read->data.list)+ {+ memcpy(read->data.list, &msg[*i], copyLen);+ }++ /**+ * if the gen2AllMemoryBankEnabled is enabled,+ * extract the values+ **/+ if (reader->u.serialReader.gen2AllMemoryBankEnabled)+ {+ uint16_t dataLength = read->data.len;+ uint8_t readOffSet = 0;+ uint8_t bank;+ uint16_t epcDataLength;+ while (dataLength != 0)+ {+ if (readOffSet >= dataLength)+ break;+ bank = ((read->data.list[readOffSet] >> 4) & 0x1F);+ epcDataLength = (read->data.list[readOffSet + 1] * 2);+ switch (bank)+ {+ case TMR_GEN2_BANK_EPC:+ {+ read->epcMemData.len = epcDataLength;+ if (epcDataLength > read->epcMemData.max)+ {+ epcDataLength = read->epcMemData.max;+ }+ if (NULL != read->epcMemData.list)+ {+ memcpy(read->epcMemData.list, (read->data.list + readOffSet + 2), epcDataLength);+ }+ readOffSet += (epcDataLength + 2);+ break;++ }+ case TMR_GEN2_BANK_RESERVED:+ {+ read->reservedMemData.len = epcDataLength;+ if (epcDataLength > read->epcMemData.max)+ {+ epcDataLength = read->reservedMemData.max;+ }+ if (NULL != read->reservedMemData.list)+ {+ memcpy(read->reservedMemData.list, (read->data.list + readOffSet + 2), epcDataLength);+ }+ readOffSet += (epcDataLength + 2);+ break;++ }+ case TMR_GEN2_BANK_TID:+ {+ read->tidMemData.len = epcDataLength;+ if (epcDataLength > read->tidMemData.max)+ {+ epcDataLength = read->tidMemData.max;+ }+ if (NULL != read->tidMemData.list)+ {+ memcpy(read->tidMemData.list, (read->data.list + readOffSet + 2), epcDataLength);+ }+ readOffSet += (epcDataLength + 2);+ break;++ }+ case TMR_GEN2_BANK_USER:+ {+ read->userMemData.len = epcDataLength;+ if (epcDataLength > read->userMemData.max)+ {+ epcDataLength = read->userMemData.max;+ }+ if (NULL != read->userMemData.list)+ {+ memcpy(read->userMemData.list, (read->data.list + readOffSet + 2), epcDataLength);+ }+ readOffSet += (epcDataLength + 2);+ break;++ }+ default:+ break;+ }+ }+ }+ /**+ * Now, we extracted all the values,+ * Disable the gen2AllMemoryBankEnabled option.+ **/+ reader->u.serialReader.gen2AllMemoryBankEnabled = false;++ *i += msgDataLen;+ }+ if (flags & TMR_TRD_METADATA_FLAG_GPIO_STATUS)+ {+ int j;+ uint8_t gpioByte=GETU8(msg, *i);+ for (j=0;j<read->gpioCount;j++) + {+ read->gpio[j].id = j+1;+ read->gpio[j].high = (((gpioByte >> j)&0x1)== 1);+ }+ }++ msgEpcLen = tm_u8s_per_bits(GETU16(msg, *i)); + if (TMR_TAG_PROTOCOL_ATA != read->tag.protocol)+ {+ /* ATA protocol does not have TAG CRC */+ msgEpcLen -= 2; /* Remove 2 bytes CRC*/+ }+ if (TMR_TAG_PROTOCOL_GEN2 == read->tag.protocol)+ { + read->tag.u.gen2.pc[0] = GETU8(msg, *i);+ read->tag.u.gen2.pc[1] = GETU8(msg, *i);+ msgEpcLen -= 2;+ read->tag.u.gen2.pcByteCount = 2;++ /* Add support for XPC bits+ * XPC_W1 is present, when the 6th most significant bit of PC word is set+ */+ if ((read->tag.u.gen2.pc[0] & 0x02) == 0x02)+ {+ /* When this bit is set, the XPC_W1 word will follow the PC word+ * Our TMR_Gen2_TagData::pc has enough space, so copying to the same.+ */+ read->tag.u.gen2.pc[2] = GETU8(msg, *i);+ read->tag.u.gen2.pc[3] = GETU8(msg, *i);+ msgEpcLen -= 2; /* EPC length will be length - 4(PC + XPC_W1)*/+ read->tag.u.gen2.pcByteCount += 2; /* PC bytes are now 4*/++ if ((read->tag.u.gen2.pc[2] & 0x80) == 0x80)+ {+ /*+ * If the most siginificant bit of XPC_W1 is set, then there exists+ * XPC_W2. A total of 6 (PC + XPC_W1 + XPC_W2 bytes)+ */+ read->tag.u.gen2.pc[4] = GETU8(msg, *i);+ read->tag.u.gen2.pc[5] = GETU8(msg, *i);+ msgEpcLen -= 2; /* EPC length will be length - 6 (PC + XPC_W1 + XPC_W2)*/+ read->tag.u.gen2.pcByteCount += 2; /* PC bytes are now 6 */+ }+ } + }+ read->tag.epcByteCount = msgEpcLen;+ if (read->tag.epcByteCount > TMR_MAX_EPC_BYTE_COUNT)+ {+ read->tag.epcByteCount = TMR_MAX_EPC_BYTE_COUNT;+ }++ memcpy(read->tag.epc, &msg[*i], read->tag.epcByteCount);+ *i += msgEpcLen;+ if (TMR_TAG_PROTOCOL_ATA != read->tag.protocol)+ { + read->tag.crc = GETU16(msg, *i);+ }+ else+ {+ read->tag.crc = 0xffff;+ }++ if(reader->continuousReading)+ {+ read->isAsyncRead = true;+ }+ else+ {+ read->isAsyncRead = false;+ }++}++void+TMR_SR_parseMetadataOnly(TMR_Reader *reader, TMR_TagReadData *read, uint16_t flags,+ uint8_t *i, uint8_t msg[])+{+ read->metadataFlags = flags;+ read->tag.protocol = TMR_TAG_PROTOCOL_NONE;+ read->readCount = 0;+ read->rssi = 0;+ read->antenna = 0;+ read->phase = 0;+ read->frequency = 0;+ read->dspMicros = 0;+ read->timestampLow = 0;+ read->timestampHigh = 0;+ read->isAsyncRead = false;++ switch(reader->u.serialReader.versionInfo.hardware[0])+ {+ case TMR_SR_MODEL_M5E:+ read->gpioCount = 2;+ break;+ case TMR_SR_MODEL_M6E:+ read->gpioCount = 4;+ break;+ default:+ read->gpioCount = 4;+ break;+ }++ /* Fill in tag data from response */+ if (flags & TMR_TRD_METADATA_FLAG_READCOUNT)+ {+ read->readCount = GETU8(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_RSSI)+ {+ read->rssi = GETU8(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_ANTENNAID)+ {+ read->antenna = GETU8(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_FREQUENCY)+ {+ read->frequency = GETU24(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_TIMESTAMP)+ {+ read->dspMicros = GETU32(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_PHASE)+ {+ read->phase = GETU16(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_PROTOCOL)+ {+ read->tag.protocol = (TMR_TagProtocol)GETU8(msg, *i);+ }+ if (flags & TMR_TRD_METADATA_FLAG_DATA)+ {+ int msgDataLen, copyLen;++ msgDataLen = tm_u8s_per_bits(GETU16(msg, *i));+ read->data.len = msgDataLen;+ copyLen = msgDataLen;+ if (copyLen > read->data.max)+ {+ copyLen = read->data.max;+ }+ memcpy(read->data.list, &msg[*i], copyLen);+ *i += msgDataLen;+ }+ if (flags & TMR_TRD_METADATA_FLAG_GPIO_STATUS)+ {+ int j;+ uint8_t gpioByte=GETU8(msg, *i);+ for (j=0;j<read->gpioCount ;j++) + {+ read->gpio[j].id = j+1;+ read->gpio[j].high = (((gpioByte >> j)&0x1)== 1);+ }+ }+}++void+TMR_SR_postprocessReaderSpecificMetadata(TMR_TagReadData *read, TMR_SR_SerialReader *sr)+{+ uint16_t j;+ uint32_t timestampLow;+ uint64_t currTime64, lastSentTagTime64; /*for comparison*/+ int32_t tempDiff;++ timestampLow = sr->readTimeLow;+ read->timestampHigh = sr->readTimeHigh;++ timestampLow = timestampLow + read->dspMicros;+ currTime64 = ((uint64_t)read->timestampHigh << 32) | timestampLow;+ lastSentTagTime64 = ((uint64_t)sr->lastSentTagTimestampHigh << 32) | sr->lastSentTagTimestampLow;+ if (lastSentTagTime64 >= currTime64)+ {+ tempDiff = (int32_t)(currTime64 - lastSentTagTime64);+ timestampLow = timestampLow - tempDiff + 1;+ if (timestampLow < sr->lastSentTagTimestampLow) /*account for overflow*/+ {+ read->timestampHigh++;+ }+ }+ if (timestampLow < sr->readTimeLow) /* Overflow */+ {+ read->timestampHigh++;+ }+ read->timestampLow = timestampLow;+ sr->lastSentTagTimestampHigh = read->timestampHigh;+ sr->lastSentTagTimestampLow = read->timestampLow;++ {+ uint8_t tx;+ uint8_t rx;+ tx = (read->antenna >> 4) & 0xF;+ rx = (read->antenna >> 0) & 0xF;++ // Due to limited space, Antenna 16 wraps around to 0+ if (0 == tx) { tx = 16; }+ if (0 == rx) { rx = 16; }++ for (j = 0; j < sr->txRxMap->len; j++)+ {+ if (rx == sr->txRxMap->list[j].rxPort &&+ tx == sr->txRxMap->list[j].txPort)+ {+ read->antenna = sr->txRxMap->list[j].antenna;+ if (read->gpioCount > 2)+ {+ if (read->gpio[2].high)+ read->antenna += 16;+ }+ break;+ }+ }+ }+}++#ifdef TMR_ENABLE_ISO180006B+TMR_Status+TMR_SR_cmdISO180006BReadTagData(TMR_Reader *reader,+ uint16_t timeout, uint8_t address,+ uint8_t length, const TMR_TagFilter *filter,+ TMR_TagReadData *read)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t copylen, i;++ if (length > 8+ || filter == NULL+ || TMR_FILTER_TYPE_TAG_DATA != filter->type+ || filter->u.tagData.epcByteCount != 8)+ {+ return TMR_ERROR_INVALID;+ }++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_READ_TAG_DATA);+ SETU16(msg, i, timeout);+ SETU8(msg, i, 0x01); /* Standard read operations */+ SETU8(msg, i, TMR_SR_ISO180006B_COMMAND_READ);+ SETU8(msg, i, 0x00); /* RFU */+ SETU8(msg, i, length);+ SETU8(msg, i, address);+ memcpy(&msg[i], filter->u.tagData.epc, 8);+ i += 8;+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ read->metadataFlags = TMR_TRD_METADATA_FLAG_DATA;+ read->tag.protocol = TMR_TAG_PROTOCOL_ISO180006B;+ read->tag.epcByteCount = 0;++ read->data.len = msg[1];+ copylen = (uint8_t)read->data.len;+ if (copylen > read->data.max)+ {+ copylen = (uint8_t)read->data.max;+ }+ if (NULL != read->data.list)+ {+ memcpy(read->data.list, &msg[5], copylen);+ }++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdISO180006BWriteTagData(TMR_Reader *reader,+ uint16_t timeout, uint8_t address,+ uint8_t count, const uint8_t data[],+ const TMR_TagFilter *filter)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;++ SETU8(msg, i, TMR_SR_OPCODE_WRITE_TAG_DATA);+ SETU16(msg, i, timeout);+ if (NULL != filter+ && TMR_FILTER_TYPE_TAG_DATA == filter->type+ && filter->u.tagData.epcByteCount == 8)+ {+ SETU8(msg, i, + TMR_SR_ISO180006B_WRITE_OPTION_READ_VERIFY_AFTER+ | TMR_SR_ISO180006B_WRITE_OPTION_COUNT_PROVIDED); + SETU8(msg, i, TMR_SR_ISO180006B_COMMAND_WRITE4BYTE);+ SETU8(msg, i, TMR_SR_ISO180006B_WRITE_LOCK_NO);+ SETU8(msg, i, address);+ memcpy(&msg[i], filter->u.tagData.epc, 8);+ i += 8;+ }+ else+ {+ SETU8(msg, i, TMR_SR_ISO180006B_WRITE_OPTION_GROUP_SELECT + | TMR_SR_ISO180006B_WRITE_OPTION_COUNT_PROVIDED);+ SETU8(msg, i, TMR_SR_ISO180006B_COMMAND_WRITE4BYTE_MULTIPLE);+ SETU8(msg, i, TMR_SR_ISO180006B_WRITE_LOCK_NO);+ SETU8(msg, i, address);+ /* + * Actually, we don't use password in case of iso.+ * passing 1, instead of '0' fixes the crash.+ */+ ret = filterbytes(TMR_TAG_PROTOCOL_ISO180006B, filter, NULL,+ &i, msg, 1, false);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ }+ SETU16(msg, i, count);+ memcpy(&msg[i], data, count);+ i += count;+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);++}+++TMR_Status+TMR_SR_cmdISO180006BLockTag(TMR_Reader *reader, uint16_t timeout,+ uint8_t address, const TMR_TagFilter *filter)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ if (filter == NULL+ || TMR_FILTER_TYPE_TAG_DATA != filter->type+ || filter->u.tagData.epcByteCount != 8)+ {+ return TMR_ERROR_INVALID;+ }++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_LOCK_TAG);+ SETU16(msg, i, timeout);+ SETU8(msg, i, TMR_SR_ISO180006B_LOCK_OPTION_TYPE_FOLLOWS);+ SETU8(msg, i, TMR_SR_ISO180006B_LOCK_TYPE_QUERYLOCK_THEN_LOCK);+ SETU8(msg, i, address);+ memcpy(&msg[i], filter->u.tagData.epc, 8);+ i += 8;+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}+#endif /* TMR_ENABLE_ISO180006B */++TMR_Status+TMR_SR_cmdGEN2WriteTagData(TMR_Reader *reader,+ uint16_t timeout, TMR_GEN2_Bank bank,+ uint32_t address, uint8_t count,+ const uint8_t data[],+ TMR_GEN2_Password accessPassword,+ const TMR_TagFilter *filter)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t optbyte, i;++ i = 2;+ TMR_SR_msgAddGEN2DataWrite(msg, &i, timeout, bank, address);+ optbyte = 5;+ ret = filterbytes(TMR_TAG_PROTOCOL_GEN2, filter, &msg[optbyte], &i, msg,+ accessPassword, true);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ if (i + count + 1 > TMR_SR_MAX_PACKET_SIZE)+ {+ return TMR_ERROR_TOO_BIG;+ }+ memcpy(&msg[i], data, count);+ i += count;+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++TMR_Status+TMR_SR_cmdGEN2LockTag(TMR_Reader *reader, uint16_t timeout,+ uint16_t mask, uint16_t action, + TMR_GEN2_Password accessPassword, + const TMR_TagFilter *filter)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t optbyte, i;++ i = 2;+ TMR_SR_msgAddGEN2LockTag(msg, &i, timeout, mask, action, accessPassword);+ optbyte = 5;+ ret = filterbytes(TMR_TAG_PROTOCOL_GEN2, filter, &msg[optbyte], &i, msg,+ 0, false);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++TMR_Status+TMR_SR_cmdrebootReader(TMR_Reader *reader)+{+ TMR_Status ret;+ TMR_SR_SerialReader *sr;+ TMR_SR_SerialTransport *transport;++ sr = &reader->u.serialReader;+ transport = &sr->transport;++ /*+ * 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);++ return ret;+}++TMR_Status+TMR_SR_cmdKillTag(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password killPassword, + const TMR_TagFilter *filter)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t optbyte, i;++ i = 2;+ TMR_SR_msgAddGEN2KillTag(msg, &i, timeout, killPassword);+ optbyte = 5;+ ret = filterbytes(TMR_TAG_PROTOCOL_GEN2, filter, &msg[optbyte], &i, msg, + 0, false);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}+++TMR_Status+TMR_SR_cmdGEN2ReadTagData(TMR_Reader *reader,+ uint16_t timeout, TMR_GEN2_Bank bank,+ uint32_t address, uint8_t length,+ uint32_t accessPassword, const TMR_TagFilter *filter,+ TMR_TagReadData *read)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t optbyte, i, mdfbyte;+ uint32_t starttimeHigh, starttimeLow;++ i = 2;+ TMR_SR_msgAddGEN2DataRead(msg, &i, timeout, bank, address, length, 0x00, true);+ optbyte = 5;+ ret = filterbytes(TMR_TAG_PROTOCOL_GEN2, filter, &msg[optbyte], &i, msg, + accessPassword, true);+++ msg[optbyte] |= 0x10;+ mdfbyte = 6;+ read->metadataFlags |= TMR_TRD_METADATA_FLAG_DATA | TMR_TRD_METADATA_FLAG_PROTOCOL;+ SETU16(msg, mdfbyte, read->metadataFlags);+++ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ msg[1] = i - 3; /* Install length */++ /* Cache the read time so it can be put in tag read data later */+ tm_gettime_consistent(&starttimeHigh, &starttimeLow);+ reader->u.serialReader.readTimeHigh = starttimeHigh;+ reader->u.serialReader.readTimeLow = starttimeLow;++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ if (NULL != read->data.list)+ {+ i = 8;+ + TMR_SR_parseMetadataOnly(reader, read, read->metadataFlags , &i, msg);+ TMR_SR_postprocessReaderSpecificMetadata(read, &reader->u.serialReader);++ /* Read Tag Data doesn't put actual tag data inside the metadata fields.+ * Read the actual data here (remainder of response.) */+ {+ uint16_t dataLength;+ uint16_t copyLength;+ + copyLength = dataLength = msg[1] + 5 - i;+ if (copyLength > read->data.max)+ {+ copyLength = read->data.max;+ }+ read->data.len = copyLength;+ memcpy(read->data.list, &msg[i], copyLength);+ i += dataLength;+ }+ }++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdSetTxRxPorts(TMR_Reader *reader, uint8_t txPort, uint8_t rxPort)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_ANTENNA_PORT);+ SETU8(msg, i, txPort);+ SETU8(msg, i, rxPort);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetAntennaSearchList(TMR_Reader *reader, uint8_t count,+ const TMR_SR_PortPair *ports)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ uint8_t j;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_ANTENNA_PORT);+ SETU8(msg, i, 2); /* logical antenna list option */+ for (j = 0; j < count ; j++)+ {+ SETU8(msg, i, ports[j].txPort);+ SETU8(msg, i, ports[j].rxPort);+ }+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}++TMR_Status+TMR_SR_cmdSetAntennaPortPowersAndSettlingTime(+ TMR_Reader *reader, uint8_t count, const TMR_SR_PortPowerAndSettlingTime *ports)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t j, i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_ANTENNA_PORT);+ SETU8(msg, i, 4); /* power and settling time option */++ for (j = 0; j < count; j++)+ {+ SETU8(msg, i, ports[j].port);+ SETS16(msg, i, (int16_t) ports[j].readPower);+ SETS16(msg, i, (int16_t)ports[j].writePower);+ SETU16(msg, i, ports[j].settlingTime);+ }+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetReadTxPower(TMR_Reader *reader, int32_t power)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_READ_TX_POWER);++ /** The read power should always be a 16 bit value */+ if (power > 32767 || power < -32768)+ {+ return TMR_ERROR_ILLEGAL_VALUE;+ }++ SETS16(msg,i, (int16_t)power);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetProtocol(TMR_Reader *reader, TMR_TagProtocol protocol)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_TAG_PROTOCOL);+ SETU16(msg, i, protocol);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetWriteTxPower(TMR_Reader *reader, int32_t power)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_WRITE_TX_POWER);++ /** The write power should always be a 16 bit value */+ if (power > 32767 || power < -32768)+ {+ return TMR_ERROR_ILLEGAL_VALUE;+ }++ SETS16(msg, i, (int16_t)power);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetFrequencyHopTable(TMR_Reader *reader, uint8_t count,+ const uint32_t *table)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, j;++ i = 2;++ if (count > 62)+ {+ return TMR_ERROR_TOO_BIG;+ }++ SETU8(msg, i, TMR_SR_OPCODE_SET_FREQ_HOP_TABLE);+ for (j = 0; j < count; j++)+ {+ SETU32(msg, i, table[j]);+ }+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetFrequencyHopTime(TMR_Reader *reader, uint32_t hopTime)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_FREQ_HOP_TABLE);+ SETU8(msg, i, 1); /* hop time option */+ SETU32(msg, i, hopTime);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetGPIO(TMR_Reader *reader, uint8_t gpio, bool high)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_USER_GPIO_OUTPUTS);+ SETU8(msg, i, gpio);+ SETU8(msg, i, (high == true));+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetRegion(TMR_Reader *reader, TMR_Region region)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_REGION);+ SETU8(msg, i, region);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetRegionLbt(TMR_Reader *reader, TMR_Region region, bool lbt)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_REGION);+ SETU8(msg, i, region);+ SETU8(msg, i, lbt ? 1 : 0);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetPowerMode(TMR_Reader *reader, TMR_SR_PowerMode mode)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_POWER_MODE);+ SETU8(msg, i, mode);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetUserMode(TMR_Reader *reader, TMR_SR_UserMode mode)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_USER_MODE);+ SETU8(msg, i, mode);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}+++TMR_Status+TMR_SR_cmdSetReaderConfiguration(TMR_Reader *reader, TMR_SR_Configuration key,+ const void *value)+{+ TMR_SR_SerialReader *sr = &reader->u.serialReader;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_READER_OPTIONAL_PARAMS);+ SETU8(msg, i, 1); /* key-value form of command */+ SETU8(msg, i, key);++ switch (key)+ {+ case TMR_SR_CONFIGURATION_ANTENNA_CONTROL_GPIO:+ SETU8(msg, i, *(uint8_t *)value);+ break;+ case TMR_SR_CONFIGURATION_TRIGGER_READ_GPIO:+ SETU8(msg, i, *(uint8_t *)value);+ break;+++ case TMR_SR_CONFIGURATION_UNIQUE_BY_ANTENNA:+ case TMR_SR_CONFIGURATION_UNIQUE_BY_DATA:+ case TMR_SR_CONFIGURATION_UNIQUE_BY_PROTOCOL:+ SETU8(msg, i, *(bool *)value ? 0 : 1);+ break;+ case TMR_SR_CONFIGURATION_TRANSMIT_POWER_SAVE:+ if(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0])+ {+ // Open loop power calibration+ SETU8(msg, i, *(bool *)value ? 2 : 1);+ }+ else+ {+ // Closed loop power calibration+ SETU8(msg, i, *(bool *)value ? 1 : 0);+ }+ break;+ case TMR_SR_CONFIGURATION_EXTENDED_EPC:+ case TMR_SR_CONFIGURATION_SAFETY_ANTENNA_CHECK:+ case TMR_SR_CONFIGURATION_SAFETY_TEMPERATURE_CHECK:+ case TMR_SR_CONFIGURATION_RECORD_HIGHEST_RSSI:+ case TMR_SR_CONFIGURATION_RSSI_IN_DBM:+ case TMR_SR_CONFIGURATION_SELF_JAMMER_CANCELLATION:+ case TMR_SR_CONFIGURATION_ENABLE_READ_FILTER:+ case TMR_SR_CONFIGURATION_SEND_CRC:+ SETU8(msg, i, *(bool *)value ? 1 : 0);+ break;++ case TMR_SR_CONFIGURATION_READ_FILTER_TIMEOUT:+ SETS32(msg, i, *(int32_t *)value);+ break;++ default:+ return TMR_ERROR_NOT_FOUND;+ }+ msg[1] = i - 3; /* Install length */++ return TMR_SR_send(reader, msg);+}++/**+ * Handles license key to enable protocol + *+ * @param reader The reader+ * @param option Option to set or erase the license key+ * @param key license key+ * @param key_len Length of license key or the key array+ * @param retData The response data+*/+++TMR_Status TMR_SR_cmdSetProtocolLicenseKey(TMR_Reader *reader, + TMR_SR_SetProtocolLicenseOption option, + uint8_t key[], int key_len,uint32_t *retData)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ TMR_Status ret;+ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_PROTOCOL_LICENSEKEY);+ SETU8(msg, i, option);++ if(TMR_SR_SET_LICENSE_KEY == option)+ {+ memcpy(msg+i, key, key_len);+ i+= key_len;+ }++ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (ret != TMR_SUCCESS)+ {+ return ret;+ }++ reader->u.serialReader.versionInfo.protocols = 0x00;+ for (i = 0; i < msg[1] - 2 ; i += 2)+ {+ reader->u.serialReader.versionInfo.protocols |= (1 << (GETU8AT(msg, 7 + i) - 1)); + }++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdSetProtocolConfiguration(TMR_Reader *reader, TMR_TagProtocol protocol,+ TMR_SR_ProtocolConfiguration key,+ const void *value)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ uint8_t BLF = 0;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_PROTOCOL_PARAM);+ SETU8(msg, i, protocol);+ if (TMR_TAG_PROTOCOL_GEN2 == key.protocol)+ {+ SETU8(msg, i, key.u.gen2);+ switch (key.u.gen2)+ {+ case TMR_SR_GEN2_CONFIGURATION_SESSION:+ SETU8(msg, i, *(TMR_GEN2_Session *)value);+ break;++ case TMR_SR_GEN2_CONFIGURATION_TAGENCODING:+ SETU8(msg, i, *(TMR_GEN2_TagEncoding *)value);+ break;++ case TMR_SR_GEN2_CONFIGURATION_LINKFREQUENCY:+ #ifndef BARE_METAL+ switch (*(int *)value)+ #else+ switch (*(TMR_GEN2_LinkFrequency *)value)+ #endif+ {+ case 40:+ BLF = 0x03;+ break;+ case 250:+ BLF = 0x00;+ break;+ case 320:+ BLF = 0x02;+ break;+ case 400:+ BLF = 0x02;+ break;+ case 640:+ BLF = 0x04;+ break;+ default:+ return TMR_ERROR_INVALID;+ }+ SETU8(msg, i, BLF);+ break;++ case TMR_SR_GEN2_CONFIGURATION_TARI:+ SETU8(msg, i, *(TMR_GEN2_Tari *)value);+ break;++ case TMR_SR_GEN2_CONFIGURATION_PROTCOLEXTENSION:+ SETU8(msg, i, *(TMR_GEN2_ProtocolExtension *)value);+ break;+ + case TMR_SR_GEN2_CONFIGURATION_TARGET:+ switch (*(TMR_GEN2_Target *)value)+ {+ case TMR_GEN2_TARGET_A:+ SETU16(msg, i, 0x0100);+ break;+ case TMR_GEN2_TARGET_B:+ SETU16(msg, i, 0x0101);+ break;+ case TMR_GEN2_TARGET_AB:+ SETU16(msg, i, 0x0000);+ break;+ case TMR_GEN2_TARGET_BA:+ SETU16(msg, i, 0x0001);+ break;+ default:+ return TMR_ERROR_INVALID;+ }+ break;+ + case TMR_SR_GEN2_CONFIGURATION_Q:+ {+ const TMR_SR_GEN2_Q *q = value;+ if (q->type == TMR_SR_GEN2_Q_DYNAMIC)+ {+ SETU8(msg, i, 0);+ }+ else if (q->type == TMR_SR_GEN2_Q_STATIC)+ {+ SETU8(msg, i, 1);+ SETU8(msg, i, q->u.staticQ.initialQ);+ }+ else+ {+ return TMR_ERROR_INVALID;+ }+ break;+ }++ case TMR_SR_GEN2_CONFIGURATION_BAP:+ {+ TMR_GEN2_Bap *bap;+ bap = (TMR_GEN2_Bap *)value;++ SETU8(msg, i, 0x01); //version+ SETU16(msg, i, 0x03);// currently we supports only this enable bits.+ SETU32(msg, i, bap->powerUpDelayUs);+ SETU32(msg, i, bap->freqHopOfftimeUs);+ /**+ * Currently support for M value and FlexQueryPayload has been disabled+ * TO DO: add support for these parameters when firmware support has added for this.+ **/ + break;+ }++ default:+ return TMR_ERROR_NOT_FOUND;+ }+ }+#ifdef TMR_ENABLE_ISO180006B+ else if (TMR_TAG_PROTOCOL_ISO180006B == key.protocol + || TMR_TAG_PROTOCOL_ISO180006B_UCODE == key.protocol)+ {+ switch (key.u.iso180006b)+ {+ case TMR_SR_ISO180006B_CONFIGURATION_LINKFREQUENCY:+ {+ switch (*(int *)value)+ {+ case 40:+ BLF = 0x01;+ break;+ case 160:+ BLF = 0x00;+ break;+ default:+ return TMR_ERROR_INVALID;+ }+ break;+ }+ case TMR_SR_ISO180006B_CONFIGURATION_MODULATION_DEPTH:+ {+ switch (*(int *)value)+ {+ case 0:+ BLF = TMR_ISO180006B_Modulation99percent;+ break;+ case 1:+ BLF = TMR_ISO180006B_Modulation11percent;+ break;+ default:+ return TMR_ERROR_INVALID;+ }+ break;+ }+ case TMR_SR_ISO180006B_CONFIGURATION_DELIMITER:+ {+ switch (*(int *)value)+ {+ case 1:+ BLF = TMR_ISO180006B_Delimiter1;+ break;+ case 4:+ BLF = TMR_ISO180006B_Delimiter4;+ break;+ default:+ return TMR_ERROR_INVALID;+ }+ break;+ }+ default:+ return TMR_ERROR_NOT_FOUND;+ }++ SETU8(msg, i, key.u.iso180006b);+ SETU8(msg, i, BLF);+ }+#endif /* TMR_ENABLE_ISO180006B */+ else+ {+ return TMR_ERROR_INVALID;+ }++ msg[1] = i - 3; /* Install length */+ return TMR_SR_send(reader, msg);+}+++TMR_Status TMR_SR_cmdGetTxRxPorts(TMR_Reader *reader, TMR_SR_PortPair *ant)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;++ SETU8(msg, i, TMR_SR_OPCODE_GET_ANTENNA_PORT);+ SETU8(msg, i, 0); /* just configured ports */+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ ant->txPort = msg[5];+ ant->rxPort = msg[6];+ + return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdAntennaDetect(TMR_Reader *reader, uint8_t *count,+ TMR_SR_PortDetect *ports)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, j; ++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_ANTENNA_PORT);+ SETU8(msg, i, 5); /* antenna detect option */+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ + for (i = 1, j = 0; i < msg[1] && j < *count; i += 2, j++)+ {+ ports[j].port = msg[i + 5];+ ports[j].detected = (msg[i + 6] == 1);+ }+ *count = j;++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetAntennaPortPowersAndSettlingTime(+ TMR_Reader *reader, uint8_t *count, TMR_SR_PortPowerAndSettlingTime *ports)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, j;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_ANTENNA_PORT);+ SETU8(msg, i, 4); /* power and settling time option */+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ + for (i = 1, j = 0; i < msg[1] && j < *count; i += 7, j++)+ {+ ports[j].port = GETU8AT(msg, i + 5);+ ports[j].readPower = (int16_t)GETS16AT(msg, i + 6);+ ports[j].writePower = (int16_t)GETS16AT(msg, i + 8);+ ports[j].settlingTime = GETU16AT(msg, i + 10);+ }+ *count = j;++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdGetAntennaReturnLoss(TMR_Reader *reader, TMR_PortValueList *ports)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, j, count;++ count = TMR_SR_MAX_ANTENNA_PORTS;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_ANTENNA_PORT);+ SETU8(msg, i, 6); /* antenna return loss option */+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ + for (i = 1, j = 0; i < msg[1] && j < count; i += 2, j++)+ {+ if (j < ports->max)+ {+ ports->list[j].port = (uint8_t)GETU8AT(msg, i + 5);+ ports->list[j].value = (int16_t)GETU8AT(msg, i + 6);+ }+ else+ {+ /* no sufficent memory, break from here */+ break;+ }+ }+ ports->len = (uint8_t)j;++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdGetReadTxPower(TMR_Reader *reader, int32_t *power)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_READ_TX_POWER);+ SETU8(msg, i, 0); /* just return power */+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ *power = (int32_t)GETS16AT(msg, 6);++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetReadTxPowerWithLimits(TMR_Reader *reader,+ TMR_SR_PowerWithLimits *power)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_READ_TX_POWER);+ SETU8(msg, i, 1); /* return limits */+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ power->setPower = GETU16AT(msg, 6);+ power->maxPower = GETU16AT(msg, 8);+ power->minPower = GETU16AT(msg, 10);++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetWriteTxPower(TMR_Reader *reader, int32_t *power)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_WRITE_TX_POWER);+ SETU8(msg, i, 0); /* just return power */+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ *power = (int32_t)GETS16AT(msg, 6);++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetFrequencyHopTable(TMR_Reader *reader, uint8_t *count,+ uint32_t *hopTable)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, j, len;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_FREQ_HOP_TABLE);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ len = msg[1] / 4;+ for (j = 0; i < *count && j < len ; j++)+ {+ hopTable[j] = GETU32AT(msg, 5 + 4*j);+ }+ *count = len;++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetFrequencyHopTime(TMR_Reader *reader, uint32_t *hopTime)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_FREQ_HOP_TABLE);+ SETU8(msg, i, 1); /* get time */+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ *hopTime = GETU32AT(msg, 6);++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetGPIO(TMR_Reader *reader, uint8_t *count, TMR_GpioPin *state)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE] = {0};+ uint8_t i, j, len, offset;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_USER_GPIO_INPUTS);+ SETU8(msg, i, 0x01); // option+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, reader->u.serialReader.commandTimeout);+ if (TMR_SUCCESS != ret)+ return ret;++ len = (msg[1] - 1)/3;+ if (len > *count)+ {+ len = *count;+ }++ offset = 6;+ for (j = 0; j < len ; j++)+ {+ state[j].id = msg[offset++];+ state[j].output = (1 == msg[offset++]) ? true : false;+ state[j].high = (1 == msg[offset++]) ? true : false;+ }+ *count = len;++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdGetGPIODirection(TMR_Reader *reader, uint8_t pin, bool *out)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_USER_GPIO_OUTPUTS);+ SETU8(msg, i, pin);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ return ret;++ *out = (msg[6] == 1);++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdSetGPIODirection(TMR_Reader *reader, uint8_t pin, bool out)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_USER_GPIO_OUTPUTS);+ SETU8(msg, i, 1); /* Option flag */+ SETU8(msg, i, pin);+ SETU8(msg, i, (out == true) ? 1 : 0);+ SETU8(msg, i, 0); /* New value if output */+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ return ret;++ return TMR_SUCCESS;+}++TMR_Status +TMR_SR_cmdGetCurrentProtocol(TMR_Reader *reader, TMR_TagProtocol *protocol)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_TAG_PROTOCOL);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ *protocol = (TMR_TagProtocol)GETU16AT(msg, 5);++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdGetRegion(TMR_Reader *reader, TMR_Region *region)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ + i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_REGION);+ msg[1] = i - 3; /* Install length */+ + ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ *region = (TMR_Region)GETU8AT(msg, 5);+ + return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdGetRegionConfiguration(TMR_Reader *reader,+ TMR_SR_RegionConfiguration key,+ void *value)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_REGION);+ SETU8(msg, i, 1);+ SETU8(msg, i, key);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ switch (key)+ {+ case TMR_SR_REGION_CONFIGURATION_LBT_ENABLED:+ *(bool *)value = (GETU8AT(msg, 8) == 1);+ break;+ default:+ return TMR_ERROR_NOT_FOUND;+ }++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetPowerMode(TMR_Reader *reader, TMR_SR_PowerMode *mode)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_POWER_MODE);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ *mode = (TMR_SR_PowerMode)GETU8AT(msg, 5);++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetUserMode(TMR_Reader *reader, TMR_SR_UserMode *mode)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_USER_MODE);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ *mode = (TMR_SR_UserMode)GETU8AT(msg, 5);++ return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetReaderConfiguration(TMR_Reader *reader, TMR_SR_Configuration key,+ void *value)+{+ TMR_SR_SerialReader *sr = &reader->u.serialReader;+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_READER_OPTIONAL_PARAMS);+ SETU8(msg, i, 1); /* key-value form of command */+ SETU8(msg, i, key);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ switch (key)+ {+ case TMR_SR_CONFIGURATION_ANTENNA_CONTROL_GPIO:+ *(uint8_t *)value = GETU8AT(msg, 7);+ break;+ case TMR_SR_CONFIGURATION_TRIGGER_READ_GPIO:+ *(uint8_t *)value = GETU8AT(msg, 7);+ break;++ case TMR_SR_CONFIGURATION_UNIQUE_BY_ANTENNA:+ case TMR_SR_CONFIGURATION_UNIQUE_BY_DATA:+ case TMR_SR_CONFIGURATION_UNIQUE_BY_PROTOCOL:+ *(bool *)value = (GETU8AT(msg, 7) == 0);+ break;+ case TMR_SR_CONFIGURATION_TRANSMIT_POWER_SAVE:+ if(TMR_SR_MODEL_MICRO == sr->versionInfo.hardware[0])+ {+ if(GETU8AT(msg, 7) == 2)+ {+ //Open loop power calibration+ *(bool *)value = 1;+ }+ else+ {+ //Closed loop power calibration+ *(bool *)value = 0;+ }+ }+ else+ {+ *(bool *)value = (GETU8AT(msg, 7) == 1);+ }+ break;+ case TMR_SR_CONFIGURATION_EXTENDED_EPC:+ case TMR_SR_CONFIGURATION_SAFETY_ANTENNA_CHECK:+ case TMR_SR_CONFIGURATION_SAFETY_TEMPERATURE_CHECK:+ case TMR_SR_CONFIGURATION_RECORD_HIGHEST_RSSI:+ case TMR_SR_CONFIGURATION_RSSI_IN_DBM:+ case TMR_SR_CONFIGURATION_SELF_JAMMER_CANCELLATION:+ case TMR_SR_CONFIGURATION_ENABLE_READ_FILTER:+ case TMR_SR_CONFIGURATION_SEND_CRC:+ *(bool *)value = (GETU8AT(msg, 7) == 1);+ break;+ case TMR_SR_CONFIGURATION_CURRENT_MSG_TRANSPORT:+ *(uint8_t *)value = GETU8AT(msg, 7) ;+ break;+ case TMR_SR_CONFIGURATION_READ_FILTER_TIMEOUT:+ *(uint32_t *)value = GETU32AT(msg, 7);+ break;++ case TMR_SR_CONFIGURATION_PRODUCT_GROUP_ID:+ *(uint16_t *)value = GETU16AT(msg, 7);+ break;++ case TMR_SR_CONFIGURATION_PRODUCT_ID:+ *(uint16_t *)value = GETU16AT(msg, 7);+ break;++ default:+ return TMR_ERROR_NOT_FOUND;+ }++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdGetProtocolConfiguration(TMR_Reader *reader, TMR_TagProtocol protocol,+ TMR_SR_ProtocolConfiguration key,+ void *value)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_PROTOCOL_PARAM);+ SETU8(msg, i, protocol);+ if (TMR_TAG_PROTOCOL_GEN2 == key.protocol)+ {+ SETU8(msg, i, key.u.gen2);+ }+#ifdef TMR_ENABLE_ISO180006B+ else if (TMR_TAG_PROTOCOL_ISO180006B == key.protocol + || TMR_TAG_PROTOCOL_ISO180006B_UCODE == key.protocol)+ {+ SETU8(msg, i, key.u.iso180006b);+ }+#endif+ else+ {+ return TMR_ERROR_INVALID;+ }+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ if (TMR_TAG_PROTOCOL_GEN2 == key.protocol)+ {+ switch (key.u.gen2)+ {+ case TMR_SR_GEN2_CONFIGURATION_SESSION:+ *(TMR_GEN2_Session *)value = (TMR_GEN2_Session)GETU8AT(msg, 7);+ break;++ case TMR_SR_GEN2_CONFIGURATION_TAGENCODING:+ *(TMR_GEN2_TagEncoding *)value = (TMR_GEN2_TagEncoding)GETU8AT(msg, 7);+ break;++ case TMR_SR_GEN2_CONFIGURATION_LINKFREQUENCY:+ *(TMR_GEN2_LinkFrequency *)value = (TMR_GEN2_LinkFrequency)GETU8AT(msg, 7);+ break;++ case TMR_SR_GEN2_CONFIGURATION_TARI:+ *(TMR_GEN2_Tari *)value = (TMR_GEN2_Tari)GETU8AT(msg, 7);+ break;++ case TMR_SR_GEN2_CONFIGURATION_PROTCOLEXTENSION:+ *(TMR_GEN2_ProtocolExtension *)value = (TMR_GEN2_ProtocolExtension)GETU8AT(msg, 7);+ break;++ case TMR_SR_GEN2_CONFIGURATION_BAP:+ {+ TMR_GEN2_Bap *b = value;++ i = 10;+ b->powerUpDelayUs = GETU32(msg,i);+ b->freqHopOfftimeUs = GETU32(msg,i);+ break;+ }++ case TMR_SR_GEN2_CONFIGURATION_TARGET:+ {+ uint16_t target;++ target = GETU16AT(msg, 7);+ switch (target)+ {+ case 0x0100:+ *(TMR_GEN2_Target *)value = TMR_GEN2_TARGET_A;+ break;+ case 0x0101:+ *(TMR_GEN2_Target *)value = TMR_GEN2_TARGET_B;+ break;+ case 0x0000:+ *(TMR_GEN2_Target *)value = TMR_GEN2_TARGET_AB;+ break;+ case 0x0001:+ *(TMR_GEN2_Target *)value = TMR_GEN2_TARGET_BA;+ break;+ default:+ *(TMR_GEN2_Target *)value = TMR_GEN2_TARGET_INVALID;+ }+ break;+ }++ case TMR_SR_GEN2_CONFIGURATION_Q:+ {+ TMR_SR_GEN2_Q *q = value;++ q->type = (TMR_SR_GEN2_QType)GETU8AT(msg, 7);+ if (q->type == TMR_SR_GEN2_Q_DYNAMIC)+ {+ ; /* No further data to get */+ }+ else if (q->type == TMR_SR_GEN2_Q_STATIC)+ {+ q->u.staticQ.initialQ = GETU8AT(msg, 8);+ }+ break;+ }++ default:+ return TMR_ERROR_NOT_FOUND;+ }+ }+#ifdef TMR_ENABLE_ISO180006B+ else if (TMR_TAG_PROTOCOL_ISO180006B == key.protocol + || TMR_TAG_PROTOCOL_ISO180006B_UCODE == key.protocol)+ {+ switch (key.u.iso180006b)+ {+ case TMR_SR_ISO180006B_CONFIGURATION_LINKFREQUENCY:+ {+ TMR_iso18000BBLFValToInt(GETU8AT(msg, 7), value);+ break;+ }+ case TMR_SR_ISO180006B_CONFIGURATION_MODULATION_DEPTH:+ {+ uint8_t val;+ val = GETU8AT(msg, 7);+ switch (val)+ {+ case 0:+ *(TMR_ISO180006B_ModulationDepth *)value = TMR_ISO180006B_Modulation99percent;+ break;+ case 1:+ *(TMR_ISO180006B_ModulationDepth *)value = TMR_ISO180006B_Modulation11percent;+ break;+ default:+ return TMR_ERROR_NOT_FOUND;+ }+ break;+ }+ case TMR_SR_ISO180006B_CONFIGURATION_DELIMITER:+ {+ uint8_t val;+ val = GETU8AT(msg, 7);+ switch (val)+ {+ case 1:+ *(TMR_ISO180006B_Delimiter *)value = TMR_ISO180006B_Delimiter1;+ break;+ case 4:+ *(TMR_ISO180006B_Delimiter *)value = TMR_ISO180006B_Delimiter4;+ break;+ default:+ return TMR_ERROR_NOT_FOUND;+ }+ break;+ }+ default:+ return TMR_ERROR_NOT_FOUND;+ }+ } +#endif /* TMR_ENABLE_ISO180006B */+ else+ {+ return TMR_ERROR_INVALID;+ }++ return TMR_SUCCESS;+}++TMR_Status TMR_iso18000BBLFValToInt(int val, void *lf)+{+ switch (val)+ {+ case 1:+ *(TMR_ISO180006B_LinkFrequency *)lf = TMR_ISO180006B_LINKFREQUENCY_40KHZ;+ break;+ case 0:+ *(TMR_ISO180006B_LinkFrequency *)lf = TMR_ISO180006B_LINKFREQUENCY_160KHZ;+ break;+ default:+ return TMR_ERROR_NOT_FOUND;+ }+ return TMR_SUCCESS;+}++/* Helper function to frame the multiple protocol search command */+TMR_Status +TMR_SR_msgSetupMultipleProtocolSearch(TMR_Reader *reader, uint8_t *msg, TMR_SR_OpCode op, TMR_TagProtocolList *protocols, TMR_TRD_MetadataFlag metadataFlags, TMR_SR_SearchFlag antennas, TMR_TagFilter **filter, uint16_t timeout)+{+ TMR_Status ret;+ uint8_t i;+ uint32_t j;+ uint16_t subTimeout;++ ret = TMR_SUCCESS;+ i=2;++ SETU8(msg, i, TMR_SR_OPCODE_MULTI_PROTOCOL_TAG_OP); //Opcode+ if(reader->continuousReading)+ {+ /* Timeout should be zero for true continuous reading */+ SETU16(msg, i, 0);+ SETU8(msg, i, (uint8_t)0x1);//TM Option 1, for continuous reading+ }+ else+ {+ SETU16(msg, i, timeout); //command timeout+ SETU8(msg, i, (uint8_t)0x11);//TM Option, turns on metadata+ SETU16(msg, i, (uint16_t)metadataFlags);+ }++ SETU8(msg, i, (uint8_t)op);//sub command opcode++ if (TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type)+ {+ reader->isStopNTags = false;+ /**+ * in case of multi read plan look for the stop N trigger option+ **/+ for (j = 0; j < reader->readParams.readPlan->u.multi.planCount; j++)+ {+ if (reader->readParams.readPlan->u.multi.plans[j]->u.simple.stopOnCount.stopNTriggerStatus)+ {+ reader->numberOfTagsToRead += reader->readParams.readPlan->u.multi.plans[j]->u.simple.stopOnCount.noOfTags;+ reader->isStopNTags = true;+ }+ }+ }+ else+ {+ reader->numberOfTagsToRead += reader->readParams.readPlan->u.simple.stopOnCount.noOfTags;+ }++ if (reader->isStopNTags && !reader->continuousReading)+ {+ /**+ * True means atlest one sub read plan has the requested for stop N trigger.+ * Enable the flag and add the total tag count. This is only supported for sync read+ * case.+ */+ SETU16(msg, i, (uint16_t)TMR_SR_SEARCH_FLAG_RETURN_ON_N_TAGS);+ SETU32(msg, i, reader->numberOfTagsToRead);+ }+ else+ {+ SETU16(msg, i, (uint16_t)0x0000);//search flags, only 0x0001 is supported+ }++ /**+ * TODO:add the timeout as requested by the user+ **/+ subTimeout =(uint16_t)(timeout/(protocols->len));+ for (j=0;j<protocols->len;j++) // iterate through the protocol search list+ {+ int PLenIdx;+++ TMR_TagProtocol subProtocol=protocols->list[j];+ SETU8(msg, i, (uint8_t)(subProtocol)); //protocol ID+ PLenIdx = i;+ SETU8(msg, i, 0); //PLEN++ /**+ * in case of multi readplan and the total weight is not zero,+ * we should use the weight as provided by the user.+ **/+ if (TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type)+ {+ if (0 != reader->readParams.readPlan->u.multi.totalWeight)+ {+ subTimeout = (uint16_t)(reader->readParams.readPlan->u.multi.plans[j]->weight * timeout+ / reader->readParams.readPlan->u.multi.totalWeight);+ }+ }++ /**+ * In case of Multireadplan, check each simple read plan FastSearch option and+ * stop N trigger option.+ */+ if (TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type)+ {+ reader->fastSearch = reader->readParams.readPlan->u.multi.plans[j]->u.simple.useFastSearch;+ reader->triggerRead = reader->readParams.readPlan->u.multi.plans[j]->u.simple.triggerRead.enable;+ reader->isStopNTags = false;+ reader->isStopNTags = reader->readParams.readPlan->u.multi.plans[j]->u.simple.stopOnCount.stopNTriggerStatus;+ reader->numberOfTagsToRead = reader->readParams.readPlan->u.multi.plans[j]->u.simple.stopOnCount.noOfTags;+ }++ switch(op)+ {+ case TMR_SR_OPCODE_READ_TAG_ID_SINGLE :+ {+ ret = TMR_SR_msgSetupReadTagSingle(msg, &i, subProtocol,metadataFlags, filter[j], subTimeout);+ break;+ }+ case TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE:+ {+ /**+ * simple read plan uses this function, only when tagop is NULL,+ * s0, need to check for simple read plan tagop.+ **/+ if (TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type)+ {+ /* check for the tagop */+ if (NULL != reader->readParams.readPlan->u.multi.plans[j]->u.simple.tagop)+ {+ uint32_t readTimeMs = (uint32_t)subTimeout;+ uint8_t lenbyte = 0;+ //add the tagoperation here+ ret = TMR_SR_addTagOp(reader,reader->readParams.readPlan->u.multi.plans[j]->u.simple.tagop,+ reader->readParams.readPlan->u.multi.plans[j], msg, &i, readTimeMs, &lenbyte);+ }+ else+ {+ ret = TMR_SR_msgSetupReadTagMultipleWithMetadata(reader, msg, &i, subTimeout, antennas, metadataFlags ,filter[j], subProtocol, 0);+ }+ }+ else+ {+ if (NULL != reader->readParams.readPlan->u.simple.tagop)+ {+ uint32_t readTimeMs = (uint32_t)subTimeout;+ uint8_t lenbyte = 0;+ //add the tagoperation here+ ret = TMR_SR_addTagOp(reader, reader->readParams.readPlan->u.simple.tagop,+ reader->readParams.readPlan, msg, &i, readTimeMs, &lenbyte);+ }+ else+ {+ ret = TMR_SR_msgSetupReadTagMultipleWithMetadata(reader, msg, &i, subTimeout, antennas, metadataFlags ,filter[j], subProtocol, 0);+ }+ }+ break;+ }+ default :+ {+ return TMR_ERROR_INVALID_OPCODE; + }+ }++ msg[PLenIdx]= i - PLenIdx - 2; //PLEN+ msg[1]=i - 3;+ }+ return ret;+}++TMR_Status TMR_SR_cmdMultipleProtocolSearch(TMR_Reader *reader,TMR_SR_OpCode op,TMR_TagProtocolList *protocols, TMR_TRD_MetadataFlag metadataFlags,TMR_SR_SearchFlag antennas, TMR_TagFilter **filter, uint16_t timeout, uint32_t *tagsFound)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ TMR_SR_SerialReader *sr;++ sr = &reader->u.serialReader;+ *tagsFound = 0 ;++ ret = TMR_SR_msgSetupMultipleProtocolSearch(reader, msg, op, protocols, metadataFlags, antennas, filter, timeout);+ if (ret != TMR_SUCCESS)+ {+ return ret;+ }++ if (op == TMR_SR_OPCODE_READ_TAG_ID_SINGLE)+ {+ uint8_t opcode;++ sr->opCode = op;+ ret = TMR_SR_sendMessage(reader, msg, &opcode, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ sr->tagsRemaining = 1;+ }++ if (op == TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE)+ {+ sr->opCode = op;+ if(reader->continuousReading)+ {+ uint8_t opcode;+ ret = TMR_SR_sendMessage(reader, msg, &opcode, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ reader->hasContinuousReadStarted = true;+ sr->tagsRemaining=1;+ }+ else+ {+ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_ERROR_NO_TAGS_FOUND == ret)+ {+ sr->tagsRemaining = *tagsFound = 0;+ return ret;+ }+ else if ((TMR_ERROR_TM_ASSERT_FAILED == ret) ||+ (TMR_ERROR_TIMEOUT == ret))+ {+ return ret;+ }+ else if (TMR_SUCCESS != ret)+ {+ uint16_t remainingTagsCount;+ TMR_Status ret1;++ /* Check for the tag count (in case of module error)*/+ ret1 = TMR_SR_cmdGetTagsRemaining(reader, &remainingTagsCount);+ if (TMR_SUCCESS != ret1)+ {+ return ret1;+ }++ *tagsFound = remainingTagsCount;+ sr->tagsRemaining = *tagsFound;+ return ret;+ }++ *tagsFound = GETU32AT(msg , 9);+ sr->tagsRemaining = *tagsFound;+ }+ }++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdGetAvailableProtocols(TMR_Reader *reader,+ TMR_TagProtocolList *protocols)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_AVAILABLE_PROTOCOLS);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ protocols->len = 0;+ for (i = 0; i < msg[1] ; i += 2)+ {+ LISTAPPEND(protocols, (TMR_TagProtocol)GETU16AT(msg, 5 + i)); + }++ reader->u.serialReader.versionInfo.protocols = 0x0000;+ for (i = 0 ; i < protocols->len; i ++)+ {+ reader->u.serialReader.versionInfo.protocols |= (1 << (protocols->list[i] - 1)); + }+ + return TMR_SUCCESS;+}+++TMR_Status+TMR_SR_cmdGetAvailableRegions(TMR_Reader *reader, TMR_RegionList *regions)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_AVAILABLE_REGIONS);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ regions->len = 0;+ for (i = 0; i < msg[1] ; i++)+ {+ LISTAPPEND(regions, (TMR_Region)GETU8AT(msg, 5 + i)); + }++ return TMR_SUCCESS;+}++++TMR_Status+TMR_SR_cmdGetTemperature(TMR_Reader *reader, int8_t *temp)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_GET_TEMPERATURE);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ *temp = msg[5];+ return TMR_SUCCESS;+}+++static TMR_Status+filterbytes(TMR_TagProtocol protocol, const TMR_TagFilter *filter, + uint8_t *option, uint8_t *i, uint8_t *msg,+ uint32_t accessPassword, bool usePassword)+{+ int j;+ if (isSecureAccessEnabled)+ {+ *option = TMR_SR_GEN2_SINGULATION_OPTION_SECURE_READ_DATA;+ }++ if (NULL == filter && 0 == accessPassword)+ {+ *option = 0x00;+ return TMR_SUCCESS;+ }++ if (TMR_TAG_PROTOCOL_GEN2 == protocol)+ {+ if (usePassword)+ {+ if (filter && TMR_FILTER_TYPE_GEN2_SELECT == filter->type)+ {+ if (filter->u.gen2Select.bank != TMR_GEN2_EPC_LENGTH_FILTER)+ SETU32(msg, *i, accessPassword);+ }+ else+ {+ SETU32(msg, *i, accessPassword);+ }+ }+ if (NULL == filter)+ {+ *option |= TMR_SR_GEN2_SINGULATION_OPTION_USE_PASSWORD;+ }+ else if (TMR_FILTER_TYPE_GEN2_SELECT == filter->type)+ {+ const TMR_GEN2_Select *fp;++ fp = &filter->u.gen2Select;++ if (1 == fp->bank)+ {+ *option |= TMR_SR_GEN2_SINGULATION_OPTION_SELECT_ON_ADDRESSED_EPC;+ }+ else /* select based on the bank */+ {+ *option |= fp->bank;+ }++ if (fp->bank == TMR_GEN2_EPC_LENGTH_FILTER)+ {+ SETU16(msg, *i, fp->maskBitLength);+ }+ else+ {+ if(true == fp->invert)+ {+ *option |= TMR_SR_GEN2_SINGULATION_OPTION_INVERSE_SELECT_BIT;+ }++ if (fp->maskBitLength > 255)+ {+ *option |= TMR_SR_GEN2_SINGULATION_OPTION_EXTENDED_DATA_LENGTH;+ }++ SETU32(msg, *i, fp->bitPointer);++ if (fp->maskBitLength > 255)+ {+ SETU8(msg, *i, (fp->maskBitLength >> 8) & 0xFF);+ }+ SETU8(msg, *i, fp->maskBitLength & 0xFF);++ if (*i + 1 + tm_u8s_per_bits(fp->maskBitLength) > TMR_SR_MAX_PACKET_SIZE)+ {+ return TMR_ERROR_TOO_BIG;+ }++ for(j = 0; j < tm_u8s_per_bits(fp->maskBitLength) ; j++)+ {+ SETU8(msg, *i, fp->mask[j]);+ }+ }+ }+ else if (TMR_FILTER_TYPE_TAG_DATA == filter->type)+ {+ const TMR_TagData *fp;+ int bitCount;++ fp = &filter->u.tagData;+ bitCount = fp->epcByteCount * 8;++ /* select on the EPC */+ *option |= 1;+ if (bitCount > 255)+ {+ *option |= TMR_SR_GEN2_SINGULATION_OPTION_EXTENDED_DATA_LENGTH;+ SETU8(msg, *i, (bitCount>>8) & 0xFF);+ }+ SETU8(msg, *i, (bitCount & 0xFF));++ if (*i + 1 + fp->epcByteCount > TMR_SR_MAX_PACKET_SIZE)+ {+ return TMR_ERROR_TOO_BIG;+ }++ for(j = 0 ; j < fp->epcByteCount ; j++)+ {+ SETU8(msg, *i, fp->epc[j]);+ }+ }+ else+ {+ return TMR_ERROR_INVALID;+ }+ }+#ifdef TMR_ENABLE_ISO180006B+ else if (TMR_TAG_PROTOCOL_ISO180006B == protocol)+ {+ if (option)+ {+ *option = 1;+ }+ + if (NULL == filter)+ {+ /* Set up a match-anything filter, since it isn't the default */+ SETU8(msg, *i, TMR_ISO180006B_SELECT_OP_EQUALS);+ SETU8(msg, *i, 0); /* address */+ SETU8(msg, *i, 0); /* mask - don't compare anything */+ SETU32(msg, *i, 0); /* dummy tag ID bytes 0-3, not compared */+ SETU32(msg, *i, 0); /* dummy tag ID bytes 4-7, not compared */+ return TMR_SUCCESS;+ }+ else if (TMR_FILTER_TYPE_ISO180006B_SELECT == filter->type)+ {+ const TMR_ISO180006B_Select *fp;+ + fp = &filter->u.iso180006bSelect;+ if (false == fp->invert)+ {+ SETU8(msg, *i, fp->op);+ }+ else+ {+ SETU8(msg, *i, fp->op | 4);+ }+ SETU8(msg, *i, fp->address);+ SETU8(msg, *i, fp->mask);+ for (j = 0 ; j < 8 ; j++)+ {+ SETU8(msg, *i, fp->data[j]);+ }+ }+ else if (TMR_FILTER_TYPE_TAG_DATA == filter->type)+ {+ const TMR_TagData *fp;+ uint8_t mask;++ fp = &filter->u.tagData;++ if (fp->epcByteCount > 8)+ {+ return TMR_ERROR_INVALID;+ }++ /* Convert the byte count to a MSB-based bit mask */+ mask = (0xff00 >> fp->epcByteCount) & 0xff;++ SETU8(msg, *i, TMR_ISO180006B_SELECT_OP_EQUALS);+ SETU8(msg, *i, 0); /* Address - EPC is at the start of memory */+ SETU8(msg, *i, mask);+ for (j = 0 ; j < fp->epcByteCount; j++)+ {+ SETU8(msg, *i, fp->epc[j]);+ }+ for ( ; j < 8 ; j++)+ {+ SETU8(msg, *i, 0); /* EPC data must be 8 bytes */+ }+ }+ else+ {+ return TMR_ERROR_INVALID;+ }+ + }+#endif /* TMR_ENABLE_ISO180006B */+ else+ {+ return TMR_ERROR_INVALID;+ }++ return TMR_SUCCESS;+}++/** + * Alien Higgs2 and Higgs3 Specific Commands+ **/++/** Helper routine to form the Higgs2 Partial Load Image command **/+void TMR_SR_msgAddHiggs2PartialLoadImage(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, uint8_t len, const uint8_t *epc, TMR_TagFilter* target)+{+ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_ALIEN_HIGGS_SILICON); /* Chip - type*/+ SETU8(msg, *i, (uint8_t)0x01); /* Sub command, partial load image */+ SETU32(msg, *i, killPassword);+ SETU32(msg, *i, accessPassword);+ memcpy(&msg[*i], epc, len);+ *i += len;+}+/**+ * Partial Load Image (only 96-bit EPC with no user memory versions)+ * Chip type = 0x01+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to write on the tag+ * @param killPassword The kill password to write on the tag+ * @param len Length of the EPC+ * @param epc The EPC to write to the tag. Maximum of 12 bytes (96 bits)+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdHiggs2PartialLoadImage(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, + uint8_t len, const uint8_t epc[], TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ if(NULL != target)+ {+ return TMR_ERROR_UNSUPPORTED;+ }+ TMR_SR_msgAddHiggs2PartialLoadImage(msg, &i, timeout, accessPassword, killPassword, len, epc, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}+++/** Helper routine to form the Higgs2 Full Load Image command **/+void TMR_SR_msgAddHiggs2FullLoadImage(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, uint16_t lockBits, uint16_t pcWord, uint8_t len, const uint8_t *epc, TMR_TagFilter* target)+{+ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_ALIEN_HIGGS_SILICON); /* Chip - type*/+ SETU8(msg, *i, (uint8_t)0x03); /* Sub command, full load image */+ SETU32(msg, *i, killPassword);+ SETU32(msg, *i, accessPassword);+ SETU16(msg, *i, lockBits);+ SETU16(msg, *i, pcWord);+ memcpy(&msg[*i], epc, len);+ *i += len;+}+/**+ * Full Load Image (only 96-bit EPC with no user memory versions)+ * Chip type = 0x01+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to write on the tag+ * @param killPassword The kill password to write on the tag+ * @param lockBits locking the tag according to the Alien Higgs LockBits+ * @param pcWord PC Word in the Tag EPC memBank defined in the Gen2 Specification+ * @param len Length of the EPC+ * @param epc The EPC to write to the tag. Maximum of 12 bytes (96 bits)+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdHiggs2FullLoadImage(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword,+ uint16_t lockBits, uint16_t pcWord, uint8_t len,+ const uint8_t epc[], TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ if(NULL != target)+ {+ return TMR_ERROR_UNSUPPORTED;+ }+ TMR_SR_msgAddHiggs2FullLoadImage(msg, &i, timeout, accessPassword, killPassword, lockBits, pcWord, len, epc, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/** Helper routine to form the Higgs3 Fast Load Image command **/+void TMR_SR_msgAddHiggs3FastLoadImage(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, uint16_t pcWord, uint8_t len, const uint8_t *epc, TMR_TagFilter* target)+{+ uint8_t option=0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_ALIEN_HIGGS3_SILICON); /* Chip - type*/+ + rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)0x01); /* Sub command, fast load image */+ + filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, 0, false); + msg[rec]=msg[rec]|option;++ SETU32(msg, *i, currentAccessPassword);+ SETU32(msg, *i, killPassword);+ SETU32(msg, *i, accessPassword);+ SETU16(msg, *i, pcWord);+ memcpy(&msg[*i], epc, len);+ *i += len;+}+/**+ * Higgs3 Fast Load Image (only 96-bit EPC)+ * Chip type = 0x05+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param currentAccessPassword The access password to use to write to the tag+ * @param accessPassword The access password to write on the tag+ * @param killPassword The kill password to write on the tag+ * @param pcWord PC Word in the Tag EPC memBank defined in the Gen2 Specification+ * @param len Length of the EPC+ * @param epc The EPC to write to the tag. Maximum of 12 bytes (96 bits)+ * @param target Filter to be applied.+ */+TMR_Status +TMR_SR_cmdHiggs3FastLoadImage(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password currentAccessPassword, TMR_GEN2_Password accessPassword, + TMR_GEN2_Password killPassword, uint16_t pcWord, uint8_t len, const uint8_t epc[], TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddHiggs3FastLoadImage(msg, &i, timeout, currentAccessPassword, accessPassword, killPassword, pcWord, len, epc, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/** Helper routine to form the Higgs3 Load Image command **/+void TMR_SR_msgAddHiggs3LoadImage(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, uint16_t pcWord, uint8_t len, const uint8_t *epcAndUserData, TMR_TagFilter* target)+{+ uint8_t option=0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_ALIEN_HIGGS3_SILICON); /* Chip - type*/+ + rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)0x03); /* Sub command, Load image */++ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, 0, false); + msg[rec]=msg[rec]|option;++ SETU32(msg, *i, currentAccessPassword);+ SETU32(msg, *i, killPassword);+ SETU32(msg, *i, accessPassword);+ SETU16(msg, *i, pcWord);+ memcpy(&msg[*i], epcAndUserData, len);+ *i += len;+}++/**+ * Higgs3 Load Image + * Chip type = 0x05+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param currentAccessPassword The access password to use to write to the tag+ * @param accessPassword The access password to write on the tag+ * @param killPassword The kill password to write on the tag+ * @param pcWord PC Word in the Tag EPC memBank defined in the Gen2 Specification+ * @param len Length of epcAndUserData+ * @param epcAndUserData The EPC and user data to write to the tag. Must be exactly 76 bytes. + * The pcWord specifies which of this is EPC and which is user data.+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdHiggs3LoadImage(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword,+ uint16_t pcWord, uint8_t len, const uint8_t epcAndUserData[], TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddHiggs3LoadImage(msg, &i, timeout, currentAccessPassword, accessPassword, + killPassword, pcWord, len, epcAndUserData, target); /* Length of epcAndUserData must be 76 */+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/** Helper routine to form the Higgs3 Block Read Lock command**/+void TMR_SR_msgAddHiggs3BlockReadLock(uint8_t *msg, uint8_t *i, uint16_t timeout, + TMR_GEN2_Password accessPassword, uint8_t lockBits, TMR_TagFilter* target)+{+ uint8_t option=0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_ALIEN_HIGGS3_SILICON); /* Chip - type*/+ + rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)0x09); /* Sub command, Block Read Lock */+ + filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, 0, false); + msg[rec]=msg[rec]|option;++ SETU32(msg, *i, accessPassword);+ SETU8(msg, *i, lockBits);+}++/**+ * Higgs3 Block Read Lock + * Chip type = 0x05+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param lockBits A bitmask of bits to lock. Valid range 0-255+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdHiggs3BlockReadLock(TMR_Reader *reader, uint16_t timeout,+ TMR_GEN2_Password accessPassword, uint8_t lockBits, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddHiggs3BlockReadLock(msg, &i, timeout, accessPassword, lockBits, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/** + * NXP Silicon (G2xL and G2iL) Specific Commands+ * Chip Type = 0x02 and 0x07+ **/++/** Helper routine to form the NXP Set Read Protect command**/+void TMR_SR_msgAddNXPSetReadProtect(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_TagFilter* target)+{+ uint8_t option=0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)chip); /* Chip - type*/+ + rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)0x01); /* Sub command, Set Read Protect */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, 0, false);+ msg[rec]=msg[rec]|option;+ + SETU32(msg, *i, accessPassword);+}++/** Helper routine to form the NXP Set Read Protect command**/+void TMR_SR_msgAddNXPResetReadProtect(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_TagFilter* target)+{+ uint8_t option=0,rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)chip); /* Chip - type*/+ + rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)0x02); /* Sub command, Reset Read Protect */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, 0, false); + msg[rec]=msg[rec]|option;+ + SETU32(msg, *i, accessPassword);+}++/**+ * NXP Set Read Protect+ * Chip type = 0x02 or 0x07, Command = 0x01+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param chip The NXP Chip type (G2iL or G2xL)+ * @param accessPassword The access password to use to write on the tag+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdNxpSetReadProtect(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;+ + TMR_SR_msgAddNXPSetReadProtect(msg, &i, timeout, chip, accessPassword, target); /* set read protect */+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/**+ * NXP Reset Read Protect+ * Chip type = 0x02 or 0x07, Command = 0x02+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param chip The NXP Chip type (G2iL or G2xL)+ * @param accessPassword The access password to use to write on the tag+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdNxpResetReadProtect(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddNXPResetReadProtect(msg, &i, timeout, chip, accessPassword, target); /* Reset read protect */+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/** Helper routine to form the NXP Change EAS command**/+void TMR_SR_msgAddNXPChangeEAS(uint8_t *msg, uint8_t *i, uint16_t timeout, + TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, bool reset, TMR_TagFilter* target)+{+ uint8_t option=0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)chip); /* Chip - type*/+ + rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)0x03); /* Sub command, Change EAS */+ + filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, 0, false); + msg[rec]=msg[rec]|option;+ + SETU32(msg, *i, accessPassword); + if(reset)+ {+ SETU8(msg, *i, (uint8_t)0x02); /* reset EAS */+ }+ else+ {+ SETU8(msg, *i, (uint8_t)0x01); /* set EAS */+ } +}++/**+ * NXP Change EAS+ * Chip type = 0x02 or 0x07, Command = 0x03+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param chip The NXP Chip type (G2iL or G2xL)+ * @param accessPassword The access password to use to write on the tag+ * @param reset Reset or set EAS bit+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdNxpChangeEas(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, bool reset, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddNXPChangeEAS(msg, &i, timeout, chip, accessPassword, reset, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/** Helper routine to form the NXP EAS Alarm command **/+void TMR_SR_msgAddNXPEASAlarm(uint8_t *msg, uint8_t *i, uint16_t timeout, + TMR_SR_GEN2_SiliconType chip, TMR_GEN2_DivideRatio dr, TMR_GEN2_TagEncoding m, TMR_GEN2_TrExt trExt, TMR_TagFilter* target)+{+ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)chip); /* Chip - type*/+ + SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00); + SETU8(msg, *i, (uint8_t)0x04); /* Sub command, EAS Alarm */++ SETU8(msg, *i, (uint8_t)dr); + SETU8(msg, *i, (uint8_t)m);+ SETU8(msg, *i, (uint8_t)trExt);+}++/**+ * NXP EAS Alarm+ * Chip type = 0x02 or 0x07, Command = 0x04+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param chip The NXP Chip type (G2iL or G2xL)+ * @param dr Gen2 divide ratio to use+ * @param m Gen2 M(tag encoding) parameter to use+ * @param trExt Gen2 TrExt value to use+ * @param data 8 bytes of EAS alarm data will be returned, on successful operation+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdNxpEasAlarm(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_DivideRatio dr, TMR_GEN2_TagEncoding m, TMR_GEN2_TrExt trExt,+ TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ if (NULL != target)+ { /* EAS Alarm command is sent without any singulation of the tag*/+ return TMR_ERROR_UNSUPPORTED;+ }+ TMR_SR_msgAddNXPEASAlarm(msg, &i, timeout, chip, dr, m, trExt, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ + + /* Alarm data always starts at position 9 */+ /* FF 0A 2D 00 00 xx 40 00 04 [8 bytes] ?? ??+ * SOH Length OpCode Status ChipType option SubCommand [EAS AlarmData] CRC+ */+ i = 9;+ if (NULL != data)+ {+ uint16_t copyLength;+ + copyLength = msg[1] + 5 - i;+ memcpy(data->list, &msg[i], copyLength); + data->len = copyLength; + }++ return TMR_SUCCESS;+}++/** Helper routine to form the NXP Calibrate command **/+void TMR_SR_msgAddNXPCalibrate(uint8_t *msg, uint8_t *i, uint16_t timeout, + TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_TagFilter* target)+{+ uint8_t option=0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)chip); /* Chip - type*/+ + rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)0x05); /* Sub command, Calibrate */++ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, 0, false); + msg[rec]=msg[rec]|option;+ + SETU32(msg, *i, accessPassword);+}+/**+ * NXP Calibrate (only for G2xL)+ * Chip type = 0x02, Command = 0x05+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param chip The NXP Chip type (G2iL or G2xL)+ * @param accessPassword The access password to use to write on the tag+ * @param data 64 bytes of calibration data will be returned on a successful operation+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdNxpCalibrate(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddNXPCalibrate(msg, &i, timeout, chip, accessPassword, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ + + /* Calibration data always starts at position 9 */+ /* FF 42 2D 00 00 xx 40 00 05 [64 bytes] ?? ??+ * SOH Length OpCode Status ChipType option SubCommand [CalibrateData] CRC+ */+ i = 9;+ if (NULL != data)+ { + uint16_t copyLength;+ + copyLength = msg[1] + 5 - i;+ memcpy(data->list, &msg[i], copyLength); + data->len = copyLength;+ }++ return TMR_SUCCESS;+}++/** Helper routine to form the NXP ChangeConfig command **/+void TMR_SR_msgAddNXPChangeConfig(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_NXP_ConfigWord configWord, TMR_TagFilter* target)+{+ //uint16_t configData;+ uint8_t option=0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)chip); /* Chip - type*/+ rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)0x07); /* Sub command, ChangeConfig */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true); + msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)0x00); //RFU + SETU16(msg, *i, configWord.data);+}++/**+ * NXP ChangeConfig (only for G2iL)+ * Chip type = 0x07, Command = 0x07+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param chip The NXP Chip type (G2iL or G2xL)+ * @param accessPassword The access password to use to write on the tag+ * @param configWord (I/O)The config word to write on the tag. + * @param data If the operation is success, this data contains the current configword setting on the tag.+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdNxpChangeConfig(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, TMR_NXP_ConfigWord configWord,+ TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ if (chip == TMR_SR_GEN2_NXP_G2X_SILICON)+ {+ /* ChangeConfig works only for G2iL tags*/+ return TMR_ERROR_UNSUPPORTED; + }+ + TMR_SR_msgAddNXPChangeConfig(msg, &i, timeout, chip, accessPassword, configWord, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the config data from response back to the user */+ i = 9; + /* FF 06 2d 00 00 07 40 00 07 80 46 59 2f+ * SOH Length OpCode Status ChipType option SubCommand [ConfigData] CRC+ */+ {+ uint16_t copyLength;+ + copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++void TMR_SR_msgAddGen2v2NxpUntraceable(uint8_t *msg, uint8_t *i, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, uint16_t configWord, + TMR_TagOp_GEN2_NXP_Untraceable op ,TMR_TagFilter* target)+{+ uint8_t option=0,rec; + SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)chip); /* Chip - type*/+ rec=*i;+ SETU8(msg,*i,0x00);//option+ SETU8(msg, *i, (uint8_t)op.subCommand); /* Sub command, Untraceable */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, false); + msg[rec]=msg[rec]|option;+ SETU16(msg, *i, configWord);+ if(op.subCommand == 0x02)// Untraceable with Authentication+ {+ SETU8(msg,*i, op.auth.tam1Auth.Authentication);+ SETU8(msg,*i,op.auth.tam1Auth.CSI);+ SETU8(msg,*i,op.auth.tam1Auth.keyID);+ SETU8(msg,*i,op.auth.tam1Auth.KeyLength); + {+ uint32_t iWord;+ for (iWord = 0; iWord < op.auth.tam1Auth.Key.len; iWord++)+ {+ SETU8(msg, *i, (op.auth.tam1Auth.Key.list[iWord]));+ // SETU8(msg, *i, ((op.auth.tam1Auth.Key.list[iWord]>>0)&0xFF));+ }+ }+ SETU8(msg,*i,op.auth.tam1Auth.IchallengeLength);+ {+ uint32_t iWord;+ for (iWord = 0; iWord < op.auth.tam1Auth.Ichallenge.len; iWord++)+ {+ SETU8(msg, *i, (op.auth.tam1Auth.Ichallenge.list[iWord]));+ //SETU8(msg, *i, ((op.auth.tam1Auth.Ichallenge.list[iWord]>>0)&0xFF));+ }+ }+ }+ else //Untraceable with Access + {+ SETU32(msg, *i,op.auth.accessPassword);+ }+}++TMR_Status TMR_SR_cmdGen2v2NXPUntraceable(TMR_Reader *reader, uint16_t timeout,+ TMR_SR_GEN2_SiliconType chip, TMR_GEN2_Password accessPassword, uint16_t configWord,+ TMR_TagOp_GEN2_NXP_Untraceable op,TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddGen2v2NxpUntraceable(msg, &i, timeout, chip, accessPassword, configWord, op ,target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ return TMR_SUCCESS;+}+uint8_t getCmdProtModeBlockCount(uint8_t protMode, uint8_t blockCount)+{+ uint8_t protModeBlockCount = 0x01; //The UCODE AES Tag only supports ProtMode = "0001b" (CBC encryption)+ uint16_t mask = 0x0F;+ int pos = 4;+ protModeBlockCount |= ((blockCount & mask) << pos);++ return protModeBlockCount;+}+uint16_t getCmdProfileOffset(uint16_t profile, uint16_t offset)+{+ uint16_t profileOffset = 0x0000;+ uint16_t mask;+ int pos;++ mask = 0xF;+ pos = 12;+ profileOffset |= ((profile & mask) << pos);++ mask = 0xFFF;+ pos = 0;+ profileOffset |= ((offset & mask) << pos);++ return profileOffset;+}+void TMR_SR_msgAddGen2v2NxpAuthenticate(uint8_t *msg, uint8_t *i, uint16_t timeout,TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword,TMR_TagOp_GEN2_NXP_Authenticate op ,TMR_TagFilter* target)+{+ uint8_t option=0,rec; + SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)chip); /* Chip - type*/+ rec=*i;+ SETU8(msg,*i,0x00);//option+ SETU8(msg, *i, (uint8_t)op.subCommand); /* Sub command, Untraceable */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, false); + msg[rec]=msg[rec]|option;+ SETU8(msg,*i, op.tam1Auth.Authentication);+ SETU8(msg,*i,op.tam1Auth.CSI);+ SETU8(msg,*i,op.tam1Auth.keyID);+ SETU8(msg,*i,op.tam1Auth.KeyLength); + {+ uint8_t iWord;+ for (iWord = 0; iWord < op.tam1Auth.Key.len; iWord++)+ {+ SETU8(msg, *i, (op.tam1Auth.Key.list[iWord]));+ }+ }+ SETU8(msg,*i,op.tam1Auth.IchallengeLength);+ {+ uint8_t iWord;+ for (iWord = 0; iWord < op.tam1Auth.Ichallenge.len; iWord++)+ {+ SETU8(msg, *i, (op.tam1Auth.Ichallenge.list[iWord]));+ }+ }+ if(op.type == TAM2_AUTHENTICATION)+ {+ SETU16(msg, *i, getCmdProfileOffset(op.tam2Auth.profile,op.tam2Auth.Offset));+ SETU8(msg, *i, getCmdProtModeBlockCount(op.tam2Auth.ProtMode,op.tam2Auth.BlockCount));+ }+}++TMR_Status TMR_SR_cmdGen2v2NXPAuthenticate(TMR_Reader *reader, uint16_t timeout,TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword, TMR_TagOp_GEN2_NXP_Authenticate op, TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddGen2v2NxpAuthenticate(msg, &i, timeout, chip, accessPassword, op ,target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);++ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ if (NULL != data->list)+ {+ i = 8;+ {+ uint16_t dataLength;+ uint16_t copyLength;++ copyLength = dataLength = msg[1] + 5 - i;+ if (copyLength > data->max)+ {+ copyLength = data->max;+ }+ data->len = copyLength;+ memcpy(data->list, &msg[i], copyLength);+ i += dataLength;+ }+ }+ return TMR_SUCCESS;+}+uint16_t getCmdWordPointer(uint16_t wordPointer)+{+ uint16_t rdBufferWordPointer = 0x0000;+ if (wordPointer > 0)+ {+ uint16_t mask = 0x0FFF;+ int pos = 0;+ rdBufferWordPointer |= ((wordPointer & mask) << pos);+ }+ return rdBufferWordPointer;+}+uint16_t getCmdBitCount(uint16_t bitCount)+{+ uint16_t rdBufferBitCount = 0x0000;+ if (bitCount > 0)+ {+ uint16_t mask = 0x0FFF;+ int pos = 0;+ rdBufferBitCount |= ((bitCount & mask) << pos);+ }+ return rdBufferBitCount;+}+void TMR_SR_msgAddGen2v2NxpReadBuffer(uint8_t *msg, uint8_t *i, uint16_t timeout,TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword,TMR_TagOp_GEN2_NXP_Readbuffer op ,TMR_TagFilter* target)+{+ uint8_t option=0,rec; + SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)chip); /* Chip - type*/+ rec=*i;+ SETU8(msg,*i,0x00);//option+ SETU8(msg, *i, (uint8_t)op.authenticate.subCommand); /* Sub command, Untraceable */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, false); + msg[rec]=msg[rec]|option;+ SETU16(msg, *i, getCmdWordPointer(op.wordPointer));+ SETU16(msg, *i, getCmdBitCount(op.bitCount));+ SETU8(msg,*i, op.authenticate.tam1Auth.Authentication);+ SETU8(msg,*i,op.authenticate.tam1Auth.CSI);+ SETU8(msg,*i,op.authenticate.tam1Auth.keyID);+ SETU8(msg,*i,op.authenticate.tam1Auth.KeyLength); + {+ uint8_t iWord;+ for (iWord = 0; iWord < op.authenticate.tam1Auth.Key.len; iWord++)+ {+ SETU8(msg, *i, (op.authenticate.tam1Auth.Key.list[iWord]));+ }+ }+ SETU8(msg,*i,op.authenticate.tam1Auth.IchallengeLength);+ {+ uint8_t iWord;+ for (iWord = 0; iWord < op.authenticate.tam1Auth.Ichallenge.len; iWord++)+ {+ SETU8(msg, *i, (op.authenticate.tam1Auth.Ichallenge.list[iWord]));+ }+ }+ if(op.authenticate.type == TAM2_AUTHENTICATION)+ {+ SETU16(msg, *i, getCmdProfileOffset(op.authenticate.tam2Auth.profile,op.authenticate.tam2Auth.Offset));+ SETU8(msg, *i, getCmdProtModeBlockCount(op.authenticate.tam2Auth.ProtMode,op.authenticate.tam2Auth.BlockCount));+ }+}++TMR_Status TMR_SR_cmdGen2v2NXPReadBuffer(TMR_Reader *reader, uint16_t timeout,TMR_SR_GEN2_SiliconType chip,+ TMR_GEN2_Password accessPassword, TMR_TagOp_GEN2_NXP_Readbuffer op, TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddGen2v2NxpReadBuffer(msg, &i, timeout, chip, accessPassword, op ,target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ if (NULL != data->list)+ {+ i = 8;+ {+ uint16_t dataLength;+ uint16_t copyLength;++ copyLength = dataLength = msg[1] + 5 - i;+ if (copyLength > data->max)+ {+ copyLength = data->max;+ }+ data->len = copyLength;+ memcpy(data->list, &msg[i], copyLength);+ i += dataLength;+ }+ }+ return TMR_SUCCESS;+}+/** + * Monza4 Silicon Specific Commands+ * Chip Type = 0x08+ **/++/** Helper routine to form the Monza4 QT Read/Write command **/+void TMR_SR_msgAddMonza4QTReadWrite(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ TMR_Monza4_ControlByte controlByte, TMR_Monza4_Payload payload, TMR_TagFilter* target)+{+ uint8_t option=0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IMPINJ_MONZA4_SILICON); /* Chip - type*/+ rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)0x00); /* Sub command, QT Read/Write */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true); + msg[rec]=msg[rec]|option;+ SETU8(msg, *i, controlByte.data);+ SETU16(msg, *i, payload.data);+}++/**+ * Impinj Monza4 QT Read/Write+ * Chip type = 0x08, command = 0x00+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param controlByte The control byte to write on the tag+ * @param payload The payload + * @param data If the operation is success, this data contains the payload+ * When Read/Write (bit) = 0, then the payload is the value read,+ * When Read/Write (bit) = 1, then the payload is the value written.+ * @param target Filter to be applied.+ */+TMR_Status TMR_SR_cmdMonza4QTReadWrite(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, + TMR_Monza4_ControlByte controlByte, TMR_Monza4_Payload payload, TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddMonza4QTReadWrite(msg, &i, timeout, accessPassword, controlByte, payload, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ + /* Parse the payload data from response back to the user */+ i = 9; + /* FF 06 2d 00 00 08 40 00 00 xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [payload] CRC+ */+ {+ uint16_t copyLength;+ + copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;++}++/**+ * IDS SL900A specific commands+ * chip type 0A+ */++/**+ * Helper routine to form the IDS SL900A get battery level command+ */+void TMR_SR_msgAddIdsSL900aGetBatteryLevel(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, BatteryType batteryType,+ TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU8(msg, *i, batteryType);+}++/**+ * IDS SL900A Get Battery Level+ * Chip type = 0x0A, command = 0x00 AA+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aGetBatteryLevel(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level,BatteryType type,+ TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aGetBatteryLevel(msg, &i, timeout, accessPassword, CommandCode, password, level, type, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the battery level data from response back to the user */+ i = 9;+ /* FF 06 2d 00 00 0A 42 00 AD xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [level] CRC+ */+ {+ uint16_t copyLength;+ + copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * Helper routine to form the IDS SL900A get sensor value command+ */+void TMR_SR_msgAddIdsSL900aGetSensorValue(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, Sensor sensortype,+ TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU8(msg, *i, sensortype);+}++/**+ * IDS SL900A Get Sensor value+ * Chip type = 0x0A, command = 0x00 AD+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aGetSensorValue(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level,Sensor sensortype,+ TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aGetSensorValue(msg, &i, timeout, accessPassword, CommandCode, password, level, sensortype, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the sensor type data from response back to the user */+ i = 9;+ /* FF 06 2d 00 00 0A 42 00 AD xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [type] CRC+ */+ {+ uint16_t copyLength;+ + copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * Helper routine to form the IDS SL900A get measurment setup command+ */+void TMR_SR_msgAddIdsSL900aGetMeasurementSetup(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+}++/**+ * IDS SL900A Get Sensor value+ * Chip type = 0x0A, command = 0x00 A3+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aGetMeasurementSetup(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level,+ TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aGetMeasurementSetup(msg, &i, timeout, accessPassword, CommandCode, password, level, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the measurment data from response back to the user */+ i = 9;+ /* FF 06 2d 00 00 0A 42 00 AD xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [data] CRC+ */+ {+ uint16_t copyLength;+ + copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * Helper routine to form the IDS SL900A get log state command+ */+void TMR_SR_msgAddIdsSL900aGetLogState(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+}++/**+ * IDS SL900A Get log State+ * Chip type = 0x0A, command = 0x00 AD+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param to specify SL900A sensor type+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aGetLogState(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level,TMR_uint8List *data,+ TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aGetLogState(msg, &i, timeout, accessPassword, CommandCode, password, level, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the sensor type data from response back to the user */+ i = 9;+ /* FF 06 2d 00 00 0A 42 00 AD xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [type] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * Helper routine to form the IDS SL900A set log mode command+ */+void TMR_SR_msgAddIdsSL900aSetLogMode(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, LoggingForm form,+ StorageRule rule, bool Ext1Enable, bool Ext2Enable, bool TempEnable, bool BattEnable,+ uint16_t LogInterval, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;+ uint32_t logmode = 0;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);++ logmode |= (uint32_t)form << 21;+ logmode |= (uint32_t)rule << 20;+ logmode |= (uint32_t)(Ext1Enable ? 1 : 0) << 19;+ logmode |= (uint32_t)(Ext2Enable ? 1 : 0) << 18;+ logmode |= (uint32_t)(TempEnable ? 1 : 0) << 17;+ logmode |= (uint32_t)(BattEnable ? 1 : 0) << 16;+ logmode |= (uint32_t)LogInterval << 1;+ SETU8(msg, *i, (uint8_t)((logmode >> 16) & 0xFF));+ SETU8(msg, *i, (uint8_t)((logmode >> 8) & 0xFF));+ SETU8(msg, *i, (uint8_t)((logmode >> 0) & 0xFF));+}++/**+ * IDS SL900A Get log State+ * Chip type = 0x0A, command = 0x00 AD+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param level IDS password level+ * @param form IDS logging form+ * @param rule IDS storage rule+ * @param Ext1Enable to Enable log for EXT1 external sensor+ * @param Ext2Enable to Enable log for EXT2 external sensor+ * @param TempEnable to Enable log for temperature sensor+ * @param BattEnable to Enable log for battery sensor+ * @param LogInterval to Time (seconds) between log readings+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aSetLogMode(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, LoggingForm form,+ StorageRule rule, bool Ext1Enable, bool Ext2Enable, bool TempEnable, bool BattEnable,+ uint16_t LogInterval, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aSetLogMode(msg, &i, timeout, accessPassword, CommandCode, password, level, form,+ rule, Ext1Enable, Ext2Enable, TempEnable, BattEnable, LogInterval, target);++ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/* Helper routine to form the IDS SL900A initialize command */+void TMR_SR_msgAddIdsSL900aInitialize(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t delayTime,+ uint16_t applicatioData, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU16(msg, *i, delayTime);+ SETU16(msg, *i, applicatioData);+}++/**+ * IDS SL900A initialize command+ * Chip type = 0x0A, command = 0x00 AC+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param delayTime to secify delayTime+ * @param applicatioData to specify applicationData+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aInitialize(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t delayTime,+ uint16_t applicationData, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aInitialize(msg, &i, timeout, accessPassword, CommandCode, password, level, delayTime,+ applicationData, target);++ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/**+ * Helper routine to form the IDS SL900A end log command+ */+void TMR_SR_msgAddIdsSL900aEndLog(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password); +}++/**+ * IDS SL900A Initialize command+ * Chip type = 0x0A, command = 0x00 A6+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aEndLog(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aEndLog(msg, &i, timeout, accessPassword, CommandCode, password, level, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/**+ * Helper function to form the IDS SL900A SetPassword command+ */ +void TMR_SR_msgAddIdsSL900aSetPassword(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t newPassword,+ PasswordLevel newPasswordLevel, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU8(msg, *i, (uint8_t)newPasswordLevel);+ SETU32(msg, *i, newPassword);+}++/**+ * IDS SL900A SetPassword command+ * Chip type = 0x0A, command = 0x00 A0+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aSetPassword(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t newPassword,+ PasswordLevel newPasswordLevel, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aSetPassword(msg, &i, timeout, accessPassword, CommandCode, password, level, newPassword, newPasswordLevel, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/**+ * Helper routine to form the IDS SL900A AccessFifo Status command+ */+void TMR_SR_msgAddIdsSL900aAccessFifoStatus(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation operation,+ TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU8(msg, *i, (uint8_t)operation);+}++/**+ * IDS SL900A AccessFifo status command+ * Chip type = 0x0A, command = 0x00 AF+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aAccessFifoStatus(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+ uint32_t password, PasswordLevel level, AccessFifoOperation operation,TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aAccessFifoStatus(msg, &i, timeout, accessPassword, CommandCode, password, level, operation, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the sensor type data from response back to the user */+ i = 9;+ /* FF 06 2d 00 00 0A 42 00 AF xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [type] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * Helper routine to form the IDS SL900A AccessFifo Read command+ */+void TMR_SR_msgAddIdsSL900aAccessFifoRead(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation operation,+ uint8_t length, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU8(msg, *i, (uint8_t)(operation | length));+}++/**+ * IDS SL900A AccessFifo read command+ * Chip type = 0x0A, command = 0x00 AF+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aAccessFifoRead(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+ uint32_t password, PasswordLevel level, AccessFifoOperation operation, uint8_t length, TMR_uint8List *data,+ TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aAccessFifoRead(msg, &i, timeout, accessPassword, CommandCode, password, level, operation, length, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the sensor type data from response back to the user */+ i = 9;+ /* FF 06 2d 00 00 0A 42 00 AF xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [type] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * Helper routine to form the IDS SL900A AccessFifo Write command+ */+void TMR_SR_msgAddIdsSL900aAccessFifoWrite(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, AccessFifoOperation operation,+ TMR_uint8List *payLoad, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU8(msg, *i, (uint8_t)(operation | payLoad->len));+ memcpy(&msg[*i], payLoad->list, payLoad->len);+ *i += payLoad->len;+}++/**+ * IDS SL900A AccessFifo Write command+ * Chip type = 0x0A, command = 0x00 AF+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aAccessFifoWrite(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+ uint32_t password, PasswordLevel level, AccessFifoOperation operation, TMR_uint8List *payLoad, TMR_uint8List *data,+ TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aAccessFifoWrite(msg, &i, timeout, accessPassword, CommandCode, password, level, operation, payLoad, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the sensor type data from response back to the user */+ i = 9;+ /* FF 06 2d 00 00 0A 42 00 AF xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [type] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * Helper routine to form the IDS SL900A Start Log command+ */+void TMR_SR_msgAddIdsSL900aStartLog(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t time, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU32(msg, *i, time);+}++/**+ * IDS SL900A StartLog command+ * Chip type = 0x0A, command = 0x00 A7+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param startTime to specify count start time+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aStartLog(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t CommandCode,+ uint32_t password, PasswordLevel level, uint32_t time, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aStartLog(msg, &i, timeout, accessPassword, CommandCode, password, level, time, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/**+ * Helper routine to form the IDS SL900A get calibration data command+ */+void TMR_SR_msgAddIdsSL900aGetCalibrationData(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+}++/**+ * IDS SL900A Get Calibration Data+ * Chip type = 0x0A, command = 0x00 A9+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aGetCalibrationData(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level,+ TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aGetCalibrationData(msg, &i, timeout, accessPassword, CommandCode, password, level, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the calibration data from response back to the user */+ i = 9;+ /* FF 06 2d 00 00 0A 42 00 A9 xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [data] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * Helper routine to form the IDS SL900A set calibration data command+ */+void TMR_SR_msgAddIdsSL900aSetCalibrationData(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint64_t calibration, + TMR_TagFilter* target)+{+ uint8_t option = 0, rec;+ uint8_t calBytes[8];++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);++ calBytes[0] = (uint8_t) (calibration >> 56);+ calBytes[1] = (uint8_t) (calibration >> 48);+ calBytes[2] = (uint8_t) (calibration >> 40);+ calBytes[3] = (uint8_t) (calibration >> 32);+ calBytes[4] = (uint8_t) (calibration >> 24);+ calBytes[5] = (uint8_t) (calibration >> 16);+ calBytes[6] = (uint8_t) (calibration >> 8);+ calBytes[7] = (uint8_t) (calibration >> 0);++ memcpy(&msg[*i], calBytes + 1, 7);+ *i += 7;++}++/**+ * IDS SL900A Set Calibration Data+ * Chip type = 0x0A, command = 0x00 A5+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param calibration to spcify the calibration data+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aSetCalibrationData(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, + uint8_t CommandCode, uint32_t password, PasswordLevel level, uint64_t calibration,+ TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aSetCalibrationData(msg, &i, timeout, accessPassword, CommandCode, password, level, calibration, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/**+ * Helper routine to form the IDS SL900A set sfe parameters command+ */+void TMR_SR_msgAddIdsSL900aSetSfeParameters(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t sfe,+ TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU16(msg, *i, sfe);+}++/**+ * IDS SL900A Set Calibration Data+ * Chip type = 0x0A, command = 0x00 A4+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param sfe to spcify the sfe parameters+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aSetSfeParameters(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, + uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t sfe,+ TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aSetSfeParameters(msg, &i, timeout, accessPassword, CommandCode, password, level, sfe, target);+ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/**+ * Helper routine to form the IDS Sl900A set log mode command+ */+void TMR_SR_msgAddIdsSL900aSetLogLimit(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t exLower,+ uint16_t lower, uint16_t upper, uint16_t exUpper, TMR_TagFilter* target)+{+ uint8_t option = 0, rec;+ uint64_t temp = 0;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);++ temp |= (uint64_t)exLower << 30;+ temp |= (uint64_t)lower << 20;+ temp |= (uint64_t)upper << 10;+ temp |= (uint64_t)exUpper << 0;++ SETU8(msg, *i, (uint8_t)((temp >> 32) & 0xFF));+ SETU8(msg, *i, (uint8_t)((temp >> 24) & 0xFF));+ SETU8(msg, *i, (uint8_t)((temp >> 16) & 0xFF));+ SETU8(msg, *i, (uint8_t)((temp >> 8) & 0xFF));+ SETU8(msg, *i, (uint8_t)((temp >> 0) & 0xFF));+}++/**+ * IDS SL90A SetLogLimit+ * Chip type = 0x0A, command = 0x00 A2+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in millisecondds. Valid range 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param level IDS password level+ * @param exLoweer IDS extreamLower limit+ * @param lower IDS lower limit+ * @param upper IDS upper limit+ * @param exUpper IDS extreamUpper limit+ */+TMR_Status+TMR_SR_cmdSL900aSetLogLimit(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint16_t exLower,+ uint16_t lower, uint16_t upper, uint16_t exUpper, TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aSetLogLimit(msg, &i, timeout, accessPassword, CommandCode, password, level, exLower,+ lower, upper, exUpper, target);++ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/**+ * Helper routine to form the IDS SL900A SetShelfLife command+ */+void TMR_SR_msgAddIdsSL900aSetShelfLife(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t block0, uint32_t block1,+ TMR_TagFilter* target)+{+ uint8_t option = 0, rec;++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_IDS_SL900A_SILICON); /* chip type */+ rec = *i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)CommandCode);+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true);+ msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)level);+ SETU32(msg, *i, password);+ SETU32(msg, *i, block0);+ SETU32(msg, *i, block1);+}++/**+ * IDS SL900A SetShelfLife+ * Chip type = 0x0A, command = 0x00 AB+ *+ * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param commandcode to specify the operation+ * @param password to specify SL900A password access level values+ * @param data If the operation is success, this data contains the requested value+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdSL900aSetShelfLife(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t CommandCode, uint32_t password, PasswordLevel level, uint32_t block0, uint32_t block1,+ TMR_TagFilter* target)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIdsSL900aSetShelfLife(msg, &i, timeout, accessPassword, CommandCode, password, level, block0, block1, target);++ msg[1] = i - 3; /* Install length */++ return TMR_SR_sendTimeout(reader, msg, timeout);+}++/** + * Gen2 IAVDenatran Custom Commands+ * Chip Type = 0x0B+ **/+ +/** Helper routine to form the Gen2 IAVDenatran Custom commands **/+void TMR_SR_msgAddIAVDenatranCustomOp(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target)+{+ uint8_t option=0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_DENATRAN_IAV_SILICON); /* Chip - type*/+ rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)mode); /* Sub command */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true); + msg[rec]=msg[rec]|option;+ SETU8(msg, *i, (uint8_t)payload);+}++ /**+ * IAV Denatran Custom Commands+ * Chip type = 0x0B, command = 0x00+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param target Filter to be applied.+ */+TMR_Status+TMR_SR_cmdIAVDenatranCustomOp(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIAVDenatranCustomOp(msg, &i, timeout, accessPassword, mode, payload, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the response back to the user */+ i = 9; + /* FF 06 2d 00 00 08 40 00 00 xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [payload] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;++ if (copyLength > data->max)+ {+ copyLength = data->max;+ }+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/** Helper routine to form the Gen2 IAVDenatran Custom commad readFromMemMap */+void TMR_SR_msgAddIAVDenatranCustomReadFromMemMap(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, uint16_t wordAddress)+{++ TMR_SR_msgAddIAVDenatranCustomOp(msg, i, timeout, accessPassword, mode, payload, target);+ /* Add the address to be read from user bank */+ SETU16(msg, *i, wordAddress);+}++/** * IAV Denatran Custom Command Read From MemMap+ * Chip type = 0x0B, command = 0x06+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param target Filter to be applied.+ * @param wordAddress address to be read from USER bank+ */+TMR_Status+TMR_SR_cmdIAVDenatranCustomReadFromMemMap(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, uint16_t wordAddress)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIAVDenatranCustomReadFromMemMap(msg, &i, timeout, accessPassword, mode, payload, target, wordAddress);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the response back to the user */+ i = 9;+ /* FF 06 2d 00 00 08 40 00 00 xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [payload] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;++ if (copyLength > data->max)+ {+ copyLength = data->max;+ }+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/** Helper routine to form the Gen2 IAVDenatran Custom commad read sec */+void TMR_SR_msgAddIAVDenatranCustomReadSec(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, uint16_t wordAddress)+{++ TMR_SR_msgAddIAVDenatranCustomOp(msg, i, timeout, accessPassword, mode, payload, target);+ /* Add the address to be read from user bank */+ SETU16(msg, *i, wordAddress);+}++/** * IAV Denatran Custom Command Read Sec+ * Chip type = 0x0B, command = 0x0A+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param target Filter to be applied.+ * @param wordAddress address to be read from USER bank+ */+TMR_Status+TMR_SR_cmdIAVDenatranCustomReadSec(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, uint16_t wordAddress)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIAVDenatranCustomReadSec(msg, &i, timeout, accessPassword, mode, payload, target, wordAddress);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the response back to the user */+ i = 9;+ /* FF 06 2d 00 00 08 40 00 00 xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [payload] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;++ if (copyLength > data->max)+ {+ copyLength = data->max;+ }+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/** Helper routine to form the Gen2 IAVDenatran Custom commad Activate Siniav Mode */+void TMR_SR_msgAddIAVDenatranCustomActivateSiniavMode(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, bool tokenDesc, uint8_t *token)+{+ uint8_t j;++ TMR_SR_msgAddIAVDenatranCustomOp(msg, i, timeout, accessPassword, mode, payload, target);+ /* add the token field */+ if (tokenDesc)+ {+ for (j = 0; j < 8; j++)+ {+ SETU8(msg, *i, token[j]);+ }+ }+}++ /**+ * IAV Denatran Custom Commands Activate Siniav Mode+ * Chip type = 0x0B, command = 0x02+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param target Filter to be applied.+ * @param token 64bit value to active the tag+ */+TMR_Status+TMR_SR_cmdIAVDenatranCustomActivateSiniavMode(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, bool tokenDesc, uint8_t *token)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIAVDenatranCustomActivateSiniavMode(msg, &i, timeout, accessPassword, mode, payload, target, tokenDesc, token);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the response back to the user */+ i = 9; + /* FF 06 2d 00 00 08 40 00 00 xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [payload] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;++ if (copyLength > data->max)+ {+ copyLength = data->max;+ }+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/** Helper routine to form the Gen2 IAVDenatran Custom commad writeToMemMap */+void TMR_SR_msgAddIAVDenatranCustomWriteToMemMap(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, uint16_t wordPtr, uint16_t wordData, uint8_t* tagId, uint8_t* dataBuf)+{+ uint8_t j;++ TMR_SR_msgAddIAVDenatranCustomOp(msg, i, timeout, accessPassword, mode, payload, target);+ /* Add the address to be read from user bank */+ SETU16(msg, *i, wordPtr);+ SETU16(msg, *i, wordData);+ for (j = 0; j < 8; j++)+ {+ SETU8(msg, *i, tagId[j]);+ }+ for (j = 0; j < 16; j++)+ {+ SETU8(msg, *i, dataBuf[j]);+ }+}++/** Helper routine to form the Gne2 IAVDenatran Custom command get token Id */+void TMR_SR_msgAddIAVDenatranCustomGetTokenId(uint8_t *msg, uint8_t *i, uint16_t timeout, + TMR_GEN2_Password accessPassword, uint8_t mode, TMR_TagFilter* target)+{+ uint8_t option = 0,rec; ++ SETU8(msg, *i, TMR_SR_OPCODE_WRITE_TAG_SPECIFIC);+ SETU16(msg, *i, timeout);+ SETU8(msg, *i, (uint8_t)TMR_SR_GEN2_DENATRAN_IAV_SILICON); /* Chip - type*/+ rec=*i;+ SETU8(msg,*i,0x40);//option+ SETU8(msg, *i, (uint8_t)0x00);+ SETU8(msg, *i, (uint8_t)mode); /* Sub command */+ filterbytes(TMR_TAG_PROTOCOL_GEN2, target, &option, i, msg, accessPassword, true); + msg[rec]=msg[rec]|option;+}++/**+ * IAV Denatran Custom Command write to MemMap+ * Chip type = 0x0B, command = 0x06+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param target Filter to be applied.+ * @param wordPtr pointer to the USER data+ * @param wordData data to be written+ * @param dataBuf credentials written word+ */+TMR_Status+TMR_SR_cmdIAVDenatranCustomWriteToMemMap(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, uint16_t wordPtr, uint16_t wordData, uint8_t* tagId, uint8_t* dataBuf)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIAVDenatranCustomWriteToMemMap(msg, &i, timeout, accessPassword, mode, payload, target, wordPtr, wordData, tagId, dataBuf);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the response back to the user */+ i = 9;+ /* FF 06 2d 00 00 08 40 00 00 xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [payload] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;++ if (copyLength > data->max)+ {+ copyLength = data->max;+ }+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/** Helper routine to form the Gen2 IAVDenatran Custom commad write Sec */+void TMR_SR_msgAddIAVDenatranCustomWriteSec(uint8_t *msg, uint8_t *i, uint16_t timeout, TMR_GEN2_Password accessPassword,+ uint8_t mode, uint8_t payload, TMR_TagFilter* target, uint8_t* data, uint8_t* dataBuf)+{+ uint8_t j;++ TMR_SR_msgAddIAVDenatranCustomOp(msg, i, timeout, accessPassword, mode, payload, target);++ for (j = 0; j < 6; j++)+ {+ SETU8(msg, *i, data[j]);+ }+ for (j = 0; j < 16; j++)+ {+ SETU8(msg, *i, dataBuf[j]);+ }+}++/**+ * IAV Denatran Custom Command write sec+ * Chip type = 0x0B, command = 0x0B+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag+ * @param target Filter to be applied.+ * @param wordPtr pointer to the USER data+ * @param data data words+ * @param dataBuf credentials written word+ */+TMR_Status+TMR_SR_cmdIAVDenatranCustomWriteSec(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, uint8_t payload,+ TMR_uint8List *data, TMR_TagFilter* target, uint8_t* dataWords, uint8_t* dataBuf)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIAVDenatranCustomWriteSec(msg, &i, timeout, accessPassword, mode, payload, target, dataWords, dataBuf);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the response back to the user */+ i = 9;+ /* FF 06 2d 00 00 08 40 00 00 xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [payload] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;++ if (copyLength > data->max)+ {+ copyLength = data->max;+ }+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * IAV Denatran Custom Command Get Token Id+ * Chip type = 0x0B, command = 0x09+ * + * @param reader The reader+ * @param timeout The timeout of the operation, in milliseconds. Valid range is 0-65535.+ * @param accessPassword The access password to use to write on the tag + * @param target Filter to be applied.+ */ +TMR_Status+TMR_SR_cmdIAVDenatranCustomGetTokenId(TMR_Reader *reader, uint16_t timeout, TMR_GEN2_Password accessPassword, uint8_t mode, + TMR_uint8List *data, TMR_TagFilter* target)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ TMR_SR_msgAddIAVDenatranCustomGetTokenId(msg, &i, timeout, accessPassword, mode, target);+ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, timeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the response back to the user */+ i = 9;+ /* FF 06 2d 00 00 08 40 00 00 xx xx xx xx+ * SOH Length OpCode Status ChipType option SubCommand [payload] CRC+ */+ {+ uint16_t copyLength;++ copyLength = msg[1] + 5 - i;++ if (copyLength > data->max)+ {+ copyLength = data->max;+ }+ if (NULL != data)+ {+ memcpy(data->list, &msg[i], copyLength);+ data->len = copyLength;+ }+ }+ return TMR_SUCCESS;+}++/**+ * TMR_SR_cmdGetReaderStatistics+ * Get the current per-port statistics.+ *+ * @param reader [in]The reader+ * @param statFlags [in]The set of statistics together+ * @param stats [out]The ReaderStatistics structure populated with requested per-port values+ */+TMR_Status+TMR_SR_cmdGetReaderStatistics(TMR_Reader *reader, TMR_SR_ReaderStatisticsFlag statFlags,+ TMR_SR_ReaderStatistics *stats)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, length, offset;+ i = 2;++ SETU8(msg, i, TMR_SR_OPCODE_GET_READER_STATS);+ SETU8(msg, i, (uint8_t)TMR_SR_READER_STATS_OPTION_GET_PER_PORT); /* Option byte */+ SETU8(msg, i, (uint8_t)statFlags);++ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, reader->u.serialReader.commandTimeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the statistics from response */+ if (NULL != stats)+ {+ uint8_t port = 0;+ offset = 7;++ length = reader->u.serialReader.txRxMap->len;++ while (offset < (msg[1] + 2))+ {+ if (0 != (msg[offset] & TMR_SR_READER_STATS_FLAG_RF_ON_TIME))+ {+ offset += 2;++ for (i = 0; i < length; i++)+ {+ port = msg[offset];+ if (i == (port-1))+ {+ offset ++;+ stats->rfOnTime[i] = GETU32(msg, offset);+ }+ else+ {+ stats->rfOnTime[i] = 0;+ }+ }+ stats->numPorts = length;+ }+ else if (0 != (msg[offset] & TMR_SR_READER_STATS_FLAG_NOISE_FLOOR))+ {+ offset += 2;++ for (i = 0; i < length; i++)+ {+ port = msg[offset];+ if (i == (port-1))+ {+ offset ++;+ stats->noiseFloor[i] = msg[offset++];+ }+ else+ {+ stats->noiseFloor[i] = 0;+ }+ }+ stats->numPorts = length;+ }+ else if (0 != (msg[offset] & TMR_SR_READER_STATS_FLAG_NOISE_FLOOR_TX_ON))+ {+ offset += 2;++ for (i = 0; i < length; i++)+ {+ port = msg[offset];+ if (i == (port-1))+ {+ offset ++;+ stats->noiseFloorTxOn[i] = msg[offset++];+ }+ else+ {+ stats->noiseFloorTxOn[i] = 0;+ }+ }+ stats->numPorts = length;+ }+ }+ }+ return TMR_SUCCESS;+}++/**+ * TMR_SR_cmdResetReaderStatistics+ * Reset the per-port statistics.+ *+ * @param reader [in]The reader+ * @param statFlags [in]The set of statistics to reset. Only the RF on time statistic may be reset.+ */+TMR_Status+TMR_SR_cmdResetReaderStatistics(TMR_Reader *reader, TMR_SR_ReaderStatisticsFlag statFlags)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ i = 2;++ SETU8(msg, i, TMR_SR_OPCODE_GET_READER_STATS);+ SETU8(msg, i, (uint8_t)TMR_SR_READER_STATS_OPTION_RESET); /* Option byte */+ SETU8(msg, i, (uint8_t)statFlags);++ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, reader->u.serialReader.commandTimeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ return TMR_SUCCESS;+}+++/**+ * Helper function to be used in GetReaderStats+ */ +TMR_Status+TMR_fillReaderStats(TMR_Reader *reader, TMR_Reader_StatsValues* stats, uint16_t flag, uint8_t* msg, uint8_t offset)+{+ uint8_t i;+ while (offset < (msg[1] + 2))+ {+ if ((0x80) > msg[offset])+ {+ flag = msg[offset];+ }+ else+ {+ /**+ * the response flag will be in EBV format,+ * convert that to the api enum values+ */+ flag = ((msg[offset] << 8) | (msg[offset + 1]));+ flag &= 0x7fff;+ flag = ((flag >> 1) | (flag & 0x7f));+ }+++ if (flag & TMR_READER_STATS_FLAG_RF_ON_TIME)+ {+ uint8_t tx;++ offset += 2;++ for (i = 0; i < reader->u.serialReader.txRxMap->len; i++)+ {+ tx = GETU8(msg, offset);+ if (tx == reader->u.serialReader.txRxMap->list[i].txPort)+ {+ stats->perAntenna.list[i].antenna = reader->u.serialReader.txRxMap->list[i].antenna;+ stats->perAntenna.list[i].rfOnTime = GETU32(msg, offset);+ }+ }+ }++ else if (flag & TMR_READER_STATS_FLAG_NOISE_FLOOR_SEARCH_RX_TX_WITH_TX_ON)+ {+ uint8_t tx,rx, len;++ offset++;+ len = GETU8(msg, offset);+ while (len)+ {+ tx = GETU8(msg, offset);+ rx = GETU8(msg, offset);+ for (i = 0; i < reader->u.serialReader.txRxMap->len; i++)+ {+ if ((rx == reader->u.serialReader.txRxMap->list[i].rxPort) && (tx == reader->u.serialReader.txRxMap->list[i].txPort))+ {+ stats->perAntenna.list[i].antenna = reader->u.serialReader.txRxMap->list[i].antenna;+ stats->perAntenna.list[i].noiseFloor = GETU8(msg, offset);+ len -= 3;+ }+ }+ }+ }++ else if (flag & TMR_READER_STATS_FLAG_FREQUENCY)+ {+ offset += 3;+ stats->frequency = GETU24(msg, offset);+ }++ else if (flag & TMR_READER_STATS_FLAG_TEMPERATURE)+ {+ offset += 3;+ stats->temperature = GETU8(msg, offset);+ }++ else if (flag & TMR_READER_STATS_FLAG_PROTOCOL)+ {+ offset += 3;+ stats->protocol = (TMR_TagProtocol)GETU8(msg, offset);+ }++ else if (flag & TMR_READER_STATS_FLAG_ANTENNA_PORTS)+ {+ uint8_t tx, rx;++ offset += 3; + tx = GETU8(msg, offset);+ rx = GETU8(msg, offset);++ for (i = 0; i < reader->u.serialReader.txRxMap->len; i++)+ {+ if ((rx == reader->u.serialReader.txRxMap->list[i].rxPort) && (tx == reader->u.serialReader.txRxMap->list[i].txPort))+ {+ stats->antenna = reader->u.serialReader.txRxMap->list[i].antenna;+ break;+ }+ }+ }++ else if (flag & TMR_READER_STATS_FLAG_CONNECTED_ANTENNAS)+ {+ offset += 3;+ stats->connectedAntennas.len = msg[offset - 1];+ for (i = 0; i < stats->connectedAntennas.len; i++)+ {+ stats->connectedAntennas.list[i] = msg[offset++];+ }+ }+ else+ {+ return TMR_ERROR_INVALID;+ }+ }/* End of while loop */+ return TMR_SUCCESS;+}+ +/**+ * TMR_SR_cmdGetReaderStats+ * Get the current per-port statistics.+ * + * @param reader [in]The reader+ * @param statFlags [in]The set of statistics together+ * @param stats [out]The ReaderStatistics structure populated with requested per-port values+ */+TMR_Status +TMR_SR_cmdGetReaderStats(TMR_Reader *reader, TMR_Reader_StatsFlag statFlags,+ TMR_Reader_StatsValues *stats)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, offset; + uint16_t flag = 0, temp = 0;+ i = 2;++ SETU8(msg, i, TMR_SR_OPCODE_GET_READER_STATS);+ SETU8(msg, i, (uint8_t)TMR_SR_READER_STATS_OPTION_GET_PER_PORT); /* Option byte */++ /**+ * To extend the flag byte, an EBV technique is to be used.+ * When the highest order bit of the flag byte is used,+ * it signals the reader’s parser, that another flag byte is to follow+ */+ if ((0x80) > statFlags)+ {+ SETU8(msg, i, (uint8_t)statFlags);+ }+ else+ {+ temp = statFlags & 0x7f;+ statFlags &= 0xFFFE;+ statFlags = (TMR_Reader_StatsFlag)((statFlags << 1) | temp);+ statFlags &= 0xFF7F;+ SETU16(msg, i, ((uint16_t)0x8000 | statFlags));+ }++ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, reader->u.serialReader.commandTimeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Parse the statistics from response */+ if (NULL != stats)+ {+ uint8_t j;+ offset = 7;++ /**+ * preinitialize the rf ontime and the noise floor value to zero+ * berfore getting the reader stats+ */+ for (i = 0; i < stats->perAntenna.max; i++)+ {+ stats->perAntenna.list[i].antenna = 0;+ stats->perAntenna.list[i].rfOnTime = 0;+ stats->perAntenna.list[i].noiseFloor = 0;+ }++ if ((0x80) > statFlags)+ {+ offset = 7;+ }+ else+ {+ offset = 8;+ }++ ret = TMR_fillReaderStats(reader, stats, flag, msg, offset);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /**+ * iterate through the per antenna values,+ * If found any 0-antenna rows, copy the+ * later rows down to compact out the empty space.+ */+ for (i = 0; i < reader->u.serialReader.txRxMap->len; i++)+ {+ if (!stats->perAntenna.list[i].antenna )+ {+ for (j = i + 1; j < reader->u.serialReader.txRxMap->len; j++)+ {+ if (stats->perAntenna.list[j].antenna) + {+ stats->perAntenna.list[i].antenna = stats->perAntenna.list[j].antenna;+ stats->perAntenna.list[i].rfOnTime = stats->perAntenna.list[j].rfOnTime;+ stats->perAntenna.list[i].noiseFloor = stats->perAntenna.list[j].noiseFloor;+ stats->perAntenna.list[j].antenna = 0;+ stats->perAntenna.list[j].rfOnTime = 0;+ stats->perAntenna.list[j].noiseFloor = 0;++ stats->perAntenna.len++;+ break;+ }+ }+ }+ else+ {+ /* Increment the length */+ stats->perAntenna.len++;+ }+ }+ }/* end of outermost if block */++ /* Store the requested flags for future validation */+ stats->valid = reader->statsFlag;++ return TMR_SUCCESS;+}++/**+ * TMR_SR_cmdResetReaderStats+ * Reset the per-port statistics.+ * + * @param reader [in]The reader+ * @param statFlags [in]The set of statistics to reset. Only the RF on time statistic may be reset.+ */+TMR_Status +TMR_SR_cmdResetReaderStats(TMR_Reader *reader, TMR_Reader_StatsFlag statFlags)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ uint16_t temp = 0;+ i = 2;++ SETU8(msg, i, TMR_SR_OPCODE_GET_READER_STATS);+ SETU8(msg, i, (uint8_t)TMR_SR_READER_STATS_OPTION_RESET); /* Option byte */++ /**+ * To extend the flag byte, an EBV technique is to be used.+ * When the highest order bit of the flag byte is used,+ * it signals the reader’s parser, that another flag byte is to follow+ */+ if ((0x80) > statFlags)+ {+ SETU8(msg, i, (uint8_t)statFlags);+ }+ else+ {+ temp = statFlags & 0x7f;+ statFlags &= 0xFFFE;+ statFlags = (TMR_Reader_StatsFlag)((statFlags << 1) | temp);+ statFlags &= 0xFF7F;+ SETU16(msg, i, ((uint16_t)0x8000 | statFlags));+ }++ msg[1] = i - 3; /* Install length */++ ret = TMR_SR_sendTimeout(reader, msg, reader->u.serialReader.commandTimeout);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_receiveAutonomousReading(struct TMR_Reader *reader, TMR_TagReadData *trd, TMR_Reader_StatsValues *stats)+{+ TMR_Status ret;++ ret = TMR_SUCCESS;+ reader->continuousReading = true;++ ret = TMR_SR_hasMoreTags(reader);+ if (TMR_SUCCESS == ret)+ { + uint16_t flags;++ if (false == reader->isStatusResponse)+ {+ /* Ignore the fail cases and pass only valid messages */+ flags = GETU16AT(reader->u.serialReader.bufResponse, 8);+ TMR_SR_parseMetadataFromMessage(reader, trd, flags, &reader->u.serialReader.bufPointer, reader->u.serialReader.bufResponse);+ TMR_SR_postprocessReaderSpecificMetadata(trd, &reader->u.serialReader);+ trd->reader = reader;+ reader->u.serialReader.tagsRemainingInBuffer--;+ }+ else+ {+ /* A status stream response */+ uint8_t offset, i,j;+ uint16_t flags = 0; ++ TMR_STATS_init(stats);+ offset = reader->u.serialReader.bufPointer;++ /* Get status content flags */+ if ((0x80) > reader->statsFlag)+ {+ offset += 1;+ }+ else+ {+ offset += 2;+ }++ /**+ * preinitialize the rf ontime and the noise floor value to zero+ * berfore getting the reader stats+ */+ for (i = 0; i < stats->perAntenna.max; i++)+ {+ stats->perAntenna.list[i].antenna = 0;+ stats->perAntenna.list[i].rfOnTime = 0;+ stats->perAntenna.list[i].noiseFloor = 0;+ }++ TMR_fillReaderStats(reader, stats, flags, reader->u.serialReader.bufResponse, offset);++ /**+ * iterate through the per antenna values,+ * If found any 0-antenna rows, copy the+ * later rows down to compact out the empty space.+ */+ for (i = 0; i < reader->u.serialReader.txRxMap->len; i++)+ {+ if (!stats->perAntenna.list[i].antenna)+ {+ for (j = i + 1; j < reader->u.serialReader.txRxMap->len; j++)+ {+ if (stats->perAntenna.list[j].antenna)+ {+ stats->perAntenna.list[i].antenna = stats->perAntenna.list[j].antenna;+ stats->perAntenna.list[i].rfOnTime = stats->perAntenna.list[j].rfOnTime;+ stats->perAntenna.list[i].noiseFloor = stats->perAntenna.list[j].noiseFloor;+ stats->perAntenna.list[j].antenna = 0;+ stats->perAntenna.list[j].rfOnTime = 0;+ stats->perAntenna.list[j].noiseFloor = 0;++ stats->perAntenna.len++;+ break;+ }+ }+ }+ else+ {+ /* Increment the length */+ stats->perAntenna.len++;+ }+ }++ /* store the requested flags for future use */+ stats->valid = reader->statsFlag;+ }+ }+ + reader->continuousReading = false;+ return ret; +}++TMR_Status+TMR_SR_cmdStopReading(struct TMR_Reader *reader)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, op;+ + reader->hasContinuousReadStarted = false;+ i = 2;+ op = TMR_SR_OPCODE_MULTI_PROTOCOL_TAG_OP;+ SETU8(msg, i, op);+ SETU16(msg, i, 0); /* Timeout, Currently ignored */+ SETU8(msg, i, (uint8_t)0x02); /* option - stop continuous reading */++ msg[1]=i - 3; /* Install length */++ /* No need to capture the response */+ return TMR_SR_sendMessage(reader, msg, &op, reader->u.serialReader.commandTimeout);+}++TMR_Status+TMR_SR_cmdGetReaderWriteTimeOut (struct TMR_Reader *reader, TMR_TagProtocol protocol,+ TMR_SR_Gen2ReaderWriteTimeOut *value)+{+ TMR_Status ret;+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i, op;++ i = 2;+ op = TMR_SR_OPCODE_GET_PROTOCOL_PARAM;+ SETU8(msg, i, op);+ SETU8(msg, i, protocol); + SETU8(msg, i, (uint8_t)0x3f); /* option - reader write timeout */++ msg[1]=i - 3; /* Install length */++ ret = TMR_SR_send(reader, msg);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ /* Get the values */+ value->earlyexit = GETU8AT(msg, 7);+ value->writetimeout = GETU16AT(msg, 8);++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_cmdSetReaderWriteTimeOut (struct TMR_Reader *reader, TMR_TagProtocol protocol,+ TMR_SR_Gen2ReaderWriteTimeOut *value)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;++ i = 2;+ SETU8(msg, i, TMR_SR_OPCODE_SET_PROTOCOL_PARAM);+ SETU8(msg, i, protocol);+ SETU8(msg, i, (uint8_t)0x3f); /* option - reader write timeout */+ SETU8(msg, i, (uint8_t)value->earlyexit);+ SETU16(msg,i, value->writetimeout);++ msg[1] = i - 3; /* Install length */+ return TMR_SR_send(reader, msg);+}++TMR_Status+TMR_SR_cmdAuthReqResponse(struct TMR_Reader *reader, TMR_TagAuthentication *auth)+{+ uint8_t msg[TMR_SR_MAX_PACKET_SIZE];+ uint8_t i;+ uint8_t opcode;++ i = 2;+ SETU8(msg, i, (uint8_t)TMR_SR_OPCODE_MULTI_PROTOCOL_TAG_OP);+ SETU8(msg, i, (uint8_t)0x00);+ SETU8(msg, i, (uint8_t)0x00);+ SETU8(msg, i, (uint8_t)0x03);+ SETU8(msg, i, (uint8_t)0x00);+ SETU8(msg, i, (uint8_t)0x01);+ SETU8(msg, i, (uint8_t)0x00);++ switch (auth->type)+ {+ default:+ return TMR_ERROR_UNSUPPORTED;++ case TMR_AUTH_TYPE_GEN2_PASSWORD:+ {+ TMR_GEN2_Password password = auth->u.gen2Password;+ SETU8(msg, i, (uint8_t)0x20);+ SETU8(msg, i, (uint8_t)(password>>24));+ SETU8(msg, i, (uint8_t)(password>>16));+ SETU8(msg, i, (uint8_t)(password>> 8));+ SETU8(msg, i, (uint8_t)(password>> 0));+ }+ break;+ }++ msg[1] = i - 3; /* Install length */+ return TMR_SR_sendMessage(reader, msg, &opcode, 0);+}++#endif /* TMR_ENABLE_SERIAL_READER */
+ cbits/api/serial_transport_posix.c view
@@ -0,0 +1,307 @@+/**+ * @file serial_transport_posix.c+ * @brief Mercury API - POSIX serial transport implementation+ * @author Nathan Williams+ * @date 10/20/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 <sys/types.h>+#include <sys/stat.h>+#include <sys/select.h>+#include <fcntl.h>+#include <termios.h>+#include <unistd.h>+#include <errno.h>+#include <string.h>+#include <sys/ioctl.h>+#include "tm_reader.h"++#ifdef __APPLE__+#include <sys/ioctl.h>+#include <IOKit/serial/ioss.h>+#endif++#ifdef TMR_ENABLE_SERIAL_TRANSPORT_NATIVE++static TMR_Status+s_open(TMR_SR_SerialTransport *this)+{+ int ret;+ struct termios t;+#if TMR_MAX_READER_NAME_LENGTH > 0+ TMR_SR_SerialPortNativeContext *c;++ c = this->cookie;++ c->handle = open(c->devicename, O_RDWR);+ if (c->handle == -1)+ return TMR_ERROR_COMM_ERRNO(errno);+#endif++ /*+ * Set 8N1, disable high-bit stripping, soft flow control, and hard+ * flow control (modem lines).+ */+ ret = tcgetattr(c->handle, &t);+ if (-1 == ret)+ return TMR_ERROR_COMM_ERRNO(errno);+ t.c_iflag &= ~(ICRNL | IGNCR | INLCR | INPCK | ISTRIP | IXANY + | IXON | IXOFF | PARMRK);+ t.c_oflag &= ~OPOST;+ t.c_cflag &= ~(CRTSCTS | CSIZE | CSTOPB | PARENB);+ t.c_cflag |= CS8 | CLOCAL | CREAD | HUPCL;+ t.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);+ t.c_cc[VMIN] = 0;+ t.c_cc[VTIME] = 1;+ ret = tcsetattr(c->handle, TCSANOW, &t);+ if (-1 == ret)+ return TMR_ERROR_COMM_ERRNO(errno);++ return TMR_SUCCESS;+}++static TMR_Status+s_sendBytes(TMR_SR_SerialTransport *this, uint32_t length, + uint8_t* message, const uint32_t timeoutMs)+{+ TMR_SR_SerialPortNativeContext *c;+ int ret;++ c = this->cookie;+ do + {+ ret = write(c->handle, message, length);+ if (ret == -1)+ {+ if (ENXIO == errno)+ {+ return TMR_ERROR_TIMEOUT; + }+ else+ {+ return TMR_ERROR_COMM_ERRNO(errno);+ }+ }+ length -= ret;+ message += ret;+ }+ while (length > 0);++ return TMR_SUCCESS;+}++static TMR_Status+s_receiveBytes(TMR_SR_SerialTransport *this, uint32_t length, + uint32_t *messageLength, uint8_t* message, const uint32_t timeoutMs)+{+ TMR_SR_SerialPortNativeContext *c;+ int ret;+ struct timeval tv;+ fd_set set;+ int status = 0;++ *messageLength = 0;+ c = this->cookie;++ do+ {+ do+ {+ FD_ZERO(&set);+ FD_SET(c->handle, &set);+ tv.tv_sec = timeoutMs / 1000;+ tv.tv_usec = (timeoutMs % 1000) * 1000;+ /* Ideally should reset this timeout value every time through */+ ret = select(c->handle + 1, &set, NULL, NULL, &tv);+ } while (ret == -1 && errno == EINTR);+ if (ret == -1)+ {+ return TMR_ERROR_COMM_ERRNO(errno);+ }+ if (ret < 1)+ {+ return TMR_ERROR_TIMEOUT;+ }+ ret = read(c->handle, message, length);+ if (ret == -1)+ {+ if (ENXIO == errno)+ {+ return TMR_ERROR_TIMEOUT; + }+ else+ {+ return TMR_ERROR_COMM_ERRNO(errno);+ }+ }++ if (0 == ret)+ {+ /**+ * We should not be here, coming here means the select()+ * is success , but we are not able to read the data.+ * check the serial port connection status.+ **/+ ret = ioctl(c->handle, TIOCMGET, &status);+ if (-1 == ret)+ {+ /* not success. check for errno */+ if (EIO == errno)+ {+ /**+ * EIO means I/O error, may serial port got disconnected,+ * throw the error.+ **/+ return TMR_ERROR_TIMEOUT;+ }+ }+ }++ length -= ret;+ *messageLength += ret;+ message += ret;+ }+ while (length > 0);++ return TMR_SUCCESS;+}++static TMR_Status+s_setBaudRate(TMR_SR_SerialTransport *this, uint32_t rate)+{+ TMR_SR_SerialPortNativeContext *c;+ + c = this->cookie;++#if defined(__APPLE__)+ {+ speed_t speed = rate;++ if (ioctl(c->handle, IOSSIOSPEED, &speed) == -1)+ return TMR_ERROR_COMM_ERRNO(errno);+ }+#else+ {+ struct termios t;++ tcgetattr(c->handle, &t);++#define BCASE(t,n) case n: cfsetispeed((t),B##n); cfsetospeed((t),B##n); break;+ switch (rate)+ {+ BCASE(&t, 9600);+ BCASE(&t, 19200);+ BCASE(&t, 38400);+ // Believe it or not, speeds beyond 38400 aren't required by POSIX.+#ifdef B57600+ BCASE(&t, 57600);+#endif+#ifdef B115200+ BCASE(&t, 115200);+#endif+#ifdef B230400+ BCASE(&t, 230400);+#endif+#ifdef B460800+ BCASE(&t, 460800);+#endif+#ifdef B921600+ BCASE(&t, 921600);+#endif+ default:+ return TMR_ERROR_INVALID;+ }+#undef BCASE+ if (tcsetattr(c->handle, TCSANOW, &t) != 0)+ {+ return TMR_ERROR_COMM_ERRNO(errno);+ }+ }+#endif /* __APPLE__ */++ return TMR_SUCCESS;+}++static TMR_Status+s_shutdown(TMR_SR_SerialTransport *this)+{+ TMR_SR_SerialPortNativeContext *c;++ c = this->cookie;++ close(c->handle);+ /* What, exactly, would be the point of checking for an error here? */++ return TMR_SUCCESS;+}++static TMR_Status+s_flush(TMR_SR_SerialTransport *this)+{+ TMR_SR_SerialPortNativeContext *c;++ c = this->cookie;++ if (tcflush(c->handle, TCOFLUSH) == -1)+ {+ return TMR_ERROR_COMM_ERRNO(errno);+ }++ return TMR_SUCCESS;+}++TMR_Status+TMR_SR_SerialTransportNativeInit(TMR_SR_SerialTransport *transport,+ TMR_SR_SerialPortNativeContext *context,+ const char *device)+{++#if TMR_MAX_READER_NAME_LENGTH > 0+ if (strlen(device) + 1 > TMR_MAX_READER_NAME_LENGTH)+ {+ return TMR_ERROR_INVALID;+ }+ strcpy(context->devicename, device);+#else+ /* No space to store the device name, so open it now */+ context->handle = open(device, O_RDWR);+ if (context->handle == -1)+ {+ return TMR_ERROR_COMM_ERRNO(errno);+ }+#endif++ transport->cookie = context;+ transport->open = s_open;+ transport->sendBytes = s_sendBytes;+ transport->receiveBytes = s_receiveBytes;+ transport->setBaudRate = s_setBaudRate;+ transport->shutdown = s_shutdown;+ transport->flush = s_flush;++ return TMR_SUCCESS;+}++#endif
+ cbits/api/serial_transport_win32.c view
@@ -0,0 +1,234 @@+/**+ * @file serial_transport_win32.c+ * @brief Mercury API - Serial transport over local serial port on Win32+ * @author Nathan Williams+ * @date 10/20/2009+ */+++/*+ * Copyright (c) 2010 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 "tm_config.h"+#include "tmr_status.h"++#if defined(WIN32) || defined(WINCE)+#if !defined(_WINSOCK2API_) && !defined(_WINSOCKAPI_)+#include <winsock2.h>+#endif+#include <stdio.h>++# if defined(WINCE)+# define snprintf _snprintf+# elif !defined(__GNUC__)+# define snprintf sprintf_s+# endif++#endif /* WIN32 */++#include "tm_reader.h"++__declspec(dllexport) TMR_Status+s_open(TMR_SR_SerialTransport *this)+{+ TMR_SR_SerialPortNativeContext *c;+ COMMTIMEOUTS timeOuts;+ DCB dcb;++ c = this->cookie;+ + c->handle = CreateFile((TCHAR*)c->devicename,+ GENERIC_READ | GENERIC_WRITE,+ 0, /* not shared */+ NULL, /* default security */+ OPEN_EXISTING, /* don't create a new file */+ 0, /* flags and attributes */+ NULL); /* template file */+ + if (INVALID_HANDLE_VALUE == c->handle)+ return TMR_ERROR_INVALID; /* @todo use GetLastError() */++ timeOuts.ReadIntervalTimeout = 0xFFFFFFFF;+ timeOuts.ReadTotalTimeoutConstant = 0;+ timeOuts.ReadTotalTimeoutMultiplier = 0;+ timeOuts.WriteTotalTimeoutConstant = 5000;+ timeOuts.WriteTotalTimeoutMultiplier = 0;+ + SetCommTimeouts(c->handle, &timeOuts);++ dcb.DCBlength = sizeof(DCB);+ GetCommState(c->handle, &dcb);+ dcb.fOutxCtsFlow = 0;+ dcb.fOutxDsrFlow = 0;+ dcb.fDtrControl = DTR_CONTROL_DISABLE;+ dcb.fDsrSensitivity = 0;+ dcb.fOutX = 0;+ dcb.fInX = 0;+ dcb.fNull = 0;+ dcb.fRtsControl = RTS_CONTROL_DISABLE;+ dcb.ByteSize = 8;+ dcb.fParity = NOPARITY;+ dcb.StopBits = ONESTOPBIT;+ if ((0 == SetCommState(c->handle, &dcb)) ||+ (0 == SetupComm(c->handle, 10000, 10000)))+ {+ return TMR_ERROR_INVALID; /* @todo use GetLastError() */+ }+ + return TMR_SUCCESS;+}++__declspec(dllexport) TMR_Status+s_sendBytes(TMR_SR_SerialTransport *this, uint32_t length,+ uint8_t* message, const uint32_t timeoutMs)+{+ TMR_SR_SerialPortNativeContext *c;+ BOOL writeStatus;+ COMMTIMEOUTS timeOuts;++ c = this->cookie;+ GetCommTimeouts(c->handle, &timeOuts);+ timeOuts.WriteTotalTimeoutConstant = timeoutMs;+ SetCommTimeouts(c->handle, &timeOuts);+ + {+ long numberOfBytesWritten;+ writeStatus = WriteFile(c->handle, message, length, &numberOfBytesWritten, NULL);+ }+ if (0 == writeStatus)+ {+ return TMR_ERROR_TIMEOUT; /* @todo use GetLastError() */+ }+ return TMR_SUCCESS;+}++__declspec(dllexport) TMR_Status+s_receiveBytes(TMR_SR_SerialTransport *this, uint32_t length,+ uint32_t* messageLength, uint8_t* message, const uint32_t+timeoutMs)+{+ DWORD readLength;+ DWORD errorFlags;+ COMSTAT comStat;+ TMR_SR_SerialPortNativeContext *c;+ BOOL readStatus;+ COMMTIMEOUTS timeOuts;++ c = this->cookie;+ *messageLength=0;++ GetCommTimeouts(c->handle, &timeOuts);+ timeOuts.ReadTotalTimeoutConstant = timeoutMs;+ SetCommTimeouts(c->handle, &timeOuts);++ ClearCommError(c->handle, &errorFlags, &comStat);+ while (length > 0)+ {+ readLength=0;+ readStatus = ReadFile(c->handle, message, length, &readLength, NULL);+ *messageLength += readLength;+ if (0 == readStatus)+ {+ return TMR_ERROR_TIMEOUT; /* @todo use GetLastError() */+ }+ if(readLength == 0)+ {+ return TMR_ERROR_TIMEOUT;+ }+ length -= readLength;+ message += readLength;++ }+ return TMR_SUCCESS;+}+++__declspec(dllexport) TMR_Status+s_setBaudRate(TMR_SR_SerialTransport *this, uint32_t rate)+{+ TMR_SR_SerialPortNativeContext *c;+ DCB dcb;++ c = this->cookie;++ dcb.DCBlength = sizeof(DCB);+ GetCommState(c->handle, &dcb);+ dcb.BaudRate = rate;++ if (0 == SetCommState(c->handle, &dcb)) /* @todo use GetLastError() */+ {+ return TMR_ERROR_INVALID;+ }++ return TMR_SUCCESS;+}++static TMR_Status+s_shutdown(TMR_SR_SerialTransport *this)+{+ TMR_SR_SerialPortNativeContext *c;++ c = this->cookie;++ CloseHandle(c->handle);+ /* What, exactly, would be the point of checking for an error here? */++ return TMR_SUCCESS;+}++static TMR_Status+s_flush(TMR_SR_SerialTransport *this)+{+ TMR_SR_SerialPortNativeContext *c;++ c = this->cookie;++ if (PurgeComm(c->handle, PURGE_RXCLEAR) == 0)+ {+ return TMR_ERROR_COMM_ERRNO(errno);+ }+ return TMR_SUCCESS;+}++__declspec(dllexport)TMR_Status+TMR_SR_SerialTransportNativeInit(TMR_SR_SerialTransport *transport,+ TMR_SR_SerialPortNativeContext *context,+ const char *device)+{+ // Transform COM port name from "/COMnn" to "\\\\.\\COMnn"+ if (strlen(device)-1 + 4 + 1 > TMR_MAX_READER_NAME_LENGTH)+ {+ return TMR_ERROR_INVALID;+ }+ snprintf(context->devicename, sizeof(context->devicename),+ "\\\\.\\%s", device+1);++ transport->cookie = context;+ transport->open = s_open;+ transport->sendBytes = s_sendBytes;+ transport->receiveBytes = s_receiveBytes;+ transport->setBaudRate = s_setBaudRate;+ transport->shutdown = s_shutdown;+ transport->flush = s_flush;++ return TMR_SUCCESS;+}
+ cbits/api/tm_config.h view
@@ -0,0 +1,263 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TM_CONFIG_H+#define _TM_CONFIG_H++/**+ * @file tm_config.h+ * @brief Mercury API - Build Configuration+ * @author Nathan Williams+ * @date 10/20/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.+ */++#ifdef __cplusplus+extern "C" {+#endif++/**+ * API version number+ */+#define TMR_VERSION "1.29.3.34"++/**+ * Define this to enable support for devices that support the serial+ * reader command set (M5e, M6e, Vega, etc.)+ */+#define TMR_ENABLE_SERIAL_READER++/**+ * Define this to enable support for local serial port access via+ * native interfaces (COM1 on Windows, /dev/ttyS0, /dev/ttyUSB0 on+ * Linux, etc.).+ */+#define TMR_ENABLE_SERIAL_TRANSPORT_NATIVE++/**+ * The longest possible name for a reader.+ */+#define TMR_MAX_READER_NAME_LENGTH 256++/**+ * The maximum number of protocols supported in a multiprotocol search command+ */+#define TMR_MAX_SERIAL_MULTIPROTOCOL_LENGTH 5++/**+ * The maximum size of the Queue, used to share the streamed messages+ * between the do_background_reads thread and parse_tag_reads thread.+ */+#define TMR_MAX_QUEUE_SLOTS 20++/** + * Number of bytes to allocate for embedded data return+ * in each TagReadData.+ */+#define TMR_MAX_EMBEDDED_DATA_LENGTH 128 ++/**+ * The maximum length of the probe baudrate list. This list specifies the + * baudrates which are used while connecting to the serial reader.+ */+#define TMR_MAX_PROBE_BAUDRATE_LENGTH 8++/**+ * Define this to enable support for LLRP readers.+ * (Not yet available for Windows)+ */+#define TMR_ENABLE_LLRP_TRANSPORT+#ifndef WIN32+#define TMR_ENABLE_LLRP_SERIAL_TRANSPORT+#endif++/**+ * LLRP reader keep alive timeout in milli seconds+ */+#define TMR_LLRP_KEEP_ALIVE_TIMEOUT 5000++/**+ * Define this to enable async read using single thread++Note:To run readsync_baremetal codelet you have to + define it.+ Otherwise keep it undefined.+ */+#undef SINGLE_THREAD_ASYNC_READ++/**+ * Define this to enable for BARE_METAL API + */+#ifndef BARE_METAL+/**+ * Define this to enable support for the GEN2 Custom Tag Operations parameters+ * and access commands+ */+#define TMR_ENABLE_GEN2_CUSTOM_TAGOPS++/**+ * Define this to enable support for the ISO180006B protocol parameters+ * and access commands+ */+#define TMR_ENABLE_ISO180006B++/**+ * Define this to enable support for small microcontrollers.+ * Enabling this option will reduce the code which is not relevant to + * serial readers in order to minimize the program footprint+ * To compile for Serial Reader only.+ *+ * To compile for Serial Reader only, use one of the following options:+ ** Uncomment the following define+ ** Run make with TMR_ENABLE_SERIAL_READER_ONLY=1 defined+ ** Add -DTMR_ENABLE_SERIAL_READER_ONLY=1 to your compiler flags+ */ +//#define TMR_ENABLE_SERIAL_READER_ONLY++/**+ * Define this to enable support for background reads using native threads.+ * This feature is also available for windows (using pthreads-win32)+ */++#define TMR_ENABLE_BACKGROUND_READS+++/**+ * Define this to include TMR_strerror().+ */+#define TMR_ENABLE_ERROR_STRINGS++/**+ * Define this to include TMR_paramName() and TMR_paramID().+ */+#define TMR_ENABLE_PARAM_STRINGS++/**+ * Enabling this option will enable the support for the parameters defined + * in stdio.h header file like FILE *. This check is required as stdio.h does not+ * exist in some of the embedded architectures.+ */+#define TMR_ENABLE_STDIO+ +/**+ * Enabling this option will enable the support for the parameters defined + * in string.h header file like strerror(). This check is required as string.h does not+ * exist in some of the embedded architectures.+ */+#define TMR_USE_STRERROR+#if defined(WINCE)+#undef TMR_USE_STRERROR+#endif++#else+/**+ * Define this to enable support for the GEN2 Custom Tag Operations parameters+ * and access commands+ */+#undef TMR_ENABLE_GEN2_CUSTOM_TAGOPS++/**+ * Define this to enable support for the ISO180006B protocol parameters+ * and access commands+ */+#undef TMR_ENABLE_ISO180006B++/**+ * Define this to enable support for small microcontrollers.+ * Enabling this option will reduce the code which is not relevant to + * serial readers in order to minimize the program footprint+ * To compile for Serial Reader only.+ *+ * To compile for Serial Reader only, use one of the following options:+ ** Uncomment the following define+ ** Run make with TMR_ENABLE_SERIAL_READER_ONLY=1 defined+ ** Add -DTMR_ENABLE_SERIAL_READER_ONLY=1 to your compiler flags+ */ +#define TMR_ENABLE_SERIAL_READER_ONLY++/**+ * Define this to enable support for background reads using native threads.+ * This feature is also available for windows (using pthreads-win32)+ */++#undef TMR_ENABLE_BACKGROUND_READS+++/**+ * Define this to include TMR_strerror().+ */+#undef TMR_ENABLE_ERROR_STRINGS++/**+ * Define this to include TMR_paramName() and TMR_paramID().+ */+#undef TMR_ENABLE_PARAM_STRINGS++/**+ * Enabling this option will enable the support for the parameters defined + * in stdio.h header file like FILE *. This check is required as stdio.h does not+ * exist in some of the embedded architectures.+ */+#undef TMR_ENABLE_STDIO+ +/**+ * Enabling this option will enable the support for the parameters defined + * in string.h header file like strerror(). This check is required as string.h does not+ * exist in some of the embedded architectures.+ */+#undef TMR_USE_STRERROR++#endif /*Bare_metal*/++/**+ * Define the largest number serial reader antenna ports that will be supported+ */+#define TMR_SR_MAX_ANTENNA_PORTS (32)++/**+ * Define when compiling on a big-endian host platform to enable some+ * endian optimizations. Without this, no endianness will be assumed.+ */ +#undef TMR_BIG_ENDIAN_HOST++/**+ * Define this to enable API-side tag read deduplication. Under+ * certain conditions, the module runs out of buffer space to detect+ * reads of a previously-seen EPC. + */+#define TMR_ENABLE_API_SIDE_DEDUPLICATION++/**+ * Default read filter timeout.+ */+#define TMR_DEFAULT_READ_FILTER_TIMEOUT -1++/**+ * The max length of the custom transport scheme name+ */+#define TMR_MAX_TRANSPORT_SCHEME_NAME 50++#ifdef __cplusplus+}+#endif++#endif /* _TM_CONFIG_H */
+ cbits/api/tm_reader.c view
@@ -0,0 +1,3680 @@+/**+ * @file tm_reader.c+ * @brief Mercury API - top 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 <stddef.h>+#include <stdio.h>+#include <stdlib.h>+#include <string.h>++#include "tm_reader.h"+#include "serial_reader_imp.h"+#include "tmr_utils.h"++#define EAPI_PREFIX "eapi://"+#define EAPI_PREFIX_LEN (sizeof(EAPI_PREFIX)-1)++#define TMR_PREFIX "tmr://"+#define TMR_PREFIX_LEN (sizeof(TMR_PREFIX)-1)++#define LLRP_EAPI_PREFIX "llrp+eapi://"+#define LLRP_EAPI_PREFIX_LEN (sizeof(LLRP_EAPI_PREFIX)-1)++#define LLRP_PREFIX "llrp://"+#define LLRP_PREFIX_LEN (sizeof(LLRP_PREFIX)-1)++TMR_Status restart_reading(struct TMR_Reader *reader);++/**+ * Private: Should not be used by user level application.+ * structure containing the transport scheme name and the+ * pointer to the factory init function.+ **/+static void TMR_initSerialTransportTable();++void* do_background_receiveAutonomousReading(void * arg);++typedef struct TMR_SerialTransportDispatchTableData+{+ char transportScheme[TMR_MAX_TRANSPORT_SCHEME_NAME];+ TMR_TransportNativeInit transportInit;+}TMR_SerialTransportDispatchTableData;++typedef struct TMR_SerialTransportDispatchTable+{+ TMR_SerialTransportDispatchTableData *list;+ uint8_t max;+ uint8_t len;+}TMR_SerialTransportDispatchTable;++static bool transportTableInitialized = false;+static TMR_SerialTransportDispatchTableData tdTableData[10];+static TMR_SerialTransportDispatchTable tdTable;++static void TMR_initSerialTransportTable()+{+ if (false == transportTableInitialized)+ {+ /** + * We did not get a chance to initialize the transport table.+ * Initialize it now.+ */+ memset(tdTableData, 0, (sizeof(tdTableData)/sizeof(tdTableData[0])));+ tdTable.list = tdTableData;+ tdTable.max = sizeof(tdTableData)/sizeof(tdTableData[0]);+ tdTable.len = 0;++ /* Add default schemes to the table */+ {+ TMR_String str;++ str.max = TMR_MAX_TRANSPORT_SCHEME_NAME;+ str.value = tdTable.list[tdTable.len].transportScheme;+ TMR_stringCopy(&str, "eapi", (int)strlen("eapi"));+ tdTable.list[tdTable.len].transportInit = TMR_SR_SerialTransportNativeInit;+ tdTable.len++;++ str.value = tdTable.list[tdTable.len].transportScheme;+ TMR_stringCopy(&str, "tmr", (int)strlen("tmr"));+ tdTable.list[tdTable.len].transportInit = TMR_SR_SerialTransportNativeInit;+ tdTable.len++;+ }+ transportTableInitialized = true;+ }+}++TMR_Status+TMR_create_alloc(TMR_Reader **reader, const char* deviceUri)+{++ *reader = malloc(sizeof(**reader));+ if (NULL == *reader)+ return TMR_ERROR_OUT_OF_MEMORY;+ return TMR_create(*reader, deviceUri);+}+++TMR_Status+TMR_create(TMR_Reader *reader, const char* deviceUri)+{+ TMR_Status ret;++ ret = TMR_ERROR_INVALID;++#ifdef TMR_ENABLE_BACKGROUND_READS+ /* Because destruction of the readers may rely on the locks, these must be+ * created before any possible error can cause an early exit+ */+ pthread_mutex_init(&reader->backgroundLock, NULL);+ pthread_mutex_init(&reader->parserLock, NULL);+ pthread_cond_init(&reader->backgroundCond, NULL);+ pthread_cond_init(&reader->parserCond, NULL);+ pthread_cond_init(&reader->readCond, NULL);+ pthread_mutex_init(&reader->listenerLock, NULL);+ pthread_mutex_init(&reader->queue_lock, NULL);+ reader->authReqListeners = NULL;+ reader->readExceptionListeners = NULL;+ reader->statsListeners = NULL;+ reader->statusListeners = NULL;+ reader->readState = TMR_READ_STATE_IDLE;+ reader->backgroundSetup = false;+ reader->parserSetup = false;+#endif+ reader->readListeners = NULL;+ reader->dutyCycle = false;+ reader->paramWait = false;+ reader->hasContinuousReadStarted = false;++#ifdef TMR_ENABLE_SERIAL_READER+#ifdef TMR_ENABLE_SERIAL_TRANSPORT_NATIVE+if ((strncmp(deviceUri, EAPI_PREFIX, EAPI_PREFIX_LEN) == 0)+ || ((strncmp(deviceUri, TMR_PREFIX, TMR_PREFIX_LEN) == 0)+ && *(deviceUri + TMR_PREFIX_LEN) == '/'))+{+ uint8_t i;+ char *scheme;+ char devname[TMR_MAX_READER_NAME_LENGTH];+ bool scheme_exists = false;++ TMR_initSerialTransportTable();++ strcpy(devname, deviceUri);+ scheme = strtok((char *)devname, ":");++ for (i = 0; i < tdTable.len; i++)+ {+ if (0 == strcmp(scheme, tdTable.list[i].transportScheme))+ {+ if ('e' == deviceUri[0])+ {+ scheme = (char *)deviceUri + EAPI_PREFIX_LEN;+ }+ else+ {+ scheme = (char *)deviceUri + TMR_PREFIX_LEN;+ }+ strncpy(reader->uri, deviceUri, TMR_MAX_READER_NAME_LENGTH);++ /* Entry exists */+ ret = tdTable.list[i].transportInit(&reader->u.serialReader.transport,+ &reader->u.serialReader.+ transportContext.nativeContext,+ scheme);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ scheme_exists = true;+ break;+ }+ }++ if (false == scheme_exists)+ {+ /* No entry found */+ return TMR_ERROR_INVALID;+ }+ return TMR_SR_SerialReader_init(reader);+}+else+#endif /* TMR_ENABLE_SERIAL_TRANSPORT_NATIVE */+ if ((strncmp(deviceUri, LLRP_PREFIX, LLRP_PREFIX_LEN) == 0)+ || (strncmp(deviceUri, TMR_PREFIX, TMR_PREFIX_LEN) == 0))+{+#ifdef TMR_ENABLE_LLRP_READER+ const char *host, *port;+ char hostCopy[256];++ if ('t' == deviceUri[0])+ {+ host = deviceUri + TMR_PREFIX_LEN;+ }+ else+ {+ host = deviceUri + LLRP_PREFIX_LEN;+ }+ port = strchr(host, ':');+ strcpy(hostCopy, host);+ if (port == NULL)+ {+ char *slash;+ reader->u.llrpReader.portNum = TMR_LLRP_READER_DEFAULT_PORT;+ slash = strchr(hostCopy, '/');+ if (slash)+ {+ *slash = '\0';+ }+ }+ else+ {+ reader->u.llrpReader.portNum = atoi(port + 1);+ hostCopy[port - host] = '\0';+ }++ strncpy(reader->uri, hostCopy, TMR_MAX_READER_NAME_LENGTH); + return TMR_LLRP_LlrpReader_init(reader);++#else+ return TMR_ERROR_UNSUPPORTED_READER_TYPE;+#endif /* TMR_ENABLE_LLRP_READER */+}+else+{+ /**+ * we are here means user requested for custom transport+ * scheme.+ **/+ uint8_t i;+ char* scheme;+ bool scheme_exists = false;++ scheme = strtok((char *)deviceUri, ":");++ for (i = 0; i < tdTable.len; i++)+ {+ if (0 == strcmp(scheme, tdTable.list[i].transportScheme))+ {+ deviceUri += strlen(scheme) + 2;+ strncpy(reader->uri, deviceUri, TMR_MAX_READER_NAME_LENGTH);++ /* Entry exists */+ ret = tdTable.list[i].transportInit(&reader->u.serialReader.transport,+ &reader->u.serialReader.+ transportContext.nativeContext,+ reader->uri);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }++ scheme_exists = true;+ break;+ }+ }++ if (false == scheme_exists)+ {+ /* No entry found */+ return TMR_ERROR_INVALID;+ }+ return TMR_SR_SerialReader_init(reader);+}+++#else /* TMR_ENABLE_SERIAL_READER */+/* No readers supported! */+return TMR_ERROR_INVALID;+#endif+}++TMR_Status+TMR_reader_init_internal(struct TMR_Reader *reader)+{+ reader->connected = false;+ reader->pSupportsResetStats = NULL;+ reader->transportListeners = NULL;+++ TMR_RP_init_simple(&reader->readParams.defaultReadPlan, 0, NULL, + TMR_TAG_PROTOCOL_GEN2, 1);+ reader->readParams.readPlan = &reader->readParams.defaultReadPlan;+#ifdef SINGLE_THREAD_ASYNC_READ+ reader->readParams.asyncOnTime = 250;+ reader->readParams.asyncOffTime = 0;+#endif+#ifdef TMR_ENABLE_BACKGROUND_READS+ reader->readParams.asyncOnTime = 250; + reader->readParams.asyncOffTime = 0;+#if 0+ pthread_mutex_init(&reader->backgroundLock, NULL);+ pthread_mutex_init(&reader->parserLock, NULL);+ pthread_cond_init(&reader->backgroundCond, NULL);+ pthread_cond_init(&reader->parserCond, NULL);+ pthread_cond_init(&reader->readCond, NULL);+ pthread_mutex_init(&reader->listenerLock, NULL);+ pthread_mutex_init(&reader->queue_lock, NULL);+ reader->readListeners = NULL;+ reader->authReqListeners = NULL;+ reader->readExceptionListeners = NULL;+ reader->statsListeners = NULL;+ reader->statusListeners = NULL;+ reader->readState = TMR_READ_STATE_IDLE;+ reader->backgroundSetup = false;+ reader->parserSetup = false;+#endif+ reader->backgroundEnabled = false;+ reader->trueAsyncflag = false;+ reader->parserEnabled = false;+ reader->tagQueueHead = NULL;+ reader->tagQueueTail = NULL;+ reader->isStatusResponse = false; + reader->statsFlag = TMR_READER_STATS_FLAG_NONE;+ reader->streamStats = TMR_SR_STATUS_NONE;+ reader->finishedReading = true;+#endif+ reader->continuousReading = false;+ reader->searchStatus = false;+ reader->fastSearch = false;+ reader->backgroundThreadCancel = false;+ reader->isStopNTags = false;+ reader->numberOfTagsToRead = 0;+ reader->userMetadataFlag = TMR_TRD_METADATA_FLAG_ALL;+ reader->portmask = 0;++ return TMR_SUCCESS;+}++TMR_Status+TMR_setSerialTransport(char* scheme, TMR_TransportNativeInit nativeInit)+{+ bool scheme_exists = false;+ uint8_t i;++ TMR_initSerialTransportTable();++ if ((0 == strcmp("llrp", scheme))+ || (0 == strcmp("llrp", scheme)))+ {+ /**+ * Currently set serial transport is only supported for+ * serial readers only.+ **/+ return TMR_ERROR_UNSUPPORTED;+ }++ for (i = 0; i < tdTable.len; i++)+ {+ if (0 == strcmp(scheme, tdTable.list[i].transportScheme))+ {+ /* Entry exists already, just update it */+ if (NULL != nativeInit)+ {+ tdTable.list[i].transportInit = nativeInit;+ }+ scheme_exists = true;+ break;+ }+ }++ if (false == scheme_exists)+ {++ TMR_String str;+ /* Its a new entry, add it to table */++ str.max = TMR_MAX_TRANSPORT_SCHEME_NAME;+ str.value = tdTable.list[tdTable.len].transportScheme;+ TMR_stringCopy(&str, scheme, (int)strlen(scheme));+ tdTable.list[tdTable.len].transportInit = nativeInit;+ tdTable.len++;+ }+ return TMR_SUCCESS;+}+#ifdef TMR_ENABLE_API_SIDE_DEDUPLICATION++static int+TMR_findDupTag(TMR_Reader *reader,+ TMR_TagReadData* newRead,+ TMR_TagReadData oldReads[], int32_t oldLength,+ bool uniqueByAntenna, bool uniqueByData, bool uniqueByProtocol)+{+ int i;++ for (i=0; i<oldLength; i++)+ {+ TMR_TagReadData* oldRead = &oldReads[i];+ TMR_TagData* oldTag = &oldRead->tag;+ TMR_TagData* newTag = &newRead->tag;++ if ((oldTag->epcByteCount != newTag->epcByteCount) ||+ (0 != memcmp(oldTag->epc, newTag->epc,+ (oldTag->epcByteCount)*sizeof(uint8_t))))+ {+ continue;+ }+ if (uniqueByAntenna)+ {+ if (oldRead->antenna != newRead->antenna)+ {+ continue;+ }+ }+ if (uniqueByData)+ {+ if ((oldRead->data.len != newRead->data.len) ||+ (0 != memcmp(oldRead->data.list, newRead->data.list,+ (oldRead->data.len)*sizeof(uint8_t))))+ {+ continue;+ }+ }+ if (uniqueByProtocol)+ {+ if (oldRead->tag.protocol != newRead->tag.protocol)+ {+ continue;+ }+ }+ /* No fields mismatched; this tag is a match */+ break;+ }++ return (i < oldLength) ? i : -1;+}++static void+TMR_updateDupTag(TMR_Reader* reader,+ TMR_TagReadData* oldRead, TMR_TagReadData* newRead,+ bool highestRssi)+{+ oldRead->readCount += newRead->readCount;++ if (highestRssi)+ {+ if (newRead->rssi > oldRead->rssi)+ {+ uint32_t saveCount = oldRead->readCount;++ memcpy(oldRead, newRead, sizeof(TMR_TagReadData));+ /* TODO: TagReadData.data field not yet supported, pending a+ * comprehensive strategy for dynamic memory allocation. */++ oldRead->readCount = saveCount;+ }+ }+}++#endif /* TMR_ENABLE_API_SIDE_DEDUPLICATION */++TMR_Status+TMR_readIntoArray(struct TMR_Reader *reader, uint32_t timeoutMs,+ int32_t *tagCount, TMR_TagReadData *result[])+{+ int32_t tagsRead, count, alloc;+ TMR_TagReadData *results;+ TMR_Status ret;+ uint32_t startHi, startLo, nowHi, nowLo;+#ifdef TMR_ENABLE_API_SIDE_DEDUPLICATION+ bool uniqueByAntenna, uniqueByData, recordHighestRssi, uniqueByProtocol;+#endif /* TMR_ENABLE_API_SIDE_DEDUPLICATION */++#ifdef TMR_ENABLE_API_SIDE_DEDUPLICATION+ {+ bool bval;++ ret = TMR_paramGet(reader, TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA, &bval);+ if (TMR_ERROR_NOT_FOUND == ret) { bval = false; }+ else if (TMR_SUCCESS != ret) { return ret; }+ uniqueByAntenna = bval;++ ret = TMR_paramGet(reader, TMR_PARAM_TAGREADDATA_UNIQUEBYDATA, &bval);+ if (TMR_ERROR_NOT_FOUND == ret) { bval = false; }+ else if (TMR_SUCCESS != ret) { return ret; }+ uniqueByData = bval;++ ret = TMR_paramGet(reader, TMR_PARAM_TAGREADDATA_UNIQUEBYPROTOCOL, &bval);+ if (TMR_ERROR_NOT_FOUND == ret) { bval = false; }+ else if (TMR_SUCCESS != ret) { return ret; }+ uniqueByProtocol = bval;++ ret = TMR_paramGet(reader, TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI, &bval);+ if (TMR_ERROR_NOT_FOUND == ret) { bval = false; }+ else if (TMR_SUCCESS != ret) { return ret; }+ recordHighestRssi = bval;+ }+#endif /* TMR_ENABLE_API_SIDE_DEDUPLICATION */++ tagsRead = 0;+ alloc = 0;+ results = NULL;++ tm_gettime_consistent(&startHi, &startLo);+ do + {++ ret = TMR_read(reader, timeoutMs, &count);+ if ((TMR_SUCCESS != ret) && (TMR_ERROR_TAG_ID_BUFFER_FULL != ret))+ {+ goto out;+ }++ if (0 == count)+ {+ goto out;+ }+ else if (-1 == count) /* Unknown - streaming */+ {+ alloc += 4;+ }+ else+ {+ alloc += count;+ }++ {+ TMR_TagReadData *newResults;+ newResults = realloc(results, alloc * sizeof(*results));+ if (NULL == newResults)+ {+ ret = TMR_ERROR_OUT_OF_MEMORY;+ goto out;+ }+ results = newResults;+ }+ while (TMR_SUCCESS == TMR_hasMoreTags(reader))+ {+ if (tagsRead == alloc)+ {+ TMR_TagReadData *newResults;+ alloc *= 2;+ newResults = realloc(results, alloc * sizeof(*results));+ if (NULL == newResults)+ {+ ret = TMR_ERROR_OUT_OF_MEMORY;+ goto out;+ }+ results = newResults;+ }+ TMR_TRD_init(&results[tagsRead]);+ ret = TMR_getNextTag(reader, &results[tagsRead]);+ if (TMR_SUCCESS != ret)+ {+ goto out;+ }+#ifndef TMR_ENABLE_API_SIDE_DEDUPLICATION+ tagsRead++;+#else+ /* Search array for record duplicating the one just fetched.+ * If no dup found, commit fetched tag by incrementing tag count.+ * If dup found, copy last record to found position, don't advance count.+ */+ if (true == reader->u.serialReader.enableReadFiltering)+ {+ TMR_TagReadData* last = &results[tagsRead];+ int dupIndex = TMR_findDupTag(reader, last, results, tagsRead,+ uniqueByAntenna, uniqueByData, uniqueByProtocol);+ if (-1 == dupIndex)+ {+ tagsRead++;+ }+ else+ {+ TMR_updateDupTag(reader, &results[dupIndex], last,+ recordHighestRssi);+ }+ }+ else+ {+ tagsRead++;+ }+#endif /* TMR_ENABLE_API_SIDE_DEDUPLICATION */+ }++ tm_gettime_consistent(&nowHi, &nowLo);+ }+ while (tm_time_subtract(nowLo, startLo) < timeoutMs);++out:+ if (NULL != tagCount)+ *tagCount = tagsRead;+ *result = results;+ return ret;+}++TMR_Status+validateReadPlan(TMR_Reader *reader, TMR_ReadPlan *plan,+ TMR_AntennaMapList *txRxMap, uint32_t protocols)+{+ TMR_Status ret;+ int i, j;++ if (TMR_READ_PLAN_TYPE_MULTI == plan->type)+ {+ plan->u.multi.totalWeight = 0;+ for (i = 0; i < plan->u.multi.planCount; i++)+ {+ ret = validateReadPlan(reader, plan->u.multi.plans[i], txRxMap, protocols);+ if (TMR_SUCCESS != ret)+ {+ return ret;+ }+ plan->u.multi.totalWeight += plan->u.multi.plans[i]->weight;+ }+ }+ else if (TMR_READ_PLAN_TYPE_SIMPLE == plan->type)+ {+ if (0 == ((1 << (plan->u.simple.protocol - 1)) & protocols))+ {+ return TMR_ERROR_INVALID_PROTOCOL_SPECIFIED;+ }+ for (i = 0 ; i < plan->u.simple.antennas.len; i++)+ {+ for (j = 0; j < txRxMap->len; j++)+ { + if (plan->u.simple.antennas.list[i] == txRxMap->list[j].antenna)+ {+ break;+ }+ }+ if (j == txRxMap->len)+ {+ return TMR_ERROR_INVALID_ANTENNA_CONFIG;+ }+ }+ if (NULL != plan->u.simple.tagop)+ {+ if (TMR_TAGOP_LIST == plan->u.simple.tagop->type)+ return TMR_ERROR_UNSUPPORTED; /* not yet supported */+ }+ }++ return TMR_SUCCESS;+}++TMR_Status+TMR_paramSet(struct TMR_Reader *reader, TMR_Param key, const void *value)+{+ TMR_Status ret;++ ret = TMR_SUCCESS;++ switch (key)+ {+#if defined(TMR_ENABLE_BACKGROUND_READS)|| defined(SINGLE_THREAD_ASYNC_READ)+ case TMR_PARAM_READ_ASYNCOFFTIME:+ {+ if (TMR_READER_TYPE_LLRP != reader->readerType)+ {+ if (reader->readParams.asyncOffTime != *(uint32_t *)value)+ {+ uint32_t asyncOffTime = reader->readParams.asyncOffTime;+ reader->readParams.asyncOffTime = *(uint32_t *)value;+ if (reader->continuousReading)+ {+ ret = restart_reading(reader);+ if(ret != TMR_SUCCESS)+ {+ reader->readParams.asyncOffTime = asyncOffTime;+ }+ }+ }+ }+ else+ {+ goto LEVEL1;+ }+ }+ break;+ case TMR_PARAM_READ_ASYNCONTIME:+ {+ if (reader->readParams.asyncOnTime != *(uint32_t *)value)+ {+ uint32_t asyncOnTime = reader->readParams.asyncOnTime;+ reader->readParams.asyncOnTime = *(uint32_t *)value;+ if (reader->continuousReading)+ {+ ret = restart_reading(reader);+ if(ret != TMR_SUCCESS)+ {+ reader->readParams.asyncOnTime = asyncOnTime;+ }+ }+ }+ }+ break;+LEVEL1:+#endif+ default:+ ret = reader->paramSet(reader, key, value);+ }+ return ret;+}+++TMR_Status+TMR_paramGet(struct TMR_Reader *reader, TMR_Param key, void *value)+{+ TMR_Status ret;++ ret = TMR_SUCCESS;++ switch (key)+ {+ case TMR_PARAM_READ_PLAN:+ {+ TMR_ReadPlan *plan = value;+ *plan = *reader->readParams.readPlan;+ break;+ }+#if defined(TMR_ENABLE_BACKGROUND_READS)|| defined(SINGLE_THREAD_ASYNC_READ) + case TMR_PARAM_READ_ASYNCOFFTIME:+ {+ if (TMR_READER_TYPE_LLRP != reader->readerType)+ {+ *(uint32_t *)value = reader->readParams.asyncOffTime;+ }+ else+ {+ goto LEVEL;+ }+ break;+ }+ case TMR_PARAM_READ_ASYNCONTIME:+ *(uint32_t *)value = reader->readParams.asyncOnTime;+ break;+LEVEL:+#endif+ default:+ ret = reader->paramGet(reader, key, value);+ }+ return ret;+}+++TMR_Status+TMR_addTransportListener(TMR_Reader *reader, TMR_TransportListenerBlock *b)+{++ b->next = reader->transportListeners;+ reader->transportListeners = b;++ return TMR_SUCCESS;+}+++TMR_Status+TMR_removeTransportListener(TMR_Reader *reader, TMR_TransportListenerBlock *b)+{+ TMR_TransportListenerBlock *block, **prev;++ prev = &reader->transportListeners;+ block = reader->transportListeners;+ while (NULL != block)+ {+ if (block == b)+ {+ *prev = block->next;+ break;+ }+ prev = &block->next;+ block = block->next;+ }+ if (block == NULL)+ {+ return TMR_ERROR_INVALID;+ }++ return TMR_SUCCESS;+}+++void+TMR__notifyTransportListeners(TMR_Reader *reader, bool tx, + uint32_t dataLen, uint8_t *data,+ int timeout)+{+ TMR_TransportListenerBlock *block;++ block = reader->transportListeners;+ while (NULL != block)+ {+ block->listener(tx, dataLen, data, timeout, block->cookie);+ block = block->next;+ }+}++bool+TMR_memoryProvider(void *cookie, uint16_t *size, uint8_t *data)+{+ TMR_memoryCookie *mc;+ int len;++ mc = cookie;++ if (0 == mc->firmwareSize)+ {+ return false;+ }++ if (*size > mc->firmwareSize)+ {+ *size =(uint16_t) mc->firmwareSize;+ }++ len = *size;++ memcpy(data, mc->firmwareStart, len);+ + mc->firmwareSize -= len;+ mc->firmwareStart += len;++ return true;+}++#ifdef TMR_ENABLE_STDIO+bool+TMR_fileProvider(void *cookie, uint16_t *size, uint8_t *data)+{+ FILE *fp;+ size_t len;++ fp = cookie;++ len = fread(data, 1, *size, fp);+ if (0 == len)+ {+ return false;+ }+ + *size = (uint16_t) len;+ return true;+}+#endif++/**+ * Initialize TMR_TagReadData with default values.+ * The tagData buffer will be initialized to TMR_MAX_EMBEDDED_DATA_LENGTH+ * which can be found in tm_config.h. + * If this value is zero, then the buffer is pointed to NULL.+ * @param trd Pointer to the TMR_TagReadData structure to initialize+ */+TMR_Status+TMR_TRD_init(TMR_TagReadData *trd)+{+ trd->tag.protocol = TMR_TAG_PROTOCOL_NONE;+ trd->tag.epcByteCount = 0;+ trd->tag.crc = 0;+ trd->metadataFlags = 0;+ trd->phase = 0;+ memset(trd->gpio, 0, sizeof(trd->gpio));+ trd->gpioCount = 0;+ trd->readCount = 0;+ trd->rssi = 0;+ trd->frequency = 0;+ trd->dspMicros = 0;+ trd->timestampLow = 0;+ trd->timestampHigh = 0;++#if TMR_MAX_EMBEDDED_DATA_LENGTH+ trd->data.list = trd->_dataList;+ trd->epcMemData.list = trd->_epcMemDataList;+ trd->tidMemData.list = trd->_tidMemDataList;+ trd->userMemData.list = trd->_userMemDataList;+ trd->reservedMemData.list = trd->_reservedMemDataList;++ trd->data.max = TMR_MAX_EMBEDDED_DATA_LENGTH;+ trd->epcMemData.max = TMR_MAX_EMBEDDED_DATA_LENGTH;+ trd->userMemData.max = TMR_MAX_EMBEDDED_DATA_LENGTH;+ trd->reservedMemData.max = TMR_MAX_EMBEDDED_DATA_LENGTH;+ trd->tidMemData.max = TMR_MAX_EMBEDDED_DATA_LENGTH;+#else+ trd->data.list = NULL;+ trd->epcMemData.list = NULL;+ trd->userMemData.list = NULL;+ trd->tidMemData.list = NULL;+ trd->reservedMemData.list = NULL;++ trd->data.max = 0;+ trd->epcMemData.max = 0;+ trd->userMemData.max = 0;+ trd->reservedMemData.max = 0;+ trd->tidMemData.max = 0;+#endif+ trd->data.len = 0;+ trd->epcMemData.len = 0;+ trd->userMemData.len = 0;+ trd->tidMemData.len = 0;+ trd->reservedMemData.len = 0;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagReadData with the provided data storage area.+ *+ * @param trd Pointer to the TMR_TagReadData structure to initialize+ * @param size The number of bytes pointed to+ * @param buf Pointer to the uint8_t storage area+ */+TMR_Status+TMR_TRD_init_data(TMR_TagReadData *trd, uint16_t size, uint8_t *buf)+{+ trd->data.max = size;+ trd->data.len = 0;+ trd->data.list = buf;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagReadDataMemBank with provided data storage area+ *+ * @param data to the TMR_uint8List structure to initialize+ * @param size The nuber of bytes pointed to+ * @param buf pointer to the uint8_t storage area+ **/+TMR_Status+TMR_TRD_MEMBANK_init_data(TMR_uint8List *data, uint16_t size, uint8_t *buf)+{+ data->max = size;+ data->len = 0;+ data->list = buf;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_GEN2_Bap with the provided parameters+ *+ * @param bapVal pointer to the TMR_GEN2_Bap structure+ * @param powerUpDelayUs the power up delay time+ * @param freqHopOfftimeUs the offtime for frequencyHop+ **/+TMR_Status+TMR_GEN2_init_BapParams(TMR_GEN2_Bap *bapVal, int32_t powerUpDelayUs, int32_t freqHopOfftimeUs)+{++ bapVal->powerUpDelayUs = powerUpDelayUs;+ bapVal->freqHopOfftimeUs=freqHopOfftimeUs;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_Filter structure as tag data (EPC) filter with the+ * provided tag (which is copied).+ * + * @param filter Pointer to the filter structure to initialize+ * @param tag TMR_TagData to use as the filter value+ */+TMR_Status+TMR_TF_init_tag(TMR_TagFilter *filter, TMR_TagData *tag)+{+ + filter->type = TMR_FILTER_TYPE_TAG_DATA;+ filter->u.tagData = *tag;+ + return TMR_SUCCESS;+}++/**+ * Initialize a TMR_Filter structure as a Gen2 select filter with the+ * provided parameters.+ * + * @param filter Pointer to the filter structure to initialize+ * @param invert Whether to invert the result of the select+ * @param bank The memory bank on the tag to compare with the data+ * @param bitPointer The bit address of the tag data to compare+ * @param maskBitLength The length of the data to compare+ * @param mask The data to compare+ */+TMR_Status+TMR_TF_init_gen2_select(TMR_TagFilter *filter, bool invert, TMR_GEN2_Bank bank,+ uint32_t bitPointer, uint16_t maskBitLength,+ uint8_t *mask)+{+ + filter->type = TMR_FILTER_TYPE_GEN2_SELECT;+ filter->u.gen2Select.invert = invert;+ filter->u.gen2Select.bank = bank;+ filter->u.gen2Select.bitPointer = bitPointer;+ filter->u.gen2Select.maskBitLength = maskBitLength;+ filter->u.gen2Select.mask = mask;++ return TMR_SUCCESS;+}+++#ifdef TMR_ENABLE_ISO180006B+/**+ * Initialize a TMR_Filter structure as an ISO180006B select filter with the+ * provided parameters.+ * + * @param filter Pointer to the filter structure to initialize+ * @param invert Whether to invert the result of the select+ * @param op The operation to use to compare the provided data with the tag data+ * @param address The address of the 8 bytes of data on the tag to compare + * @param mask 8-bit mask of the bytes to compare+ * @param wordData The data to compare to the tag data+ */+TMR_Status TMR_TF_init_ISO180006B_select(TMR_TagFilter *filter, bool invert,+ TMR_ISO180006B_SelectOp op,+ uint8_t address, uint8_t mask,+ uint8_t wordData[8])+{++ filter->type = TMR_FILTER_TYPE_ISO180006B_SELECT;+ filter->u.iso180006bSelect.invert = invert;+ filter->u.iso180006bSelect.op = op;+ filter->u.iso180006bSelect.address = address;+ filter->u.iso180006bSelect.mask = mask;+ memcpy(filter->u.iso180006bSelect.data, wordData, 8);+ + return TMR_SUCCESS;+}+#endif /* TMR_ENABLE_ISO180006B */+++bool+TMR_TF_match(TMR_TagFilter *filter, TMR_TagData *tag)+{+ int32_t i, bitAddr;+ bool match;+ TMR_GEN2_Select *sel;++ if (TMR_FILTER_TYPE_GEN2_SELECT != filter->type)+ {+ return false;+ }++ if (TMR_TAG_PROTOCOL_GEN2 != tag->protocol)+ {+ return false;+ }++ sel = &filter->u.gen2Select;++ if (TMR_GEN2_BANK_EPC != sel->bank)+ {+ /*+ * Can't perform non-EPC matches, since we don't have the rest of+ * the tag data.+ */+ return false;+ }++ i = 0;+ bitAddr = sel->bitPointer;+ /*+ * Matching against the CRC and PC does not have defined+ * behavior; see section 6.3.2.11.1.1 of Gen2 version 1.2.0.+ * We choose to let it match, because that's simple.+ */+ bitAddr -= 32;+ if (bitAddr < 0)+ {+ i -= bitAddr;+ bitAddr = 0;+ }++ match = true;+ for (; i < sel->maskBitLength; i++, bitAddr++)+ {+ if (bitAddr >(int32_t) (tag->epcByteCount * 8))+ {+ match = false;+ break;+ }+ /* Extract the relevant bit from both the EPC and the mask. */+ if (((tag->epc[bitAddr / 8] >> (7 - (bitAddr & 7))) & 1) !=+ ((sel->mask[i / 8] >> (7 - (i & 7))) & 1))+ {+ match = false;+ break;+ }+ }+ if (sel->invert)+ match = match ? false : true;++ return match;+}+++/**+ * Initialize a TMR_TagAuthentication structure as a Gen2 password.+ *+ * @param auth Pointer to the structure to initialize.+ * @param password The password 32-bit Gen2 password value.+ */+TMR_Status+TMR_TA_init_gen2(TMR_TagAuthentication *auth, TMR_GEN2_Password password)+{++ auth->type = TMR_AUTH_TYPE_GEN2_PASSWORD;+ auth->u.gen2Password = password;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagAuthentication structure as Denatran IAV write credential+ *+ * @param auth Pointer to the structure to initialize.+ * @param data Gen2 Denatran IAV write credential+ */+TMR_Status+TMR_TA_init_gen2_Denatran_IAV_writeCredentials(TMR_TagAuthentication *auth, uint8_t idLength, uint8_t* tagId, uint8_t len, uint8_t *data)+{+ uint8_t i;+ auth->type = TMR_AUTH_TYPE_GEN2_DENATRAN_IAV_WRITE_CREDENTIALS;++ /* The length should be 16 byte */+ auth->u.writeCreds.credentialLength = len;+ if (16 != auth->u.writeCreds.credentialLength)+ {+ return TMR_ERROR_INVALID;+ }++ /* The length for tag ID should be 8 bytes */+ auth->u.writeCreds.tagIdLength = idLength;+ if (8 != auth->u.writeCreds.tagIdLength)+ {+ return TMR_ERROR_INVALID;+ }++ /* Copy the data */+ for (i = 0; i < auth->u.writeCreds.tagIdLength; i++)+ {+ memcpy(auth->u.writeCreds.tagId, tagId, auth->u.writeCreds.tagIdLength);+ }++ /* Copy the data */+ for (i = 0; i < auth->u.writeCreds.credentialLength; i++)+ {+ memcpy(auth->u.writeCreds.value, data, auth->u.writeCreds.credentialLength);+ }++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagAuthentication structure as Denatran IAV write credential+ *+ * @param auth Pointer to the structure to initialize.+ * @param data Gen2 Denatran IAV write credential+ */+TMR_Status+TMR_TA_init_gen2_Denatran_IAV_writeSecCredentials(TMR_TagAuthentication *auth, uint8_t length, uint8_t* data, uint8_t len, uint8_t* credentials)+{+ uint8_t i;+ auth->type = TMR_AUTH_TYPE_GEN2_DENATRAN_IAV_WRITE_SEC_CREDENTIALS;++ /* The length should be 16 byte */+ auth->u.writeSecCreds.credentialLength = len;+ if (16 != auth->u.writeSecCreds.credentialLength)+ {+ return TMR_ERROR_INVALID;+ }++ /* The length for data words should be 6 bytes */+ auth->u.writeSecCreds.dataLength = length;+ if (6 != auth->u.writeSecCreds.dataLength)+ {+ return TMR_ERROR_INVALID;+ }++ /* Copy the data */+ for (i = 0; i < auth->u.writeSecCreds.dataLength; i++)+ {+ memcpy(auth->u.writeSecCreds.data, data, auth->u.writeSecCreds.dataLength);+ }++ /* Copy the data */+ for (i = 0; i < auth->u.writeSecCreds.credentialLength; i++)+ {+ memcpy(auth->u.writeSecCreds.value, credentials, auth->u.writeSecCreds.credentialLength);+ }++ return TMR_SUCCESS;+}++/** Initialize a TMR_StatValues structure with the default vales+ *+ * @param stats Pointer to the TMR_StatValues structure to initialize.+ */+TMR_Status+TMR_STATS_init(TMR_Reader_StatsValues *stats)+{+ if (NULL != stats)+ {+ stats->valid = TMR_READER_STATS_FLAG_NONE;+ /* Allocate space for the parameters */+ stats->connectedAntennas.len = 0;+ stats->connectedAntennas.max = TMR_SR_MAX_ANTENNA_PORTS;+ stats->connectedAntennas.list = stats->_connectedAntennasStorage;+ stats->perAntenna.len = 0;+ stats->perAntenna.max = TMR_SR_MAX_ANTENNA_PORTS;+ stats->perAntenna.list = stats->_perAntStorage;+ }+ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_GPITriggerRead structure with default values.+ *+ * @param triggerRead Pointer to the read plan to initialize.+ * @param enable Option to enable trigger read.+ */+TMR_Status+TMR_GPITR_init_enable(TMR_GPITriggerRead *triggerRead, bool enable)+{+ triggerRead->enable = enable;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_ReadPlan structure as a simple read plan with the+ * provided parameters. + *+ * Only the mandatory elements are parameters to+ * this function. The optional elements, filters and tag operations,+ * can be set with TMR_RP_set_filter() and TMR_RP_set_tagop().+ *+ * @param plan Pointer to the read plan to initialize.+ * @param antennaCount Number of antennas in antenna list. A+ * zero-length list requests the reader to use all antennas known to+ * be connected at the time of the read operation.+ * @param antennaList Pointer to antenna numbers.+ * @param protocol Protocol+ * @param weight Weight.+ */+TMR_Status+TMR_RP_init_simple(TMR_ReadPlan *plan, uint8_t antennaCount,+ uint8_t *antennaList, TMR_TagProtocol protocol,+ uint32_t weight) +{+ + plan->type = TMR_READ_PLAN_TYPE_SIMPLE;+ plan->u.simple.antennas.max = antennaCount;+ plan->u.simple.antennas.len = antennaCount;+ plan->u.simple.antennas.list = antennaList;+ plan->u.simple.protocol = protocol;+ plan->u.simple.filter = NULL;+ plan->u.simple.tagop = NULL;+ plan->weight = weight;+ plan->u.simple.useFastSearch = false;+ plan->u.simple.stopOnCount.stopNTriggerStatus = false;+ plan->u.simple.stopOnCount.noOfTags = 0;+ plan->u.simple.triggerRead.enable = false;+ plan->u.simple.triggerRead.gpiList.len = 0;+ plan->u.simple.triggerRead.gpiList.list = NULL;+ plan->u.simple.triggerRead.gpiList.max = 0;+ plan->enableAutonomousRead = false;+ + return TMR_SUCCESS;+}++/**+ * Set the stop on N tags option of a read plan+ *+ * @param plan Pointer to the read plan+ * @param nCount the number of tags user requested to search.+ */+TMR_Status+TMR_RP_set_stopTrigger(TMR_ReadPlan *plan, uint32_t nCount)+{++ if (TMR_READ_PLAN_TYPE_SIMPLE != plan->type)+ return TMR_ERROR_INVALID;++ plan->u.simple.stopOnCount.stopNTriggerStatus = true;+ plan->u.simple.stopOnCount.noOfTags = nCount;++ return TMR_SUCCESS;+}++/**+ * Set the filter of a simple read plan.+ *+ * @param plan Pointer to the read plan+ * @param filter Pointer to the filter + */+TMR_Status+TMR_RP_set_filter(TMR_ReadPlan *plan, TMR_TagFilter *filter)+{++ if (TMR_READ_PLAN_TYPE_SIMPLE != plan->type)+ return TMR_ERROR_INVALID;++ plan->u.simple.filter = filter;++ return TMR_SUCCESS;+}++/**+ * Set the fast search option of a read plan+ *+ * @param plan Pointer to the read plan+ * @param useFastSearch Option for FastSearch+ */ +TMR_Status+TMR_RP_set_useFastSearch(TMR_ReadPlan *plan, bool useFastSearch)+{++ if (TMR_READ_PLAN_TYPE_SIMPLE != plan->type)+ return TMR_ERROR_INVALID;++ plan->u.simple.useFastSearch = useFastSearch;++ return TMR_SUCCESS;+}++/**+ * Set the autonomous read option of a read plan+ *+ * @param plan Pointer to the read plan+ * @param autonomousRead Option for autonomous read.+ */ +TMR_Status+TMR_RP_set_enableAutonomousRead(TMR_ReadPlan *plan, bool autonomousRead)+{+ plan->enableAutonomousRead = autonomousRead;+ return TMR_SUCCESS;+}++/**+ * Set the trigger read option of a read plan+ *+ * @param plan Pointer to the read plan+ * @param triggerRead Pointer for trigger read+ */+TMR_Status+TMR_RP_set_enableTriggerRead(TMR_ReadPlan *plan, TMR_GPITriggerRead *triggerRead)+{+ if (TMR_READ_PLAN_TYPE_SIMPLE != plan->type)+ return TMR_ERROR_INVALID;++ plan->u.simple.triggerRead.enable = triggerRead->enable;+ /*+ * TODO: extent the set_enableTriggerRead() method to accept the GPI list directly+ as a part of read plan. Current the GPI list can be set through TMR_paramSet().+ */+ plan->u.simple.triggerRead.gpiList.list = NULL;+ plan->u.simple.triggerRead.gpiList.len = 0;+ plan->u.simple.triggerRead.gpiList.max = 0; ++ return TMR_SUCCESS;+}++/**+ * Set the tagop of a simple read plan.+ *+ * @param plan Pointer to the read plan+ * @param tagop Pointer to the tagop + */+TMR_Status+TMR_RP_set_tagop(TMR_ReadPlan *plan, TMR_TagOp *tagop)+{++ if (TMR_READ_PLAN_TYPE_SIMPLE != plan->type)+ return TMR_ERROR_INVALID;++ plan->u.simple.tagop = tagop;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_ReadPlan structure as a multi-read plan with the+ * provided parameters.+ *+ * @param plan Pointer to the read plan to initialize.+ * @param plans Array of pointers to read plans to include+ * @param planCount Number of elements in array+ * @param weight Weight.+ */+TMR_Status+TMR_RP_init_multi(TMR_ReadPlan *plan, TMR_ReadPlan **plans, uint8_t planCount,+ uint32_t weight)+{+ plan->type = TMR_READ_PLAN_TYPE_MULTI;+ plan->u.multi.plans = plans;+ plan->u.multi.planCount = planCount;+ plan->u.multi.totalWeight = 0;+ plan->weight = weight;++ return TMR_SUCCESS;+}+++/**+ * Initialize a TMR_TagLockAction as a Gen2 lock action with the+ * provided parameters.+ *+ * @param lockAction Pointer to the structure to initialize.+ * @param mask mask+ * @param action action+ */+TMR_Status+TMR_TLA_init_gen2(TMR_TagLockAction *lockAction, uint16_t mask, uint16_t action)+{++ lockAction->type = TMR_LOCK_ACTION_TYPE_GEN2_LOCK_ACTION;+ lockAction->u.gen2LockAction.mask = mask;+ lockAction->u.gen2LockAction.action = action;++ return TMR_SUCCESS;+}+++#ifdef TMR_ENABLE_ISO180006B+/**+ * Initialize a TMR_TagLockAction as an ISO180006B lock action with the+ * provided parameters.+ *+ * @param lockAction Pointer to the structure to initialize.+ * @param address The byte to lock+ */+TMR_Status+TMR_TLA_init_ISO180006B(TMR_TagLockAction *lockAction, uint8_t address)+{++ lockAction->type = TMR_LOCK_ACTION_TYPE_ISO180006B_LOCK_ACTION;+ lockAction->u.iso180006bLockAction.address = address;++ return TMR_SUCCESS;+}++#endif /* TMR_ENABLE_ISO180006B */+++/**+ * Initialize a TMR_TagOp as a GEN2 EPC write operation with the+ * provided parameters.+ * + * @param tagop Pointer to the tagop structure to initialize.+ * @param epc EPC to write+ */+TMR_Status+TMR_TagOp_init_GEN2_WriteTag(TMR_TagOp *tagop, TMR_TagData* epc)+{+ tagop->type = TMR_TAGOP_GEN2_WRITETAG;+ tagop->u.gen2.u.writeTag.epcptr = epc; /* Takes pointer to EPC; doesn't make an actual copy */++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a GEN2 data read operation with the+ * provided parameters.+ * + * @param tagop Pointer to the tagop structure to initialize.+ * @param bank Memory bank from which to read+ * @param wordAddress Word address of location in bank from which to read+ * @param len Number of words to read+ */+TMR_Status+TMR_TagOp_init_GEN2_ReadData(TMR_TagOp *tagop, TMR_GEN2_Bank bank,+ uint32_t wordAddress, uint8_t len)+{++ tagop->type = TMR_TAGOP_GEN2_READDATA;+ tagop->u.gen2.u.readData.bank = bank;+ tagop->u.gen2.u.readData.wordAddress = wordAddress;+ tagop->u.gen2.u.readData.len = len;++ return TMR_SUCCESS;+}++/** + * Initialize a TMR_TagOp as a GEN2 Secure data read operation with the+ * provided parameters.+ *+ * @param tagop Pointer to the tagop structure to initialize.+ * @param bank Memory bank from which to read+ * @param wordAddress Word address of location in bank from which to read+ * @param len Number of words to read+ * @param tagtype to select Alien Higgs 3 secure access and Monza 4 secure access+ * @param passwordType specifying the mode of password + */+TMR_Status+TMR_TagOp_init_GEN2_SecureReadData(TMR_TagOp *tagop, TMR_GEN2_Bank bank, uint32_t wordAddress,+ uint8_t len, uint8_t tagtype, uint8_t passwordType)+{+ tagop->type = TMR_TAGOP_GEN2_SECURE_READDATA;+ tagop->u.gen2.u.secureReadData.passwordType = (SecurePasswordType)passwordType;+ tagop->u.gen2.u.secureReadData.readData.bank = bank;+ tagop->u.gen2.u.secureReadData.readData.wordAddress = wordAddress;+ tagop->u.gen2.u.secureReadData.readData.len = len;+ tagop->u.gen2.u.secureReadData.type = (SecureTagType)tagtype;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Secure Password with the + * provided parameters.+ *+ * @param tagop Pointer to the tagop structure to initialize+ * @param passwordType specifying the mode of password + * @param gen2PassWord Gen2 access password+ * @param addressLength Number of bits used to address the AP list+ * @param addressOffset EPC word offset+ * @param flashOffset User flash offset+ */+TMR_Status+TMR_TagOp_init_GEN2_SecurePassWord(TMR_TagOp *tagop, uint8_t passwordType, uint32_t gen2PassWord,+ uint8_t addressLength, uint8_t addressOffset, uint16_t flashOffset)+{+ + tagop->u.gen2.u.secureReadData.passwordType = (SecurePasswordType)passwordType;+ tagop->u.gen2.u.secureReadData.password.gen2PassWord.u.gen2Password = gen2PassWord;+ tagop->u.gen2.u.secureReadData.password.secureAddressLength = addressLength;+ tagop->u.gen2.u.secureReadData.password.secureAddressOffset = addressOffset;+ tagop->u.gen2.u.secureReadData.password.secureFlashOffset = flashOffset;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a ISO18000B data read operation with the+ * provided parameters.+ * + * @param tagop Pointer to the tagop structure to initialize.+ * @param byteAddress Address of location in bank from which to read+ * @param len Number of bytes to read+ */+TMR_Status+TMR_TagOp_init_ISO180006B_ReadData(TMR_TagOp *tagop, uint8_t byteAddress, uint8_t len)+{++ tagop->type = TMR_TAGOP_ISO180006B_READDATA;+ tagop->u.iso180006b.u.readData.byteAddress = byteAddress;+ tagop->u.iso180006b.u.readData.len = len;++ return TMR_SUCCESS;+}+++/**+ * Initialize a TMR_TagOp as a GEN2 data write operation with the+ * provided parameters.+ * + * @param tagop Pointer to the tagop structure to initialize.+ * @param bank Memory bank to write into+ * @param wordAddress Word address of location to begin write+ * @param data Data to write+ */+TMR_Status+TMR_TagOp_init_GEN2_WriteData(TMR_TagOp *tagop, TMR_GEN2_Bank bank,+ uint32_t wordAddress, TMR_uint16List *data)+{+ tagop->type = TMR_TAGOP_GEN2_WRITEDATA;+ tagop->u.gen2.u.writeData.bank = bank;+ tagop->u.gen2.u.writeData.wordAddress = wordAddress;+ tagop->u.gen2.u.writeData.data = *data; /* Copies pointer to the words adata but not data */++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a ISO180006B data write operation with the+ * provided parameters.+ * + * @param tagop Pointer to the tagop structure to initialize.+ * @param byteAddress address of location to begin write+ * @param data Data to write+ */+TMR_Status+TMR_TagOp_init_ISO180006B_WriteData(TMR_TagOp *tagop, uint8_t byteAddress, TMR_uint8List *data)+{+ tagop->type = TMR_TAGOP_ISO180006B_WRITEDATA;+ tagop->u.iso180006b.u.writeData.byteAddress = byteAddress;+ tagop->u.iso180006b.u.writeData.data = *data;+ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a GEN2 lock operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param mask mask+ * @param action action+ * @param accessPassword The password to use to lock the tag.+ */+TMR_Status+TMR_TagOp_init_GEN2_Lock(TMR_TagOp *tagop, uint16_t mask, uint16_t action, TMR_GEN2_Password accessPassword)+{++ tagop->type = TMR_TAGOP_GEN2_LOCK;+ tagop->u.gen2.u.lock.mask = mask;+ tagop->u.gen2.u.lock.action = action;+ tagop->u.gen2.u.lock.accessPassword = accessPassword;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a ISO180006B lock operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param address The memory address of the byte to lock.+ */+TMR_Status+TMR_TagOp_init_ISO180006B_Lock(TMR_TagOp *tagop, uint8_t address)+{++ tagop->type = TMR_TAGOP_ISO180006B_LOCK;+ tagop->u.iso180006b.u.lock.address = address;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a GEN2 kill operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param killPassword tag kill password+ */+TMR_Status+TMR_TagOp_init_GEN2_Kill(TMR_TagOp *tagop, TMR_GEN2_Password killPassword)+{++ tagop->type = TMR_TAGOP_GEN2_KILL;+ tagop->u.gen2.u.kill.password = killPassword;++ return TMR_SUCCESS;+}+++/**+ * Initialize a TMR_TagOp as a GEN2 BlockWrite operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param bank bank+ * @param wordPtr word pointer+ * @param data data (The length of the data specifies the word count)+ */+TMR_Status+TMR_TagOp_init_GEN2_BlockWrite(TMR_TagOp *tagop, TMR_GEN2_Bank bank, uint32_t wordPtr, TMR_uint16List *data)+{+ tagop->type = TMR_TAGOP_GEN2_BLOCKWRITE;+ tagop->u.gen2.u.blockWrite.bank = bank;+ tagop->u.gen2.u.blockWrite.wordPtr = wordPtr;+ tagop->u.gen2.u.blockWrite.data.len = data->len;+ tagop->u.gen2.u.blockWrite.data.list = data->list;+ tagop->u.gen2.u.blockWrite.data.max = data->max;+ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a GEN2 BlockPermaLock operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param readLock readLock+ * @param bank bank+ * @param blockPtr block pointer+ * @param mask mask (The length of the mask specifies the block range)+ */+TMR_Status+TMR_TagOp_init_GEN2_BlockPermaLock(TMR_TagOp *tagop, uint8_t readLock, TMR_GEN2_Bank bank, uint32_t blockPtr, TMR_uint16List *mask)+{+ tagop->type = TMR_TAGOP_GEN2_BLOCKPERMALOCK;+ tagop->u.gen2.u.blockPermaLock.readLock = readLock;+ tagop->u.gen2.u.blockPermaLock.bank = bank;+ tagop->u.gen2.u.blockPermaLock.blockPtr = blockPtr;+ tagop->u.gen2.u.blockPermaLock.mask.len = mask->len;+ tagop->u.gen2.u.blockPermaLock.mask.list = mask->list;+ tagop->u.gen2.u.blockPermaLock.mask.max = mask->max;+ return TMR_SUCCESS;++}++/**+ * Initialize a TMR_TagOp as a GEN2 BlockErase operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param bank bank+ * @param wordPtr The starting word address to erase+ * @param wordCount Number of words to erase+ */+TMR_Status +TMR_TagOp_init_GEN2_BlockErase(TMR_TagOp *tagop, TMR_GEN2_Bank bank, uint32_t wordPtr, uint8_t wordCount)+{+ tagop->type = TMR_TAGOP_GEN2_BLOCKERASE;+ tagop->u.gen2.u.blockErase.bank = bank;+ tagop->u.gen2.u.blockErase.wordCount = wordCount;+ tagop->u.gen2.u.blockErase.wordPtr = wordPtr;+ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Higgs2 Partial Load Image operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param killPassword kill password+ * @param accessPassword access password+ * @param epc EPC to write+ */++#ifdef TMR_ENABLE_GEN2_CUSTOM_TAGOPS++TMR_Status +TMR_TagOp_init_GEN2_Alien_Higgs2_PartialLoadImage(TMR_TagOp *tagop, TMR_GEN2_Password killPassword,+ TMR_GEN2_Password accessPassword, TMR_TagData *epc)+{+ tagop->type = TMR_TAGOP_GEN2_ALIEN_HIGGS2_PARTIALLOADIMAGE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_ALIEN_HIGGS_SILICON;+ tagop->u.gen2.u.custom.u.alien.u.higgs2.u.partialLoadImage.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs2.u.partialLoadImage.killPassword = killPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs2.u.partialLoadImage.epcptr = epc; /* Takes pointer to EPC; doesn't make an actual copy */++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Higgs2 Full Load Image operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param killPassword kill password+ * @param accessPassword access password+ * @param lockBits Lock bits to write to the tag+ * @param pcWord PC word to write to the tag+ * @param epc EPC to write+ */+TMR_Status+TMR_TagOp_init_GEN2_Alien_Higgs2_FullLoadImage(TMR_TagOp *tagop, TMR_GEN2_Password killPassword,+ TMR_GEN2_Password accessPassword, uint16_t lockBits, + uint16_t pcWord, TMR_TagData *epc)+{+ tagop->type = TMR_TAGOP_GEN2_ALIEN_HIGGS2_FULLLOADIMAGE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_ALIEN_HIGGS_SILICON;+ tagop->u.gen2.u.custom.u.alien.u.higgs2.u.fullLoadImage.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs2.u.fullLoadImage.killPassword = killPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs2.u.fullLoadImage.lockBits = lockBits;+ tagop->u.gen2.u.custom.u.alien.u.higgs2.u.fullLoadImage.pcWord = pcWord;+ tagop->u.gen2.u.custom.u.alien.u.higgs2.u.fullLoadImage.epcptr = epc; /* Takes pointer to EPC; doesn't make an actual copy */++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Higgs3 Fast Load Image operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param currentAccessPassword The access password used to write to the tag+ * @param accessPassword access password+ * @param killPassword kill password+ * @param pcWord PC word to write to the tag+ * @param epc EPC to write+ */+TMR_Status TMR_TagOp_init_GEN2_Alien_Higgs3_FastLoadImage(TMR_TagOp *tagop, TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, + uint16_t pcWord, TMR_TagData *epc)+{+ tagop->type = TMR_TAGOP_GEN2_ALIEN_HIGGS3_FASTLOADIMAGE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_ALIEN_HIGGS3_SILICON;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.fastLoadImage.currentAccessPassword = currentAccessPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.fastLoadImage.killPassword = killPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.fastLoadImage.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.fastLoadImage.pcWord = pcWord;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.fastLoadImage.epcptr = epc; /* Takes pointer to EPC; doesn't make an actual copy */++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Higgs3 Load Image operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param currentAccessPassword The access password used to write to the tag+ * @param accessPassword access password+ * @param killPassword kill password+ * @param pcWord PC word to write to the tag+ * @param epcAndUserData Tag EPC and user data to write to the tag (76 bytes)+ */+TMR_Status TMR_TagOp_init_GEN2_Alien_Higgs3_LoadImage(TMR_TagOp *tagop, TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, + uint16_t pcWord, TMR_uint8List *epcAndUserData)+{+ tagop->type = TMR_TAGOP_GEN2_ALIEN_HIGGS3_LOADIMAGE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_ALIEN_HIGGS3_SILICON;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.loadImage.currentAccessPassword = currentAccessPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.loadImage.killPassword = killPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.loadImage.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.loadImage.pcWord = pcWord;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.loadImage.epcAndUserData = epcAndUserData; /* Takes pointer epcAndUserData; doesn't make an actual copy */++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Higgs3 Block Read Lock operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ * @param lockBits A bitmask of bits to lock+ */+TMR_Status TMR_TagOp_init_GEN2_Alien_Higgs3_BlockReadLock(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, uint8_t lockBits)+{+ tagop->type = TMR_TAGOP_GEN2_ALIEN_HIGGS3_BLOCKREADLOCK;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_ALIEN_HIGGS3_SILICON;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.blockReadLock.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.alien.u.higgs3.u.blockReadLock.lockBits = lockBits;+ + return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2I set read protect operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_SetReadProtect(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_SETREADPROTECT;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2I_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.setReadProtect.accessPassword = accessPassword;+ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2X set read protect operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_SetReadProtect(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_SETREADPROTECT;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2X_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.setReadProtect.accessPassword = accessPassword;+ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2I reset read protect operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_ResetReadProtect(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_RESETREADPROTECT;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2I_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.resetReadProtect.accessPassword = accessPassword;+ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2X reset read protect operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_ResetReadProtect(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_RESETREADPROTECT;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2X_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.resetReadProtect.accessPassword = accessPassword;+ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2I Change EAS operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ * @param resetEAS - if true, Reset EAS+ * if false, Set EAS+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_ChangeEAS(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, bool resetEAS)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_CHANGEEAS;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2I_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.changeEAS.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.nxp.u.changeEAS.reset = resetEAS;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2X Change EAS operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ * @param resetEAS - if true, Reset EAS+ * if false, Set EAS+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_ChangeEAS(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, bool resetEAS)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_CHANGEEAS;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2X_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.changeEAS.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.nxp.u.changeEAS.reset = resetEAS;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2I EAS alarm operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param dr Gen2 divide ratio to use+ * @param m Gen2 M(tag encoding) parameter to use+ * @param trExt txExt Gen2 TrExt value to use+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_EASAlarm(TMR_TagOp *tagop, TMR_GEN2_DivideRatio dr, TMR_GEN2_TagEncoding m, TMR_GEN2_TrExt trExt)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_EASALARM;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2I_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.EASAlarm.dr = dr;+ tagop->u.gen2.u.custom.u.nxp.u.EASAlarm.m = m;+ tagop->u.gen2.u.custom.u.nxp.u.EASAlarm.trExt = trExt;+ return TMR_SUCCESS;+}++TMR_Status TMR_TagOp_init_GEN2_NXP_AES_Untraceable(TMR_TagOp *tagop,TMR_GEN2_UNTRACEABLE_Epc epc, int epclen , TMR_GEN2_UNTRACEABLE_Tid tid, TMR_GEN2_UNTRACEABLE_UserMemory user,+ TMR_GEN2_UNTRACEABLE_Range range, TMR_TagOp_GEN2_NXP_Untraceable *untraceable)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_UNTRACEABLE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_AES_UCODE;+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.epc = epc;+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.epcLength = epclen;+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.tid = tid;+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.userMemory = user;+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.range = range;+ if(untraceable->auth.authType == UNTRACEABLE_WITH_AUTHENTICATION)+ {+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.subCommand = 0x02;+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.auth.tam1Auth = untraceable->auth.tam1Auth;+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.auth.tam1Auth.Authentication |= 0x03;+ }+ else+ {+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.subCommand = 0x03;+ tagop->u.gen2.u.custom.u.nxp.u.untraceable.auth.accessPassword = untraceable->auth.accessPassword;+ }+ return TMR_SUCCESS;+}++TMR_Status TMR_TagOp_init_GEN2_NXP_AES_Authenticate(TMR_TagOp *tagop, TMR_TagOp_GEN2_NXP_Authenticate *authenticate)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_AUTHENTICATE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_AES_UCODE;+ if(authenticate->type == TAM1_AUTHENTICATION)+ {+ tagop->u.gen2.u.custom.u.nxp.u.authenticate.type = authenticate->type;+ tagop->u.gen2.u.custom.u.nxp.u.authenticate.subCommand = 0x01;+ tagop->u.gen2.u.custom.u.nxp.u.authenticate.tam1Auth = authenticate->tam1Auth;+ tagop->u.gen2.u.custom.u.nxp.u.authenticate.tam1Auth.Authentication |= 0x03;+ }+ else+ {+ tagop->u.gen2.u.custom.u.nxp.u.authenticate.tam1Auth = authenticate->tam2Auth.tam1Auth;+ tagop->u.gen2.u.custom.u.nxp.u.authenticate.type = authenticate->type;+ tagop->u.gen2.u.custom.u.nxp.u.authenticate.subCommand = 0x01;+ tagop->u.gen2.u.custom.u.nxp.u.authenticate.tam2Auth = authenticate->tam2Auth;+ tagop->u.gen2.u.custom.u.nxp.u.authenticate.tam1Auth.Authentication |= 0x07;+ }+ return TMR_SUCCESS;+}++TMR_Status TMR_TagOp_init_GEN2_NXP_AES_Tam2authentication(TMR_TagOp_GEN2_NXP_Tam2Authentication *auth, TMR_NXP_KeyId keyid, TMR_uint8List *key, + TMR_uint8List *ichallenge, TMR_NXP_Profile profile, uint16_t Offset,uint8_t blockCount,bool sendRawData)+{+ auth->tam1Auth.Authentication = sendRawData ? 0x80 : 0x00;+ auth->tam1Auth.CSI = 0x00;+ auth->tam1Auth.KeyLength = 0x10;+ auth->tam1Auth.IchallengeLength = 0x0A;+ auth->tam1Auth.Ichallenge.len = ichallenge->len;+ auth->tam1Auth.Ichallenge.list = ichallenge->list;+ auth->tam1Auth.Ichallenge.max = ichallenge->max;+ auth->tam1Auth.Key.len = key->len;+ auth->tam1Auth.Key.list = key->list;+ auth->tam1Auth.Key.max = key->max;+ auth->tam1Auth.keyID = keyid;+ auth->Offset = Offset;+ auth->BlockCount = blockCount;+ auth->ProtMode = 0x0001;+ auth->profile = profile;+ return TMR_SUCCESS;+}+TMR_Status TMR_TagOp_init_GEN2_NXP_AES_ReadBuffer(TMR_TagOp *tagop, uint16_t wordPointer, uint16_t bitCount, TMR_TagOp_GEN2_NXP_Readbuffer *readbuffer)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_READBUFFER;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_AES_UCODE;+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.wordPointer = wordPointer;+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.bitCount = bitCount;+ if(readbuffer->authenticate.type == TAM1_AUTHENTICATION)+ {+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.authenticate.type = readbuffer->authenticate.type;+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.authenticate.subCommand = 0x04;+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.authenticate.tam1Auth = readbuffer->authenticate.tam1Auth;+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.authenticate.tam1Auth.Authentication |= 0x00;+ }+ else+ {+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.authenticate.tam1Auth = readbuffer->authenticate.tam2Auth.tam1Auth;+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.authenticate.type = readbuffer->authenticate.type;+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.authenticate.subCommand = 0x04;+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.authenticate.tam2Auth = readbuffer->authenticate.tam2Auth;+ tagop->u.gen2.u.custom.u.nxp.u.readBuffer.authenticate.tam1Auth.Authentication |= 0x04;+ }+ return TMR_SUCCESS;+}++TMR_Status TMR_TagOp_init_GEN2_NXP_AES_Tam1authentication(TMR_TagOp_GEN2_NXP_Tam1Authentication *auth, TMR_NXP_KeyId keyid, TMR_uint8List *key, + TMR_uint8List *ichallenge ,bool sendRawData )+{+ auth->Authentication = sendRawData ? 0x80 : 0x00;+ auth->CSI = 0x00;+ auth->KeyLength = 0x10;+ auth->IchallengeLength = 0x0A;+ auth->Ichallenge.len = ichallenge->len;+ auth->Ichallenge.list = ichallenge->list;+ auth->Ichallenge.max = ichallenge->max;+ auth->Key.len = key->len;+ auth->Key.list = key->list;+ auth->Key.max = key->max;+ auth->keyID = keyid;+ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2X EAS alarm operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param dr Gen2 divide ratio to use+ * @param m Gen2 M(tag encoding) parameter to use+ * @param trExt txExt Gen2 TrExt value to use+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_EASAlarm(TMR_TagOp *tagop, TMR_GEN2_DivideRatio dr, TMR_GEN2_TagEncoding m, TMR_GEN2_TrExt trExt)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_EASALARM;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2X_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.EASAlarm.dr = dr;+ tagop->u.gen2.u.custom.u.nxp.u.EASAlarm.m = m;+ tagop->u.gen2.u.custom.u.nxp.u.EASAlarm.trExt = trExt;+ + return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2i Calibrate operation with the provided parameters.+ *+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_Calibrate(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_CALIBRATE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2I_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.calibrate.accessPassword = accessPassword;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2x Calibrate operation with the provided parameters.+ *+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_Calibrate(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_CALIBRATE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2X_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.calibrate.accessPassword = accessPassword;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2i Change Config operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ * @param configWord ConfigWord to write to the tag.+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_ChangeConfig(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, TMR_NXP_ConfigWord configWord)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_CHANGECONFIG;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2I_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.changeConfig.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.nxp.u.changeConfig.configWord = configWord;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a NXP G2x Change Config operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ * @param configWord ConfigWord to write to the tag.+ */+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_ChangeConfig(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, TMR_NXP_ConfigWord configWord)+{+ tagop->type = TMR_TAGOP_GEN2_NXP_CHANGECONFIG;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_NXP_G2X_SILICON;+ tagop->u.gen2.u.custom.u.nxp.u.changeConfig.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.nxp.u.changeConfig.configWord = configWord;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Monza4 QT Read/Write operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword access password+ * @param controlByte The QT control Byte + * @param payload The QT payload+ */+TMR_Status +TMR_TagOp_init_GEN2_Impinj_Monza4_QTReadWrite(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ TMR_Monza4_ControlByte controlByte, TMR_Monza4_Payload payload)+{+ tagop->type = TMR_TAGOP_GEN2_IMPINJ_MONZA4_QTREADWRITE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IMPINJ_MONZA4_SILICON;+ tagop->u.gen2.u.custom.u.impinj.u.monza4.u.qtReadWrite.accessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.impinj.u.monza4.u.qtReadWrite.controlByte = controlByte;+ tagop->u.gen2.u.custom.u.impinj.u.monza4.u.qtReadWrite.payload = payload;++ return TMR_SUCCESS;+}++ /**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran ActivateSecureMode operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize+ * @param payload 1byte->[TC(Transmission Count) 1bit + RFFU(Reserved For Furture Use) 7bits]+ */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_Activate_Secure_Mode(TMR_TagOp *tagop, uint8_t payload)+{+ tagop->type = TMR_TAGOP_GEN2_DENATRAN_IAV_ACTIVATESECUREMODE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON; + tagop->u.gen2.u.custom.u.IavDenatran.u.secureMode.mode = GEN2_ACTIVATE_SECURE_MODE;+ tagop->u.gen2.u.custom.u.IavDenatran.u.secureMode.payload = payload;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran AuthenticateOBU operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload 1byte->[TC(Transmission Count) 1bit + RFFU(Reserved For Furture Use) 7bits]+ */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_Authenticate_OBU(TMR_TagOp *tagop, uint8_t payload)+{+ tagop->type = TMR_TAGOP_GEN2_DENATRAN_IAV_AUTHENTICATEOBU;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON; + tagop->u.gen2.u.custom.u.IavDenatran.u.authenticateOBU.mode = GEN2_AUTHENTICATE_OBU;+ tagop->u.gen2.u.custom.u.IavDenatran.u.authenticateOBU.payload = payload;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran ACTIVATE_SINIAV_MODE operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload 1byte->[TC(Transmission Count) 1bit + RFFU(Reserved For Furture Use) 7bits]+ * @param data 64 bits of token number to activate the tag+ */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_Activate_Siniav_Mode(TMR_TagOp *tagop, uint8_t payload, TMR_uint8List *token)+{+ uint8_t tokenDesc;++ tagop->type = TMR_TAGOP_GEN2_ACTIVATE_SINIAV_MODE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON; + tagop->u.gen2.u.custom.u.IavDenatran.u.activateSiniavMode.mode = GEN2_ACTIVATE_SINIAV_MODE;+ tagop->u.gen2.u.custom.u.IavDenatran.u.activateSiniavMode.payload = payload;++ /**+ * Currently last two bits of the payload is used as TokenDesc+ * (Token Descriptor): 2 bits parameter indicating the presence and format of Token+ * 00 : No Token.+ * 01 : Token of 64 bits.+ */+ tokenDesc = 0x03 & payload;+ if (0x01 == tokenDesc)+ { + /* the token field is always 64 bits in this case */ + if (0x08 != token->len)+ {+ return TMR_ERROR_INVALID;+ }+ memcpy(tagop->u.gen2.u.custom.u.IavDenatran.u.activateSiniavMode.token, token->list, token->len);+ tagop->u.gen2.u.custom.u.IavDenatran.u.activateSiniavMode.isTokenDesc = true; + }+ else+ {+ tagop->u.gen2.u.custom.u.IavDenatran.u.activateSiniavMode.isTokenDesc = false;+ }++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran OBU_Auth_ID operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload 1byte->[TC(Transmission Count) 1bit + RFFU(Reserved For Furture Use) 7bits] + */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_OBU_Auth_ID(TMR_TagOp *tagop, uint8_t payload)+{+ tagop->type = TMR_TAGOP_GEN2_OBU_AUTH_ID;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON; + tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthId.mode = GEN2_OBU_AUTH_ID;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthId.payload = payload;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran OBU_Auth_Full_Pass1 operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload 1byte->[TC(Transmission Count) 1bit + RFFU(Reserved For Furture Use) 7bits] + */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_OBU_Auth_Full_Pass1(TMR_TagOp *tagop, uint8_t payload)+{+ tagop->type = TMR_TAGOP_GEN2_AUTHENTICATE_OBU_FULL_PASS1;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON; + tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass1.mode = GEN2_AUTHENTICATE_OBU_FULL_PASS1;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass1.payload = payload;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran OBU_Auth_Full_Pass2 operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload 1byte->[TC(Transmission Count) 1bit + RFFU(Reserved For Furture Use) 7bits] + */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_OBU_Auth_Full_Pass2(TMR_TagOp *tagop, uint8_t payload)+{+ tagop->type = TMR_TAGOP_GEN2_AUTHENTICATE_OBU_FULL_PASS2;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON; + tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass2.mode = GEN2_AUTHENTICATE_OBU_FULL_PASS2;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass2.payload = payload;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran OBU_ReadFromMemMap operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload The OBU_ReadFromMemMap Payload+ * @param wordAddress pointer indicating the address to be read from USER memory bank+ */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_OBU_ReadFromMemMap(TMR_TagOp *tagop, uint8_t payload, uint16_t wordAddress)+{+ tagop->type = TMR_TAGOP_GEN2_OBU_READ_FROM_MEM_MAP;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuReadFromMemMap.mode = GEN2_OBU_READ_FROM_MEM_MAP;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuReadFromMemMap.payload = payload;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuReadFromMemMap.readPtr = wordAddress;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran OBU_WriteToMemMap operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload The OBU_WriteToMemMap Payload+ * @param wordAddress pointer to the USER data+ * @param word data to be written+ * @param data credentials written word+ */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_OBU_WriteToMemMap(TMR_TagOp *tagop, uint8_t payload, uint16_t wordAddress, uint16_t word, uint8_t* tagId, uint8_t* data)+{+ tagop->type = TMR_TAGOP_GEN2_OBU_WRITE_TO_MEM_MAP;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuWriteToMemMap.mode = GEN2_OBU_WRITE_TO_MEM_MAP;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuWriteToMemMap.payload = payload;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuWriteToMemMap.writePtr = wordAddress;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuWriteToMemMap.wordData = word;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuWriteToMemMap.tagIdentification = tagId;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuWriteToMemMap.dataBuf = data;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran Write Sec operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload The OBU_WriteToMemMap Payload+ * @param wordAddress pointer to the USER data+ * @param dataWords 4 data words+ * @param data credentials written word+ */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_WriteSec(TMR_TagOp *tagop, uint8_t payload, uint8_t* data, uint8_t* credentials)+{+ tagop->type = TMR_TAGOP_GEN2_DENATRAN_IAV_WRITE_SEC;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON;+ tagop->u.gen2.u.custom.u.IavDenatran.u.writeSec.mode = GEN2_WRITE_SEC;+ tagop->u.gen2.u.custom.u.IavDenatran.u.writeSec.payload = payload;+ tagop->u.gen2.u.custom.u.IavDenatran.u.writeSec.dataWords = data;+ tagop->u.gen2.u.custom.u.IavDenatran.u.writeSec.dataBuf = credentials;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran OBU_Auth_Full_Pass operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload 1byte->[TC(Transmission Count) 1bit + RFFU(Reserved For Furture Use) 7bits] + */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_OBU_Auth_Full_Pass(TMR_TagOp *tagop, uint8_t payload)+{+ tagop->type = TMR_TAGOP_GEN2_DENATRAN_IAV_AUTHENTICATE_OBU_FULL_PASS;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON; + tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass.mode = GEN2_AUTHENTICATE_OBU_FULL_PASS;+ tagop->u.gen2.u.custom.u.IavDenatran.u.obuAuthFullPass.payload = payload;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran G0_PA_OBU_Auth_ID operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + * @param payload 1byte->[TC(Transmission Count) 1bit + RFFU(Reserved For Furture Use) 7bits] + */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_G0_PA_OBU_Auth(TMR_TagOp *tagop, uint8_t payload)+{+ tagop->type = TMR_TAGOP_GEN2_DENATRAN_IAV_G0_PA_OBU_AUTHENTICATE_ID;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON; + tagop->u.gen2.u.custom.u.IavDenatran.u.g0paobuauthid.mode = GEN2_PA_G0_AUTHENTICATE;+ tagop->u.gen2.u.custom.u.IavDenatran.u.g0paobuauthid.payload = payload;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran Get Token Id operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize + */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_GetTokenId(TMR_TagOp *tagop)+{+ tagop->type = TMR_TAGOP_GEN2_DENATRAN_IAV_GET_TOKEN_ID;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON;+ tagop->u.gen2.u.custom.u.IavDenatran.u.getTokenId.mode = GEN2_GET_TOKEN_ID;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 IAVDenatran read sec operation with the provided parameter+ * @param tagop Pointer to the tagop structure to initialize+ * @param payLoad 8 bits for future use+ * @param wordAddress pointer indicating the sector to be read from USER memory bank+ */+TMR_Status+TMR_TagOp_init_GEN2_Denatran_IAV_ReadSec(TMR_TagOp *tagop, uint8_t payload, uint16_t wordAddress)+{+ tagop->type = TMR_TAGOP_GEN2_DENATRAN_IAV_READ_SEC;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_DENATRAN_IAV_SILICON;+ tagop->u.gen2.u.custom.u.IavDenatran.u.readSec.mode = GEN2_READ_SEC;+ tagop->u.gen2.u.custom.u.IavDenatran.u.readSec.payload = payload;+ tagop->u.gen2.u.custom.u.IavDenatran.u.readSec.readPtr = wordAddress;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A GetCalibrationData value operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetCalibrationData(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_GETCALIBRATIONDATA;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.calibrationData.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.calibrationData.CommandCode = 0xA9;+ tagop->u.gen2.u.custom.u.ids.u.calibrationData.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.calibrationData.sl900A.level = level;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a GEn2 IDs SL900A SetPassword value with+ * @param tagop pointer to the tagop struture to SetPassword+ * @param accessPassword Gen2 accessPassword+ * @param level IDS passwordLevel+ * @param password IDS password+ * @param newPasswordLevel IDS NewPasswordLevel+ * @param newPassword IDS NewPassword+ */ +TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetPassword(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password, PasswordLevel newPasswordLevel, uint32_t newPassword)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_SETPASSWORD;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.setPassword.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.setPassword.CommandCode = 0xA0;+ tagop->u.gen2.u.custom.u.ids.u.setPassword.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.setPassword.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.setPassword.NewPasswordLevel = newPasswordLevel;+ tagop->u.gen2.u.custom.u.ids.u.setPassword.NewPassword = newPassword;+ + return TMR_SUCCESS;+}+/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A SetCalibrationData value operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ * @param data IDS calibration data+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetCalibrationData(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level, + uint32_t password, TMR_TagOp_GEN2_IDS_SL900A_CalibrationData *data)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_SETCALIBRATIONDATA;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.setCalibration.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.setCalibration.CommandCode = 0xA5;+ tagop->u.gen2.u.custom.u.ids.u.setCalibration.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.setCalibration.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.setCalibration.cal.raw = data->raw;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A SetSfeParameters value operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ * @param data IDS sfe parameters+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetSfeParameters(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password, TMR_TagOp_GEN2_IDS_SL900A_SfeParameters *data)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_SETSFEPARAMETERS;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.setSfeParameters.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.setSfeParameters.CommandCode = 0xA4;+ tagop->u.gen2.u.custom.u.ids.u.setSfeParameters.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.setSfeParameters.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.setSfeParameters.sfe = data;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A GetSensor value operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ * @param type IDS sensor type+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetSensorValue(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, Sensor type)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_GETSENSOR;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.sensor.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.sensor.CommandCode = 0xAD;+ tagop->u.gen2.u.custom.u.ids.u.sensor.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.sensor.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.sensor.sl900A.sensortype = type;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A GetMeasurementSetup operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetMeasurementSetup(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password)+{+ tagop->type =TMR_TAGOP_GEN2_IDS_SL900A_GETMEASUREMENTSETUP;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.measurementSetup.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.measurementSetup.CommandCode = 0xA3;+ tagop->u.gen2.u.custom.u.ids.u.measurementSetup.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.measurementSetup.sl900A.level = level;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A GetLogState operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetLogState(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_GETLOGSTATE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.getLog.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.getLog.CommandCode = 0xA8;+ tagop->u.gen2.u.custom.u.ids.u.getLog.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.getLog.sl900A.level = level;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A Set Log Mode operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ * @param form IDS logging form+ * @param rule IDS storage rule+ * @param Ext1Enable to Enable log for EXT1 external sensor+ * @param Ext2Enable to Enable log for EXT2 external sensor+ * @param TempEnable to Enable log for temperature sensor+ * @param BattEnable to Enable log for battery sensor+ * @param LogInterval to Time (seconds) between log readings+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetLogMode(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password, LoggingForm form, StorageRule rule, bool Ext1Enable,+ bool Ext2Enable, bool TempEnable, bool BattEnable, uint16_t LogInterval)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_SETLOGMODE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.CommandCode = 0xA1;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.sl900A.dataLog = form;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.sl900A.rule = rule;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.Ext1Enable = Ext1Enable;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.Ext2Enable = Ext2Enable;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.TempEnable = TempEnable;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.BattEnable = BattEnable;+ tagop->u.gen2.u.custom.u.ids.u.setLogMode.LogInterval = LogInterval;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A EndLog operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_EndLog(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_ENDLOG;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.endLog.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.endLog.CommandCode = 0xA6;+ tagop->u.gen2.u.custom.u.ids.u.endLog.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.endLog.sl900A.level = level;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A initialize operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param level IDS passwordlevel+ * @param password IDS password+ * @param delayMode IDS delaymode+ * @param delayTime specifying IDS Delay time+ * @param timeEnable IDS timeenable+ * @param numberOfWords specifying Number of user bank memory words to reserve+ * @param BrokenWordPointer IDS broken word pointer+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_Initialize(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, uint8_t delayMode, + uint16_t delayTime, bool timeEnable, uint16_t numberOfWords, + uint8_t BrokenWordPointer)+{+ uint16_t mask = 0x1 << 1;++ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_INITIALIZE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.initialize.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.initialize.CommandCode = 0xAC;+ tagop->u.gen2.u.custom.u.ids.u.initialize.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.initialize.sl900A.level = level;++ if (TMR_GEN2_IDS_SL900A_DELAYMODE_TIMER == delayMode)+ { + uint16_t raw = 0;+ raw &= (uint16_t)~mask;+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.raw = raw;+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.Mode = (DelayMode)delayMode;+ }+ else+ {+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.raw |= mask;+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.Mode = (DelayMode)delayMode;+ }++ if (delayTime)+ {+ uint16_t maskDelayTime = 0xFFF << 4;+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.raw &= (uint16_t)~maskDelayTime;+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.raw |= (uint16_t)(delayTime << 4);+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.Time = delayTime;+ }+ mask = 0x1;+ if(timeEnable)+ {+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.raw |= mask;+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.IrqTimerEnable = timeEnable;+ }+ else+ {+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.raw &= (uint16_t)~mask;+ tagop->u.gen2.u.custom.u.ids.u.initialize.delayTime.IrqTimerEnable = timeEnable;+ }++ mask = 0x1FF;+ if (numberOfWords)+ {+ tagop->u.gen2.u.custom.u.ids.u.initialize.applicationData.raw &= (uint16_t)~mask;+ tagop->u.gen2.u.custom.u.ids.u.initialize.applicationData.raw |= (uint16_t)(numberOfWords << 7);+ tagop->u.gen2.u.custom.u.ids.u.initialize.applicationData.NumberOfWords = numberOfWords;+ }++ mask = 0x7;+ if (BrokenWordPointer)+ {+ tagop->u.gen2.u.custom.u.ids.u.initialize.applicationData.raw &= (uint16_t)~mask;+ tagop->u.gen2.u.custom.u.ids.u.initialize.applicationData.raw |= (uint16_t)(BrokenWordPointer);+ tagop->u.gen2.u.custom.u.ids.u.initialize.applicationData.BrokenWordPointer = BrokenWordPointer;+ }++ return TMR_SUCCESS;+}+++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A AcessFifo Status operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_AccessFifoStatus(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOSTATUS;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoStatus.status.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoStatus.status.CommandCode = 0xAF;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoStatus.status.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoStatus.status.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoStatus.status.operation = TMR_GEN2_IDS_SL900A_ACCESSFIFO_STATUS;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A AcessFifo Read operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ * @param readLength specify no of data to be read from fifo+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_AccessFifoRead(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, uint8_t readLength)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOREAD;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoRead.read.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoRead.read.CommandCode = 0xAF;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoRead.read.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoRead.read.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoRead.read.operation = TMR_GEN2_IDS_SL900A_ACCESSFIFO_READ;+ + if (readLength != (readLength & 0xF))+ {+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }+ tagop->u.gen2.u.custom.u.ids.u.accessFifoRead.length = readLength;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A AcessFifo Write operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param password IDS password+ * @param level IDS passwordlevel+ * @param payLoad specify data to be written into fifo+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_AccessFifoWrite(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, TMR_uint8List *payLoad)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOWRITE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoWrite.write.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoWrite.write.CommandCode = 0xAF;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoWrite.write.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoWrite.write.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.accessFifoWrite.write.operation = TMR_GEN2_IDS_SL900A_ACCESSFIFO_WRITE;+ + if (payLoad->len != (payLoad->len & 0xF))+ {+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }+ tagop->u.gen2.u.custom.u.ids.u.accessFifoWrite.payLoad = payLoad;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A StartLog operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param level IDS passwordlevel+ * @param password IDS password+ * @param timestamp pointer to TMR_TimeStructure (timestamp structure) + */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_StartLog(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, TMR_TimeStructure *timestamp)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_STARTLOG;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.startLog.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.startLog.CommandCode = 0xA7;+ tagop->u.gen2.u.custom.u.ids.u.startLog.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.startLog.sl900A.level = level;+ if (NULL == timestamp)+ {+ /** in case user not providing the time stamp+ * use current system time+ */+ return TMR_ERROR_TIMESTAMP_NULL;+ }+ + tagop->u.gen2.u.custom.u.ids.u.startLog.startTime = 0;+ tagop->u.gen2.u.custom.u.ids.u.startLog.startTime |= (uint32_t)((timestamp->tm_year - 2010) << 26);+ tagop->u.gen2.u.custom.u.ids.u.startLog.startTime |= (uint32_t)((timestamp->tm_mon) << 22);+ tagop->u.gen2.u.custom.u.ids.u.startLog.startTime |= (uint32_t)(timestamp->tm_mday << 17);+ tagop->u.gen2.u.custom.u.ids.u.startLog.startTime |= (uint32_t)(timestamp->tm_hour << 12);+ tagop->u.gen2.u.custom.u.ids.u.startLog.startTime |= (uint32_t)(timestamp->tm_min << 6);+ tagop->u.gen2.u.custom.u.ids.u.startLog.startTime |= (uint32_t)(timestamp->tm_sec);++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A GetBatteryLevel operation with the provided parameters.+ * @param tagop Pointer to the tagop structure to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param level IDS passwordlevel+ * @param password IDS password+ * @param type IDS batterytype+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetBatteryLevel(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, BatteryType type)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_GETBATTERYLEVEL;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.batteryLevel.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.batteryLevel.CommandCode = 0xAA;+ tagop->u.gen2.u.custom.u.ids.u.batteryLevel.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.batteryLevel.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.batteryLevel.batteryType = type;++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A Set Log Limits operation with+ * @param tagop Pointer to the tagop struture to initialize.+ * @param accessPassword Gen2 accessPassword+ * @param level IDS apsswordlevel+ * @param passowrd IDS password+ * @param logLimits pointer to IDS LogLimits+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetLogLimit(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password, LogLimits *logLimits)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_SETLOGLIMITS;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.setLogLimit.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.setLogLimit.CommandCode = 0xA2;+ tagop->u.gen2.u.custom.u.ids.u.setLogLimit.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.setLogLimit.sl900A.level = level;++ /**+ * LogLimit values are only 10 bit long,+ */+ if (0x03FF < logLimits->extremeLower)+ {+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE; + }++ tagop->u.gen2.u.custom.u.ids.u.setLogLimit.limit.extremeLower = logLimits->extremeLower;++ if (0x03FF < logLimits->lower)+ {+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }+ tagop->u.gen2.u.custom.u.ids.u.setLogLimit.limit.lower = logLimits->lower;++ if (0x03FF < logLimits->upper)+ {+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }+ tagop->u.gen2.u.custom.u.ids.u.setLogLimit.limit.upper = logLimits->upper;++ if (0x03FF < logLimits->extremeUpper)+ {+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }+ tagop->u.gen2.u.custom.u.ids.u.setLogLimit.limit.extremeUpper = logLimits->extremeUpper;++ return TMR_SUCCESS;++}++/**+ * Initialize the Gen2 IDS SL900A SetShelfLifeBlock0 with+ * @param block0 pointer to the TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock0,+ * @param tmax SetShelfLife Tmax+ * @param tmin SetShelfLife Tmin+ * @param tstd SetshelfLIfe Tstd;+ * @param ea SetshelfLife Ea;+ */ +TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_ShelfLifeBlock0(TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock0 *block0,+ uint8_t tmax, uint8_t tmin, uint8_t tstd, uint8_t ea)+{+ uint64_t mask;+ block0->raw = 0;++ /* Copying the tmax to block0 raw value */ + {+ block0->Tmax = tmax;+ mask = TMR_makeBitMask(24, 8);+ block0->raw &= ~mask;+ block0->raw |= (uint32_t)((uint32_t)tmax << 24);+ }++ /* Copying the tmin to block0 raw value */ + {+ block0->Tmin = tmin;+ mask = TMR_makeBitMask(16, 8);+ block0->raw &= ~mask;+ block0->raw |= (uint32_t)((uint32_t)tmin << 16);+ }++ /* Copying the tstd to block0 raw value */ + {+ block0->Tstd = tstd;+ mask = TMR_makeBitMask(8, 8);+ block0->raw &= ~mask;+ block0->raw |= (uint32_t)((uint32_t)tstd << 8);+ }++ /* Copying the ea to block0 raw value */ + {+ block0->Ea = ea;+ mask = TMR_makeBitMask(0, 8);+ block0->raw &= ~mask;+ block0->raw |= (uint32_t)((uint32_t)ea << 0);+ }++ return TMR_SUCCESS;+}+++/**+ * Initialize the Gen2 IDS SL900A SetShelfLifeBlock1 with+ * @param block1 pointer to the TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock1,+ * @param slinit SetShelfLife SLinit+ * @param tint SetShelfLife Tint+ * @param sensorid SetshelfLIfe sensorID+ * @param negative SetshelfLife enableNegative+ * @param algorithm SetShelfLife algorithmEnable+ */ +TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_ShelfLifeBlock1(TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock1 *block1,+ uint16_t slinit, uint16_t tint, uint8_t sensorid,+ bool negative, bool algorithm)+{+ uint64_t mask;+ block1->raw = 0;++ /* Copying the SLinit value to block1 raw value */+ {+ block1->SLinit = slinit;+ mask = TMR_makeBitMask(16, 16);+ block1->raw &= ~mask;+ block1->raw |= (uint32_t)((uint32_t)slinit << 16);+ }++ /* Copying the tint value to block1 raw value */+ {+ block1->Tint = tint;+ mask = TMR_makeBitMask(6, 10);+ block1->raw &= ~mask;+ block1->raw |= (uint32_t)((uint32_t)tint << 6);+ }++ /* Copying the sensorID to block1 raw value */+ {+ block1->sensorID = sensorid;+ mask = TMR_makeBitMask(4, 2);+ block1->raw &= ~mask;+ block1->raw |= (uint32_t)((uint32_t)sensorid << 4);+ }++ /* Copying the enableNegative value to block1 raw value */+ {+ block1->enableNegative = negative;+ mask = TMR_makeBitMask(3, 1);+ block1->raw &= ~mask;+ block1->raw |= (uint32_t)(negative << 3);+ }++ /* Copying the algorithemEnable value to block1 raw value */+ {+ block1->algorithmEnable = algorithm;+ mask = TMR_makeBitMask(2, 1);+ block1->raw &= ~mask;+ block1->raw |= (uint32_t)(negative << 2);+ }++ /* Setting the RFU bytes to zero */+ block1->rfu = 0;+ mask = TMR_makeBitMask(0, 2);+ block1->raw &= ~mask;+ block1->raw |= (uint32_t)(0 << 0);++ return TMR_SUCCESS;+}++/**+ * Initialize a TMR_TagOp as a Gen2 Ids SL900A Set Shelf Life operation with+ * @param tagop pointer to the tagop struture to setShelfLife+ * @param accessPassword Gen2 accessPassword+ * @param level IDS passwordlevel+ * @param password IDS password+ * @param block0 pointer to the TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock0,+ * @param block1 pointer to the TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock1,+ */+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetShelfLife(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password,TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock0 *block0,+ TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock1 *block1)+{+ tagop->type = TMR_TAGOP_GEN2_IDS_SL900A_SETSHELFLIFE;+ tagop->u.gen2.u.custom.chipType = TMR_SR_GEN2_IDS_SL900A_SILICON;+ tagop->u.gen2.u.custom.u.ids.u.setShelfLife.AccessPassword = accessPassword;+ tagop->u.gen2.u.custom.u.ids.u.setShelfLife.CommandCode = 0xAB;+ tagop->u.gen2.u.custom.u.ids.u.setShelfLife.Password = password;+ tagop->u.gen2.u.custom.u.ids.u.setShelfLife.sl900A.level = level;+ tagop->u.gen2.u.custom.u.ids.u.setShelfLife.shelfLifeBlock0 = block0;+ tagop->u.gen2.u.custom.u.ids.u.setShelfLife.shelfLifeBlock1 = block1;++ return TMR_SUCCESS;+}++/**+ * Initialize TMR_UserConfigOp to set the default category.+ * @param config pointer to the TMR_UserConfigOp structure to initialize+ * @param op user configuration opeartion (save, restore or clear)+ */+TMR_Status+TMR_init_UserConfigOp(TMR_SR_UserConfigOp *config, TMR_SR_UserConfigOperation op)+{+ config->category = TMR_SR_ALL;+ config->op = op;++ return TMR_SUCCESS;+}++/**+ * Initialize TMR_NXP_ConfigWord to set the default value.+ * If the instance of the above structure is created as 'static',+ * then no need to call this constructor.+ * @param configWord Instance of TMR_NXP_ConfigWord+ */+TMR_Status +TMR_init_GEN2_NXP_G2I_ConfigWord(TMR_NXP_ConfigWord *configWord)+{+ configWord->data = 0x0000;+ return TMR_SUCCESS;+}++/**+ * Initialize TMR_Monza4_ControlByte to set the default value to 0.+ * If the instance of the above structure is created as 'static' or+ * if it is already initialized to 0, then no need to call this constructor.+ * @param controlByte Instance of TMR_Monza4_ControlByte+ */+TMR_Status+TMR_init_GEN2_Impinj_Monza4_ControlByte(TMR_Monza4_ControlByte *controlByte)+{+ controlByte->data = 0x00;+ return TMR_SUCCESS;+}++/**+ * Initialize TMR_Monza4_Payload to set the default value to 0.+ * If the instance of the above structure is created as 'static' or+ * if it is already initialized to 0, then no need to call this constructor.+ * @param payload Instance of TMR_Monza4_Payload+ */+TMR_Status+TMR_init_GEN2_Impinj_Monza4_Payload(TMR_Monza4_Payload *payload)+{+ payload->data = 0x0000;+ return TMR_SUCCESS;+}++/**+ * Helper function to update or modifying the sfe parameters+ */+TMR_Status+TMR_update_GEN2_IDS_SL900A_SfeParameters(TMR_TagOp_GEN2_IDS_SL900A_SfeParameters *sfe)+{+ uint64_t mask;+ /* Update the raw value as per the field set by the user */+ switch (sfe->type)+ {+ case TMR_GEN2_IDS_SL900A_SFE_RANG:+ {+ mask = TMR_makeBitMask(11, 5);+ sfe->raw &= ~mask;+ sfe->raw |= ((uint64_t)(((uint64_t)sfe->Rang) << 11));++ break;+ }+ case TMR_GEN2_IDS_SL900A_SFE_SETI:+ {+ mask = TMR_makeBitMask(6, 5);+ sfe->raw &= ~mask;+ sfe->raw |= ((uint64_t)(((uint64_t)sfe->Seti) << 6));++ break;+ }+ case TMR_GEN2_IDS_SL900A_SFE_EXT1:+ {+ mask = TMR_makeBitMask(4, 2);+ sfe->raw &= ~mask;+ sfe->raw |= ((uint64_t)(((uint64_t)sfe->Ext1) << 4));++ break;+ }+ case TMR_GEN2_IDS_SL900A_SFE_EXT2:+ {+ mask = TMR_makeBitMask(3, 1);+ sfe->raw &= ~mask;+ sfe->raw |= ((uint64_t)(((uint64_t)sfe->Ext2) << 3));++ break;+ }+ case TMR_GEN2_IDS_SL900A_SFE_AUTORANGEDISABLE:+ {+ mask = TMR_makeBitMask(2, 1);+ sfe->raw &= ~mask;+ sfe->raw |= ((uint64_t)(((uint64_t)sfe->AutorangeDisable) << 2));++ break;+ }+ case TMR_GEN2_IDS_SL900A_SFE_VERIFYSENSORID:+ {+ mask = TMR_makeBitMask(0, 2);+ sfe->raw &= ~mask;+ sfe->raw |= ((uint64_t)(((uint64_t)sfe->VerifySensorID) << 0));++ break;+ }+ default: + break;+ }+ return TMR_SUCCESS;+}++/**+ * Helper function to update or modifying the calibration Data+ */+TMR_Status+TMR_update_GEN2_IDS_SL900A_CalibrationData(TMR_TagOp_GEN2_IDS_SL900A_CalibrationData *cal)+{+ uint64_t mask;+ /* Update the raw value as per the field set by the user */+ switch (cal->type)+ {+ case TMR_GEN2_IDS_SL900A_CALIBRATION_COARSE1:+ {+ mask = TMR_makeBitMask(48, 3);+ cal->raw &= ~mask;+ cal->raw |= ((uint64_t)(((uint64_t)cal->Coarse1) << 48));+ cal->raw = cal->raw;++ break;+ }+ case TMR_GEN2_IDS_SL900A_CALIBRATION_COARSE2:+ {+ mask = TMR_makeBitMask(40, 3);+ cal->raw &= ~mask;+ cal->raw |= ((uint64_t)(((uint64_t)cal->Coarse2) << 40));+ cal->raw = cal->raw;++ break;+ }+ case TMR_GEN2_IDS_SL900A_CALIBRATION_GNDSWITCH:+ {+ mask = TMR_makeBitMask(39, 1);+ cal->raw &= ~mask;+ cal->raw |= ((uint64_t)(((uint64_t)cal->GndSwitch) << 39));+ cal->raw = cal->raw;++ break;+ }+ case TMR_GEN2_IDS_SL900A_CALIBRATION_SELP12:+ {+ mask = TMR_makeBitMask(37, 2);+ cal->raw &= ~mask;+ cal->raw |= ((uint64_t)(((uint64_t)cal->Selp12) << 37));+ cal->raw = cal->raw;++ break;+ }+ case TMR_GEN2_IDS_SL900A_CALIBRATION_DF:+ {+ mask = TMR_makeBitMask(24, 8);+ cal->raw &= ~mask;+ cal->raw |= ((uint64_t)(((uint64_t)cal->Df) << 24));+ cal->raw = cal->raw;++ break;+ }+ case TMR_GEN2_IDS_SL900A_CALIBRATION_SWEXTEN:+ {+ mask = TMR_makeBitMask(23, 1);+ cal->raw &= ~mask;+ cal->raw |= ((uint64_t)(((uint64_t)cal->SwExtEn) << 23));+ cal->raw = cal->raw;++ break;+ }+ case TMR_GEN2_IDS_SL900A_CALIBRATION_SELP22:+ {+ mask = TMR_makeBitMask(21, 2);+ cal->raw &= ~mask;+ cal->raw |= ((uint64_t)(((uint64_t)cal->Selp22) << 21));+ cal->raw = cal->raw;++ break;+ }+ case TMR_GEN2_IDS_SL900A_CALIBRATION_IRLEV:+ {+ mask = TMR_makeBitMask(19, 2);+ cal->raw &= ~mask;+ cal->raw |= ((uint64_t)(((uint64_t)cal->Irlev) << 19));+ cal->raw = cal->raw;++ break;+ }+ case TMR_GEN2_IDS_SL900A_CALIBRATION_EXCRES:+ {+ mask = TMR_makeBitMask(2, 1);+ cal->raw &= ~mask;+ cal->raw |= ((uint64_t)(((uint64_t)cal->ExcRes) << 2));+ cal->raw = cal->raw;++ break;+ }+ default: + break;+ }+ return TMR_SUCCESS;+}++/**+ * Helper function to set the calibration Data+ */+TMR_Status+TMR_init_GEN2_IDS_SL900A_CalibrationData(uint8_t byte[7], TMR_TagOp_GEN2_IDS_SL900A_CalibrationData *cal)+{+ if (NULL != byte)+ {+ /**+ * ToU64 requires 8 bytes of input, but CalibrationData is only 7 bytes long+ * Create a temporary array to provide the necessary padding.+ */+ uint8_t tmp[] = {0,0,0,0,0,0,0,0,};+ memcpy(tmp+1, byte, 7);+ cal->raw = (uint64_t)(0+ | ((uint64_t)(tmp[ 0]) << 56)+ | ((uint64_t)(tmp[ 1]) << 48)+ | ((uint64_t)(tmp[ 2]) << 40)+ | ((uint64_t)(tmp[3]) << 32)+ | ((uint64_t)(tmp[4]) << 24)+ | ((uint64_t)(tmp[5]) << 16)+ | ((uint64_t)(tmp[ 6]) << 8)+ | ((uint64_t)(tmp[7]) << 0));++ cal->raw &= (uint64_t)0x00FFFFFFFFFFFFFFLL;+ }++ return TMR_SUCCESS;+}++/**+ * Helper function to set the sfe parameters+ */+TMR_Status+TMR_init_GEN2_IDS_SL900A_SfeParameters(uint8_t byte[2], TMR_TagOp_GEN2_IDS_SL900A_SfeParameters *sfe)+{+ /* Create SFEParameters object from raw 2-byte reply */+ int hi, lo;+ hi = (uint16_t)(byte[0]) << 8;+ lo = (uint16_t)(byte[1]);+ sfe->raw = (hi | lo);++ return TMR_SUCCESS;+}++/**+ * Initialize TMR_GEN2_SL900A_SensorReading to Get Sensor Value response.+ * @param reply instance of TMR_uint8List+ * @param sensor instance of TMR_TagOp_GEN2_IDS_SL900A_SensorReading,+ * response for sl900A getSensorvalue command.+ */+TMR_Status+TMR_init_GEN2_IDS_SL900A_SensorReading(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_SensorReading *sensor)+{ ++ if (2 != reply->len)+ {+ /* Sensor Reading value must be exactly 2 bytes long */+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }+ sensor->reply = reply->list[0] << 8 | reply->list[1];+ sensor->Raw = sensor->reply;+ sensor->ADError = (((sensor->reply >> 15) & 0x1) != 0);+ sensor->RangeLimit = (uint8_t) ((sensor->reply >> 10) & 0x1F);+ sensor->Value = ((sensor->reply >> 0 ) & 0x3FF);++ return TMR_SUCCESS;+}++/**+ * Initialize TMR_GEN2_SL900A_CalSfe to Get getcalibration response.+ * @param reply instance of TMR_uint8List+ * @param calSfe instance of TMR_TagOp_GEN2_IDS_SL900A_CalSfe,+ * response for CalibrationData and SfeParameters.+ */+TMR_Status+TMR_init_GEN2_IDS_SL900A_CalSfe(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_CalSfe *calSfe)+{+ uint64_t mask;+ TMR_init_GEN2_IDS_SL900A_CalibrationData(reply->list, &calSfe->Cal);+ TMR_init_GEN2_IDS_SL900A_SfeParameters(reply->list + 7, &calSfe->Sfe);++ mask = TMR_makeBitMask(51, 5);+ calSfe->Cal.Ad1 = (uint8_t)((calSfe->Cal.raw & mask) >> 51);++ mask = TMR_makeBitMask(48, 3);+ calSfe->Cal.Coarse1 = (uint8_t)((calSfe->Cal.raw & mask) >> 48);++ mask = TMR_makeBitMask(43, 5);+ calSfe->Cal.Ad2 = (uint8_t)((calSfe->Cal.raw & mask) >> 43);++ mask = TMR_makeBitMask(40, 3);+ calSfe->Cal.Coarse2 = (uint8_t)((calSfe->Cal.raw & mask) >> 40);++ mask = TMR_makeBitMask(39, 1);+ calSfe->Cal.GndSwitch = (uint8_t)((calSfe->Cal.raw & mask) >> 39);++ mask = TMR_makeBitMask(37, 2);+ calSfe->Cal.Selp12 = (uint8_t)((calSfe->Cal.raw & mask) >> 37);++ mask = TMR_makeBitMask(32, 5);+ calSfe->Cal.Adf = (uint8_t)((calSfe->Cal.raw & mask) >> 32);++ mask = TMR_makeBitMask(24, 8);+ calSfe->Cal.Df = (uint8_t)((calSfe->Cal.raw & mask) >> 24);++ mask = TMR_makeBitMask(23, 1);+ calSfe->Cal.SwExtEn = (uint8_t)((calSfe->Cal.raw & mask) >> 23);++ mask = TMR_makeBitMask(21, 2);+ calSfe->Cal.Selp22 = (uint8_t)((calSfe->Cal.raw & mask) >> 21);++ mask = TMR_makeBitMask(19, 2);+ calSfe->Cal.Irlev = (uint8_t)((calSfe->Cal.raw & mask) >> 19);++ mask = TMR_makeBitMask(14, 5);+ calSfe->Cal.RingCal = (uint8_t)((calSfe->Cal.raw & mask) >> 14);++ mask = TMR_makeBitMask(7, 7);+ calSfe->Cal.OffInt = (uint8_t)((calSfe->Cal.raw & mask) >> 7);++ mask = TMR_makeBitMask(3, 4);+ calSfe->Cal.Reftc = (uint8_t)((calSfe->Cal.raw & mask) >> 3);++ mask = TMR_makeBitMask(2, 1);+ calSfe->Cal.ExcRes = (uint8_t)((calSfe->Cal.raw & mask) >> 2);++ mask = TMR_makeBitMask(0, 2);+ calSfe->Cal.RFU = (uint8_t)((calSfe->Cal.raw & mask) >> 0);++ mask = TMR_makeBitMask(11, 5);+ calSfe->Sfe.Rang = (uint8_t)((calSfe->Sfe.raw & mask) >> 11);++ mask = TMR_makeBitMask(6, 5);+ calSfe->Sfe.Seti = (uint8_t)((calSfe->Sfe.raw & mask) >> 6);++ mask = TMR_makeBitMask(4, 2);+ calSfe->Sfe.Ext1 = (uint8_t)((calSfe->Sfe.raw & mask) >> 4);++ mask = TMR_makeBitMask(3, 1);+ calSfe->Sfe.Ext2 = (uint8_t)((calSfe->Sfe.raw & mask) >> 3);++ mask = TMR_makeBitMask(2, 1);+ calSfe->Sfe.AutorangeDisable = (uint8_t)((calSfe->Sfe.raw & mask) >> 2);++ mask = TMR_makeBitMask(0, 2);+ calSfe->Sfe.VerifySensorID = (uint8_t)((calSfe->Sfe.raw & mask) >> 0);++ return TMR_SUCCESS;+}++/**+ * Initialize TMR_GEN2_SL900A_BatteryLevelReading to get the getBatteryLevel response.+ * @param reply instance of TMR_uint8List+ * @param battery instance of TMR_TagOp_GEN2_IDS_SL900A_BatteryLevelReading,+ * the reply structure of getBatteryLevel+ */ ++TMR_Status+TMR_init_GEN2_IDS_SL900A_BatteryLevelReading(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_BatteryLevelReading *battery)+{ ++ if (2 != reply->len)+ {+ /* Sensor Reading value must be exactly 2 bytes long */+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }+ battery->reply = (uint16_t)(reply->list[0] << 8 | reply->list[1]);+ battery->ADError = (bool)(((battery->reply >> 15) & 0x1) != 0);+ battery->BatteryType = (uint8_t) ((battery->reply >> 14) & 0x1);+ battery->Value = (uint16_t)((battery->reply >> 0 ) & 0x3FF);++ return TMR_SUCCESS;+}+/**+ * Initialize TMR_GEN2_SL900A_FifoStatus to Get status of fifo reply+ * @param statusReply instance of TMR_uint8List+ * @param status instance of TMR_TagOp_GEN2_IDS_SL900A_FifoStatus,+ * the reply structure of sl900A fifistatus command. + */+TMR_Status+TMR_init_GEN2_IDS_SL900A_FifoStatus(TMR_uint8List *statusReply, TMR_TagOp_GEN2_IDS_SL900A_FifoStatus *status)+{++ uint8_t reply;+ if (1 != statusReply->len)+ {+ /* Fifo Status value must be exactly 1 byte long */+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }+ status->raw = statusReply->list[0];+ reply = statusReply->list[0];+ status->fifoBusy = (0 != ((reply >> 7) & 1));+ status->dataReady = (0 != ((reply >> 6) & 1));+ status->noData = (0 != ((reply >> 5) & 1));+ status->numValidBytes = (uint8_t)(reply & 0xF);++ return TMR_SUCCESS;+}++/**+ * Initialize TMR_GEN2_SL900A_LogState to Get get log state Value response.+ * @param reply instance of TMR_uint8List+ * @param log instance of TMR_TagOp_GEN2_IDS_SL900A_LogState,+ * sl900A logging parameters.+ */+TMR_Status+TMR_init_GEN2_IDS_SL900A_LogState(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_LogState *log)+{ ++ uint32_t offset = 0;+ uint32_t raw; + if ((9 != reply->len) && (20 != reply->len))+ {+ /* GetLogState replies must be 9 or 21 bytes in length */+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }++ if (9 == reply->len)+ {+ log->limitCount.extremeLower = reply->list[offset + 0]; + log->limitCount.lower = reply->list[offset + 1];+ log->limitCount.upper = reply->list[offset + 2];+ log->limitCount.extremeUpper = reply->list[offset + 3];++ offset += 4;+ raw = TMR_byteArrayToInt(reply->list, offset);+ log->statStatus.MeasurementAddressPointer = (uint16_t)((raw >> 22) & 0x1FF);+ log->statStatus.NumMemReplacements = (uint8_t) ((raw >> 16) & 0x3F);+ log->statStatus.NumMeasurements = (uint16_t) ((raw >> 1) & 0x7FFF);+ log->statStatus.Active = (bool)(0 != (raw & 0x1));+ offset += 4;+ }+ if (20 == reply->len)+ {+ /* @todo Fully support shelf life arguments. For now, just skip over them */+ offset += 8;+ offset += 4;+ }+ raw = TMR_byteArrayToInt(reply->list, offset);+ log->statFlag.Active = (bool)(0 != ((raw >> 7) & 1));+ log->statFlag.Full = (bool)(0 != ((raw >> 6) & 1));+ log->statFlag.Overwritten = (bool)(0 != ((raw >> 5) & 1));+ log->statFlag.ADError = (bool) (0 != ((raw >> 4) & 1));+ log->statFlag.LowBattery = (bool) (0 != ((raw >> 3) & 1));+ log->statFlag.ShelfLifeLow = (bool) (0 != ((raw >> 2) & 1));+ log->statFlag.ShelfLifeHigh = (bool)(0 != ((raw >> 1) & 1));+ log->statFlag.ShelfLifeExpired = (bool)(0 != ((raw >> 0) & 1));+ + return TMR_SUCCESS;+}++/**+ * Initialize TMR_TagOp_GEN2_IDS_SL900A_MeasurementSetupData to Get measurment setup data + * Value response.+ * @param reply instance of TMR_uint8List+ * @param measurement instance of TMR_TagOp_GEN2_IDS_SL900A_MeasurementSetupData,+ * response structure for sl900A getMeasurementSetupData command.+ */+TMR_Status+TMR_init_GEN2_IDS_SL900A_MeasurementSetupData(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_MeasurementSetupData *measurement)+{+ if(16 != reply->len)+ {+ /* MeasurementSetupData value must be exactly 16 byte long */+ return TMR_ERROR_MSG_INVALID_PARAMETER_VALUE;+ }++ memcpy(measurement->Raw, reply->list, reply->len);++ //get the start time+ {+ uint32_t temp;+ temp = TMR_byteArrayToInt(reply->list, 0);+ measurement->startTime.tm_year = (int)(2010+((temp >> 26) & 0x3F));+ measurement->startTime.tm_mon = (int)((temp >> 22) & 0xF);+ measurement->startTime.tm_mday = (int)((temp >> 17) & 0x1F);+ measurement->startTime.tm_hour = (int)((temp >> 12) & 0x1F);+ measurement->startTime.tm_min = (int)((temp >> 6) & 0x3F);+ measurement->startTime.tm_sec = (int)((temp >> 0) & 0x3F);+ }+ //get the log limits+ {+ int offset = 4;+ uint64_t value = 0;+ /* LogLimits value is of 40 bits+ * extract that from the response+ */+ value = TMR_byteArrayToLong(reply->list, offset);+ /* + * Indivisual field in LogLimits is of 10 bits+ * masking each of them to a 16 bit value for convinence+ */+ measurement->loglimit.extremeLower = (uint16_t) ((value >> 54) & 0x03FF);+ measurement->loglimit.lower = (uint16_t) ((value >> 44) & 0x03FF);+ measurement->loglimit.upper = (uint16_t) ((value >> 34) & 0x03FF);+ measurement->loglimit.extremeUpper = (uint16_t) ((value >> 24) & 0x03FF);+ }+ //get log mode+ {+ uint8_t temp = (uint8_t)reply->list[9];+ measurement->logModeData.Raw = temp;+ measurement->logModeData.Form = (LoggingForm)((temp >> 5) & 7);+ measurement->logModeData.Storage = (StorageRule)(((temp >> 4) & 1));+ measurement->logModeData.Ext1Enable = (0 != ((temp >> 3) & 1));+ measurement->logModeData.Ext2Enable = (0 != ((temp >> 2) & 1));+ measurement->logModeData.TempEnable = (0 != ((temp >> 1) & 1));+ measurement->logModeData.BattEnable = (0 != ((temp>> 0) & 1));+ }+ //log interval+ {+ uint16_t temp;+ temp = TMR_byteArrayToShort(reply->list, 10);+ temp = ((temp >> 1) & 0x0001);+ measurement->logInterval = temp;+ }+ //delay time+ {+ uint16_t temp;+ temp = TMR_byteArrayToShort(reply->list, 12);+ measurement->delyTime.raw = temp;+ measurement->delyTime.Mode = (0 == ((temp >> 1) & 0x1)) ? TMR_GEN2_IDS_SL900A_DELAYMODE_TIMER+ : TMR_GEN2_IDS_SL900A_DELAYMODE_EXTSWITCH;+ measurement->delyTime.Time = (uint16_t)((temp >> 4) & 0xFFF);+ measurement->delyTime.IrqTimerEnable = (0 != (temp & 0x1));+ }+ //application data+ {+ uint16_t temp;+ temp = TMR_byteArrayToShort(reply->list, 14);+ measurement->addData.raw = temp;+ measurement->addData.NumberOfWords = (uint16_t)((temp >> 7) & 0x1FF);+ measurement->addData.BrokenWordPointer = (uint8_t)(temp & 0x7);+ }++ return TMR_SUCCESS;+}++#endif /* TMR_ENABLE_GEN2_CUSTOM_TAGOPS */+void+TMR_paramProbe(struct TMR_Reader *reader, TMR_Param key)+{++ /* buf is at least as large as the largest parameter, with all values 0+ * (NULL pointers and 0 lengths).+ */+ uint32_t buf[] = {0, 0, 0, 0, 0, 0, 0, 0};+ TMR_Status ret;++ ret = TMR_paramGet(reader, key, &buf);+ if (TMR_SUCCESS == ret)+ {+ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ BITSET(reader->u.serialReader.paramPresent, key);+ BITSET(reader->u.serialReader.paramConfirmed, key);+ }+#ifdef TMR_ENABLE_LLRP_READER+ if (TMR_READER_TYPE_LLRP == reader->readerType)+ {+ BITSET(reader->u.llrpReader.paramPresent, key);+ BITSET(reader->u.llrpReader.paramConfirmed, key);+ }+#endif+ }+}+++/**+ * Get a list of the parameters available+ * @reader pointer of reader object+ * @key pointer of TMR_Param+ * @len pointer to uint32_t+ */++TMR_Status+TMR_paramList(struct TMR_Reader *reader, TMR_Param *keys, uint32_t *len)+{+ int i, count, max;++ max = *len;+ count = 0;+ for (i = TMR_PARAM_MIN; i <= TMR_PARAM_MAX ; i++)+ {+ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ if (0 == BITGET(reader->u.serialReader.paramConfirmed, i))+ {+ /* Fix me */+ TMR_paramProbe(reader, (TMR_Param)i);+ }++ if (BITGET(reader->u.serialReader.paramPresent, i))+ {+ if (count < max)+ keys[count] = (TMR_Param)i;+ count++;+ }+ }+#ifdef TMR_ENABLE_LLRP_READER+ if (TMR_READER_TYPE_LLRP == reader->readerType)+ {+ if (0 == BITGET(reader->u.llrpReader.paramConfirmed, i))+ {+ TMR_paramProbe(reader, i);+ }++ if (BITGET(reader->u.llrpReader.paramPresent, i))+ {+ if (count < max)+ keys[count] = i;+ count++;+ }+ }+#endif+ }++ *len = count;++ return TMR_SUCCESS;+}++ TMR_Status+TMR_receiveAutonomousReading(struct TMR_Reader *reader, TMR_TagReadData *trd, TMR_Reader_StatsValues *stats)+{+ TMR_Status ret;++ ret = TMR_SUCCESS;++ if (TMR_READER_TYPE_SERIAL != reader->readerType)+ {+ /* Currently supporting only serial reader */+ return TMR_ERROR_UNSUPPORTED;+ }++#ifdef TMR_ENABLE_BACKGROUND_READS+ {+ /**+ * * * create the thread+ * * */+ ret = pthread_create(&reader->autonomousBackgroundReader, NULL,+ do_background_receiveAutonomousReading, reader);+ if (0 != ret)+ {+ return TMR_ERROR_NO_THREADS;+ }+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);+ pthread_detach(reader->autonomousBackgroundReader);+ }+#else+ {+ /* This will add support for non thread platform */+ ret = TMR_SR_receiveAutonomousReading(reader, trd, stats);+ }+#endif++ return ret;+}+
+ cbits/api/tm_reader.h view
@@ -0,0 +1,1289 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TM_READER_H+#define _TM_READER_H+/**+ * @file tm_reader.h+ * @brief Mercury API Reader Interface+ * @author Brian Fiegel+ * @date 4/18/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.+ */++/* Due to incompatibilities between winsock.h and winsock2.h (plus interactions+ * with windows.h) you're in for a storm of "redefinition" errors if you don't+ * include winsock2.h first.+ * + * This is surprisingly hard, because lots of other headers include winsock.h+ * themselves. So include winsock2.h as early as possible.+ */+#if defined(WIN32) || defined(WINCE)+#include <winsock2.h>+#endif++#include "tm_config.h"++/**+ * TMR_ENABLE_JNI_SERIAL_READER_ONLY is used for building JNI project, and is defined from+ * Makefile.jni+ **/+#if !defined(TMR_ENABLE_SERIAL_READER_ONLY) && !defined(TMR_ENABLE_JNI_SERIAL_READER_ONLY) && defined(TMR_ENABLE_LLRP_TRANSPORT)+#define TMR_ENABLE_LLRP_READER+#endif++#ifdef TMR_ENABLE_BACKGROUND_READS+#include <pthread.h>+#include <semaphore.h>+#endif++typedef struct TMR_Reader TMR_Reader;++#include "tmr_types.h"+#include "tmr_status.h"++#include "tmr_gpio.h"+#include "tmr_params.h"+#include "tmr_read_plan.h"+#include "tmr_tag_auth.h"+#include "tmr_tag_data.h"+#include "tmr_tag_lock_action.h"+#include "tmr_tag_protocol.h"+#include "tmr_tagop.h"++#include "tmr_serial_reader.h"+#ifdef TMR_ENABLE_LLRP_READER+#include "tmr_llrp_reader.h"+#endif++#ifdef __cplusplus+extern "C" {+#endif+++#ifndef DOXYGEN_IGNORE+typedef TMR_Status (*TMR_TransportNativeInit)(TMR_SR_SerialTransport *transport, TMR_SR_SerialPortNativeContext *context,+ const char *device);++typedef struct TMR_readParams+{+#if defined(TMR_ENABLE_BACKGROUND_READS)|| defined(SINGLE_THREAD_ASYNC_READ)+ uint32_t asyncOnTime;+ uint32_t asyncOffTime;+#endif+ TMR_ReadPlan defaultReadPlan;+ TMR_ReadPlan *readPlan;+} TMR_readParams;++typedef struct TMR_tagOpParams+{+ uint8_t antenna;+ TMR_TagProtocol protocol;+}TMR_tagOpParams;++typedef enum TMR_ReaderType+{+ TMR_READER_TYPE_INVALID,+ TMR_READER_TYPE_RQL,+ TMR_READER_TYPE_SERIAL,+ TMR_READER_TYPE_LLRP,+} TMR_ReaderType;++typedef enum TMR_ReadState+{+ TMR_READ_STATE_IDLE,+ TMR_READ_STATE_STARTING,+ TMR_READ_STATE_STARTED,+ TMR_READ_STATE_ACTIVE,+ TMR_READ_STATE_DONE,+} TMR_ReadState;+++#endif /* DOXYGEN_IGNORE */++/**+ * Reader Stats Flag Enum+ */+typedef enum TMR_Reader_StatsFlag+{+ TMR_READER_STATS_FLAG_NONE = 0x00,+ /** Total time the port has been transmitting, in milliseconds. Resettable */+ TMR_READER_STATS_FLAG_RF_ON_TIME = (1 << 0),+ /** Noise floor with the TX on for the antennas were last configured for searching */+ TMR_READER_STATS_FLAG_NOISE_FLOOR_SEARCH_RX_TX_WITH_TX_ON = (1 << 6),+ /** Current frequency in units of Khz */+ TMR_READER_STATS_FLAG_FREQUENCY = (1 << 7),+ /** Current temperature of the device in units of Celsius */+ TMR_READER_STATS_FLAG_TEMPERATURE = (1 << 8),+ /** Current antenna */+ TMR_READER_STATS_FLAG_ANTENNA_PORTS = (1 << 9),+ /** Current protocol */ + TMR_READER_STATS_FLAG_PROTOCOL = (1 << 10),+ /** Current connected antennas */+ TMR_READER_STATS_FLAG_CONNECTED_ANTENNAS = (1 << 11),+ /* ALL */+ TMR_READER_STATS_FLAG_ALL = (TMR_READER_STATS_FLAG_RF_ON_TIME |+ TMR_READER_STATS_FLAG_NOISE_FLOOR_SEARCH_RX_TX_WITH_TX_ON |+ TMR_READER_STATS_FLAG_TEMPERATURE |+ TMR_READER_STATS_FLAG_PROTOCOL |+ TMR_READER_STATS_FLAG_ANTENNA_PORTS |+ TMR_READER_STATS_FLAG_FREQUENCY |+ TMR_READER_STATS_FLAG_CONNECTED_ANTENNAS),+}TMR_Reader_StatsFlag;++/**+ * Per Antenna stats+ */+typedef struct TMR_StatsPerAntennaValues+{+ /** Antenna number */+ uint8_t antenna;+ /** Current RF on time (since start of search) (milliseconds) */+ uint32_t rfOnTime;+ /** Noise Floor (TX on, all connected antennas) (dBm) */+ int8_t noiseFloor;+} TMR_StatsPerAntennaValues;++/**+ * Object to hold the per antenna stats+ */+typedef struct TMR_StatsPerAntennaValuesList+{+ TMR_StatsPerAntennaValues *list;+ uint16_t max;+ uint16_t len;+} TMR_StatsPerAntennaValuesList;++/**+ * This object is returned from TMR_cmdGetReaderStats+ */+typedef struct TMR_Reader_StatsValues+{+ TMR_Reader_StatsFlag valid;+ /** Current temperature (degrees C) */+ int8_t temperature;+ /** Current tag protocol */+ TMR_TagProtocol protocol;+ /** Current antenna */+ uint16_t antenna;+ /** Current RF carrier frequency (KHZ) */+ uint32_t frequency;+ /** Current connected antennas */+ TMR_uint8List connectedAntennas;+ uint8_t _connectedAntennasStorage[TMR_SR_MAX_ANTENNA_PORTS];+ /** Per-antenna values */+ TMR_StatsPerAntennaValuesList perAntenna;+ TMR_StatsPerAntennaValues _perAntStorage[TMR_SR_MAX_ANTENNA_PORTS];+}TMR_Reader_StatsValues;++/** Type of functions to be registered as read callbacks */+typedef void (*TMR_ReadListener)(TMR_Reader *reader, const TMR_TagReadData *t,+ void *cookie);+/**+ * User-allocated structure containing the callback pointer and the+ * value to pass to that callback.+ */+typedef struct TMR_ReadListenerBlock+{+ /** Pointer to callback function */+ TMR_ReadListener listener;+ /** Value to pass to callback function */+ void *cookie;+ /** @private */+ struct TMR_ReadListenerBlock *next;+} TMR_ReadListenerBlock;++/** Type of functions to be registered as tagauth request callbacks + * @param reader Reader object+ * @param trd TagReadData object+ * @param cookie Arbitrary data structure to be passed to callback+ * @param auth [OUTPUT] Tag authentication value to initialize based on inputs+ */+typedef void (*TMR_AuthReqListener)(TMR_Reader *reader, const TMR_TagReadData *trd,+ void *cookie, TMR_TagAuthentication *auth);+/**+ * User-allocated structure containing the callback pointer and the+ * value to pass to that callback.+ */+typedef struct TMR_AuthReqListenerBlock+{+ /** Pointer to callback function */+ TMR_AuthReqListener listener;+ /** Value to pass to callback function */+ void *cookie;+ /** @private */+ struct TMR_AuthReqListenerBlock *next;+} TMR_AuthReqListenerBlock;++/** Type of functions to be registered as read error callbacks */+typedef void (*TMR_ReadExceptionListener)(TMR_Reader *reader, TMR_Status error, void *cookie);+/**+ * User-allocated structure containing the callback pointer and the+ * value to pass to that callback.+ */+typedef struct TMR_ReadExceptionListenerBlock+{+ /** Pointer to callback function */+ TMR_ReadExceptionListener listener;+ /** Value to pass to callback function */+ void *cookie;+ /** @private */+ struct TMR_ReadExceptionListenerBlock *next;+} TMR_ReadExceptionListenerBlock;++/** Type of functions to be registered as transport callbacks */+typedef void (*TMR_TransportListener) (bool tx, uint32_t dataLen,+ const uint8_t data[], uint32_t timeout,+ void *cookie);+/**+ * User-allocated structure containing the callback pointer and the+ * value to pass to that callback.+ */+typedef struct TMR_TransportListenerBlock+{+ /** Pointer to callback function */+ TMR_TransportListener listener;+ /** Value to pass to callback function */+ void *cookie;+ /** @private */+ struct TMR_TransportListenerBlock *next;+} TMR_TransportListenerBlock;++/** Type of functions to be registered as Status read callbacks */+typedef void (*TMR_StatsListener)(TMR_Reader *reader, const TMR_Reader_StatsValues* value,+ void *cookie);+typedef void (*TMR_StatusListener)(TMR_Reader *reader, const TMR_SR_StatusReport report[],+ void *cookie);+/**+ * User-allocated structure containing the callback pointer and the+ * value to pass to that callback.+ */+typedef struct TMR_StatsListenerBlock+{+ /** Pointer to callback function */+ TMR_StatsListener listener;+ /** Value to pass to callback function */+ void *cookie;+ /** @private */+ struct TMR_StatsListenerBlock *next;+} TMR_StatsListenerBlock;++/**+ * User-allocated structure containing the callback pointer and the+ * value to pass to that callback.+ */+typedef struct TMR_StatusListenerBlock+{+ /** Pointer to callback function */+ TMR_StatusListener listener;+ /** Value to pass to callback function */+ void *cookie;+ /** @private */+ struct TMR_StatusListenerBlock *next;+} TMR_StatusListenerBlock;++/**+ * Private: should not be used by user level application.+ */+typedef struct TMR_Queue_tagReads+{+ union+ {+ /* Buffer to hold serial message response */+ uint8_t *sMsg;+#ifdef TMR_ENABLE_LLRP_READER+ /* Buffer to hold LLRP message response */+ LLRP_tSMessage *lMsg;+#endif+ } tagEntry;++ uint8_t bufPointer;+ /* Object to hold tag results */+ TMR_TagReadData trd;+ bool isStatusResponse;+ struct TMR_Queue_tagReads *next;+}TMR_Queue_tagReads;++typedef TMR_SR_GEN2_QType TMR_GEN2_QType;+typedef TMR_SR_GEN2_QStatic TMR_GEN2_QStatic;+typedef TMR_SR_GEN2_Q TMR_GEN2_Q;++/**+ * @defgroup reader Reader+ *+ * TMR_Reader encapsulates a connection to a ThingMagic RFID reader+ * device and provides an interface to perform RFID operations such as+ * reading tags and writing tag IDs. + *+ * Reads can be done on demand, with the TMR_read() function, or+ * continuously in the background with the TMR_startReading()+ * function. Background reads notify registered listeners of tags+ * that are read.+ *+ * Operations which take an argument for a tag to operate on may+ * optionally be passed a @c NULL argument. This lets the reader choose+ * what tag to use, but may not work if multiple tags are+ * present. This use is recommended only when exactly one tag is known+ * to be in range.+ */++/**+ * @ingroup reader+ * @struct TMR_Reader+ * + * The structure that represents a RFID reader. The user should+ * allocate a TMR_Reader structure and initialize it with+ * TMR_create().+ */+struct TMR_Reader+{+ /** @privatesection */++ enum TMR_ReaderType readerType;+ bool connected;+ TMR_TransportListenerBlock *transportListeners;++ TMR_readParams readParams;+ TMR_tagOpParams tagOpParams;+ char uri[TMR_MAX_READER_NAME_LENGTH];+ + bool continuousReading;+ bool trueAsyncflag;+ bool searchStatus;+ /* Statistics response indicator */+ bool isStatusResponse;+ /* Option for Fast Search */+ bool fastSearch;+ /* Option for Trigger Read */+ bool triggerRead;+ /* Option for Duty cycle*/+ bool dutyCycle;+ /* Option for stop N tag trigger */+ bool isStopNTags;+ /* Param wait indicator for Reader and protocol param control during continuous read */+ bool paramWait;+ /* Param response for Reader and protocol param control during continuous read */+ uint8_t paramMessage[256];+ /* True Continuous Read Start indicator */+ bool hasContinuousReadStarted;+ /* Total tag count for sto N trigger */+ uint32_t numberOfTagsToRead;+ /* Does ResetStats feature work on this reader?+ * Unknown: NULL == pSupportsResetStats+ * Yes: (NULL != pSupportsResetStats) && (true == *pSupportsResetStats)+ * No: (NULL != pSupportsResetStats) && (false == *pSupportsResetStats)+ */+ bool* pSupportsResetStats/* = NULL*/;+ bool _storeSupportsResetStats;+ /* the option to request for background thread cancel */+ bool backgroundThreadCancel;++ union+ {+ TMR_SR_SerialReader serialReader;+ /*+ *TMR_RQL_RqlReader rqlReader;+ */+#ifdef TMR_ENABLE_LLRP_READER+ TMR_LLRP_LlrpReader llrpReader;+#endif+ }u;++#ifdef TMR_ENABLE_BACKGROUND_READS+ bool backgroundSetup, backgroundEnabled, backgroundRunning;+ bool parserSetup, parserEnabled, parserRunning;+#endif+ bool finishedReading;+#ifdef TMR_ENABLE_BACKGROUND_READS+ enum TMR_ReadState readState;+ unsigned int queue_depth;+ sem_t queue_slots, queue_length;+ pthread_mutex_t queue_lock;+ pthread_mutex_t backgroundLock;+ pthread_mutex_t parserLock;+ pthread_mutex_t listenerLock; + pthread_cond_t backgroundCond;+ pthread_cond_t parserCond;+ pthread_cond_t readCond;+ pthread_t backgroundReader;+ pthread_t backgroundParser;+ pthread_t autonomousBackgroundReader;+ TMR_AuthReqListenerBlock *authReqListeners;+#endif+ TMR_ReadListenerBlock *readListeners;+ TMR_ReadExceptionListenerBlock *readExceptionListeners;+ TMR_StatsListenerBlock *statsListeners;+#ifdef TMR_ENABLE_BACKGROUND_READS+ TMR_StatusListenerBlock *statusListeners;+ TMR_Queue_tagReads *tagQueueTail;+ TMR_Queue_tagReads *tagQueueHead;+#endif+ TMR_Reader_StatsFlag statsFlag;+ TMR_SR_StatusType streamStats;+ TMR_TRD_MetadataFlag userMetadataFlag;+ uint8_t portmask;+++ /* Level 1 */+#ifndef TMR_ENABLE_SERIAL_READER_ONLY+ TMR_Status (*connect)(struct TMR_Reader *reader);+ TMR_Status (*destroy)(struct TMR_Reader *reader);+ TMR_Status (*read)(struct TMR_Reader *reader, uint32_t timeoutMs, int32_t *tagCount);+ TMR_Status (*hasMoreTags)(struct TMR_Reader *reader);+ TMR_Status (*getNextTag)(struct TMR_Reader *reader, TMR_TagReadData *read);+ TMR_Status (*writeTag)(struct TMR_Reader *reader, const TMR_TagFilter *filter, const TMR_TagData *data);+#endif /* TMR_ENABLE_SERIAL_READER_ONLY */+ TMR_Status (*paramGet)(struct TMR_Reader *reader, TMR_Param key, void *value);+ TMR_Status (*paramSet)(struct TMR_Reader *reader, TMR_Param key, const void *value);+ + /* Level 2 */+#ifndef TMR_ENABLE_SERIAL_READER_ONLY+ TMR_Status (*killTag)(struct TMR_Reader *reader, const TMR_TagFilter *filter, const TMR_TagAuthentication *auth);+ TMR_Status (*lockTag)(struct TMR_Reader *reader, const TMR_TagFilter *filter, TMR_TagLockAction *action);+ TMR_Status (*executeTagOp)(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *filter, TMR_uint8List *data);+ TMR_Status (*readTagMemBytes)(struct TMR_Reader *reader, const TMR_TagFilter *filter, + uint32_t bank, uint32_t address,+ uint16_t count, uint8_t data[]);+ TMR_Status (*readTagMemWords)(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t address,+ uint16_t count, uint16_t *data);+ TMR_Status (*writeTagMemBytes)(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t address,+ uint16_t count, const uint8_t data[]);+ TMR_Status (*writeTagMemWords)(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t address,+ uint16_t count, const uint16_t data[]);+ TMR_Status (*gpoSet)(struct TMR_Reader *reader, uint8_t count, const TMR_GpioPin state[]);+ TMR_Status (*gpiGet)(struct TMR_Reader *reader, uint8_t *count, TMR_GpioPin state[]);+ TMR_Status (*firmwareLoad)(TMR_Reader *reader, void *cookie, TMR_FirmwareDataProvider provider);+ TMR_Status (*modifyFlash) (TMR_Reader *reader, uint8_t sector, uint32_t address, uint32_t password,+ uint8_t length, const uint8_t data[], uint32_t offset);+ TMR_Status (*reboot) (TMR_Reader *reader);+#endif /* TMR_ENABLE_SERIAL_READER_ONLY */++ /* Level 3 */+#ifdef TMR_ENABLE_BACKGROUND_READS+ TMR_Status (*cmdAutonomousReading)(struct TMR_Reader *reader, TMR_TagReadData *trd, TMR_Reader_StatsValues *stats);+#endif+ TMR_Status (*cmdStopReading)(struct TMR_Reader *reader);+};++/**+ * @ingroup reader+ * The TMR_Reader struct being initialized should be preallocated by+ * the user. No memory is allocated during the initialization+ * process, and the reader is not contacted at this point.+ *+ * @param reader The TMR_Reader structure to initialize+ * @param deviceUri an identifier for the reader to connect to, with+ * a URI syntax. The scheme can be \c eapi for the embedded+ * module protocol, \c rql for the request query language, or+ * \c tmr to guess. The remainder of the URI identifies the+ * stream that the protocol will be spoken over, either a local host+ * serial port device or a TCP network port.+ * Example URIs are:+ * - tmr://192.168.10.8/ - Reader at TCP/IP address 192.168.10.8, RQL assumed+ * - rql://192.168.10.8/ - RQL reader at TCP/IP address 192.168.10.8+ * - tmr:///dev/ttyS1 - reader on serial port /dev/ttyS1, EAPI (serial) assumed+ * - eapi:///COM2 - EAPI (serial) reader on serial port COM2+ * - llrp+eapi://192.168.10.8 - EAPI tunneled over LLRP to a reader at+ * TCP/IP address 192.168.10.8+ *+ * @test Call with valid URI should not fail.+ * @test Call with invalid URI should fail.+ */+TMR_Status TMR_create(TMR_Reader *reader, const char* deviceUri);++ /**+ * @ingroup reader+ *+ * This function is a version of TMR_create() that dynamically+ * allocates the TMR_Reader structure and stores the pointer in+ * *reader.+ * + * @param[out] readerPointer Pointer to the TMR_Reader* in which to place the+ * pointer to the newly allocated reader structure.+ @ @param deviceUri As described in TMR_create().+ *+ * @test Call with valid URI should not fail.+ * @test Call with invalid URI should fail.+ * @test Multiple calls with different URIs should return distinct objects.+ */+TMR_Status TMR_create_alloc(TMR_Reader **readerPointer, const char* deviceUri);+++/**+ * @ingroup reader+ * Establishes the connection to the reader at the URI specified in+ * the TMR_create() call. The existence of a reader at the address is+ * verified and the reader is brought into a state appropriate for+ * performing RF operations.+ *+ * @param reader The reader to connect + *+ * + * @test Connecting to existing reader should succeed.+ * @test Connecting to nonexisting reader should fail.+ */+TMR_Status TMR_connect(struct TMR_Reader *reader);++/**+ * @ingroup reader+ * Closes the connection to the reader and releases any resources+ * that have been consumed by the reader structure.+ *+ * @param reader The reader to shut down.+ *+ * @test Destroying existing connected reader should succed.+ * @test Destroying existing unconnected reader should succeed.+ * @test Destroying already-destroyed reader should fail.+ * @test Destroying reader allocated by TMR_create_alloc() should+ * free the allocated memory.+ */+TMR_Status TMR_destroy(TMR_Reader *reader);++/**+ * @ingroup reader+ * Search for tags for a fixed duration. Once this returns, the tags+ * are retrieved by calling TMR_getNextTag() until TMR_hasMoreTags()+ * returns false.+ *+ * @param reader The reader being operated on+ * @param timeoutMs The number of milliseconds to search for tags+ * @param[out] tagCount The number of tags read, or -1 if the number+ * is unknown. If NULL, no value will be stored.+ *+ * @test Call should fail if reader is not connected.+ * @test If call is successful as per TMR_Error, *tagCount should be+ * modified and contain a positive value.+ */+TMR_Status TMR_read(TMR_Reader *reader, uint32_t timeoutMs, int32_t *tagCount);++/**+ * @ingroup reader+ * @retval TMR_SUCCESS if there are more tags to be retrieved from the most recent TMR_read() operation.+ * @retval TMR_ERROR_NO_TAGS if no more tags are available for retrieval.+ * @retval Other TMR_ERRORs when appropriate.+ *+ * @param reader The reader being operated on+ * + * @test Call should return false before a read() call.+ * @test Call should return false after a read() call that set+ * *tagCount to zero.+ * @test Call should return true after a read() call that set+ * *tagCount to a nonzero value.+ * @test Call should return true through exactly as many getNextTag()+ * calls as specified by *tagCount.+ */+TMR_Status TMR_hasMoreTags(TMR_Reader *reader);++/**+ * @ingroup reader+ * Fetches the next tag from the last TMR_read() operation.+ *+ * @param reader The reader being operated on+ * @param[out] tagData The TMR_TagReadData structure to fill.+ * + * @test Call should fail before a read() call.+ * @test Call should fail after a read() call that set *tagCount to+ * zero.+ * @test Call should fill in a tag after a read() call that set+ * *tagCount to a nonzero value.+ * @test Call should succeed exactly as many times as specified by+ * *tagCount.+ */+TMR_Status TMR_getNextTag(TMR_Reader *reader, TMR_TagReadData *tagData);++/**+ * @ingroup reader+ * This method provides the direct execution of TagOp commands+ * Reader operates on the first tag found, with applicable tag filtering+ * Reader stops and the call returns immediately after finding one tag+ * and operating on it, unless the command timeout expires first+ * The operation is performed on the antenna specified in+ * /reader/tagop/antenna parameter+ * /reader/tagop/protocol specifies the protocol to be used+ *+ * @param reader The reader being operated on+ * @param tagop Pointer to the TMR_TagOp which needs to be executed+ * @param filter Tag Filter to be used+ * @param[out] data Data returned as a result of tag operation+ */+TMR_Status TMR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *filter, TMR_uint8List *data);++/**+ * @ingroup reader+ * Wrapper routine that searches for tags, allocates space for the+ * results, and returns the results in a single array.+ * + * @param reader The reader being operated on+ * @param timeoutMs The number of milliseconds to search for tags+ * @param[out] tagCount The number of tags found and the size of the allocated array.+ * @param[out] result The array of tag read data.+ *+ * @test Call should fail if reader is not connected.+ * @test If call is successful as per TMR_Error, *tagCount should be+ * modified and contain a positive value, and *result should be+ * modified and contain the corresponding number of tag read values.+ *+ * Out param "result" should be freed after using it.+ */++TMR_Status TMR_readIntoArray(struct TMR_Reader *reader, uint32_t timeoutMs, int32_t *tagCount, TMR_TagReadData *result[]);++/**+ * @deprecated This method is deprecated + *+ * Write a new EPC to an existing tag. + * + * The @c /reader/tagop/antenna parameter controls which antenna will+ * be used for the write operation. The @c /reader/tagop/protocol+ * parameter controls which protocol will be used.+ * + * @param reader The reader being operated on+ * @param target The existing tag to write.+ * @param data The EPC to write to the tag+ * @note target is not supported on serial or Astra readers and only+ * TagData filters are supported on other fixed readers.+ *+ * @return TMR_ERROR_NO_TAG_FOUND if no tag matching the filter could be found.+ *+ * @test Call should fail if reader is not connected.+ * @test Upon success, a subsequent TMR_read() should find the new tag ID.+ */+TMR_Status TMR_writeTag(TMR_Reader *reader, const TMR_TagFilter *target, TMR_TagData *data);++/**+ * @deprecated This method is deprecated+ *+ * Sends a kill command to a tag.+ *+ * @param reader The reader being operated on.+ * @param target The tag to kill, or @c NULL to kill the first tag seen.+ * @param auth The authentication needed to kill the tag.+ *+ * @return TMR_ERROR_NO_TAG_FOUND if no tag matching the filter could be found.+ */+TMR_Status TMR_killTag(TMR_Reader *reader, TMR_TagFilter *target, TMR_TagAuthentication *auth);+++/**+ * @deprecated This method is deprecated+ *+ * Sends a lock command to a tag.+ *+ * @param reader The reader being operated on.+ * @param target The tag to kill, or @c NULL to kill the first tag seen.+ * @param action The locking action to apply.+ *+ * @return TMR_ERROR_NO_TAG_FOUND if no tag matching the filter could be found.+ */+TMR_Status TMR_lockTag(TMR_Reader *reader, TMR_TagFilter *target, TMR_TagLockAction *action);+++/**+ * @ingroup reader+ * Read 8-bit bytes from the memory bank of a tag.+ *+ * @param reader The reader being operated on.+ * @param target The tag to read from, or @c NULL.+ * @param bank The tag memory bank to read from.+ * @param byteAddress The byte address to start reading at.+ * @param byteCount The number of bytes to read+ * @param[out] data The read data.+ */+TMR_Status TMR_readTagMemBytes(TMR_Reader *reader, TMR_TagFilter *target, + uint32_t bank, uint32_t byteAddress, + uint16_t byteCount, uint8_t data[]);++/**+ * @ingroup reader+ * Read 16-bit words from the memory bank of a tag.+ *+ * @param reader The reader being operated on.+ * @param target The tag to read from, or @c NULL.+ * @param bank The tag memory bank to read from.+ * @param wordAddress The word address to start reading at.+ * @param wordCount The number of words to read+ * @param[out] data The read data.+ */+TMR_Status TMR_readTagMemWords(TMR_Reader *reader, TMR_TagFilter *target, + uint32_t bank, uint32_t wordAddress, + uint16_t wordCount, uint16_t data[]);++/**+ * @deprecated This method is deprecated+ *+ * Write 8-bit bytes to the memory bank of a tag. If the tag's+ * fundamental memory unit is larger than 8 bits, trying to write+ * sub-unit quantities will produce an error.+ *+ * @param reader The reader to operate on.+ * @param target The tag to write to, or @c NULL.+ * @param bank The tag memory bank to write to.+ * @param byteAddress The byte address to start writing to.+ * @param byteCount The number of bytes to write.+ * @param data The bytes to write.+ */+TMR_Status TMR_writeTagMemBytes(TMR_Reader *reader, TMR_TagFilter *target,+ uint32_t bank, uint32_t byteAddress,+ uint16_t byteCount, const uint8_t data[]);++/**+ * @deprecated This method is deprecated+ *+ * Write 16-bit words to the memory bank of a tag. If the tag's+ * fundamental memory unit is larger than 16 bits, trying to write+ * sub-unit quantities will produce an error.+ *+ * @param reader The reader to operate on.+ * @param target The tag to write to, or @c NULL.+ * @param bank The tag memory bank to write to.+ * @param wordAddress The word address to start writing to.+ * @param wordCount The number of words to write.+ * @param data The words to write.+ */+TMR_Status TMR_writeTagMemWords(TMR_Reader *reader, TMR_TagFilter *target,+ uint32_t bank, uint32_t wordAddress,+ uint16_t wordCount, const uint16_t data[]);+++/**+ * @ingroup reader+ * Set the state of some GPO pins.+ *+ * @param reader The reader to operate on.+ * @param count The length of the state array.+ * @param state Array of reader pins and the state to set them to.+ */+TMR_Status TMR_gpoSet(TMR_Reader *reader, uint8_t count, const TMR_GpioPin state[]);++/**+ * @ingroup reader+ * Get the state of all GPI pins.+ *+ * @param reader The reader to operate on.+ * @param[in] count Pointer to the allocated length of the state array.+ * @param[out] count Pointer to the number of entries in the state array.+ * @param[out] state Array of reader pins and the state to set them to.+ */+TMR_Status TMR_gpiGet(TMR_Reader *reader, uint8_t *count, TMR_GpioPin state[]);++/**+ * @ingroup reader+ * The TMR_firmwareLoad() method attempts to install firmware on the+ * reader, then restart and reinitialize.+ * + * @param reader The reader to operate on+ * @param cookie Value to pass to the callback function.+ * @param provider Callback function to provide firmware data.+ */+TMR_Status TMR_firmwareLoad(TMR_Reader *reader, void *cookie, TMR_FirmwareDataProvider provider);++/**+ * Cookie for state storage of a TMR_memoryProvider.+ */+typedef struct TMR_memoryCookie {+ /** Pointer to the start of the firmware image in memory */+ uint8_t *firmwareStart;+ /** Size of the firmware image */+ uint32_t firmwareSize;+} TMR_memoryCookie;++/**+ * This function can be used as a callback to TMR_firmwareLoad when+ * the firmware image exists in system memory. The cookie is a pointer+ * to a TMR_memoryCookie that is initialized with the start of the firmware+ * image in memory and its size.+ *+ * @param cookie TMR_memoryCookie value.+ * @param[in] size The number of bytes requested.+ * @param[out] size The number of bytes returned.+ * @param data Pointer to buffer to fill.+ * @return true if there is more firmware data to return.+ */+bool TMR_memoryProvider(void *cookie, uint16_t *size, uint8_t *data);++/**+ * This function can be used as a callback to TMR_firmwareLoad when+ * the firmware image exists as a file. + *+ * @param cookie FILE * pointing to the file to read from.+ * @param[in] size The number of bytes requested.+ * @param[out] size The number of bytes returned.+ * @param data Pointer to buffer to fill.+ * @return true if there is more firmware data to return.+ */+bool TMR_fileProvider(void *cookie, uint16_t *size, uint8_t *data);++/**+ * @ingroup reader+ * Set the value of a reader parameter.+ * + * @param reader The reader to operate on.+ * @param key The string identifying the parameter.+ * @param value The new value to use for the parameter. The caller may+ * not alter the value after passing it to this function.+ *+ * @test Call should fail if key is an invalid parameter name.+ * @test Call should fail if key is valid but unsupported by connected reader.+ * @test Call should succeed if key matches parameter name, independent of case.+ */+TMR_Status TMR_paramSet(struct TMR_Reader *reader, TMR_Param key, const void *value);++/**+ * @ingroup reader+ * Get the value of a reader parameter.+ *+ * @param reader The reader to operate on.+ * @param key The string identifying the parameter.++ * @param[out] value Pointer to the parameter value. For list types+ * (including TMR_String), the caller must allocate the pointed-to+ * space and set the size of the allocated space in the max field, and+ * the function will write into that space and set the actual length+ * of the data. If the list or string is larger than will fit in the+ * pointed-to space, the length will be larger than the allocated+ * space - be careful iterating over the results if there is a chance+ * of not passing in a large enough structure.+ *+ * @test Call should fail if key is an invalid parameter name.+ * @test Call should fail if key is valid but unsupported by connected reader.+ * @test Call should succeed if key matches parameter name, independent of case.+ */+TMR_Status TMR_paramGet(struct TMR_Reader *reader, TMR_Param key, void *value);++/**+ * @ingroup reader+ * Reboot the reader+ *+ * @param reader The reader to operate on.+ **/ +TMR_Status TMR_reboot(struct TMR_Reader *reader);++/**+ * Get a list of the parameters available+ *+ * Supported Parameters:+ * @li /reader/antenna/checkPort+ * @li /reader/antenna/connectedPortList+ * @li /reader/antenna/portList+ * @li /reader/antenna/portSwitchGpos+ * @li /reader/antenna/returnLoss+ * @li /reader/antenna/settlingTimeList+ * @li /reader/antenna/txRxMap+ * @li /reader/asyncofftime+ * @li /reader/baudRate+ * @li /reader/commandTimeout+ * @li /reader/currentTime+ * @li /reader/description+ * @li /reader/extendedEpc+ * @li /reader/gen2/BLF+ * @li /reader/gen2/accessPassword+ * @li /reader/gen2/bap+ * @li /reader/gen2/protocolExtension+ * @li /reader/gen2/q+ * @li /reader/gen2/session+ * @li /reader/gen2/tagEncoding+ * @li /reader/gen2/target+ * @li /reader/gen2/tari+ * @li /reader/gen2/writeEarlyExit+ * @li /reader/gen2/writeMode+ * @li /reader/gen2/writeReplyTimeout+ * @li /reader/gpio/inputList+ * @li /reader/gpio/outputList+ * @li /reader/hostname+ * @li /reader/iso180006b/BLF+ * @li /reader/iso180006b/delimiter+ * @li /reader/iso180006b/modulationDepth+ * @li /reader/licenseKey+ * @li /reader/licensedFeatures+ * @li /reader/metadataflags+ * @li /reader/powerMode+ * @li /reader/probeBaudRates+ * @li /reader/radio/enablePowerSave+ * @li /reader/radio/enableSJC+ * @li /reader/radio/portReadPowerList+ * @li /reader/radio/portWritePowerList+ * @li /reader/radio/powerMax+ * @li /reader/radio/powerMin+ * @li /reader/radio/readPower+ * @li /reader/radio/temperature+ * @li /reader/radio/writePower+ * @li /reader/read/asyncOffTime+ * @li /reader/read/asyncOnTime+ * @li /reader/read/plan+ * @li /reader/region/hopTable+ * @li /reader/region/hopTime+ * @li /reader/region/id+ * @li /reader/region/lbt/enable+ * @li /reader/region/supportedRegions+ * @li /reader/selectedProtocols+ * @li /reader/statistics+ * @li /reader/stats+ * @li /reader/stats/enable+ * @li /reader/status/antennaEnable+ * @li /reader/status/frequencyEnable+ * @li /reader/status/temperatureEnable+ * @li /reader/tagReadData/enableReadFilter+ * @li /reader/tagReadData/readFilterTimeout+ * @li /reader/tagReadData/recordHighestRssi+ * @li /reader/tagReadData/reportRssiInDbm+ * @li /reader/tagReadData/tagopFailures+ * @li /reader/tagReadData/tagopSuccesses+ * @li /reader/tagReadData/uniqueByAntenna+ * @li /reader/tagReadData/uniqueByData+ * @li /reader/tagReadData/uniqueByProtocol+ * @li /reader/tagop/antenna+ * @li /reader/tagop/protocol+ * @li /reader/transportTimeout+ * @li /reader/trigger/read/Gpi+ * @li /reader/uri+ * @li /reader/userConfig+ * @li /reader/userMode+ * @li /reader/version/hardware+ * @li /reader/version/model+ * @li /reader/version/productGroup+ * @li /reader/version/productGroupID+ * @li /reader/version/productID+ * @li /reader/version/serial+ * @li /reader/version/software+ * @li /reader/version/supportedProtocols+ *+ * @ingroup reader+ *+ * @param reader The reader to operate on.+ * @param[out] keys Pointer to the list of parameters. The caller must+ * allocate space for the parameters.+ * @param[in] len Pointer to the allocated length of the space pointed to by keys.+ * @param[out] len Pointer to the number of parameters supported by+ * the reader, which may be larger or smaller than the provided+ * array. If it is larger than the provided array, the list is+ * truncated.+ */+TMR_Status TMR_paramList(struct TMR_Reader *reader, TMR_Param *keys, uint32_t *len);+/**+ * @reader pointer to TMR_Reader+ * @key pointer to TMR_Param+ */ +void TMR_paramProbe (struct TMR_Reader *reader, TMR_Param key);++/**+ * @ingroup reader+ * Return the string name corresponding to a TMR_Param value.+ * Only present if TMR_ENABLE_PARAM_STRINGS is set.+ *+ * @param key The parameter ID.+ * @return The corresponding string name.+ */+const char* TMR_paramName(TMR_Param key);++/**+ * @ingroup reader+ * Return the TMR_Param ID corresponding to a string name.+ * Only present if TMR_ENABLE_PARAM_STRINGS is set.+ *+ * @param name the parameter + * @return The TMR_Param value of the name, or TMR_PARAM_NONE if no such+ * parameter exists.+ */+TMR_Param TMR_paramID(const char *name);+++/**+ * @ingroup reader+ * + * Add a listener to the list of functions that will be called for+ * each message sent to or received from the reader.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_addTransportListener(TMR_Reader *reader, TMR_TransportListenerBlock *block);+++/**+ * @ingroup reader+ * + * Remove a listener from the list of functions that will be called+ * for each message sent to or received from the reader.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_removeTransportListener(TMR_Reader *reader, TMR_TransportListenerBlock *block);++/**+ * @ingroup reader+ * Add a listener to the list of functions that will be called for+ * each background tag read.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_addReadListener(struct TMR_Reader *reader,+ TMR_ReadListenerBlock *block);++/**+ * @ingroup reader+ * Add a listener to the list of functions that will be called for+ * each background tag read.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_addAuthReqListener(struct TMR_Reader *reader,+ TMR_AuthReqListenerBlock *block);++/**+ * @ingroup reader+ * Remove a listener from the list of functions that will be called+ * for each background tag read.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_removeReadListener(struct TMR_Reader *reader,+ TMR_ReadListenerBlock *block);++/**+ * @ingroup reader+ * Add a listener to the list of functions that will be called for+ * each error that occurs during background tag reading.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_addReadExceptionListener(struct TMR_Reader *reader,+ TMR_ReadExceptionListenerBlock *block);++/**+ * @ingroup reader+ * Remove a listener from the list of functions that will be called+ * for each error that occurs during background tag reading.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_removeReadExceptionListener(struct TMR_Reader *reader,+ TMR_ReadExceptionListenerBlock *block);++/**+ * @ingroup reader+ * Add a listener to the list of functions that will be called for+ * each background status response.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_addStatusListener(struct TMR_Reader *reader,+ TMR_StatusListenerBlock *block);++/**+ * @ingroup reader+ * Remove a listener from the list of functions that will be called+ * for each background status response.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_removeStatusListener(struct TMR_Reader *reader,+ TMR_StatusListenerBlock *block);+++/**+ * @ingroup reader+ * Add a listener to the list of functions that will be called for+ * each background status response.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_addStatsListener(struct TMR_Reader *reader,+ TMR_StatsListenerBlock *block);++/**+ * @ingroup reader+ * Remove a listener from the list of functions that will be called+ * for each background status response.+ *+ * @param reader The reader to operate on.+ * @param block A structure containing a pointer to the listener+ * function and a user-supplied cookie value to pass to the function+ * when called.+ */+TMR_Status TMR_removeStatsListener(struct TMR_Reader *reader,+ TMR_StatsListenerBlock *block);+++/**+ * @ingroup reader+ * Start reading tags in the background. The tags found will be passed+ * to the registered read listeners, and any errors that occur during+ * reading will be passed to the registered exception+ * listeners. Reading will continue until stopReading() is called.+ * The read listeners will be called from a background thread.+ *+ * @param reader The reader to operate on.+ */++TMR_Status TMR_startReading(struct TMR_Reader *reader);+TMR_Status TMR_receiveAutonomousReading(struct TMR_Reader *reader, TMR_TagReadData *trd, TMR_Reader_StatsValues *stats);+/**+ * @ingroup reader+ * Stop reading tags in the background. This function will wait until+ * the reader has stopped.+ *+ * @param reader The reader to operate on.+ */+TMR_Status TMR_stopReading(struct TMR_Reader *reader);++/**+ * @ingroup reader+ * Stores the transport init function against the provided scheme.+ *+ * @param scheme the transport scheme name.+ * @param nativeInit reference to the init function.+ */ +TMR_Status TMR_setSerialTransport(char* scheme, TMR_TransportNativeInit nativeInit);++/**+ * @ingroup reader+ * This function will convert the error codes into proper error messages.+ *+ * @param reader The reader which resulted in error+ * @param status The status code which is to be converted+ */+const char *TMR_strerr(TMR_Reader *reader, TMR_Status status);++/**+ * @ingroup reader+ * This function will initialize the+ * TMR_StatValues structure with the default values+ */+TMR_Status TMR_STATS_init(TMR_Reader_StatsValues *stats);++/**+ * @ingroup reader+ * This function loads the reader configuration parameters from file and applies to module.+ *+ * @param reader The reader to operate on.+ * @param filePath load reader configurations from filepath.+ */+TMR_Status TMR_loadConfig(struct TMR_Reader *reader, char *filePath);++/**+ * @ingroup reader+ * This function saves the current reader configuration parameters and its values to a file.+ *+ * @param reader The reader to operate on.+ * @param filePath save reader configurations from filepath.+ */+TMR_Status TMR_saveConfig(struct TMR_Reader *reader, char *filePath);++#ifndef DOXYGEN_IGNORE++TMR_Status TMR_reader_init_internal(struct TMR_Reader *reader);+/*TMR_Status TMR_init_statusListenerBlock(TMR_StatusListenerBlock *slb, TMR_StatusListener listener,+ void *cookie, TMR_SR_StatusContentFlags statusFlags);*/+TMR_Status validateReadPlan(TMR_Reader *reader, TMR_ReadPlan *plan, TMR_AntennaMapList *txRxMap, uint32_t protocols);++void TMR__notifyTransportListeners(TMR_Reader *reader, bool tx, + uint32_t dataLen, uint8_t *data,+ int timeout);++void notify_exception_listeners(TMR_Reader *reader, TMR_Status status);+void cleanup_background_threads(TMR_Reader *reader);++#ifdef TMR_ENABLE_SERIAL_READER_ONLY++#define TMR_connect(reader) (TMR_SR_connect(reader))+#define TMR_destroy(reader) (TMR_SR_destroy(reader))+#define TMR_read(reader, timeoutMs, tagCount) (TMR_SR_read((reader),(timeoutMs),(tagCount)))+#define TMR_hasMoreTags(reader) (TMR_SR_hasMoreTags(reader))+#define TMR_getNextTag(reader, read) (TMR_SR_getNextTag((reader),(read)))+#define TMR_writeTag(reader, filter, data) (TMR_SR_writeTag((reader),(filter),(data)))+#define TMR_readTagMemWords(reader, target, bank, address, count, data) (TMR_SR_readTagMemWords((reader),(target),(bank),(address),(count),(data)))+#define TMR_readTagMemBytes(reader, target, bank, address, count, data) (TMR_SR_readTagMemBytes((reader),(target),(bank),(address),(count),(data)))+#define TMR_writeTagMemWords(reader, target, bank, address, count, data) (TMR_SR_writeTagMemWords((reader),(target),(bank),(address),(count),(data)))+#define TMR_writeTagMemBytes(reader, target, bank, address, count, data) (TMR_SR_writeTagMemBytes((reader),(target),(bank),(address),(count),(data)))+#define TMR_killTag(reader, filter, auth) (TMR_SR_killTag((reader),(filter),(auth)))+#define TMR_lockTag(reader, filter, action) (TMR_SR_lockTag((reader),(filter),(action)))+#define TMR_executeTagOp(reader, tagop, filter, data) (TMR_SR_executeTagOp((reader), (tagop), (filter), (data)))+#define TMR_gpoSet(reader, count, state) (TMR_SR_gpoSet((reader),(count),(state)))+#define TMR_gpiGet(reader, count, state) (TMR_SR_gpiGet((reader),(count),(state)))+#define TMR_firmwareLoad(reader, cookie, provider) (TMR_SR_firmwareLoad((reader),(cookie),(provider)))+#define TMR_reboot(reader) (TMR_SR_reboot((reader)))++#else+/** + * The fact that these functions are implemented via macros is an+ * implementation detail, not something for the public API+ * documentation.+ */+#define TMR_connect(reader) ((reader)->connect(reader))+#define TMR_destroy(reader) ((reader)->destroy(reader))+#define TMR_read(reader, timeoutMs, tagCount) ((reader)->read((reader),(timeoutMs),(tagCount)))+#define TMR_hasMoreTags(reader) ((reader)->hasMoreTags(reader))+#define TMR_getNextTag(reader, read) ((reader)->getNextTag((reader),(read)))+#define TMR_writeTag(reader, filter, data) ((reader)->writeTag((reader),(filter),(data)))+#define TMR_readTagMemWords(reader, target, bank, address, count, data) ((reader)->readTagMemWords((reader),(target),(bank),(address),(count),(data)))+#define TMR_readTagMemBytes(reader, target, bank, address, count, data) ((reader)->readTagMemBytes((reader),(target),(bank),(address),(count),(data)))+#define TMR_writeTagMemWords(reader, target, bank, address, count, data) ((reader)->writeTagMemWords((reader),(target),(bank),(address),(count),(data)))+#define TMR_writeTagMemBytes(reader, target, bank, address, count, data) ((reader)->writeTagMemBytes((reader),(target),(bank),(address),(count),(data)))+#define TMR_killTag(reader, filter, auth) ((reader)->killTag((reader),(filter),(auth)))+#define TMR_lockTag(reader, filter, action) ((reader)->lockTag((reader),(filter),(action)))+#define TMR_executeTagOp(reader, tagop, filter, data) ((reader)->executeTagOp((reader), (tagop), (filter), (data)))+#define TMR_gpoSet(reader, count, state) ((reader)->gpoSet((reader),(count),(state)))+#define TMR_gpiGet(reader, count, state) ((reader)->gpiGet((reader),(count),(state)))+#define TMR_firmwareLoad(reader, cookie, provider) ((reader)->firmwareLoad((reader),(cookie),(provider)))+#define TMR_modifyFlash(reader, sector, address, password, length, data, offset) ((reader->modifyFlash((reader),(sector),(address),(password),(length),(data),(offset)))+#define TMR_reboot(reader) ((reader)->reboot(reader))+#endif /* TMR_ENABLE_SERIAL_READER_ONLY */++#endif /* DOXYGEN_IGNORE */++#ifdef __cplusplus+}+#endif++#endif /* _TM_READER_H_ */
+ cbits/api/tm_reader_async.c view
@@ -0,0 +1,1599 @@+/**+ * @file tm_reader_async.c+ * @brief Mercury API - background reading implementation+ * @author Nathan Williams+ * @date 11/18/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 "tm_config.h"+#include "tm_reader.h"+#include "serial_reader_imp.h"+#include <stdio.h>++bool IsDutyCycleEnabled(TMR_Reader *reader);+TMR_Status restart_reading(struct TMR_Reader *reader);+#ifdef TMR_ENABLE_BACKGROUND_READS++#include <stdlib.h>+#include <pthread.h>+#include <semaphore.h>+#include <time.h>+#include <stdio.h>+#include <string.h>++#ifndef WIN32+#include <sys/time.h>+#endif++#ifdef TMR_ENABLE_LLRP_READER+#include "llrp_reader_imp.h"+#endif+#include "osdep.h"+#include "tmr_utils.h"++static void *do_background_reads(void *arg);+static void *parse_tag_reads(void *arg);+static void process_async_response(TMR_Reader *reader);+bool isBufferOverFlow = false;+#endif /* TMR_ENABLE_BACKGROUND_READS */++TMR_Status+TMR_startReading(struct TMR_Reader *reader)+{+#ifdef SINGLE_THREAD_ASYNC_READ+ TMR_Status ret;+ uint32_t ontime;+ + TMR_paramGet(reader, TMR_PARAM_READ_ASYNCONTIME, &ontime);+ reader->continuousReading = true; + 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_MICRO == reader->u.serialReader.versionInfo.hardware[0]) ||+ (TMR_SR_MODEL_M6E_NANO == reader->u.serialReader.versionInfo.hardware[0])) &&+ (reader->readParams.asyncOffTime == 0 || (reader->readParams.asyncOffTime != 0 && IsDutyCycleEnabled(reader)) ) &&+ ((TMR_READ_PLAN_TYPE_SIMPLE == reader->readParams.readPlan->type) ||+ ((TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type) &&+ (compareAntennas(&reader->readParams.readPlan->u.multi))))+ )+ {+ if (reader->readParams.asyncOffTime == 0)+ {+ reader->dutyCycle = false;+ }+ else+ {+ reader->dutyCycle = true;+ }+ }+ else+ {+ reader->dutyCycle = false;+ }+ ret = TMR_read(reader, ontime, NULL);+ if(TMR_SUCCESS != ret)+ return ret;+ +#else+#ifdef TMR_ENABLE_BACKGROUND_READS+ int ret;+ bool createParser = true;++ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+#ifdef TMR_ENABLE_SERIAL_READER+ /**+ * Currently we are not supporting stop N trigger for async read case.+ * This is also true for pseudo continuous case as well. Pop up the error+ * if user is trying to do so.+ **/+ if (TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type)+ {+ uint8_t loop = 0;+ TMR_MultiReadPlan *multi;++ multi = &reader->readParams.readPlan->u.multi;++ for (loop = 0; loop < multi->planCount; loop++)+ {+ if (multi->plans[loop]->u.simple.stopOnCount.stopNTriggerStatus)+ {+ /* Not supporting stop N trigger */+ return TMR_ERROR_UNSUPPORTED; + }+ }+ }+ else if (TMR_READ_PLAN_TYPE_SIMPLE == reader->readParams.readPlan->type)+ {+ if (reader->readParams.readPlan->u.simple.stopOnCount.stopNTriggerStatus)+ {+ /* Not supporting stop N trigger */+ return TMR_ERROR_UNSUPPORTED;+ }+ }+ else+ {+ /* do nothing */+ }++ /**+ * if model is M6e and it's varient+ * asyncOffTime == 0+ * only then use streaming+ */+ 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_MICRO == reader->u.serialReader.versionInfo.hardware[0]) ||+ (TMR_SR_MODEL_M6E_NANO == reader->u.serialReader.versionInfo.hardware[0])) &&+ (reader->readParams.asyncOffTime == 0 || (reader->readParams.asyncOffTime != 0 && IsDutyCycleEnabled(reader)) ) &&+ ((TMR_READ_PLAN_TYPE_SIMPLE == reader->readParams.readPlan->type) || + ((TMR_READ_PLAN_TYPE_MULTI == reader->readParams.readPlan->type) && + (compareAntennas(&reader->readParams.readPlan->u.multi))))+ )+ {+ if (reader->readParams.asyncOffTime == 0)+ {+ reader->dutyCycle = false;+ }+ else+ {+ reader->dutyCycle = true;+ }+ }+ else+ {+ createParser = false;+ reader->dutyCycle = false;+ }+#else+ return TMR_ERROR_UNSUPPORTED;+#endif/* TMR_ENABLE_SERIAL_READER */ + }+#ifdef TMR_ENABLE_LLRP_READER+ if (TMR_READER_TYPE_LLRP == reader->readerType)+ {+ /**+ * In case of LLRP reader and continuous reading, disable the+ * LLRP background receiver.+ **/+ TMR_LLRP_setBackgroundReceiverState(reader, false);+ /**+ * Note the keepalive start time+ * Keepalive monitoring happens only + * for async reads.+ **/+ reader->u.llrpReader.ka_start = tmr_gettime();+ }+#endif++ /**+ * Initialize read_started semaphore+ **/+ pthread_mutex_lock(&reader->backgroundLock);+ reader->readState = TMR_READ_STATE_STARTING;+ pthread_cond_broadcast(&reader->readCond);+ pthread_mutex_unlock(&reader->backgroundLock);++ if (true == createParser)+ {+ /** Background parser thread initialization+ *+ * Only M6e supports Streaming, and in case of other readers+ * we still use pseudo-async mechanism for continuous read.+ * To achieve continuous reading, create a parser thread+ */+ pthread_mutex_lock(&reader->parserLock);+ + if (false == reader->parserSetup)+ {+ ret = pthread_create(&reader->backgroundParser, NULL,+ parse_tag_reads, reader);+ if (0 != ret)+ {+ pthread_mutex_unlock(&reader->parserLock);+ return TMR_ERROR_NO_THREADS;+ }+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);+ pthread_detach(reader->backgroundParser);+ /** Initialize semaphores only for the first time+ * These semaphores are used only in case of streaming+ */+ reader->queue_depth = 0;+ sem_init(&reader->queue_length, 0, 0);+ sem_init(&reader->queue_slots, 0, TMR_MAX_QUEUE_SLOTS);+ reader->parserSetup = true;+ }++ reader->parserEnabled = true;+++ /* Enable streaming */+ reader->continuousReading = true;+ reader->finishedReading = false;+ pthread_cond_signal(&reader->parserCond);+ pthread_mutex_unlock(&reader->parserLock);+ }++ /* Background reader thread initialization */+ pthread_mutex_lock(&reader->backgroundLock);++ if (false == reader->backgroundSetup)+ {+ ret = pthread_create(&reader->backgroundReader, NULL,+ do_background_reads, reader);+ if (0 != ret)+ {+ pthread_mutex_unlock(&reader->backgroundLock);+ return TMR_ERROR_NO_THREADS;+ }+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);+ reader->backgroundSetup = true;+ }++ reader->backgroundEnabled = true;+ reader->searchStatus = true;++#ifdef TMR_ENABLE_SERIAL_READER + if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ reader->u.serialReader.tagopFailureCount = 0;+ reader->u.serialReader.tagopSuccessCount = 0;+ }+#endif/* TMR_ENABLE_SERIAL_READER */ + pthread_cond_signal(&reader->backgroundCond);+ pthread_mutex_unlock(&reader->backgroundLock);++ /* End of Background reader thread initialization */+ /**+ * Wait for the Background thread to send the read command.+ * This will prevent of adding extra sleep in the application+ * after TMR_startReading() call.+ **/ + pthread_mutex_lock(&reader->backgroundLock);+ while (TMR_READ_STATE_STARTING == reader->readState)+ {+ pthread_cond_wait(&reader->readCond, &reader->backgroundLock);+ }+ pthread_mutex_unlock(&reader->backgroundLock);+#endif /* TMR_ENABLE_BACKGROUND_READS */+#endif++ return TMR_SUCCESS;+}++#if defined(TMR_ENABLE_BACKGROUND_READS)|| defined(SINGLE_THREAD_ASYNC_READ)+bool IsDutyCycleEnabled(struct TMR_Reader *reader)+{+ uint16_t i; + uint8_t *readerVersion = reader->u.serialReader.versionInfo.fwVersion ;+ uint8_t checkVersion[4];+ switch (reader->u.serialReader.versionInfo.hardware[0])+ {+ case TMR_SR_MODEL_M6E:+ case TMR_SR_MODEL_M6E_I:+ checkVersion[0] = 0x01; checkVersion[1] = 0x21; checkVersion[2] = 0x01; checkVersion[3] = 0x07;+ break;+ case TMR_SR_MODEL_MICRO:+ checkVersion[0] = 0x01; checkVersion[1] = 0x09; checkVersion[2] = 0x00; checkVersion[3] = 0x02;+ break;+ case TMR_SR_MODEL_M6E_NANO:+ checkVersion[0] = 0x01; checkVersion[1] = 0x07; checkVersion[2] = 0x00; checkVersion[3] = 0x02;+ break;+ default:+ checkVersion[0] = 0xFF; checkVersion[1] = 0xFF; checkVersion[2] = 0xFF; checkVersion[3] = 0xFF;+ }+ for (i = 0; i < 4; i++)+ {+ if (readerVersion[i] < checkVersion[i])+ return false;+ else if (readerVersion[i] > checkVersion[i])+ return true;+ }+ return true;+}++#endif /* TMR_ENABLE_BACKGROUND_READS */++void+reset_continuous_reading(struct TMR_Reader *reader, bool dueToError)+{+ if (true == reader->continuousReading)+ {+#ifndef SINGLE_THREAD_ASYNC_READ+#ifdef TMR_ENABLE_LLRP_READER+ if (TMR_READER_TYPE_LLRP == reader->readerType)+ {+ /**+ * In case of LLRP reader, re-enable the+ * LLRP background receiver as continuous reading is finished+ **/+ TMR_LLRP_setBackgroundReceiverState(reader, true);+ }+#endif++#ifdef TMR_ENABLE_SERIAL_READER + if ((false == dueToError) && (TMR_READER_TYPE_SERIAL == reader->readerType))+ {+ /**+ * Disable filtering on module+ **/+ TMR_Status ret;+ bool value = reader->u.serialReader.enableReadFiltering;+ reader->hasContinuousReadStarted = false;+ ret = TMR_SR_cmdSetReaderConfiguration(reader, TMR_SR_CONFIGURATION_ENABLE_READ_FILTER, &value);+ if (TMR_SUCCESS != ret)+ {+#ifndef BARE_METAL+ notify_exception_listeners(reader, ret);+#endif+ }+ }+#endif/* TMR_ENABLE_SERIAL_READER */ +#endif /*SINGLE_THREAD_ASYNC_READ*/+ /* disable streaming */+ reader->continuousReading = false;+ }+}++TMR_Status+TMR_stopReading(struct TMR_Reader *reader)+{+ reader->hasContinuousReadStarted = false;+#ifdef SINGLE_THREAD_ASYNC_READ+ reader->cmdStopReading(reader);+#else+#ifdef TMR_ENABLE_BACKGROUND_READS++ /* Check if background setup is active */+ pthread_mutex_lock(&reader->backgroundLock);++ if (false == reader->backgroundSetup)+ {+ pthread_mutex_unlock(&reader->backgroundLock);+ return TMR_SUCCESS;+ }++ if (false == reader->searchStatus)+ {+ /**+ * searchStatus is false, i.e., reading is already+ * stopped. Returen success.+ **/+ pthread_mutex_unlock(&reader->backgroundLock);+ return TMR_SUCCESS;+ }+ /**+ * Else, read is in progress. Set+ * searchStatus to false;+ **/+ reader->searchStatus = false;+ pthread_mutex_unlock(&reader->backgroundLock);++ /**+ * Wait until the reading has started+ **/+ pthread_mutex_lock(&reader->backgroundLock);+ while (TMR_READ_STATE_STARTING == reader->readState)+ {+ pthread_cond_wait(&reader->readCond, &reader->backgroundLock);+ }+ pthread_mutex_unlock(&reader->backgroundLock);++ if ((true == reader->continuousReading) && (true == reader->trueAsyncflag))+ {+ /**+ * In case of true continuous reading, we need to send+ * stop reading message immediately.+ **/+ if(!isBufferOverFlow)+ {+ reader->cmdStopReading(reader);+ }++ /**+ * Wait logic has been changed in case of continuous reading.+ * Wait while the background reader is still reading.+ **/+ pthread_mutex_lock(&reader->backgroundLock);+ while (TMR_READ_STATE_DONE != reader->readState)+ {+ pthread_cond_wait(&reader->readCond, &reader->backgroundLock);+ }+ pthread_mutex_unlock(&reader->backgroundLock);+ /**+ * By this time, reader->backgroundEnabled is+ * already set to false. i.e., background reader thread+ * is suspended.+ **/+ }++ /**+ * wait until background reader thread finishes.+ * This is needed for pseudo-async reads and also+ * worst case of continuous reading, when read isn't success+ **/+ pthread_mutex_lock(&reader->backgroundLock);+ reader->backgroundEnabled = false;+ while (true == reader->backgroundRunning)+ {+ pthread_cond_wait(&reader->backgroundCond, &reader->backgroundLock);+ }+ pthread_mutex_unlock(&reader->backgroundLock);++ /**+ * Reset continuous reading settings, so that+ * the subsequent startReading() call doesn't have+ * any surprises.+ **/+#else+ reader->cmdStopReading(reader);+#endif+ reset_continuous_reading(reader, false);+#endif+ return TMR_SUCCESS;+}++void+notify_read_listeners(TMR_Reader *reader, TMR_TagReadData *trd)+{+ TMR_ReadListenerBlock *rlb;++ /* notify tag read to listener */+ if (NULL != reader)+ {+#ifndef SINGLE_THREAD_ASYNC_READ+ pthread_mutex_lock(&reader->listenerLock);+#endif+ rlb = reader->readListeners;+ while (rlb)+ {+ rlb->listener(reader, trd, rlb->cookie);+ rlb = rlb->next;+ }+#ifndef SINGLE_THREAD_ASYNC_READ+ pthread_mutex_unlock(&reader->listenerLock);+#endif+ }+}++void+notify_stats_listeners(TMR_Reader *reader, TMR_Reader_StatsValues *stats)+{+ TMR_StatsListenerBlock *slb;++ /* notify stats to the listener */+#ifndef SINGLE_THREAD_ASYNC_READ+ pthread_mutex_lock(&reader->listenerLock);+#endif+ slb = reader->statsListeners;+ while (slb)+ {+ slb->listener(reader, stats, slb->cookie);+ slb = slb->next;+ }+#ifndef SINGLE_THREAD_ASYNC_READ+ pthread_mutex_unlock(&reader->listenerLock);+#endif+}+++TMR_Status restart_reading(struct TMR_Reader *reader)+{+ TMR_Status ret = TMR_SUCCESS;++ //Stop continuous reading+ ret = TMR_stopReading(reader);+ if(ret != TMR_SUCCESS)+ {+ return ret;+ }++ #ifdef SINGLE_THREAD_ASYNC_READ+ //Receive all tags from the previous reading+ {+ TMR_TagReadData trd;+ while(true)+ {+ ret = TMR_hasMoreTags(reader);+ if (TMR_SUCCESS == ret)+ {+ TMR_getNextTag(reader, &trd);+ notify_read_listeners(reader, &trd);+ }+ else if(ret == TMR_ERROR_END_OF_READING)+ break;+ }+ }+ #endif+ //Restart reading+ ret = TMR_startReading(reader);++ return ret;+}+++#ifdef TMR_ENABLE_BACKGROUND_READS+/* NOTE: There is only one auth object for all the authreq listeners, so whichever listener touches it last wins.+ * For now (2012 Jul 20) we only anticipate having a single authreq listener, but there may be future cases which + * require multiples. Revise this design if necessary. */+void+notify_authreq_listeners(TMR_Reader *reader, TMR_TagReadData *trd, TMR_TagAuthentication *auth)+{+ TMR_AuthReqListenerBlock *arlb;++ /* notify tag read to listener */+ pthread_mutex_lock(&reader->listenerLock);+ arlb = reader->authReqListeners;+ while (arlb)+ {+ arlb->listener(reader, trd, arlb->cookie, auth);+ arlb = arlb->next;+ }+ pthread_mutex_unlock(&reader->listenerLock);+}+#endif /* TMR_ENABLE_BACKGROUND_READS */++TMR_Status+TMR_addReadExceptionListener(TMR_Reader *reader,+ TMR_ReadExceptionListenerBlock *b)+{+#ifndef SINGLE_THREAD_ASYNC_READ+ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;+#endif+ b->next = reader->readExceptionListeners;+ reader->readExceptionListeners = b;++#ifndef SINGLE_THREAD_ASYNC_READ+ pthread_mutex_unlock(&reader->listenerLock);+#endif+ return TMR_SUCCESS;+}++#ifdef TMR_ENABLE_BACKGROUND_READS+TMR_Status+TMR_removeReadExceptionListener(TMR_Reader *reader,+ TMR_ReadExceptionListenerBlock *b)+{+ TMR_ReadExceptionListenerBlock *block, **prev;++ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;++ prev = &reader->readExceptionListeners;+ block = reader->readExceptionListeners;+ while (NULL != block)+ {+ if (block == b)+ {+ *prev = block->next;+ break;+ }+ prev = &block->next;+ block = block->next;+ }++ pthread_mutex_unlock(&reader->listenerLock);++ if (block == NULL)+ {+ return TMR_ERROR_INVALID;+ }++ return TMR_SUCCESS;+}+#endif++void+notify_exception_listeners(TMR_Reader *reader, TMR_Status status)+{+ TMR_ReadExceptionListenerBlock *relb;++ if (NULL != reader)+ {+#ifndef SINGLE_THREAD_ASYNC_READ+ pthread_mutex_lock(&reader->listenerLock);+#endif+ relb = reader->readExceptionListeners;+ while (relb)+ {+ relb->listener(reader, status, relb->cookie);+ relb = relb->next;+ }+#ifndef SINGLE_THREAD_ASYNC_READ+ pthread_mutex_unlock(&reader->listenerLock);+#endif+ }+}++#ifdef TMR_ENABLE_BACKGROUND_READS+TMR_Queue_tagReads *+dequeue(TMR_Reader *reader)+{+ TMR_Queue_tagReads *tagRead = NULL;+ pthread_mutex_lock(&reader->queue_lock);+ if (NULL != reader->tagQueueHead)+ {+ /* Fetch the head always */+ tagRead = reader->tagQueueHead;+ reader->tagQueueHead = reader->tagQueueHead->next;+ }+ reader->queue_depth --;+ pthread_mutex_unlock(&reader->queue_lock);+ return(tagRead);+}+++void enqueue(TMR_Reader *reader, TMR_Queue_tagReads *tagRead)+{+ pthread_mutex_lock(&reader->queue_lock);+ if (NULL == reader->tagQueueHead)+ {+ /* first tag */+ reader->tagQueueHead = tagRead;+ reader->tagQueueHead->next = NULL;+ reader->tagQueueTail = reader->tagQueueHead;+ }+ else+ {+ reader->tagQueueTail->next = tagRead;+ reader->tagQueueTail = tagRead;+ tagRead->next = NULL;+ }+ reader->queue_depth ++;+ pthread_mutex_unlock(&reader->queue_lock);+}++static void *+parse_tag_reads(void *arg)+{+ TMR_Reader *reader;+ TMR_Queue_tagReads *tagRead;+ reader = arg; ++ while (1)+ {+ pthread_mutex_lock(&reader->parserLock);+ reader->parserRunning = false;+ pthread_cond_broadcast(&reader->parserCond);+ while (false == reader->parserEnabled)+ {+ pthread_cond_wait(&reader->parserCond, &reader->parserLock);+ }++ reader->parserRunning = true;+ pthread_mutex_unlock(&reader->parserLock);++ /**+ * Wait until queue_length is more than zero,+ * i.e., Queue should have atleast one tagRead to process+ */+ sem_wait(&reader->queue_length);++ if (NULL != reader->tagQueueHead)+ {+ /**+ * At this point there is a tagEntry in the queue+ * dequeue it and parse it.+ */ + tagRead = dequeue(reader);+ if (false == tagRead->isStatusResponse)+ {+ /* Tag Buffer stream response */++#ifdef TMR_ENABLE_SERIAL_READER + if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ /**+ * For serial readers, the tags results are already processed+ * and placed in the queue. Just notify that to the listener.+ */+ notify_read_listeners(reader, &tagRead->trd);+ }+#endif/* TMR_ENABLE_SERIAL_READER */ +#ifdef TMR_ENABLE_LLRP_READER+ if (TMR_READER_TYPE_LLRP == reader->readerType)+ {+ /* Else it is LLRP message, parse it */+ LLRP_tSRO_ACCESS_REPORT *pReport;+ LLRP_tSTagReportData *pTagReportData;++ pReport = (LLRP_tSRO_ACCESS_REPORT *)tagRead->tagEntry.lMsg;++ for(pTagReportData = pReport->listTagReportData;+ NULL != pTagReportData;+ pTagReportData = (LLRP_tSTagReportData *)pTagReportData->hdr.pNextSubParameter)+ {+ TMR_TagReadData trd;++ TMR_TRD_init(&trd);+ TMR_LLRP_parseMetadataFromMessage(reader, &trd, pTagReportData);+ + trd.reader = reader;+ notify_read_listeners(reader, &trd);+ }+ }+#endif+ }+ else+ {+ /* A status stream response */++ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ TMR_Reader_StatsValues stats;+ uint8_t offset, i,j;+ uint16_t flags = 0; ++ TMR_STATS_init(&stats);+ offset = tagRead->bufPointer;++ if (NULL != reader->statusListeners && NULL== reader->statsListeners)+ {+ /* A status stream response */+ TMR_StatusListenerBlock *slb;+ uint8_t index = 0, j;+ TMR_SR_StatusReport report[TMR_SR_STATUS_MAX];+++ /* Get status content flags */+ flags = GETU16(tagRead->tagEntry.sMsg, offset);++ if (0 != (flags & TMR_SR_STATUS_FREQUENCY))+ {+ report[index].type = TMR_SR_STATUS_FREQUENCY;+ report[index].u.fsr.freq = (uint32_t)(GETU24(tagRead->tagEntry.sMsg, offset));+ index ++;+ }+ if (0 != (flags & TMR_SR_STATUS_TEMPERATURE))+ {+ report[index].type = TMR_SR_STATUS_TEMPERATURE;+ report[index].u.tsr.temp = GETU8(tagRead->tagEntry.sMsg, offset);+ index ++;+ }+ if (0 != (flags & TMR_SR_STATUS_ANTENNA))+ {+ uint8_t tx, rx;+ report[index].type = TMR_SR_STATUS_ANTENNA;+ tx = GETU8(tagRead->tagEntry.sMsg, offset);+ rx = GETU8(tagRead->tagEntry.sMsg, offset);++ for (j = 0; j < reader->u.serialReader.txRxMap->len; j++)+ {+ if ((rx == reader->u.serialReader.txRxMap->list[j].rxPort) && (tx == reader->u.serialReader.txRxMap->list[j].txPort))+ {+ report[index].u.asr.ant = reader->u.serialReader.txRxMap->list[j].antenna;+ break;+ }+ }+ index ++;+ }++ report[index].type = TMR_SR_STATUS_NONE;+ /* notify status response to listener */+ pthread_mutex_lock(&reader->listenerLock);+ slb = reader->statusListeners;+ while (slb)+ {+ slb->listener(reader, report, slb->cookie);+ slb = slb->next;+ }+ pthread_mutex_unlock(&reader->listenerLock);++ }+ else if (NULL != reader->statsListeners && NULL== reader->statusListeners)+ {+ /* Get status content flags */+ if ((0x80) > reader->statsFlag)+ {+ offset += 1;+ }+ else+ {+ offset += 2;+ }++ /**+ * preinitialize the rf ontime and the noise floor value to zero+ * berfore getting the reader stats+ */+ for (i = 0; i < stats.perAntenna.max; i++)+ {+ stats.perAntenna.list[i].antenna = 0;+ stats.perAntenna.list[i].rfOnTime = 0;+ stats.perAntenna.list[i].noiseFloor = 0;+ }++ TMR_fillReaderStats(reader, &stats, flags, tagRead->tagEntry.sMsg, offset);++ /**+ * iterate through the per antenna values,+ * If found any 0-antenna rows, copy the+ * later rows down to compact out the empty space.+ */+ for (i = 0; i < reader->u.serialReader.txRxMap->len; i++)+ {+ if (!stats.perAntenna.list[i].antenna)+ {+ for (j = i + 1; j < reader->u.serialReader.txRxMap->len; j++)+ {+ if (stats.perAntenna.list[j].antenna)+ {+ stats.perAntenna.list[i].antenna = stats.perAntenna.list[j].antenna;+ stats.perAntenna.list[i].rfOnTime = stats.perAntenna.list[j].rfOnTime;+ stats.perAntenna.list[i].noiseFloor = stats.perAntenna.list[j].noiseFloor;+ stats.perAntenna.list[j].antenna = 0;+ stats.perAntenna.list[j].rfOnTime = 0;+ stats.perAntenna.list[j].noiseFloor = 0;++ stats.perAntenna.len++;+ break;+ }+ }+ }+ else+ {+ /* Increment the length */+ stats.perAntenna.len++;+ }+ }++ /* store the requested flags for future use */+ stats.valid = reader->statsFlag;++ /* notify status response to listener */+ notify_stats_listeners(reader, &stats);+ }+ else+ {+ /**+ * Control comes here when, user added both the listeners,+ * We should pop up error for that+ **/+ TMR_Status ret;+ ret = TMR_ERROR_UNSUPPORTED;+ notify_exception_listeners(reader, ret);+ }+ }+#ifdef TMR_ENABLE_LLRP_READER+ else+ {+ /**+ * TODO: Handle RFSurveyReports in case of+ * async read+ **/+ }+#endif+ }++ /* Free the memory */+ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ free(tagRead->tagEntry.sMsg);+ }+#ifdef TMR_ENABLE_LLRP_READER+ else+ {+ TMR_LLRP_freeMessage(tagRead->tagEntry.lMsg);+ }+#endif+ free(tagRead);++ /* Now, increment the queue_slots as we have removed one entry */+ sem_post(&reader->queue_slots);+ }+ }+ return NULL;+}+++static void+process_async_response(TMR_Reader *reader)+{+ TMR_Queue_tagReads *tagRead;+ uint16_t flags = 0;++ /* Decrement Queue slots */+ sem_wait(&reader->queue_slots);++ tagRead = (TMR_Queue_tagReads *) malloc(sizeof(TMR_Queue_tagReads));+ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ tagRead->tagEntry.sMsg = (uint8_t *) malloc(TMR_SR_MAX_PACKET_SIZE); /* size of bufResponse */+ memcpy(tagRead->tagEntry.sMsg, reader->u.serialReader.bufResponse, TMR_SR_MAX_PACKET_SIZE);+ tagRead->bufPointer = reader->u.serialReader.bufPointer;+ }+#ifdef TMR_ENABLE_LLRP_READER+ else+ {+ tagRead->tagEntry.lMsg = reader->u.llrpReader.bufResponse[0];+ reader->u.llrpReader.bufResponse[0] = NULL;+ }+#endif++ tagRead->isStatusResponse = reader->isStatusResponse;+ /**+ * Process the tag results here. The stats responses will be extracted+ * later by the parser thread.+ */+ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ if (false == tagRead->isStatusResponse)+ {+ TMR_TRD_init(&tagRead->trd);+ flags = GETU16AT(tagRead->tagEntry.sMsg, 8);+ TMR_SR_parseMetadataFromMessage(reader, &tagRead->trd, flags, &tagRead->bufPointer, tagRead->tagEntry.sMsg);+ TMR_SR_postprocessReaderSpecificMetadata(&tagRead->trd, &reader->u.serialReader);+ tagRead->trd.reader = reader;+ }+ }++ /* Enqueue the tagRead into Queue */+ enqueue(reader, tagRead);+ /* Increment queue_length */+ sem_post(&reader->queue_length);++ if ((false == reader->isStatusResponse) && (TMR_READER_TYPE_SERIAL == reader->readerType))+ {+ reader->u.serialReader.tagsRemainingInBuffer--;+ }+}++static void *+do_background_reads(void *arg)+{+ TMR_Status ret;+ TMR_Reader *reader;+ uint32_t onTime, offTime;+ int32_t sleepTime;+ uint64_t end, now, difftime;++ reader = arg;+ reader->trueAsyncflag = false;++ TMR_paramGet(reader, TMR_PARAM_READ_ASYNCOFFTIME, &offTime);++ while (1)+ {+ /* Wait for reads to be enabled */+ pthread_mutex_lock(&reader->backgroundLock);+ reader->backgroundRunning = false;++ pthread_cond_broadcast(&reader->backgroundCond);+ while (false == reader->backgroundEnabled)+ {+ reader->trueAsyncflag = false;+ pthread_cond_wait(&reader->backgroundCond, &reader->backgroundLock);+ if (true == reader->backgroundThreadCancel)+ {+ /**+ * thread is no more, required,+ * hence, making it terminated+ **/ + goto EXIT;+ }+ }++ TMR_paramGet(reader, TMR_PARAM_READ_ASYNCONTIME, &onTime);++ if (!reader->trueAsyncflag)+ {+ ret = TMR_read(reader, onTime, NULL);+ if (TMR_SUCCESS != ret)+ {+ if ((TMR_ERROR_TIMEOUT == ret) || (TMR_ERROR_CRC_ERROR == ret) ||+ (TMR_ERROR_SYSTEM_UNKNOWN_ERROR == ret) || (TMR_ERROR_TM_ASSERT_FAILED == ret))+ {+ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ reader->u.serialReader.transport.flush(&reader->u.serialReader.transport);+ }+ reader->backgroundEnabled = false;+ }++ /**+ * M5e and its variants hardware does not have a real PA protection.So, doing the read with out+ * antenna may cause the damage to the reader.+ *+ * it's okay to let M6e and its variants continue to operate because it has a PA protection mechanism.+ **/+ if (((TMR_ERROR_HIGH_RETURN_LOSS == ret) || (TMR_ERROR_NO_ANTENNA == ret))+ &&+ ((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])))+ {+ reader->backgroundEnabled = false;+ reader->readState = TMR_READ_STATE_DONE;+ pthread_mutex_unlock(&reader->backgroundLock);+ notify_exception_listeners(reader, ret);+ break;+ }++ notify_exception_listeners(reader, ret);+ if(false == reader->searchStatus)+ {+ /**+ * There could be something wrong in initiating a search, continue the+ * effort to initiate a search. But meanwhile if stopReading()+ * is called, it will be blocked as the search itself is not started.+ * sem_post on read_started will unblock it.+ **/+ reader->readState = TMR_READ_STATE_STARTED;+ pthread_cond_broadcast(&reader->readCond);+ reader->backgroundEnabled = false;+ }+ pthread_mutex_unlock(&reader->backgroundLock);+ continue;+ }+ if(reader->continuousReading)+ {+ /**+ * Set this flag, In case of true async reading+ * we have to send the command only once.+ */+ reader->trueAsyncflag = true;+ }++ /**+ * Set an indication that the reading is started+ **/+ reader->readState = TMR_READ_STATE_ACTIVE;+ pthread_cond_broadcast(&reader->readCond);+ }++ reader->backgroundRunning = true;+ pthread_mutex_unlock(&reader->backgroundLock);++ if (true == reader->continuousReading)+ {+ /** + * Streaming is enabled only in case of M6e, + * read till the end of stream.+ */+ /* Make the time stamp zero for serial reader */+ while (true)+ {+ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ if (false == reader->u.serialReader.isBasetimeUpdated)+ {+ /* Update the base time stamp */+ TMR_SR_updateBaseTimeStamp(reader);+ reader->u.serialReader.isBasetimeUpdated = true;+ }+ }+ ret = TMR_hasMoreTags(reader);+ if (TMR_SUCCESS == ret)+ {+ /* Got a valid message, before posting it to queue+ * check whether we have slots free in the queue or+ * not. Validate this only for Serial reader.+ */+ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ int slotsFree = 0;+ int semret;+ /* Get the semaphore value */+ semret = sem_getvalue(&reader->queue_slots, &slotsFree);+ if (0 == semret)+ {+ if (10 > slotsFree)+ {+ tmr_sleep(20);+ }+ if (0 >= slotsFree)+ {+ /* In a normal case we should not come here.+ * we are here means there is no place to+ * store the tags. May be the read listener+ * is not fast enough.+ * In this case stop the read and exit.+ */+ if (true == reader->searchStatus)+ {+ isBufferOverFlow = true;+ ret = TMR_ERROR_BUFFER_OVERFLOW;+ notify_exception_listeners(reader, ret);+ ret = verifySearchStatus(reader);+ /*isBufferOverFlow = false;+ pthread_mutex_lock(&reader->backgroundLock);+ reader->backgroundEnabled = false;+ reader->readState = TMR_READ_STATE_DONE;+ pthread_cond_broadcast(&reader->readCond);+ pthread_mutex_unlock(&reader->backgroundLock);+ reader->searchStatus = false;*/+ /* Waiting till all slots are free */+ while(slotsFree < TMR_MAX_QUEUE_SLOTS)+ {+ tmr_sleep(20);+ semret = sem_getvalue(&reader->queue_slots, &slotsFree);+ }+ reader->trueAsyncflag = false;+ break;+ }+ }+ }+ }++ /* There is place to store the response. Post it */+ process_async_response(reader);+ }+ else if (TMR_ERROR_CRC_ERROR == ret)+ {+ /* Currently, just drop the corrupted packet,+ * inform the user about the error and move on.+ *+ * TODO: Fix the error by tracing the exact reason of failour+ */+ notify_exception_listeners(reader, ret);+ }+ else if (TMR_ERROR_TAG_ID_BUFFER_FULL == ret)+ {+ /* In case of buffer full error, notify the exception */+ notify_exception_listeners(reader, ret);++ /**+ * If stop read is already called, no need to resumbit the seach again.+ * Just spin in the curent loop and wait for the stop read command response.+ **/ + if (true == reader->searchStatus)+ {+ /**+ * Stop read is not called. Resubmit the search immediately, without user interaction+ * Resetting the trueAsyncFlag will send the continuous read command again.+ */++ ret = TMR_hasMoreTags(reader);+ reader->trueAsyncflag = false;+ reader->hasContinuousReadStarted = false;+ break;+ }+ }+ else+ {+ if ((TMR_ERROR_TIMEOUT == ret) || (TMR_ERROR_SYSTEM_UNKNOWN_ERROR == ret) || + (TMR_ERROR_TM_ASSERT_FAILED == ret) || (TMR_ERROR_LLRP_READER_CONNECTION_LOST == ret))+ {+ notify_exception_listeners(reader, ret);+ /** + * In case of timeout error or CRC error, flush the transport buffer.+ * this avoids receiving of junk response.+ */+ if (TMR_READER_TYPE_SERIAL == reader->readerType)+ {+ /* Handling this fix for serial reader now */+ reader->u.serialReader.transport.flush(&reader->u.serialReader.transport);+ }++ /**+ * Check if reading is finished.+ * If not, send stop command.+ **/+ if (!reader->finishedReading)+ {+ reader->cmdStopReading(reader);+ }++ pthread_mutex_lock(&reader->backgroundLock);+ reader->backgroundEnabled = false;+ reader->readState = TMR_READ_STATE_DONE;+ pthread_cond_broadcast(&reader->readCond);+ pthread_mutex_unlock(&reader->backgroundLock);+++ /**+ * Forced stop + * Reset continuous reading settings, so that+ * the subsequent startReading() call doesn't have+ * any surprises.+ **/+ reader->searchStatus = false;+ reset_continuous_reading(reader, true);+ }+ else if (TMR_ERROR_END_OF_READING == ret)+ {+ while(0 < reader->queue_depth)+ {+ /**+ * reader->queue_depth is greater than zero. i.e.,+ * there are still some tags left in queue.+ * Give some time for the parser to parse all of them.+ * 5 ms sleep shouldn't cause much delay.+ **/+ tmr_sleep(5);+ }++ /**+ * Since the reading is finished, disable this+ * thread.+ **/+ pthread_mutex_lock(&reader->backgroundLock);+ reader->backgroundEnabled = false;+ reader->readState = TMR_READ_STATE_DONE;+ pthread_cond_broadcast(&reader->readCond);+ pthread_mutex_unlock(&reader->backgroundLock);+ break;+ }+ else if ((TMR_ERROR_NO_TAGS_FOUND != ret) && (TMR_ERROR_NO_TAGS != ret) && (TMR_ERROR_TAG_ID_BUFFER_AUTH_REQUEST != ret) && (TMR_ERROR_TOO_BIG != ret))+ {+ /* Any exception other than 0x400 should be notified */+ notify_exception_listeners(reader, ret);+ }+ break;+ }+ }+ }+ else+ {+ /** + * On M5e and its variants, streaming is not supported+ * So still, retain the pseudo-async mechanism+ * Also, when asyncOffTime is non-zero the API should fallback to + * pseudo async mode.+ */++ end = tmr_gettime();++ while (TMR_SUCCESS == TMR_hasMoreTags(reader))+ {+ TMR_TagReadData trd;+ TMR_ReadListenerBlock *rlb;++ TMR_TRD_init(&trd);++ ret = TMR_getNextTag(reader, &trd);+ if (TMR_SUCCESS != ret)+ {+ pthread_mutex_lock(&reader->backgroundLock);+ reader->backgroundEnabled = false;+ pthread_mutex_unlock(&reader->backgroundLock);+ notify_exception_listeners(reader, ret);+ break;+ }++ pthread_mutex_lock(&reader->listenerLock);+ rlb = reader->readListeners;+ while (rlb)+ { + rlb->listener(reader, &trd, rlb->cookie);+ rlb = rlb->next;+ }+ pthread_mutex_unlock(&reader->listenerLock);+ }++ /* Wait for the asyncOffTime duration to pass */+ now = tmr_gettime();+ difftime = now - end;++ sleepTime = offTime - (uint32_t)difftime;+ if(sleepTime > 0)+ {+ tmr_sleep(sleepTime);+ }+ }+EXIT:+ if (reader->backgroundThreadCancel)+ {+ /**+ * oops.. time to exit+ **/ + pthread_exit(NULL);+ }+ }+ return NULL;+}+#endif /* TMR_ENABLE_BACKGROUND_READS */++TMR_Status+TMR_addReadListener(TMR_Reader *reader, TMR_ReadListenerBlock *b)+{+#ifndef SINGLE_THREAD_ASYNC_READ+ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;+#endif+ b->next = reader->readListeners;+ reader->readListeners = b;+#ifndef SINGLE_THREAD_ASYNC_READ+ pthread_mutex_unlock(&reader->listenerLock);+#endif+ return TMR_SUCCESS;+}+#ifdef TMR_ENABLE_BACKGROUND_READS++TMR_Status+TMR_removeReadListener(TMR_Reader *reader, TMR_ReadListenerBlock *b)+{+ TMR_ReadListenerBlock *block, **prev;++ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;++ prev = &reader->readListeners;+ block = reader->readListeners;+ while (NULL != block)+ {+ if (block == b)+ {+ *prev = block->next;+ break;+ }+ prev = &block->next;+ block = block->next;+ }++ pthread_mutex_unlock(&reader->listenerLock);++ if (block == NULL)+ {+ return TMR_ERROR_INVALID;+ }++ return TMR_SUCCESS;+}+++TMR_Status+TMR_addAuthReqListener(TMR_Reader *reader, TMR_AuthReqListenerBlock *b)+{++ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;++ b->next = reader->authReqListeners;+ reader->authReqListeners = b;++ pthread_mutex_unlock(&reader->listenerLock);++ return TMR_SUCCESS;+}+++TMR_Status+TMR_removeAuthReqListener(TMR_Reader *reader, TMR_AuthReqListenerBlock *b)+{+ TMR_AuthReqListenerBlock *block, **prev;++ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;++ prev = &reader->authReqListeners;+ block = reader->authReqListeners;+ while (NULL != block)+ {+ if (block == b)+ {+ *prev = block->next;+ break;+ }+ prev = &block->next;+ block = block->next;+ }++ pthread_mutex_unlock(&reader->listenerLock);++ if (block == NULL)+ {+ return TMR_ERROR_INVALID;+ }++ return TMR_SUCCESS;+}++TMR_Status+TMR_addStatusListener(TMR_Reader *reader, TMR_StatusListenerBlock *b)+{++ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;++ b->next = reader->statusListeners;+ reader->statusListeners = b;++ /*reader->streamStats |= b->statusFlags & TMR_SR_STATUS_CONTENT_FLAGS_ALL;*/++ pthread_mutex_unlock(&reader->listenerLock);++ return TMR_SUCCESS;+}+#endif /* TMR_ENABLE_BACKGROUND_READS */++TMR_Status+TMR_addStatsListener(TMR_Reader *reader, TMR_StatsListenerBlock *b)+{+#ifndef SINGLE_THREAD_ASYNC_READ+ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;+#endif+ b->next = reader->statsListeners;+ reader->statsListeners = b;++ /*reader->streamStats |= b->statusFlags & TMR_SR_STATUS_CONTENT_FLAGS_ALL; */+#ifndef SINGLE_THREAD_ASYNC_READ+ pthread_mutex_unlock(&reader->listenerLock);+#endif+ return TMR_SUCCESS;+}+#ifdef TMR_ENABLE_BACKGROUND_READS++TMR_Status+TMR_removeStatsListener(TMR_Reader *reader, TMR_StatsListenerBlock *b)+{+ TMR_StatsListenerBlock *block, **prev;++ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;++ prev = &reader->statsListeners;+ block = reader->statsListeners;+ while (NULL != block)+ {+ if (block == b)+ {+ *prev = block->next;+ break;+ }+ prev = &block->next;+ block = block->next;+ }++ /* Remove the status flags requested by this listener and reframe */+ /*reader->streamStats = TMR_SR_STATUS_CONTENT_FLAG_NONE;+ {+ TMR_StatusListenerBlock *current;+ current = reader->statusListeners;+ while (NULL != current)+ {+ reader->streamStats |= current->statusFlags;+ current = current->next;+ } + }*/+ + pthread_mutex_unlock(&reader->listenerLock);++ if (block == NULL)+ {+ return TMR_ERROR_INVALID;+ }++ return TMR_SUCCESS;+}++TMR_Status+TMR_removeStatusListener(TMR_Reader *reader, TMR_StatusListenerBlock *b)+{+ TMR_StatusListenerBlock *block, **prev;++ if (0 != pthread_mutex_lock(&reader->listenerLock))+ return TMR_ERROR_TRYAGAIN;++ prev = &reader->statusListeners;+ block = reader->statusListeners;+ while (NULL != block)+ {+ if (block == b)+ {+ *prev = block->next;+ break;+ }+ prev = &block->next;+ block = block->next;+ }++ /* Remove the status flags requested by this listener and reframe */+ /*reader->streamStats = TMR_SR_STATUS_CONTENT_FLAG_NONE;+ {+ TMR_StatusListenerBlock *current;+ current = reader->statusListeners;+ while (NULL != current)+ {+ reader->streamStats |= current->statusFlags;+ current = current->next;+ }+ }*/++ pthread_mutex_unlock(&reader->listenerLock);++ if (block == NULL)+ {+ return TMR_ERROR_INVALID;+ }++ return TMR_SUCCESS;+}++void cleanup_background_threads(TMR_Reader *reader)+{+ if (NULL != reader)+ {+ pthread_mutex_lock(&reader->backgroundLock);+ pthread_mutex_lock(&reader->listenerLock);+ reader->readExceptionListeners = NULL;+ reader->statsListeners = NULL;+ if (true == reader->backgroundSetup)+ {+ /**+ * Signal for the thread exit by + * removing all the pthread lock dependency+ **/+ reader->backgroundThreadCancel = true;+ pthread_cond_broadcast(&reader->backgroundCond);+ }+ pthread_mutex_unlock(&reader->listenerLock);+ pthread_mutex_unlock(&reader->backgroundLock);++ if (true == reader->backgroundSetup)+ {+ /**+ * Wait for the back ground thread to exit+ **/ + pthread_join(reader->backgroundReader, NULL);+ }++ pthread_mutex_lock(&reader->parserLock);+ pthread_mutex_lock(&reader->listenerLock);+ reader->readListeners = NULL;+ if (true == reader->parserSetup)+ {+ pthread_cancel(reader->backgroundParser);+ }+ pthread_mutex_unlock(&reader->listenerLock);+ pthread_mutex_unlock(&reader->parserLock);+ }+}++void*+do_background_receiveAutonomousReading(void * arg)+{+ TMR_Status ret;+ TMR_TagReadData trd;+ TMR_Reader *reader;+ TMR_Reader_StatsValues stats; ++ reader = arg;+ TMR_TRD_init(&trd);++ while (1)+ {+ ret = TMR_SR_receiveAutonomousReading(reader, &trd, &stats);+ if (TMR_SUCCESS == ret)+ {+ if (false == reader->isStatusResponse)+ {+ /* Notify the read listener */+ notify_read_listeners(reader, &trd);+ }+ else+ {+ notify_stats_listeners(reader, &stats);+ }+ }+ }+ return NULL;+}+#endif /* TMR_ENABLE_BACKGROUND_READS */+
+ cbits/api/tmr_filter.h view
@@ -0,0 +1,102 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_FILTER_H+#define _TMR_FILTER_H+/**+ * @file tmr_filter.h+ * @brief Mercury API - Tag Filter Interface+ * @author Brian Fiegel+ * @date 4/18/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 "tmr_tag_data.h"+#include "tmr_gen2.h"+#include "tmr_iso180006b.h"++/**+ * @defgroup filter Tag filters+ *+ * Tag filters cause the reader to limit an inventory to a subset of+ * tags (in a TMR_ReadPlan) or a tag operation to an individual tag+ * (as a parameter to a tag operation function).+ */++#ifdef __cplusplus+extern "C" {+#endif++/** Type of a TMR_TagFilter structure */+typedef enum TMR_FilterType+{+ /** Tag data filter - non-protocol-specific */+ TMR_FILTER_TYPE_TAG_DATA = 0,+ /** Gen2 Select filter */+ TMR_FILTER_TYPE_GEN2_SELECT = 1, + /** ISO180006B Select filter */+ TMR_FILTER_TYPE_ISO180006B_SELECT = 2+} TMR_FilterType;++/**+ * Structure representing a filter or subset of avaliable tags.+ * @ingroup filter+ */+typedef struct TMR_TagFilter+{+ TMR_FilterType type;+ union+ {+ /** A particular tag EPC */+ TMR_TagData tagData;+ /** A Gen2 select operation */+ TMR_GEN2_Select gen2Select;+ /** An ISO180006B select operation */+ TMR_ISO180006B_Select iso180006bSelect;+ } u;+} TMR_TagFilter;++/**+ * Test if a tag matches this filter. Only applies to selects based+ * on the EPC.+ * + * @param filter The filter to test with.+ * @param tag The tag to test.+ * @return true if the tag matches the filter.+ */+bool TMR_TF_match(TMR_TagFilter *filter, TMR_TagData *tag);++TMR_Status TMR_TF_init_tag(TMR_TagFilter *filter, TMR_TagData *tag);++TMR_Status TMR_TF_init_gen2_select(TMR_TagFilter *filter, bool invert,+ TMR_GEN2_Bank bank, uint32_t bitPointer,+ uint16_t maskBitLength, uint8_t *mask);++TMR_Status TMR_TF_init_ISO180006B_select(TMR_TagFilter *filter, bool invert,+ TMR_ISO180006B_SelectOp op,+ uint8_t address, uint8_t mask,+ uint8_t wordData[8]);+#ifdef __cplusplus+}+#endif++#endif /* _TMR_FILTER_H_ */
+ cbits/api/tmr_gen2.h view
@@ -0,0 +1,537 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_GEN2_H+#define _TMR_GEN2_H+/** + * @file tmr_gen2.h + * @brief Mercury API - Gen2 tag information and interfaces+ * @author Brian Fiegel+ * @date 5/7/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.+ */++#ifdef __cplusplus+extern "C" {+#endif++/** Memory lock bits */+typedef enum TMR_GEN2_LockBits+{+ /** User memory bank lock permalock bit */+ TMR_GEN2_LOCK_BITS_USER_PERM = (1 << 0),+ /** User memory bank lock bit */+ TMR_GEN2_LOCK_BITS_USER = (1 << 1),+ /** TID memory bank lock permalock bit */+ TMR_GEN2_LOCK_BITS_TID_PERM = (1 << 2),+ /** TID memory bank lock bit */+ TMR_GEN2_LOCK_BITS_TID = (1 << 3),+ /** EPC memory bank lock permalock bit */+ TMR_GEN2_LOCK_BITS_EPC_PERM = (1 << 4),+ /** EPC memory bank lock bit */+ TMR_GEN2_LOCK_BITS_EPC = (1 << 5),+ /** Access password lock permalock bit */+ TMR_GEN2_LOCK_BITS_ACCESS_PERM = (1 << 6),+ /** Access password lock bit */+ TMR_GEN2_LOCK_BITS_ACCESS = (1 << 7),+ /** Kill password lock permalock bit */+ TMR_GEN2_LOCK_BITS_KILL_PERM = (1 << 8),+ /** Kill password lock bit */+ TMR_GEN2_LOCK_BITS_KILL = (1 << 9)+} TMR_GEN2_LockBits;++/**+ * The arguments to a TMR_lockTag() method for Gen2 tags. + */+typedef struct TMR_GEN2_LockAction+{+ /** The gen2 lock mask bits */+ uint16_t mask;+ /** The gen2 lock action bits */+ uint16_t action;+}TMR_GEN2_LockAction;++/**+ * @ingroup tagauth+ * A 32-bit password (access or kill) in the Gen2 protocol.+ */+typedef uint32_t TMR_GEN2_Password;++/**+ * @ingroup tagauth+ * a 16 byte(128 bit) Gen2 Denatran IAV write credentials+ */+typedef struct TMR_GEN2_DENATRAN_IAV_WriteCredentials+{+ uint8_t value[16];+ uint8_t tagId[8];+ uint8_t credentialLength;+ uint8_t tagIdLength;+}TMR_GEN2_DENATRAN_IAV_WriteCredentials;++/**+ * @ingroup tagauth+ * a 16 byte(128 bit) Gen2 Denatran IAV write sec credentials+ */+typedef struct TMR_GEN2_DENATRAN_IAV_WriteSecCredentials+{+ uint8_t value[16];+ uint8_t data[6];+ uint8_t credentialLength;+ uint8_t dataLength;+}TMR_GEN2_DENATRAN_IAV_WriteSecCredentials;++/** Gen2 memory banks */+typedef enum TMR_GEN2_Bank+{+ /** Reserved bank (kill and access passwords) */+ TMR_GEN2_BANK_RESERVED = 0x0,+ /** EPC memory bank */+ TMR_GEN2_BANK_EPC = 0x1,+ /** TID memory bank */+ TMR_GEN2_BANK_TID = 0x2,+ /** User memory bank */+ TMR_GEN2_BANK_USER = 0x3,+ /** Used to enable the read of additional membanks - reserved mem bank */+ TMR_GEN2_BANK_RESERVED_ENABLED = 0x4,+ /** Used to Filter Gen2 Tag with specified EPC length */+ TMR_GEN2_EPC_LENGTH_FILTER = 0x6,+ /** Gen2 Truncate Option */+ TMR_GEN2_EPC_TRUNCATE = 0x7,+ /** Used to enable the read of additional membanks - epc mem bank */+ TMR_GEN2_BANK_EPC_ENABLED = 0x8,+ /** Used to enable the read of additional membanks - tid mem bank */+ TMR_GEN2_BANK_TID_ENABLED = 0x10,+ /** Used to enable the read of additional membanks - user mem bank */+ TMR_GEN2_BANK_USER_ENABLED = 0x20+} TMR_GEN2_Bank;++/**+ * A single selection operation in the Gen2 protocol.+ * @ingroup filter+ */+typedef struct TMR_GEN2_Select+{+ /** Whether to invert the selection (deselect tags that meet the comparison) */+ bool invert;+ /** The memory bank in which to compare the mask */+ TMR_GEN2_Bank bank;+ /** The location (in bits) at which to begin comparing the mask */+ uint32_t bitPointer;+ /** The length (in bits) of the mask */+ uint16_t maskBitLength;+ /** The mask value to compare with the specified region of tag memory, MSB first */ + uint8_t *mask;+} TMR_GEN2_Select;++/** Gen2 session values */+typedef enum TMR_GEN2_Session+{+ TMR_GEN2_SESSION_MIN= 0x00,+ /** Session 0 */+ TMR_GEN2_SESSION_S0 = 0x00,+ /** Session 1 */+ TMR_GEN2_SESSION_S1 = 0x01,+ /** Session 2 */ + TMR_GEN2_SESSION_S2 = 0x02,+ /** Session 3 */ + TMR_GEN2_SESSION_S3 = 0x03,+ TMR_GEN2_SESSION_MAX = TMR_GEN2_SESSION_S3,+ TMR_GEN2_SESSION_INVALID = TMR_GEN2_SESSION_MAX + 1+} TMR_GEN2_Session;++/** Gen2 divide ratio values */+typedef enum TMR_GEN2_DivideRatio+{+ /** DR of 8 */+ TMR_GEN2_DIVIDE_RATIO_8 = 0,+ /** DR of 64/3 */+ TMR_GEN2_DIVIDE_RATIO_64_3 = 1+} TMR_GEN2_DivideRatio;++/** Gen2 TrExt bit */+typedef enum TMR_GEN2_TrExt+{+ /** No pilot tone in tag response */+ TMR_GEN2_TR_EXT_NO_PILOT_TONE = 0,+ /** Pilot tone in tag response */+ TMR_GEN2_TR_EXT_PILOT_TONE = 1+} TMR_GEN2_TrExt;++/** Gen2 target search algorithms */+typedef enum TMR_GEN2_Target+{+ TMR_GEN2_TARGET_MIN= 0,+ /** Search target A */+ TMR_GEN2_TARGET_A = 0,+ /** Search target B */+ TMR_GEN2_TARGET_B = 1,+ /** Search target A until exhausted, then search target B */+ TMR_GEN2_TARGET_AB = 2,+ /** Search target B until exhausted, then search target A */+ TMR_GEN2_TARGET_BA = 3,+ TMR_GEN2_TARGET_MAX = TMR_GEN2_TARGET_BA,+ TMR_GEN2_TARGET_INVALID = TMR_GEN2_TARGET_MAX+1+}TMR_GEN2_Target;++/** Gen2 tag encoding modulation values */+typedef enum TMR_GEN2_TagEncoding+{+ /** FM0 **/+ TMR_GEN2_FM0 = 0,++ TMR_GEN2_MILLER_MIN = 1,+ /** M = 2 */+ TMR_GEN2_MILLER_M_2 = 1,+ /** M = 4 */+ TMR_GEN2_MILLER_M_4 = 2,+ /** M = 8 */+ TMR_GEN2_MILLER_M_8 = 3,+ TMR_GEN2_MILLER_MAX = TMR_GEN2_MILLER_M_8,+ TMR_GEN2_MILLER_INVALID = TMR_GEN2_MILLER_MAX+1+}TMR_GEN2_TagEncoding;++/** Gen2 link frequencies */+typedef enum TMR_GEN2_LinkFrequency+{+ /** 250 kHz */+ TMR_GEN2_LINKFREQUENCY_250KHZ = 250,+ /** 320 KHZ */+ TMR_GEN2_LINKFREQUENCY_320KHZ = 320,+ /**640 kHz*/+ TMR_GEN2_LINKFREQUENCY_640KHZ = 640,+ TMR_GEN2_LINKFREQUENCY_MAX = 640,+ TMR_GEN2_LINKFREQUENCY_INVALID = TMR_GEN2_LINKFREQUENCY_MAX + 1,+} TMR_GEN2_LinkFrequency;++/** Gen2 Protcol Extension parameters */+typedef enum TMR_GEN2_ProtocolExtension+{+ TMR_GEN2_PROTOCOLEXTENSION_LICENSE_NONE = 0,+ TMR_GEN2_PROTOCOLEXTENSION_LICENSE_IAV_DENATRAN = 1+}TMR_GEN2_ProtocolExtension;++/** Gen2 bap parameters */+typedef struct TMR_GEN2_Bap+{+ /* Default to 3000 us */+ int32_t powerUpDelayUs;+ /* Default to 20000 us */+ int32_t freqHopOfftimeUs;+}TMR_GEN2_Bap;++/** Gen2v2 untraceably hides part of EPC memory or not */+typedef enum TMR_GEN2_UNTRACEABLE_Epc+{+ /* Tag exposes EPC memory */+ EPC_SHOW = 0,+ /*Tag untraceably hides EPC memory above that*/+ EPC_HIDE = 1+}TMR_GEN2_UNTRACEABLE_Epc;++/** Gen2v2 untraceably hides part of TID memory or not */+typedef enum TMR_GEN2_UNTRACEABLE_Tid+{+ /* Tag exposes TID memory. */+ HIDE_NONE = 0,+ /*Tag untraceably hides all of TID memory.*/+ HIDE_ALL = 1,+ /* Tags allocation class identifier is E0h then the + Tag untraceably hides TID memory above 10h,inclusive;+ if the Tags allocation class identifier is E2h then the+ Tag untraceably hides TID memory above 20h, inclusive. */+ HIDE_SOME = 2,+ /* RFU */+ TID_RFU = 3+}TMR_GEN2_UNTRACEABLE_Tid;++/** Gen2v2 untraceably hides part of UserMemory memory or not */+typedef enum TMR_GEN2_UNTRACEABLE_UserMemory+{+ /* Tag exposes User memory */+ SHOW = 0,+ /*Tag untraceably hides User memory*/+ HIDE = 1+}TMR_GEN2_UNTRACEABLE_UserMemory;++/** specifies Gen2v2 Tags operating range */+typedef enum TMR_GEN2_UNTRACEABLE_Range+{+ /* Tag persistently enables normal operating range */+ NORMAL = 0,+ /*Tag persistently enables reduced operating range.*/+ REDUCED = 1,+ /* Tag temporarily toggles its operating range*/+ TOGGLE_TEMPORARLY = 2,+ /* RFU */+ RFU = 3+}TMR_GEN2_UNTRACEABLE_Range;++/** Authentication KeyId */+typedef enum TMR_NXP_KeyId+{+ /* key0*/+ KEY0 = 0,+ /*Key1*/+ KEY1 = 1+}TMR_NXP_KeyId;++/** Memory profile for the addition of custom data */+typedef enum TMR_NXP_Profile+{+ /* EPC memory bank */+ EPC = 0,+ /* TID memory bank */+ TID = 1,+ /* User memory bank */+ USER = 2+}TMR_NXP_Profile;++/** Gen2 Tari values */+typedef enum TMR_GEN2_Tari+{+ /** Tari of 25 microseconds */+ TMR_GEN2_TARI_25US = 0,+ /** Tari of 12.5 microseconds */+ TMR_GEN2_TARI_12_5US = 1,+ /** Tari of 6.25 microseconds */+ TMR_GEN2_TARI_6_25US = 2,+ TMR_GEN2_TARI_MAX = 2,+ TMR_GEN2_TARI_INVALID = TMR_GEN2_TARI_MAX + 1,+} TMR_GEN2_Tari;++/** Gen2 WriteMode */+typedef enum TMR_GEN2_WriteMode+{+ /** WORD ONLY */+ TMR_GEN2_WORD_ONLY = 0,+ /** BLOCK ONLY */+ TMR_GEN2_BLOCK_ONLY = 1,+ /** BLOCK FALLBACK */+ TMR_GEN2_BLOCK_FALLBACK = 2,++} TMR_GEN2_WriteMode;++/**+ * Defines the values for different gen2 silicon types.+ */+typedef enum TMR_SR_GEN2_SiliconType+{+ TMR_SR_GEN2_SILICON_ANY = 0x00,+ TMR_SR_GEN2_ALIEN_HIGGS_SILICON = 0x01,+ TMR_SR_GEN2_NXP_G2X_SILICON = 0x02,+ TMR_SR_GEN2_ALIEN_HIGGS3_SILICON = 0x05,+ TMR_SR_GEN2_NXP_G2I_SILICON = 0x07,+ TMR_SR_GEN2_IMPINJ_MONZA4_SILICON = 0x08,+ TMR_SR_GEN2_IDS_SL900A_SILICON = 0x0A,+ TMR_SR_GEN2_DENATRAN_IAV_SILICON = 0x0B,+ TMR_SR_GEN2_NXP_AES_UCODE = 0x0C,+}TMR_SR_GEN2_SiliconType;++/**+ * The argument to a ChangeConfig command for NXP G2iL tags+ * User can set the configWord directly using the 16 bit 'data' field.+ * Otherwise, provides an option to individually set each flag.+ * Instance of TMR_NXP_ConfigWord must be initialized before using either+ * by declaring it as 'static' or by using the constructor routine+ * TMR_init_NXP_ConfigWord() method.+ */+typedef union TMR_NXP_ConfigWord+{+ uint16_t data;+ /*+ * Since the bit-fields are used, The bits in configWord are shown from+ * Least significant bit to Most significant bit.+ */+ struct+ {+ /** Least significant bit */+ /** PSF alarm flag (Permanently stored in tag memory)*/+ unsigned psfAlarm:1;+ /** Read protect TID bank (permanently stored in tag memory)*/+ unsigned readProtectTID:1;+ /** Read protect EPC bank (Permanently stored in tag memory)*/+ unsigned readProtectEPC:1;+ /** Read protect User memory bank (permanently stored in tag memory)*/+ unsigned readProtectUser:1;+ /** Read range reduction on/off (permanently stored in tag memory)*/+ unsigned privacyMode:1;+ /** Digital output (permanently stored in tag memory)*/+ unsigned digitalOutput:1;+ /** Maximum backscatter strength (permanently stored in tag memory)*/+ unsigned maxBackscatterStrength:1;+ /** Conditional Read Range Reduction open/short (permanently stored in tag memory)*/+ unsigned conditionalReadRangeReduction_openShort:1;+ /** Conditional Read Range Reduction on/off (permanently stored in tag memory)*/+ unsigned conditionalReadRangeReduction_onOff:1;+ /** Transparent mode data/raw (reset at power up)*/+ unsigned dataMode:1;+ /** Transparent mode on/off (reset at power up)*/+ unsigned transparentMode:1;+ /** Invert digital output (reset at power up)*/+ unsigned invertDigitalOutput:1;+ /** RFU 3*/+ unsigned RFU3:1;+ /** RFU 2*/+ unsigned RFU2:1;+ /** External supply flag digital input (read only)*/+ unsigned externalSupply:1;+ /** Tamper alarm flag (Read only)*/+ unsigned tamperAlarm:1; + /** Most significant bit */+ }bits;+}TMR_NXP_ConfigWord;++/**+ * TMR_Monza4_ControlByte is an argument to Monza4 QTReadWrite custom command+ * User can set the control byte directly using the 8 bit 'data' field.+ * Otherwise, provides an option to individually set each flag.+ * Instance of TMR_Monza4_ControlByte must be initialized before using either+ * by declaring it as 'static' (or initializing it to 0) or by using the constructor routine+ * TMR_init_Monza4_ControlByte() method.+ */+typedef union TMR_Monza4_ControlByte+{+ /* 8-bit control byte */+ uint8_t data;+ /*+ * Since bit-fields are used, The bits in control Byte are shown from+ * Least significant bit to Most significant bit.+ */+ struct + {+ /**+ * The following bits are Reserved for Future Use. And will be ignored.+ * RFU_TM's are ThingMagic specific RFU bits, and RFU_Impinj bits are + * as per the Monza4 specification.+ */+ unsigned RFU_TM0:1;+ unsigned RFU_TM1:1;+ unsigned RFU_TM2:1;+ unsigned RFU_TM3:1;+ unsigned RFU_Impinj4:1;+ unsigned RFU_Impinj5:1;+ /**+ * If Read/Write=1, the Persistence field indicates whether the QT control is+ * written to nonvolatile (NVM) or volatile memory.+ * Persistence=0 means write to volatile memory. + * Persistence=1 means write to NVM memory+ */+ unsigned persistence:1;+ /**+ * The Read/Write bit indicates whether the tag reads or writes QT control data.+ * Read/Write=0 means read the QT control bits in cache.+ * Read/Write=1 means write the QT control bits+ */+ unsigned readWrite:1; + }bits;+}TMR_Monza4_ControlByte;++/**+ * TMR_Monza4_Payload is an argument to Monza4 QTReadWrite custom command+ * User can set the payload directly using the 16 bit 'data' field.+ * Otherwise, provides an option to individually set each flag.+ * Instance of TMR_Monza4_Payload must be initialized before using either+ * by declaring it as 'static' (or initializing it to 0) or by using the constructor routine+ * TMR_init_Monza4_Payload() method.+ * This field controls the QT functionality. These bits are ignored when the+ * Read/Write field equals 0 in control byte.+ */+typedef union TMR_Monza4_Payload+{+ /** 16-bit payload */+ uint16_t data;+ /*+ * Since bit-fields are used, The bits in payload are shown from+ * Least significant bit to Most significant bit.+ */+ struct+ {+ /**+ * The following bits are Reserved for Future Use. And will be ignored.+ * Tag will always return these bits as zero.+ * All these RFU bits are as per the monza4 spec.+ */+ unsigned RFU0:1;+ unsigned RFU1:1;+ unsigned RFU2:1;+ unsigned RFU3:1;+ unsigned RFU4:1;+ unsigned RFU5:1;+ unsigned RFU6:1;+ unsigned RFU7:1;+ unsigned RFU8:1;+ unsigned RFU9:1;+ unsigned RFU10:1;+ unsigned RFU11:1;+ unsigned RFU12:1;+ unsigned RFU13:1;+ /**+ * Bit 14 + * 1: Tag uses Public Memory Map + * 0: Tag uses Private Memory Map+ */+ unsigned QT_MEM:1;+ /**+ * Bit 15 (MSB) is first transmitted bit of the payload field.+ * Bit # Name Description+ * 1: Tag reduces range if in or about to be in OPEN or SECURED state+ * 0: Tag does not reduce range+ */+ unsigned QT_SR:1;+ }bits;+}TMR_Monza4_Payload;++typedef struct TMR_GEN2_HibikiSystemInformation+{+ uint16_t infoFlags; /* Indicates whether the banks are present and Custom Commands are implemented*/ + uint8_t reservedMemory; /* Indicates the size of this memory bank in words*/+ uint8_t epcMemory; /* Indicates the size of this memory bank in words*/+ uint8_t tidMemory; /* Indicates the size of this memory bank in words*/+ uint8_t userMemory; /* Indicates the size of this memory bank in words*/+ uint8_t setAttenuate; /**/+ uint16_t bankLock; /* Indicates Lock state for this type of lock*/+ uint16_t blockReadLock; /* Indicates Lock state for this type of lock*/+ uint16_t blockRwLock; /* Indicates Lock state for this type of lock*/+ uint16_t blockWriteLock;/* Indicates Lock state for this type of lock*/+} TMR_GEN2_HibikiSystemInformation;++/** Size allocated for storing PC data in TMR_GEN2_TagData */+#define TMR_GEN2_MAX_PC_BYTE_COUNT (6)+/**+ * Gen2-specific per-tag data+ */+typedef struct TMR_GEN2_TagData+{ + /** Length of the tag PC */+ uint8_t pcByteCount;+ /** Tag PC */+ uint8_t pc[TMR_GEN2_MAX_PC_BYTE_COUNT];+} TMR_GEN2_TagData;++++#ifdef __cplusplus+}+#endif++#endif /*_TMR_GEN2_H*/
+ cbits/api/tmr_gpio.h view
@@ -0,0 +1,55 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_GPIO_H+#define _TMR_GPIO_H+/**+ * @file tmr_gpio.h+ * @brief Mercury API - GPIO Definitons+ * @author Brian Fiegel+ * @date 4/18/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.+ */++#ifdef __cplusplus+extern "C" {+#endif++/**+ * The identity and state of a single GPIO pin.+ */+typedef struct TMR_GpioPin+{+ /** The ID number of the pin. */+ uint8_t id;+ /** Whether the pin is in the high state. */+ bool high;+ /** The direction of the pin */+ bool output;+}TMR_GpioPin;+++#ifdef __cplusplus+}+#endif++#endif /* _TMR_GPIO_H_ */
+ cbits/api/tmr_ipx.h view
@@ -0,0 +1,41 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_IPX_H+#define _TMR_IPX_H+/**+ * @file tmr_ipx.h + * @brief Mercury API - iPx tag information and interfaces+ * @author Nathan Williams+ * @date 1/21/2010+ */++/*+ * Copyright (c) 2010 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.+ */++#ifdef __cplusplus+extern "C" {+#endif++#ifdef __cplusplus+}+#endif++#endif /*_TMR_IPX_H*/
+ cbits/api/tmr_iso180006b.h view
@@ -0,0 +1,108 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_ISO180006B_H+#define _TMR_ISO180006B_H+/**+ * @file tmr_iso180006b.h + * @brief Mercury API - ISO180006B tag information and interfaces+ * @author Brian Fiegel+ * @date 5/7/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.+ */++#ifdef __cplusplus+extern "C" {+#endif++/** ISO180006B Select operations */+typedef enum TMR_ISO180006B_SelectOp+{+ /** Select if tag data matches op data */+ TMR_ISO180006B_SELECT_OP_EQUALS = 0,+ /** Select if tag data does not match op data */+ TMR_ISO180006B_SELECT_OP_NOT_EQUALS = 1,+ /** Select if tag data is less than op data */+ TMR_ISO180006B_SELECT_OP_LESS_THAN = 2,+ /** Select if tag data is greater than op data */+ TMR_ISO180006B_SELECT_OP_GREATER_THAN = 3+} TMR_ISO180006B_SelectOp;++/**+ * A single selection operation in the ISO18000-6B protocol.+ * @ingroup filter+ */ +typedef struct TMR_ISO180006B_Select+{+ /** Whether to invert the selection (deselect tags that meet the comparison). */+ bool invert;+ /** The operation to use to compare the tag data to the provided data. */+ TMR_ISO180006B_SelectOp op;+ /** The address of the tag memory to compare to the provided data. */+ uint8_t address;+ /** Bitmask of which of the eight provided data bytes to compare to the tag memory. */+ uint8_t mask;+ /** The data to compare. Exactly eight bytes. */+ uint8_t data[8];+} TMR_ISO180006B_Select;++/**+ * The arguments to a TMR_lockTag() method for ISO18000-6B tags. + * Represents the byte to be locked.+ */+typedef struct TMR_ISO180006B_LockAction+{+ /** The memory address of the byte to lock */+ uint8_t address;+} TMR_IS0180006B_LockAction;++/** ISO180006B link frequencies */+typedef enum TMR_ISO180006B_LinkFrequency+{+ /** 40 kHz */+ TMR_ISO180006B_LINKFREQUENCY_40KHZ = 40,+ /** 160 kHz */+ TMR_ISO180006B_LINKFREQUENCY_160KHZ = 160,+} TMR_ISO180006B_LinkFrequency;++/** ISO180006B modulation depth */+typedef enum TMR_ISO180006B_ModulationDepth+{+ /** 99 percent modulation */+ TMR_ISO180006B_Modulation99percent = 0x00,+ /** 11 percent modulation */+ TMR_ISO180006B_Modulation11percent = 0x01+}TMR_ISO180006B_ModulationDepth;++/** ISO180006B Delimiter */+typedef enum TMR_ISO180006B_Delimiter+{+ /** delimiter 1*/+ TMR_ISO180006B_Delimiter1 = 0x01,+ /** delimiter 4 */+ TMR_ISO180006B_Delimiter4 = 0x04+}TMR_ISO180006B_Delimiter;+#ifdef __cplusplus+}+#endif++#endif /*_TMR_ISO180006B_H*/
+ cbits/api/tmr_llrp_reader.h view
@@ -0,0 +1,278 @@+#ifndef _TMR_LLRP_READER_H+#define _TMR_LLRP_READER_H+/**+ * @file tmr_llrp_reader.h+ * @brief Mercury API - LLRP Reader interface+ * @author Somu+ * @date 05/23/2011+ */++/*+ * Copyright (c) 2011 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 <pthread.h>+#include <semaphore.h>+#include "tmr_region.h"+#include "tmr_tag_protocol.h"+#include "tmr_serial_transport.h"+#include "tmr_params.h"+#include "ltkc.h"+#include "tm_ltkc.h"++#ifdef __cplusplus+extern "C" {+#endif+ +#define TM_MANUFACTURER_ID 26554+#define TMR_LLRP_SYNC_MAX_ROSPECS 256 +#define TMR_LLRP_MAX_RFMODE_ENTRIES 7+#define TMR_LLRP_READER_DEFAULT_PORT 5084++/**+ * This structure is returned from cmdGetRFControl+ **/+typedef struct TMR_LLRP_RFControl+{+ /* RFMode index */+ llrp_u16_t index;++ /* Tari */+ TMR_GEN2_Tari tari;++} TMR_LLRP_RFControl;++/**+ * Gen2 RF Mode Table structure.+ * Currently we use only BLF and Encoding from + * RF Mode table. + **/+typedef struct TMR_LLRP_C1G2RFModeTable+{+ /* Gen2 BLF */+ TMR_GEN2_LinkFrequency blf;++ /* Gen2 Tag encoding */+ TMR_GEN2_TagEncoding m;++ /* Min Tari Value*/+ TMR_GEN2_Tari minTari;++ /* Max Tari Value*/+ TMR_GEN2_Tari maxTari;++} TMR_LLRP_C1G2RFModeTable;++/**+ * This structure is returned from cmdGetReaderCapabilities.+ **/+typedef struct TMR_LLRP_ReaderCapabilities+{+ /** Country code */+ llrp_u16_t countryCode;++ /** Reader model */+ uint32_t model;++ /** Software version */+ char softwareVersion[128];++ /** Power level table */+ TMR_uint16List powerTable;+ uint16_t powerList[255];++ /** Frequency table */+ TMR_uint32List freqTable;+ uint32_t freqList[64];++ union+ {+ /** + * Gen2 RF Mode tables+ * FIXME: Max RFModes available for now is 5.+ * and the index start from 1-5+ **/+ TMR_LLRP_C1G2RFModeTable gen2Modes[TMR_LLRP_MAX_RFMODE_ENTRIES];+ /**+ * Can have RF Mode table specific to + * other protocols. + **/+ } u;++} TMR_LLRP_ReaderCapabilities;++/** + * This struture used to+ * moniter the protocol+ * in read plan+ **/+typedef struct ROSpecProtocolTable+{+ /* rospecid */+ uint8_t rospecID;+ /*protocol */+ TMR_TagProtocol rospecProtocol;+}ROSpecProtocolTable;++/**+ * This is the structure used to+ * store the unhandled async response+ **/+typedef struct TMR_LLRP_UnhandledAsyncResponse+{+ /** Buffer to hold the LLRP message */+ LLRP_tSMessage *lMsg;+}TMR_LLRP_UnhandledAsyncResponse;++/**+ * LLRP reader structure+ */+typedef struct TMR_LLRP_LlrpReader+{+ /* @privatesection */+ LLRP_tSTypeRegistry * pTypeRegistry;+ LLRP_tSConnection * pConn;+ int portNum;+ llrp_u32_t msgId;+ llrp_u32_t roSpecId, accessSpecId;+ llrp_u16_t opSpecId;++ TMR_AntennaMapList *txRxMap;+ uint32_t transportTimeout;+ uint32_t commandTimeout;+ TMR_Region regionId;+ TMR_GEN2_Password gen2AccessPassword;++ /* Static storage for the default map */+ TMR_AntennaMap staticTxRxMapData[TMR_SR_MAX_ANTENNA_PORTS];+ TMR_AntennaMapList staticTxRxMap;++ uint32_t portMask;+ /* Bit mask of supported protocol list */+ uint32_t supportedProtocols;++ TMR_TagProtocol currentProtocol;++ /* Buffer to store additional error message */+ /* TODO: Change TMR_SR_MAX_PACKET_SIZE to appropriate value */+ char errMsg[TMR_SR_MAX_PACKET_SIZE];++ /* Large bitmask that stores whether each parameter's presence+ * is known or not.+ */+ uint32_t paramConfirmed[TMR_PARAMWORDS];++ /* Large bitmask that, if the corresponding bit in paramConfirmed is set,+ * stores whether each parameter is present or not.+ */+ uint32_t paramPresent[TMR_PARAMWORDS];+ + /* Number of tags reported by reader */+ int tagsRemaining;++ /* Array of LLRP_tSMessage pointers holding the tag read responses */+ LLRP_tSMessage **bufResponse;++ /* bufResponse read index */+ uint8_t bufPointer;+ uint8_t bufIndex;++ /* Pointer to buffer holding the tag read data */+ LLRP_tSTagReportData *pTagReportData;++ int searchTimeoutMs;++ /* Cache LLRP Reader Capabilities */+ TMR_LLRP_ReaderCapabilities capabilities;++ /**+ * LLRP Asynchronous receiver to handle+ * keep alive and events.+ **/+ pthread_t llrpReceiver;+ bool receiverSetup, receiverRunning, receiverEnabled;+ pthread_cond_t receiverCond;+ int numOfROSpecEvents;+ /** The above variables must be protected by this lock */+ pthread_mutex_t receiverLock;++ /**+ * For monitoring keepalives:+ * Used only in case of async reading+ **/+ uint64_t ka_start, ka_now;+ bool get_report, reportReceived;+ /**+ * For monitoring protcol type+ * in case of multiprotocol read+ **/+ ROSpecProtocolTable readPlanProtocol[TMR_SR_MAX_PACKET_SIZE];++ /**+ * For monitoring the unhandeled responses+ * during the async read+ **/+ TMR_LLRP_UnhandledAsyncResponse unhandledAsyncResponse;+ /** To check the status of async unhandled responses */+ bool isResponsePending;+ /** To cancel the receiver thread */+ bool threadCancel;+ /* To hold the No.of Keep alives missed count*/+ uint8_t keepAliveAckMissCnt;+}TMR_LLRP_LlrpReader;+++TMR_Status TMR_LLRP_connect(TMR_Reader *reader);+TMR_Status TMR_LLRP_destroy(TMR_Reader *reader);+TMR_Status TMR_LLRP_hasMoreTags(TMR_Reader *reader); +TMR_Status TMR_LLRP_getNextTag(TMR_Reader *reader, TMR_TagReadData *trd);+TMR_Status TMR_LLRP_executeTagOp(TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *filter, TMR_uint8List *data);+TMR_Status TMR_LLRP_gpiGet(struct TMR_Reader *reader,uint8_t *count, TMR_GpioPin state[]);+TMR_Status TMR_LLRP_gpoSet(struct TMR_Reader *reader,uint8_t count, const TMR_GpioPin state[]);+TMR_Status TMR_LLRP_readTagMemBytes(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t addreass,+ uint16_t count,uint8_t data[]);+TMR_Status TMR_LLRP_readTagMemWords(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t address,+ uint16_t count, uint16_t *data);+TMR_Status TMR_LLRP_writeTagMemBytes(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t addreass,+ uint16_t count,const uint8_t data[]);+TMR_Status TMR_LLRP_writeTagMemWords(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t address,+ uint16_t count, const uint16_t *data);+TMR_Status TMR_LLRP_firmwareLoad( TMR_Reader *reader, void *cookie, TMR_FirmwareDataProvider provider);+TMR_Status TMR_LLRP_writeTag(TMR_Reader *reader, const TMR_TagFilter *filter, const TMR_TagData *data);+TMR_Status TMR_LLRP_killTag(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ const TMR_TagAuthentication *auth);+TMR_Status TMR_LLRP_lockTag(struct TMR_Reader *reader,const TMR_TagFilter *filter, TMR_TagLockAction *action);+TMR_Status TMR_LLRP_reboot(struct TMR_Reader *reader);+/**+ * Initialize LLRP reader.+ */+TMR_Status TMR_LLRP_LlrpReader_init(TMR_Reader *reader);++TMR_Status TMR_LLRP_read(struct TMR_Reader *reader, uint32_t timeoutMs, int32_t *tagCount);+#ifdef __cplusplus+}+#endif++#endif /* _TMR_LLRP_READER_H */
+ cbits/api/tmr_param.c view
@@ -0,0 +1,152 @@+/**+ * @file tmr_param.c+ * @brief Mercury API - parameter string implementation+ * @author Nathan Williams+ * @date 11/3/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 <string.h>++#include "tm_reader.h"+#include "tmr_utils.h"++#ifdef TMR_ENABLE_PARAM_STRINGS++static const char *paramNames[1 + TMR_PARAM_MAX] = {+ "", /* TMR_PARAM_NONE */+ "/reader/baudRate", /* TMR_PARAM_BAUDRATE */+ "/reader/probeBaudRates",/* TMR_PARAM_PROBEBAUDRATES */+ "/reader/commandTimeout", /* TMR_PARAM_COMMANDTIMEOUT */+ "/reader/transportTimeout", /* TMR_PARAM_TRANSPORTTIMEOUT */+ "/reader/powerMode", /* TMR_PARAM_POWERMODE */+ "/reader/userMode", /* TMR_PARAM_USERMODE */+ "/reader/antenna/checkPort", /* TMR_PARAM_ANTENNA_CHECKPORT */+ "/reader/antenna/portList", /* TMR_PARAM_ANTENNA_PORTLIST */+ "/reader/antenna/connectedPortList", /* TMR_PARAM_ANTENNA_CONNECTEDPORTLIST */+ "/reader/antenna/portSwitchGpos", /* TMR_PARAM_ANTENNA_PORTSWITCHGPOS */+ "/reader/antenna/settlingTimeList", /* TMR_PARAM_ANTENNA_SETTLINGTIMELIST */+ "/reader/antenna/returnLoss", /* TMR_PARAM_ANTENNA_RETURNLOSS */+ "/reader/antenna/txRxMap", /* TMR_PARAM_ANTENNA_TXRXMAP */+ "/reader/gpio/inputList", /* TMR_PARAM_GPIO_INPUTLIST */+ "/reader/gpio/outputList", /* TMR_PARAM_GPIO_OUTPUTLIST */+ "/reader/gen2/accessPassword", /* TMR_PARAM_GEN2_ACCESSPASSWORD */+ "/reader/gen2/q", /* TMR_PARAM_GEN2_Q */+ "/reader/gen2/tagEncoding", /* TMR_PARAM_GEN2_TAGENCODING*/+ "/reader/gen2/session", /* TMR_PARAM_GEN2_SESSION */+ "/reader/gen2/target", /* TMR_PARAM_GEN2_TARGET */+ "/reader/gen2/BLF", /* TMR_PARAM_GEN2_BLF */+ "/reader/gen2/tari", /* TMR_PARAM_GEN2_TARI */+ "/reader/gen2/writeMode",/*TMR_PARAM_GEN2_WRITEMODE*/+ "/reader/gen2/bap", /* TMR_PARAM_GEN2_BAP */+ "/reader/gen2/protocolExtension", /* TMR_PARAM_GEN2_PROTOCOLEXTENSION */+ "/reader/iso180006b/BLF", /* TMR_PARAM_ISO18000_6B_LINKFREQUENCY */+ "/reader/iso180006b/modulationDepth", /* TMR_PARAM_ISO18000_6B_MODULATION_DEPTH */+ "/reader/iso180006b/delimiter", /* TMR_PARAM_ISO18000_6B_DELIMITER */+ "/reader/read/asyncOffTime", /* TMR_PARAM_READ_ASYNCOFFTIME */+ "/reader/read/asyncOnTime", /* TMR_PARAM_READ_ASYNCONTIME */+ "/reader/read/plan", /* TMR_PARAM_READ_PLAN */+ "/reader/radio/enablePowerSave", /* TMR_PARAM_RADIO_ENABLEPOWERSAVE */+ "/reader/radio/powerMax", /* TMR_PARAM_RADIO_POWERMAX */+ "/reader/radio/powerMin", /* TMR_PARAM_RADIO_POWERMIN */+ "/reader/radio/portReadPowerList", /* TMR_PARAM_RADIO_PORTREADPOWERLIST */+ "/reader/radio/portWritePowerList", /* TMR_PARAM_RADIO_PORTWRITEPOWERLIST */+ "/reader/radio/readPower", /* TMR_PARAM_RADIO_READPOWER */+ "/reader/radio/writePower", /* TMR_PARAM_RADIO_WRITEPOWER */+ "/reader/radio/temperature", /* TMR_PARAM_RADIO_TEMPERATURE */+ "/reader/tagReadData/recordHighestRssi", /* TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI */+ "/reader/tagReadData/reportRssiInDbm", /* TMR_PARAM_TAGREADDATA_REPORTRSSIINDBM */+ "/reader/tagReadData/uniqueByAntenna", /* TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA */+ "/reader/tagReadData/uniqueByData", /* TMR_PARAM_TAGREADDATA_UNIQUEBYDATA */+ "/reader/tagop/antenna", /* TMR_PARAM_TAGOP_ANTENNA */+ "/reader/tagop/protocol", /* TMR_PARAM_TAGOP_PROTOCOL */+ "/reader/version/hardware", /* TMR_PARAM_VERSION_HARDWARE */+ "/reader/version/serial", /* TMR_PARAM_VERSION_SERIAL */+ "/reader/version/model", /* TMR_PARAM_VERSION_MODEL */+ "/reader/version/software", /* TMR_PARAM_VERSION_SOFTWARE */+ "/reader/version/supportedProtocols", /* TMR_PARAM_VERSION_SUPPORTEDPROTOCOLS */+ "/reader/region/hopTable", /* TMR_PARAM_REGION_HOPTABLE */+ "/reader/region/hopTime", /* TMR_PARAM_REGION_HOPTIME */+ "/reader/region/id", /* TMR_PARAM_REGION_ID */+ "/reader/region/supportedRegions", /* TMR_PARAM_REGION_SUPPORTEDREGIONS */+ "/reader/region/lbt/enable", /* TMR_PARAM_REGION_LBT_ENABLE */+ "/reader/licenseKey", /* TMR_PARAM_LICENSE_KEY */+ "/reader/userConfig", /* TMR_PARAM_USER_CONFIG */+ "/reader/radio/enableSJC", /* TMR_PARAM_RADIO_ENABLESJC */+ "/reader/extendedEpc", /* TMR_PARAM_EXTENDEDEPC */+ "/reader/statistics", /* TMR_PARAM_READER_STATISTICS */+ "/reader/stats", /* TMR_PARAM_READER_STATS */+ "/reader/uri", /* TMR_PARAM_URI */+ "/reader/version/productGroupID", /* TMR_PARAM_PRODUCT_GROUP_ID */+ "/reader/version/productGroup", /* TMR_PARAM_PRODUCT_GROUP */+ "/reader/version/productID", /* TMR_PARAM_PRODUCT_ID */+ "/reader/tagReadData/tagopSuccesses", /* TMR_PARAM_TAGREADATA_TAGOPSUCCESSCOUNT */+ "/reader/tagReadData/tagopFailures", /* TMR_PARAM_TAGREADATA_TAGOPFAILURECOUNT */+ "/reader/status/antennaEnable", /* TMR_PARAM_STATUS_ENABLE_ANTENNAREPORT */+ "/reader/status/frequencyEnable", /* TMR_PARAM_STATUS_ENABLE_FREQUENCYREPORT */+ "/reader/status/temperatureEnable", /* TMR_PARAM_STATUS_ENABLE_TEMPERATUREREPORT */+ "/reader/tagReadData/enableReadFilter", /* TMR_PARAM_TAGREADDATA_ENABLEREADFILTER */+ "/reader/tagReadData/readFilterTimeout", /* TMR_PARAM_TAGREADDATA_READFILTERTIMEOUT */+ "/reader/tagReadData/uniqueByProtocol", /* TMR_PARAM_TAGREADDATA_UNIQUEBYPROTOCOL */+ "/reader/description", /* TMR_PARAM_READER_DESCRIPTION */+ "/reader/hostname", /* TMR_PARAM_READER_HOSTNAME */+ "/reader/currentTime", /* TMR_PARAM_CURRENTTIME */+ "/reader/gen2/writeReplyTimeout", /* TMR_PARAM_READER_WRITE_REPLY_TIMEOUT */+ "/reader/gen2/writeEarlyExit", /* /reader/gen2/writeEarlyExit */+ "/reader/stats/enable", /* /reader/stats/enable */+ "/reader/trigger/read/Gpi", /* TMR_PARAM_TRIGGER_READ_GPI */+ "/reader/metadataflags", /* TMR_PARAM_METADATAFLAG */+ "/reader/licensedFeatures", /* TMR_PARAM_LICENSED_FEATURES */+ "/reader/selectedProtocols", /* TMR_PARAM_SELECTED_PROTOCOLS */+};+++TMR_Param+TMR_paramID(const char *name)+{+ int i;++ for (i = 1 ; i <= TMR_PARAM_MAX ; i++)+ {+ if (0 == strcasecmp(name, paramNames[i]))+ {+ return (TMR_Param)i;+ }+ }++ return TMR_PARAM_NONE;+}++const char *+TMR_paramName(TMR_Param key)+{++ if (key <= TMR_PARAM_MAX)+ {+ return paramNames[key];+ }+ return NULL;+}++#endif /* TMR_ENABLE_PARAM_STRINGS */
+ cbits/api/tmr_params.h view
@@ -0,0 +1,224 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_PARAMS_H+#define _TMR_PARAMS_H+/** + * @file tmr_params.h+ * @brief Mercury API - Reader parameter interface+ * @author Nathan Williams+ * @date 10/20/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.+ */++#ifdef __cplusplus+extern "C" {+#endif++/**+ * Parameter keys for TMR_paramSet() and TMR_paramGet(). Each+ * parameter is listed with its associated string name and the+ * parameter type. A pointer to that type is passed to TMR_paramGet()+ * (for example, "TMR_String *" for /reader/version/model).+ */+typedef enum TMR_Param+{+ /** No such parameter - used as a return value from TMR_paramID(). */+ TMR_PARAM_NONE,+ TMR_PARAM_MIN,+ /** "/reader/baudRate", uint32_t */+ TMR_PARAM_BAUDRATE = TMR_PARAM_MIN,+ /** "/reader/probeBaudRates", TMR_uint32List */+ TMR_PARAM_PROBEBAUDRATES,+ /** "/reader/commandTimeout", uint32_t */+ TMR_PARAM_COMMANDTIMEOUT,+ /** "/reader/transportTimeout", uint32_t */+ TMR_PARAM_TRANSPORTTIMEOUT,+ /** "/reader/powerMode", TMR_SR_PowerMode */+ TMR_PARAM_POWERMODE,+ /** "/reader/userMode", TMR_SR_UserMode */+ TMR_PARAM_USERMODE,+ /** "/reader/antenna/checkPort", bool */+ TMR_PARAM_ANTENNA_CHECKPORT,+ /** "/reader/antenna/portList", TMR_uint8List */+ TMR_PARAM_ANTENNA_PORTLIST,+ /** "/reader/antenna/connectedPortList", TMR_uint8List */+ TMR_PARAM_ANTENNA_CONNECTEDPORTLIST,+ /** "/reader/antenna/portSwitchGpos", TMR_uint8List */+ TMR_PARAM_ANTENNA_PORTSWITCHGPOS,+ /** "/reader/antenna/settlingTimeList", TMR_PortValueList */+ TMR_PARAM_ANTENNA_SETTLINGTIMELIST,+ /** "/reader/antenna/returnLoss", TMR_PortValueList */+ TMR_PARAM_ANTENNA_RETURNLOSS,+ /** "/reader/antenna/txRxMap", TMR_AntennaMapList */+ TMR_PARAM_ANTENNA_TXRXMAP,+ /** "/reader/gpio/inputList", TMR_uint8List */+ TMR_PARAM_GPIO_INPUTLIST,+ /** "/reader/gpio/outputList", TMR_uint8List */+ TMR_PARAM_GPIO_OUTPUTLIST,+ /** "/reader/gen2/accessPassword", TMR_GEN2_Password */+ TMR_PARAM_GEN2_ACCESSPASSWORD,+ /** "/reader/gen2/q", TMR_GEN2_Q */+ TMR_PARAM_GEN2_Q,+ /** "/reader/gen2/tagEncoding", TMR_GEN2_TagEncoding */+ TMR_PARAM_GEN2_TAGENCODING,+ /** "/reader/gen2/session", TMR_GEN2_Session */+ TMR_PARAM_GEN2_SESSION,+ /** "/reader/gen2/target", TMR_GEN2_Target */+ TMR_PARAM_GEN2_TARGET,+ /** "/reader/gen2/BLF", TMR_GEN2_LinkFrequency */+ TMR_PARAM_GEN2_BLF,+ /** "/reader/gen2/tari", TMR_GEN2_Tari */+ TMR_PARAM_GEN2_TARI,+ /**"/reader/gen2/writeMode", TMR_GEN2_WriteMode */+ TMR_PARAM_GEN2_WRITEMODE,+ /** "/reader/gen2/bap", TMR_GEN2_Bap */+ TMR_PARAM_GEN2_BAP,+ /** "/reader/gen2/protocolExtension", TMR_GEN2_ProtocolExtension */+ TMR_PARAM_GEN2_PROTOCOLEXTENSION,+ /** "/reader/iso180006b/BLF", TMR_ISO180006B_LinkFrequency */+ TMR_PARAM_ISO180006B_BLF,+ /** "/reader/iso180006b/modulationDepth", TMR_ISO180006B_ModulationDepth */+ TMR_PARAM_ISO180006B_MODULATION_DEPTH,+ /** "/reader/iso180006b/delimiter", TMR_PARAM_ISO18000_6B_DELIMITER */+ TMR_PARAM_ISO180006B_DELIMITER,+ /** "/reader/read/asyncOffTime", uint32_t */+ TMR_PARAM_READ_ASYNCOFFTIME,+ /** "/reader/read/asyncOnTime", uint32_t */+ TMR_PARAM_READ_ASYNCONTIME,+ /** "/reader/read/plan", TMR_ReadPlan */+ TMR_PARAM_READ_PLAN,+ /** "/reader/radio/enablePowerSave", bool **/+ TMR_PARAM_RADIO_ENABLEPOWERSAVE,+ /** "/reader/radio/powerMax", int16_t */+ TMR_PARAM_RADIO_POWERMAX,+ /** "/reader/radio/powerMin", int16_t */+ TMR_PARAM_RADIO_POWERMIN,+ /** "/reader/radio/portReadPowerList", TMR_PortValueList */+ TMR_PARAM_RADIO_PORTREADPOWERLIST,+ /** "/reader/radio/portWritePowerList", TMR_PortValueList */+ TMR_PARAM_RADIO_PORTWRITEPOWERLIST,+ /** "/reader/radio/readPower", int32_t */+ TMR_PARAM_RADIO_READPOWER,+ /** "/reader/radio/writePower", int32_t */+ TMR_PARAM_RADIO_WRITEPOWER,+ /** "/reader/radio/temperature", int8_t */+ TMR_PARAM_RADIO_TEMPERATURE,+ /** "/reader/tagReadData/recordHighestRssi", bool */+ TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI,+ /** "/reader/tagReadData/reportRssiInDbm", bool */+ TMR_PARAM_TAGREADDATA_REPORTRSSIINDBM,+ /** "/reader/tagReadData/uniqueByAntenna", bool */+ TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA,+ /** "/reader/tagReadData/uniqueByData", bool */+ TMR_PARAM_TAGREADDATA_UNIQUEBYDATA,+ /** "/reader/tagop/antenna", uint8_t */+ TMR_PARAM_TAGOP_ANTENNA,+ /** "/reader/tagop/protocol", TMR_TagProtocol */+ TMR_PARAM_TAGOP_PROTOCOL,+ /** "/reader/version/hardware", TMR_String */+ TMR_PARAM_VERSION_HARDWARE,+ /** "/reader/version/serial", TMR_String */+ TMR_PARAM_VERSION_SERIAL,+ /** "/reader/version/model", TMR_String */+ TMR_PARAM_VERSION_MODEL,+ /** "/reader/version/software", TMR_String */+ TMR_PARAM_VERSION_SOFTWARE,+ /** "/reader/version/supportedProtocols", TMR_TagProtocolList */+ TMR_PARAM_VERSION_SUPPORTEDPROTOCOLS,+ /** "/reader/region/hopTable", TMR_uint32List */+ TMR_PARAM_REGION_HOPTABLE,+ /** "/reader/region/hopTime", uint32_t */+ TMR_PARAM_REGION_HOPTIME,+ /** "/reader/region/id", TMR_Region */+ TMR_PARAM_REGION_ID,+ /** "/reader/region/supportedRegions", TMR_RegionList */+ TMR_PARAM_REGION_SUPPORTEDREGIONS,+ /** "/reader/region/lbt/enable", bool */+ TMR_PARAM_REGION_LBT_ENABLE,+ /** "/reader/licenseKey", TMR_uint8List */+ TMR_PARAM_LICENSE_KEY,+ /** "/reader/userConfig", TMR_UserConfigOption */+ TMR_PARAM_USER_CONFIG,+ /** "/reader/radio/enableSJC", bool */+ TMR_PARAM_RADIO_ENABLESJC,+ /** "/reader/extendedEpc", bool */+ TMR_PARAM_EXTENDEDEPC,+ /** "/reader/statistics", TMR_SR_ReaderStatistics */+ TMR_PARAM_READER_STATISTICS,+ /** "/reader/stats", TMR_Reader_StatsValues */+ TMR_PARAM_READER_STATS,+ /** "/reader/uri", TMR_String */+ TMR_PARAM_URI,+ /** "/reader/version/productGroupID", uint16_t */+ TMR_PARAM_PRODUCT_GROUP_ID,+ /** "/reader/version/productGroup", TMR_String */+ TMR_PARAM_PRODUCT_GROUP,+ /** "/reader/version/productID", uint16_t */+ TMR_PARAM_PRODUCT_ID,+ /** "/reader/tagReadData/tagopSuccesses", uint16_t */+ TMR_PARAM_TAGREADATA_TAGOPSUCCESSCOUNT,+ /** "/reader/tagReadData/tagopFailures", uint16_t */+ TMR_PARAM_TAGREADATA_TAGOPFAILURECOUNT,+ /** "/reader/status/antennaEnable", bool */+ TMR_PARAM_STATUS_ENABLE_ANTENNAREPORT,+ /** "/reader/status/frequencyEnable", bool */+ TMR_PARAM_STATUS_ENABLE_FREQUENCYREPORT,+ /** "/reader/status/temperatureEnable", bool */+ TMR_PARAM_STATUS_ENABLE_TEMPERATUREREPORT,+ /** "/reader/tagReadData/enableReadFilter", bool */+ TMR_PARAM_TAGREADDATA_ENABLEREADFILTER,+ /** "/reader/tagReadData/readFilterTimeout", int32_t */+ TMR_PARAM_TAGREADDATA_READFILTERTIMEOUT,+ /** "/reader/tagReadData/uniqueByProtocol", bool */+ TMR_PARAM_TAGREADDATA_UNIQUEBYPROTOCOL,+ /** "/reader/description", TMR_String */+ TMR_PARAM_READER_DESCRIPTION,+ /** "/reader/hostname", TMR_String */+ TMR_PARAM_READER_HOSTNAME,+ /** "/reader/currentTime", struct tm */+ TMR_PARAM_CURRENTTIME,+ /** "/reader/gen2/writeReplyTimeout", uint16_t */+ TMR_PARAM_READER_WRITE_REPLY_TIMEOUT,+ /** "/reader/gen2/writeEarlyExit", bool */+ TMR_PARAM_READER_WRITE_EARLY_EXIT,+ /** "/reader/stats/enable", TMR_StatsEnable */+ TMR_PARAM_READER_STATS_ENABLE,+ /** "/reader/trigger/read/Gpi", TMR_uint8List */+ TMR_PARAM_TRIGGER_READ_GPI,+ /** "/reader/metadataflags", TMR_TRD_MetadataFlag*/+ TMR_PARAM_METADATAFLAG,+ /** "/reader/licensedFeatures", TMR_uint8List */+ TMR_PARAM_LICENSED_FEATURES,+ TMR_PARAM_SELECTED_PROTOCOLS,+ TMR_PARAM_END,+ TMR_PARAM_MAX = TMR_PARAM_END-1,++} TMR_Param;++#define TMR_PARAMWORDS ((1 + TMR_PARAM_MAX +31) / 32)++#ifdef __cplusplus+}+#endif++#endif /* _TMR_PARAMS_H */
+ cbits/api/tmr_read_plan.h view
@@ -0,0 +1,211 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_READ_PLAN_H+#define _TMR_READ_PLAN_H+/** + * @file tmr_read_plan.h+ * @brief Mercury API - Read Plan Definitions+ * @author Brian Fiegel+ * @date 4/18/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 "tmr_tag_protocol.h"+#include "tmr_filter.h"+#include "tmr_tagop.h"++#ifdef __cplusplus+extern "C" {+#endif+++/**+ * @defgroup readplan Read plans+ *+ * A read plan specifies the antennas, protocols, and filters to use+ * for a search (read). Each ReadPlan structure has a numeric weight+ * that controls what fraction of a search is used by that plan when+ * combined in a MultiReadPlan (see below). Read plans are specified+ * for the reader in the @c /reader/read/plan parameter.+ *+ * @{+ */++typedef struct TMR_ReadPlan TMR_ReadPlan;+typedef struct TMR_SimpleReadPlan TMR_SimpleReadPlan;+typedef struct TMR_MultiReadPlan TMR_MultiReadPlan;+typedef struct TMR_StopOnTagCount TMR_StopOnTagCount;+typedef struct TMR_TagObservationTrigger TMR_TagObservationTrigger;+typedef struct TMR_StopTrigger TMR_StopTrigger;+typedef struct TMR_GPITriggerRead TMR_GPITriggerRead;++/**+ * TODO: to be used later.+ **/ +/*struct TMR_TagObservationTrigger+{+};++struct TMR_StopTrigger+{+ TMR_TagObservationTrigger stopTrigger; +};*/++/**+ * A StopOnTagCount will be used in case of stop N trigger option.+ * It contains a flag to specify that user is requesting for stop+ * N trigger and a count to specify the number of tags user is + * requesting to read.+ **/+struct TMR_StopOnTagCount+{+ /* option for stop N trigger */+ bool stopNTriggerStatus;++ /* Number of tags to be read */+ uint32_t noOfTags;+};++/**+ * This will be used for GPI trigger read option.+ * It contains : + * enableTriggerRead a flag to specify that user is requesting for trigger read.+ * GPIList the list of GPI ports should be used to trigger the read.+ **/+struct TMR_GPITriggerRead+{+ /* option for trigger read */+ bool enable;+ /* RFU - The list of GPI ports */+ TMR_uint8List gpiList;+};++/**+ * A SimpleReadPlan contains a protocol, a list of antennas, and an+ * optional filter. The list of antennas may be an empty list, in+ * which case the reader will use all antennas in the antenna map (see+ * @c /reader/antenna/txRxMap) where the reader has detected an+ * antenna present. The filter describes any selection or filtering+ * operation to perform in the RFID protocol during the search. The+ * filter may be @c NULL, in which case no selection or filtering is+ * performed. Invalid combinations of protocols and filters (a Gen2+ * select on ISO180006B, for example) will produce an error at read+ * time.+ */+struct TMR_SimpleReadPlan+{+ /** The list of antennas to read on */+ TMR_uint8List antennas;+ /** The protocol to use for reading */+ TMR_TagProtocol protocol;+ /** The filter to apply to reading, or NULL */+ TMR_TagFilter *filter;+ /** The tag operation to apply to each read tag, or NULL */+ TMR_TagOp *tagop;+ /** Option to use the FastSearch */+ bool useFastSearch;+ /** The stop N trigger */+ TMR_StopOnTagCount stopOnCount;+ /** The GPI trigger read */+ TMR_GPITriggerRead triggerRead;+};++/**+ * A MultiReadPlan contains a list of other ReadPlan objects. The+ * relative weights of each of the included sub-plans are used+ * determine what fraction of the total read time to allot to that+ * sub-plan (for example, if the first plan has a weight of 20 and the+ * second has a weight of 10, the first 2/3 of any read will use the+ * first plan, and the remaining 1/3 will use the second+ * plan). MultiReadPlan is useful for specifying searches over+ * multiple protocols, for using different filters on different+ * antennas, and other combinations.+ */+struct TMR_MultiReadPlan+{+ /** Array of pointers to the subsidiary read plans */+ TMR_ReadPlan **plans;+ uint32_t totalWeight; /** Internal value - initialize to 0 */+ /** Number of elements in the array of read plans */+ uint8_t planCount;+};++/** The type of a read plan */+typedef enum TMR_ReadPlanType+{+ TMR_READ_PLAN_TYPE_INVALID,+ /** Simple read plan - one protocol, a set of antennas, an optional+ * tag filter, and an optional tag operation.+ */+ TMR_READ_PLAN_TYPE_SIMPLE,+ /** Multi-read plan - a list of read plans (simple or multi). */+ TMR_READ_PLAN_TYPE_MULTI+} TMR_ReadPlanType;++/**+ * A ReadPlan structure specifies the antennas, protocols, and filters+ * to use for a search (read).+ */+struct TMR_ReadPlan+{+ /** The type of the read plan and the type of the union that is populated */+ TMR_ReadPlanType type;+ /** The relative weight of this read plan */+ uint32_t weight;+ /** Option for Autonomous read */+ bool enableAutonomousRead;+ union+ {+ /** SimpleReadPlan contents */+ TMR_SimpleReadPlan simple;+ /** MultiReadPlan contents */+ TMR_MultiReadPlan multi;+ } u;+};++TMR_Status TMR_RP_init_simple(TMR_ReadPlan *plan, uint8_t antennaCount,+ uint8_t *antennaList, TMR_TagProtocol protocol,+ uint32_t weight);++TMR_Status TMR_RP_init_multi(TMR_ReadPlan *plan, TMR_ReadPlan **plans,+ uint8_t planCount, uint32_t weight);++TMR_Status TMR_GPITR_init_enable(TMR_GPITriggerRead *triggerRead, bool enable);++TMR_Status TMR_RP_set_filter(TMR_ReadPlan *plan, TMR_TagFilter *filter);++TMR_Status TMR_RP_set_tagop(TMR_ReadPlan *plan, TMR_TagOp *tagop);+TMR_Status TMR_RP_set_enableTriggerRead(TMR_ReadPlan *plan, TMR_GPITriggerRead *triggerRead);++TMR_Status TMR_RP_set_useFastSearch(TMR_ReadPlan *plan, bool useFastSearch);+TMR_Status TMR_RP_set_stopTrigger(TMR_ReadPlan *plan, uint32_t count);+TMR_Status TMR_RP_set_enableAutonomousRead(TMR_ReadPlan *plan, bool autonomousRead);+/**+ * @}+ */++#ifdef __cplusplus+}+#endif++#endif /* _TMR_READ_PLAN_H_ */
+ cbits/api/tmr_region.h view
@@ -0,0 +1,75 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_REGION_H+#define _TMR_REGION_H+/**+ * @file tmr_region.h+ * @brief Mercury API - Region Definitions+ * @author Brian Fiegel+ * @date 4/18/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.+ */+#ifdef __cplusplus+extern "C" {+#endif++/**+ * RFID regulatory regions+ */+typedef enum TMR_Region+{+ /** Unspecified region */ TMR_REGION_NONE = 0,+ /** North America */ TMR_REGION_NA = 1,+ /** European Union */ TMR_REGION_EU = 2,+ /** Korea */ TMR_REGION_KR = 3,+ /** India */ TMR_REGION_IN = 4,+ /** Japan */ TMR_REGION_JP = 5,+ /** People's Republic of China */ TMR_REGION_PRC = 6,+ /** European Union 2 */ TMR_REGION_EU2 = 7,+ /** European Union 3 */ TMR_REGION_EU3 = 8,+ /** Korea 2*/ TMR_REGION_KR2 = 9,+ /** People's Republic of China(840MHZ)*/TMR_REGION_PRC2 = 10,+ /** Australia */ TMR_REGION_AU = 11,+ /** New Zealand !!EXPERIMENTAL!! */ TMR_REGION_NZ = 12,+ /** Reduced FCC region */ TMR_REGION_NA2 = 13,+ /** 5MHZ FCC band */ TMR_REGION_NA3 = 14,+ /** Israel **/ TMR_REGION_IS= 15,+ /** Open */ TMR_REGION_OPEN = 0xFF+} TMR_Region;++/** A list of TMR_Region values */+typedef struct TMR_RegionList+{+ /** Array of TMR_Region values */+ TMR_Region *list;+ /** Allocated size of the array */+ uint8_t max;+ /** Length of the list - may be larger than max, indicating truncated data */+ uint8_t len;+} TMR_RegionList;++#ifdef __cplusplus+}+#endif++#endif /* _TMR_REGION_H_ */
+ cbits/api/tmr_serial_reader.h view
@@ -0,0 +1,473 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_SERIAL_READER_H+#define _TMR_SERIAL_READER_H+/**+ * @file tmr_serial_reader.h+ * @brief Mercury API - Serial Reader interface+ * @author Nathan Williams+ * @date 10/20/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 "tmr_region.h"+#include "tmr_tag_protocol.h"+#include "tmr_serial_transport.h"++#define TMR_SR_MAX_PACKET_SIZE 256++#ifdef __cplusplus+extern "C" {+#endif++/**+ * Defines the values for the parameter @c /reader/powerMode and the+ * return value and parameter to TMR_SR_cmdGetPowerMode and+ * TMR_SR_cmdSetPowerMode.+ */+typedef enum TMR_SR_PowerMode+{+ TMR_SR_POWER_MODE_MIN = 0,+ TMR_SR_POWER_MODE_FULL = 0,+ TMR_SR_POWER_MODE_MINSAVE = 1,+ TMR_SR_POWER_MODE_MEDSAVE = 2,+ TMR_SR_POWER_MODE_MAXSAVE = 3,+ TMR_SR_POWER_MODE_SLEEP = 4,+ TMR_SR_POWER_MODE_MAX = TMR_SR_POWER_MODE_SLEEP,+ TMR_SR_POWER_MODE_INVALID = TMR_SR_POWER_MODE_MAX + 1,+} TMR_SR_PowerMode;++/**+Operation Options for cmdSetProtocolLicenseKey+*/+typedef enum TMR_SR_SetProtocolLicenseOption+{+/** Set Valid License Key */+TMR_SR_SET_LICENSE_KEY = 0x01, +/** Erase License Key */+TMR_SR_ERASE_LICENSE_KEY = 0x02, +}TMR_SR_SetProtocolLicenseOption;++/** +Operation Options for cmdSetUserProfile +*/+typedef enum TMR_SR_UserConfigOperation+{ +/** Save operation */+TMR_USERCONFIG_SAVE = 0x01, +/** Restore operation */+TMR_USERCONFIG_RESTORE = 0x02, +/** Verify operation */+TMR_USERCONFIG_VERIFY = 0x03, +/** Clear operation */+TMR_USERCONFIG_CLEAR = 0x04,+/** Save read plan configuration */+TMR_USERCONFIG_SAVE_WITH_READPLAN = 0x05,+}TMR_SR_UserConfigOperation; ++/**+Congfiguration category for cmdSetUserProfile+*/+typedef enum TMR_SR_UserConfigCategory+{+ /** All Configuration */+TMR_SR_ALL=0x01, +}TMR_SR_UserConfigCategory;++/** +The configuration type for cmdSetUserProfile+*/+typedef enum TMR_SR_UserConfigType+{+/** Firmware default configurations */+TMR_SR_FIRMWARE_DEFAULT=0x00,+/** Custom configurations */+TMR_SR_CUSTOM_CONFIGURATION=0x01, +}TMR_SR_UserConfigType;++/**+ * The user profile operation structure+ */+typedef struct TMR_SR_UserConfigOp+{+ /** @privatesection */++ /** User config category */+ TMR_SR_UserConfigCategory category;+ /** User config operation */+ TMR_SR_UserConfigOperation op;+}TMR_SR_UserConfigOp;++/**+ * Defines the values for the parameter /reader/userMode and the+ * return value and parameter to TMR_SR_cmdGetUserMode() and+ * TMR_SR_cmdSetUserMode.+ */+typedef enum TMR_SR_UserMode+{+ TMR_SR_USER_MODE_MIN = 0,+ TMR_SR_USER_MODE_UNSPEC = 0,+ TMR_SR_USER_MODE_PRINTER = 1,+ TMR_SR_USER_MODE_CONVEYOR = 2,+ TMR_SR_USER_MODE_PORTAL = 3,+ TMR_SR_USER_MODE_HANDHELD = 4,+ TMR_SR_USER_MODE_MAX = TMR_SR_USER_MODE_HANDHELD,+ TMR_SR_USER_MODE_INVALID = TMR_SR_USER_MODE_MAX + 1,+}TMR_SR_UserMode;++/**+ * This represents the types of Q algorithms avaliable on the reader.+ */+typedef enum TMR_SR_GEN2_QType+{+ TMR_SR_GEN2_Q_MIN = 0,+ TMR_SR_GEN2_Q_DYNAMIC = 0,+ TMR_SR_GEN2_Q_STATIC = 1,+ TMR_SR_GEN2_Q_MAX = TMR_SR_GEN2_Q_STATIC,+ TMR_SR_GEN2_Q_INVALID = TMR_SR_GEN2_Q_MAX + 1,+} TMR_SR_GEN2_QType;++/** Configuration of the static-Q algorithm. */+typedef struct TMR_SR_GEN2_QStatic+{+ /** The initial Q value to use. */+ uint8_t initialQ;+} TMR_SR_GEN2_QStatic;++/**+ * This represents a Q algorithm on the reader.+ */+typedef struct TMR_SR_GEN2_Q+{+ /** The type of Q algorithm. */+ TMR_SR_GEN2_QType type;+ union+ {+ /** Configuration of the static-Q algorithm. */+ TMR_SR_GEN2_QStatic staticQ;+ }u;+} TMR_SR_GEN2_Q;+++/** An antenna port with an associated int32_t value. */+typedef struct TMR_PortValue+{+ /** The port number */+ uint8_t port;+ /** The value */+ int32_t value;+} TMR_PortValue;++/** List of TMR_PortValue values */+typedef struct TMR_PortValueList+{+ /** The array of values */+ TMR_PortValue *list;+ /** The number of entries there is space for in the array */+ uint8_t max;+ /** The number of entries in the list - may be larger than max, indicating truncated data. */+ uint8_t len;+} TMR_PortValueList;+++/**+ * Mapping between an arbitrary "antenna" number and a TX/RX port+ * pair. Not all TX/RX pairings are valid for a device.+ */+typedef struct TMR_AntennaMap+{+ /** The antenna number - an arbitrary value. */+ uint8_t antenna;+ /** The device antenna port to use for transmission. */+ uint8_t txPort;+ /** The device antenna port to use for reception. */+ uint8_t rxPort;+} TMR_AntennaMap;++/** List of antenna mappings */+typedef struct TMR_AntennaMapList+{+ /** The array of values */+ TMR_AntennaMap *list;+ /** The number of entries there is space for in the array */+ uint8_t max;+ /** The number of entries in the list - may be larger than max, indicating truncated data. */+ uint8_t len;+} TMR_AntennaMapList;++/**+ * The version structure returned from cmdVersion().+ */+typedef struct TMR_SR_VersionInfo+{+ /** Bootloader version, as four 8-bit numbers */+ uint8_t bootloader[4];+ /** Hardware version. Opaque format */+ uint8_t hardware[4];+ /** Date app firmware was built, as BCD YYYYMMDD */+ uint8_t fwDate[4];+ /** App firmware version, as four 8-bit numbers */+ uint8_t fwVersion[4];+ /** Bitmask of the protocols supported by the device (indexed by TMR_TagProtocol values minus one). */+ uint32_t protocols;+} TMR_SR_VersionInfo;++/**+ * Current message TransportType+ **/+typedef enum TMR_TransportType+{+ /* Serial */+ TMR_SR_MSG_SOURCE_SERIAL = 0x0000,+ /* USB */+ TMR_SR_MSG_SOURCE_USB = 0x0003,+ /* Unknown */+ TMR_SR_MSG_SOURCE_UNKNOWN = 0x0004,+}TMR_TransportType;++/**+ * The serial reader structure.+ */+typedef struct TM_SR_SerialReader+{+ /** @privatesection */++ /* Serial transport information */+ TMR_SR_SerialTransport transport;+ union+ {+#ifdef TMR_ENABLE_SERIAL_TRANSPORT_NATIVE+ TMR_SR_SerialPortNativeContext nativeContext;+#endif+ } transportContext;++ /* User-configurable values */+ uint32_t baudRate;+ TMR_AntennaMapList *txRxMap;+ TMR_GEN2_Password gen2AccessPassword;+ uint32_t transportTimeout;+ uint32_t commandTimeout;+ TMR_Region regionId;++ /* Static storage for the default map */+ TMR_AntennaMap staticTxRxMapData[TMR_SR_MAX_ANTENNA_PORTS];+ TMR_AntennaMapList staticTxRxMap;++ /* Mostly-fixed information about the connected reader */+ TMR_SR_VersionInfo versionInfo;+ uint32_t portMask;++ /* Option to enable or disable the pre-amble */+ bool supportsPreamble;++ /* Cache extendedEPC setting */+ bool extendedEPC;++ /* Cached values */+ TMR_SR_PowerMode powerMode;+ TMR_TagProtocol currentProtocol;+ int8_t gpioDirections;++ /* Large bitmask that stores whether each parameter's presence+ * is known or not.+ */+ uint32_t paramConfirmed[TMR_PARAMWORDS];+ /* Large bitmask that, if the corresponding bit in paramConfirmed is set,+ * stores whether each parameter is present or not.+ */+ uint32_t paramPresent[TMR_PARAMWORDS];++ /* Temporary storage during a read and subsequent fetch of tags */+ uint32_t readTimeLow, readTimeHigh;+ uint32_t lastSentTagTimestampHigh, lastSentTagTimestampLow;+ uint32_t searchTimeoutMs;+ + /* Number of tags reported by module read command.+ * In streaming mode, exact quantity is unknown, so use+ * 0 if stream has ended, non-zero if end-of-stream has+ * not yet been detected. */+ int tagsRemaining;+ /* Buffer tag records fetched from module but not yet passed to caller. */+ uint8_t bufResponse[TMR_SR_MAX_PACKET_SIZE];+ /* bufResponse read index */+ uint8_t bufPointer;+ /* Number of tag records in buffer but not yet passed to caller */+ uint8_t tagsRemainingInBuffer;+ /*TMR opCode*/+ uint8_t opCode;+ /*Gen2 Q Value from previous tagop */+ TMR_SR_GEN2_Q oldQ;+ /*Gen2 WriteMode*/+ TMR_GEN2_WriteMode writeMode;+ /* Buffer to store additional error message */+ char errMsg[TMR_SR_MAX_PACKET_SIZE];+ /* Product group id */+ uint16_t productId;+ /* Tag operation success count */+ uint16_t tagopSuccessCount;+ /* Tag operation failure count */+ uint16_t tagopFailureCount;+ /* Enable read filtering */+ bool enableReadFiltering;+ /* Read filter timeout */+ int32_t readFilterTimeout;+ /* Option to use the user specified transportTimeout */+ bool usrTimeoutEnable;+ /* Enable CRC calculation */+ bool crcEnabled;+ /* TransportType */+ TMR_TransportType transportType;+ /* Option for Gen2 all memory bank read */+ bool gen2AllMemoryBankEnabled;+ /* option for Gen2 Bap parameter */+ bool isBapEnabled;+ /* baud rates to be used for serial communication */+ TMR_uint32List probeBaudRates;+ /* storage for the probe baud rates */+ uint32_t baudRates[TMR_MAX_PROBE_BAUDRATE_LENGTH];+ /* Flag to be raised when Autonomous read is requested */+ bool enableAutonomousRead;+ /* The flag to be used in case of tag reading */+ bool isBasetimeUpdated;+} TMR_SR_SerialReader;++/**+ * This object is returned from TMR_SR_cmdGetReaderStatistics.+ */+typedef struct TMR_SR_ReaderStatistics+{+ /** The number of entries in the arrays. */+ uint8_t numPorts;+ /** per-port RF on time, in milliseconds. */+ uint32_t rfOnTime[TMR_SR_MAX_ANTENNA_PORTS];+ /** The per-port noise floor with transmitter off */+ uint32_t noiseFloor[TMR_SR_MAX_ANTENNA_PORTS];+ /** The per-port noise floor while transmitting. */+ uint32_t noiseFloorTxOn[TMR_SR_MAX_ANTENNA_PORTS];+}TMR_SR_ReaderStatistics;++/**+ * Object of this contains antenna status report+ */+typedef struct TMR_SR_AntennaStatusReport+{+ /** Antenna */+ uint8_t ant;+}TMR_SR_AntennaStatusReport;++/**+ * Object of this contains frequency status report+ */+typedef struct TMR_SR_FrequencyStatusReport+{+ /** RF carrier frequency */+ uint32_t freq;+}TMR_SR_FrequencyStatusReport;++/**+ * Object of this contains temperature status report.+ */+typedef struct TMR_SR_TemperatureStatusReport+{+ /** Temperature */+ int8_t temp;+}TMR_SR_TemperatureStatusReport;++/**+ * Status report content flags+ */+typedef enum TMR_SR_StatusType+{+ /* None */+ TMR_SR_STATUS_NONE = 0x0000,+ /* Frequency */+ TMR_SR_STATUS_FREQUENCY = 0x0002,+ /* Temperature */+ TMR_SR_STATUS_TEMPERATURE = 0x0004,+ /* Current Antenna Ports */+ TMR_SR_STATUS_ANTENNA = 0x0008,+ /* All */+ TMR_SR_STATUS_ALL = 0x000E,+ TMR_SR_STATUS_MAX = 4,+}TMR_SR_StatusType;++/**+ * This object contains the information related to status reports+ * sent by the module during continuous reading+ */+typedef struct TMR_SR_StatusReport+{+ TMR_SR_StatusType type;+ union+ {+ /** Antenna status report */+ TMR_SR_AntennaStatusReport asr;+ /** Frequency status report */+ TMR_SR_FrequencyStatusReport fsr;+ /** Temperature status report */+ TMR_SR_TemperatureStatusReport tsr;+ } u;+}TMR_SR_StatusReport;+++TMR_Status TMR_SR_connect(struct TMR_Reader *reader);+TMR_Status TMR_SR_destroy(struct TMR_Reader *reader);+TMR_Status TMR_SR_read(struct TMR_Reader *reader, uint32_t timeoutMs, int32_t *tagCount);+TMR_Status TMR_SR_hasMoreTags(struct TMR_Reader *reader);+TMR_Status TMR_SR_getNextTag(struct TMR_Reader *reader, TMR_TagReadData *read);+TMR_Status TMR_SR_executeTagOp(struct TMR_Reader *reader, TMR_TagOp *tagop, TMR_TagFilter *filter, TMR_uint8List *data);+TMR_Status TMR_SR_writeTag(struct TMR_Reader *reader, const TMR_TagFilter *filter, const TMR_TagData *data);+TMR_Status TMR_SR_killTag(struct TMR_Reader *reader, const TMR_TagFilter *filter, const TMR_TagAuthentication *auth);+TMR_Status TMR_SR_lockTag(struct TMR_Reader *reader, const TMR_TagFilter *filter, TMR_TagLockAction *action);+TMR_Status TMR_SR_readTagMemBytes(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t address,+ uint16_t count, uint8_t data[]);+TMR_Status TMR_SR_readTagMemWords(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t address,+ uint16_t count, uint16_t *data);+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 TMR_SR_writeTagMemWords(struct TMR_Reader *reader, const TMR_TagFilter *filter,+ uint32_t bank, uint32_t address,+ uint16_t count, const uint16_t data[]);+TMR_Status TMR_SR_gpoSet(struct TMR_Reader *reader, uint8_t count, const TMR_GpioPin state[]);+TMR_Status TMR_SR_gpiGet(struct TMR_Reader *reader, uint8_t *count, TMR_GpioPin state[]);+TMR_Status TMR_SR_firmwareLoad(TMR_Reader *reader, void *cookie,+ TMR_FirmwareDataProvider provider);+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);+TMR_Status TMR_init_UserConfigOp(TMR_SR_UserConfigOp *config, TMR_SR_UserConfigOperation op);+TMR_Status TMR_SR_reboot(struct TMR_Reader *reader);++/**+ * Initialize a serial reader. The reader->u.serialReader.transport+ * structure must be initialized before calling this.+ */+TMR_Status TMR_SR_SerialReader_init(TMR_Reader *reader);++#ifdef __cplusplus+}+#endif++#endif /* _TMR_SERIAL_READER_H */
+ cbits/api/tmr_serial_transport.h view
@@ -0,0 +1,232 @@+#ifndef _TMR_SERIAL_TRANSPORT_H+#define _TMR_SERIAL_TRANSPORT_H+/**+ * @file tmr_serial_transport.h+ * @brief Mercury API - Serial Transport Interface+ * @author Nathan Williams+ * @date 10/20/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.+ */++#ifdef __cplusplus+extern "C" {+#endif++#ifdef TMR_ENABLE_SERIAL_TRANSPORT_LLRP+#include <sys/types.h>+#include <sys/socket.h>+#endif++#if defined(WIN32) || defined(WINCE)+#if !defined(_WINSOCK2API_) && !defined(_WINSOCKAPI_)+#include <winsock2.h>+#endif+#endif++#ifdef OSDEP_SERIAL_INCLUDE+#include "osdep_serial_transport.h"+#endif++#ifndef PLATFORM_HANDLE+# ifdef WIN32+# define PLATFORM_HANDLE HANDLE+# else+#if defined(ARDUINO) || defined(FREERTOS_USED)+# define PLATFORM_HANDLE void*+# else+# define PLATFORM_HANDLE int+# endif+# endif+#endif+typedef struct TMR_SR_SerialTransport TMR_SR_SerialTransport;+/**+ * The TMR_SR_SerialTransport structure is the mechanism that the+ * SerialReader layer uses to conduct low-level communications with+ * the device. Users may create their own SerialTransport objects for+ * systems with custom serial communication needs, and then use+ * TMR_SR_SerialReader_init() to complete the construction of the+ * reader object, as an alternative to using TMR_create().+ *+ * @see TMR_SR_SerialPortTransportInit and+ * TMR_SR_LlrpEapiTransportInit for pre-existing+ * TMR_SR_SerialTransport implementations.+ */+struct TMR_SR_SerialTransport+{+ /** Context value made avaliable to callback functions */+ void *cookie;++ /**+ * This callback causes the communication interface to be opened but+ * does not transmit any serial-layer data. This should perform+ * actions such as opening a serial port device or establishing a+ * network connection within a wrapper protocol.+ *+ * @param this The TMR_SR_SerialTransport structure.+ */+ TMR_Status (*open)(TMR_SR_SerialTransport *);++ /**+ * This callback transmits the provided bytes on the serial+ * transport. If the operation takes longer than timeoutMs to+ * complete, TMR_ERROR_TIMEOUT should be returned.+ *+ * @param this The TMR_SR_SerialTransport structure.+ * @param length The number of bytes to send.+ * @param message Pointer to the bytes to send.+ * @param timeoutMs The duration for the operation to complete.+ */+ TMR_Status (*sendBytes)(TMR_SR_SerialTransport *, uint32_t length, + uint8_t* message, const uint32_t timeoutMs);++ /**+ * This callback recieves bytes message on the serial transport. The+ * length parameter contains the size of the buffer pointed to by+ * message. If the operation takes longer than timeoutMs to receive+ * length bytes, TMR_ERROR_TIMEOUT should be returned.+ *+ * @param this The TMR_SR_SerialTransport structure.+ * @param length The number of bytes to receive.+ * @param[out] messageLength The number of bytes received.+ * @param[out] message Pointer to the location to store received bytes.+ * @param timeoutMs The duration for the operation to complete.+ */+ TMR_Status (*receiveBytes)(TMR_SR_SerialTransport *, uint32_t length,+ uint32_t *messageLength, uint8_t* message, const uint32_t timeoutMs);+ /**+ * This callback causes the underlying serial transport connected to+ * the device to the provided baud rate.+ *+ * @param this The TMR_SR_SerialTransport structure.+ * @param rate The baud rate to set.+ */+ TMR_Status (*setBaudRate)(TMR_SR_SerialTransport *, uint32_t rate);++ /**+ * This callback releases any resources allocated by the transport+ * layer and informs the other end, if necessary, that the+ * connection is ending.+ *+ * @param this The TMR_SR_SerialTransport structure.+ */+ TMR_Status (*shutdown)(TMR_SR_SerialTransport *);++ /**+ * This callback takes any actions necessary (possibly none) to+ * remove unsent data from the output path.+ *+ * @param this The TMR_SR_SerialTransport structure.+ */+ TMR_Status (*flush)(TMR_SR_SerialTransport *);+};++#ifdef TMR_ENABLE_SERIAL_TRANSPORT_NATIVE+/**+ * The context structure used by the provided serial port transport interface.+ */+typedef struct TMR_SR_SerialPortNativeContext+{+ /** @privatesection */+ /** The file handle for the serial device */+ PLATFORM_HANDLE handle;+ /** The filesystem name of the serial device */+ char devicename[TMR_MAX_READER_NAME_LENGTH];+} TMR_SR_SerialPortNativeContext;+#endif++#ifdef TMR_ENABLE_SERIAL_TRANSPORT_LLRP+/**+ * The context structure used by the provided+ * serial-encapsulated-in-LLRP transport interface.+ */+typedef struct TMR_SR_LlrpEapiTransportContext+{+ /** @privatesection */+ /** The network address of the remote device */+ struct sockaddr_storage addr;+ /** The length of the contents of addr */+ socklen_t addrlen;+ /** Whether or not to power-cycle the reader upon opening a connection */+ bool powerCycleAtOpen;+ /** The file handle for the network socket */+ int socket;+ /** The current LLRP message ID */+ int sequenceId;+ /** Temporary buffer for receiving and processing a LLRP packet */+ uint8_t buf[270];+ /** Pointers into the buffer */+ uint16_t bufstart, buflen;+} TMR_SR_LlrpEapiTransportContext;+#endif++#ifdef TMR_ENABLE_SERIAL_TRANSPORT_NATIVE+/**+ * Initialize a TMR_SR_SerialTransport structure with a given serial device.+ *+ * @param transport The TMR_SR_SerialTransport structure to initialize.+ * @param context A TMR_SR_SerialPortNativeContext structure for the callbacks to use.+ * @param device The path or name of the serial device (@c /dev/ttyS0, @c COM1)+ */+#if defined(WIN32) || defined(WINCE)+__declspec(dllexport)+#endif+TMR_Status TMR_SR_SerialTransportNativeInit(TMR_SR_SerialTransport *transport,+ TMR_SR_SerialPortNativeContext *context,+ const char *device);+#if defined(WIN32) || defined(WINCE)+__declspec(dllexport)+#endif+TMR_Status TMR_SR_SerialTransportTcpNativeInit(TMR_SR_SerialTransport *transport,+ TMR_SR_SerialPortNativeContext *context,+ const char *device);+#endif /* TMR_ENABLE_SERIAL_TRANSPORT_NATIVE */++#ifdef TMR_ENABLE_SERIAL_TRANSPORT_LLRP+/**+ * Initialize a TMR_SR_SerialTransport structure with a LLRP+EAPI+ * connection to the given host and port.+ *+ * @param transport The TMR_SR_SerialTransport structure to initialize.+ * @param context A TMR_SR_LlrpEapiTransportContext structure for the callbacks to use.+ * @param host The name or address of the network device implementing LLRP+EAPI.+ * @param port The TCP port to use for the connection.+ * @param powerCycleAtOpen Whether or not to power-cycle the reader upon opening a connection.+ */+TMR_Status TMR_SR_LlrpEapiTransportInit(TMR_SR_SerialTransport *transport,+ TMR_SR_LlrpEapiTransportContext *context,+ const char *host, int port,+ bool powerCycleAtOpen);++/**+ * Power-cycle a device attached via LLRP transport+ * @param transport The TMR_SR_SerialTransport connected to the device+ */+TMR_Status TMR_LlrpEapiPowerCycle(TMR_SR_SerialTransport *this);+#endif++#ifdef __cplusplus+}+#endif++#endif /* _TMR_SERIAL_TRANSPORT_H */
+ cbits/api/tmr_status.h view
@@ -0,0 +1,238 @@+#ifndef _TMR_STATUS_H+#define _TMR_STATUS_H++/**+ * @file tmr_status.h+ * @brief Mercury API - status codes+ * @author Nathan Williams+ * @date 11/24/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 "tm_config.h"+#ifdef WINCE+#include <stdint_win32.h>+#else+#include <stdint.h>+#endif++#ifdef __cplusplus+extern "C" {+#endif++typedef uint32_t TMR_Status;++#define TMR_STATUS_MAKE(type, value) (((type) << 24) | (value))+#define TMR_STATUS_GET_TYPE(x) (((x) >> 24) & 0xff)+#define TMR_STATUS_GET_VALUE(x) ((x) & 0xffffff)++#define TMR_SUCCESS_TYPE 0L+#define TMR_ERROR_TYPE_COMM 1L+#define TMR_ERROR_TYPE_CODE 2L+#define TMR_ERROR_TYPE_MISC 3L+#define TMR_ERROR_TYPE_LLRP 4L++#define TMR_SUCCESS TMR_STATUS_MAKE(TMR_SUCCESS_TYPE, 0)++#define TMR_ERROR_CODE(x) TMR_STATUS_MAKE(TMR_ERROR_TYPE_CODE, (x))+#define TMR_ERROR_IS_CODE(x) (TMR_ERROR_TYPE_CODE == TMR_STATUS_GET_TYPE(x))+#define TMR_ERROR_GET_CODE(x) TMR_STATUS_GET_VALUE(x)+/**Invalid number of arguments */+#define TMR_ERROR_MSG_WRONG_NUMBER_OF_DATA TMR_ERROR_CODE(0x100)+/**Command opcode not recognized. */+#define TMR_ERROR_INVALID_OPCODE TMR_ERROR_CODE(0x101)+/**Command opcode recognized, but is not supported. */+#define TMR_ERROR_UNIMPLEMENTED_OPCODE TMR_ERROR_CODE(0x102)+/**Requested power setting is above the allowed maximum. */+#define TMR_ERROR_MSG_POWER_TOO_HIGH TMR_ERROR_CODE(0x103)+/**Requested frequency is outside the allowed range. */+#define TMR_ERROR_MSG_INVALID_FREQ_RECEIVED TMR_ERROR_CODE(0x104)+/**Parameter value is outside the allowed range. */+#define TMR_ERROR_MSG_INVALID_PARAMETER_VALUE TMR_ERROR_CODE(0x105)+/**Requested power setting is below the allowed minimum. */+#define TMR_ERROR_MSG_POWER_TOO_LOW TMR_ERROR_CODE(0x106)+/**Command not supported. */+#define TMR_ERROR_UNIMPLEMENTED_FEATURE TMR_ERROR_CODE(0x109)+/**Requested serial speed is not supported. */+#define TMR_ERROR_INVALID_BAUD_RATE TMR_ERROR_CODE(0x10a)+/**Region is not supported. */+#define TMR_ERROR_INVALID_REGION TMR_ERROR_CODE(0x10b)+/** License key code is invalid */+#define TMR_ERROR_INVALID_LICENSE_KEY TMR_ERROR_CODE(0x10c)+/**Firmware is corrupt: Checksum doesn't match content. */+#define TMR_ERROR_BL_INVALID_IMAGE_CRC TMR_ERROR_CODE(0x200)+/**Serial protocol status code for this exception. */+#define TMR_ERROR_BL_INVALID_APP_END_ADDR TMR_ERROR_CODE(0x201)+/**Internal reader error. Contact support. */+#define TMR_ERROR_FLASH_BAD_ERASE_PASSWORD TMR_ERROR_CODE(0x300)+/**Internal reader error. Contact support. */+#define TMR_ERROR_FLASH_BAD_WRITE_PASSWORD TMR_ERROR_CODE(0x301)+/**Internal reader error. Contact support. */+#define TMR_ERROR_FLASH_UNDEFINED_SECTOR TMR_ERROR_CODE(0x302)+/**Internal reader error. Contact support. */+#define TMR_ERROR_FLASH_ILLEGAL_SECTOR TMR_ERROR_CODE(0x303)+/**Internal reader error. Contact support. */+#define TMR_ERROR_FLASH_WRITE_TO_NON_ERASED_AREA TMR_ERROR_CODE(0x304)+/**Internal reader error. Contact support. */+#define TMR_ERROR_FLASH_WRITE_TO_ILLEGAL_SECTOR TMR_ERROR_CODE(0x305)+/**Internal reader error. Contact support. */+#define TMR_ERROR_FLASH_VERIFY_FAILED TMR_ERROR_CODE(0x306)+/**Reader was asked to find tags, but none were detected. */+#define TMR_ERROR_NO_TAGS_FOUND TMR_ERROR_CODE(0x400)+/**RFID protocol has not been configured. */+#define TMR_ERROR_NO_PROTOCOL_DEFINED TMR_ERROR_CODE(0x401)+/**Requested RFID protocol is not recognized. */+#define TMR_ERROR_INVALID_PROTOCOL_SPECIFIED TMR_ERROR_CODE(0x402)+/**For write-then-lock commands, tag was successfully written, but lock failed.*/+#define TMR_ERROR_WRITE_PASSED_LOCK_FAILED TMR_ERROR_CODE(0x403)+/**Tag data was requested, but could not be read. */+#define TMR_ERROR_PROTOCOL_NO_DATA_READ TMR_ERROR_CODE(0x404)+/**Reader not fully initialized and hasn't yet turned on its radio. Have you set region?*/+#define TMR_ERROR_AFE_NOT_ON TMR_ERROR_CODE(0x405)+/**Write to tag failed. */+#define TMR_ERROR_PROTOCOL_WRITE_FAILED TMR_ERROR_CODE(0x406)+/**Command is not supported in the current RFID protocol. */+#define TMR_ERROR_NOT_IMPLEMENTED_FOR_THIS_PROTOCOL TMR_ERROR_CODE(0x407)+/**Data does not conform to protocol standards. */+#define TMR_ERROR_PROTOCOL_INVALID_WRITE_DATA TMR_ERROR_CODE(0x408)+/**Requested data address is outside the valid range. */+#define TMR_ERROR_PROTOCOL_INVALID_ADDRESS TMR_ERROR_CODE(0x409)+/**Unknown error during RFID operation. */+#define TMR_ERROR_GENERAL_TAG_ERROR TMR_ERROR_CODE(0x40a)+/**Read Tag Data was asked for more data than it supports. */+#define TMR_ERROR_DATA_TOO_LARGE TMR_ERROR_CODE(0x40b)+/**Incorrect password was provided to Kill Tag. */+#define TMR_ERROR_PROTOCOL_INVALID_KILL_PASSWORD TMR_ERROR_CODE(0x40c)+/**Kill failed for unknown reason. */+#define TMR_ERROR_PROTOCOL_KILL_FAILED TMR_ERROR_CODE(0x40e)+/**Internal reader error. Contact support. */+#define TMR_ERROR_PROTOCOL_BIT_DECODING_FAILED TMR_ERROR_CODE(0x40f)+/**Internal reader error. Contact support. */+#define TMR_ERROR_PROTOCOL_INVALID_EPC TMR_ERROR_CODE(0x410)+/**Internal reader error. Contact support. */+#define TMR_ERROR_PROTOCOL_INVALID_NUM_DATA TMR_ERROR_CODE(0x411)+/**Internal reader error. Contact support. */+#define TMR_ERROR_GEN2_PROTOCOL_OTHER_ERROR TMR_ERROR_CODE(0x420)+/**Internal reader error. Contact support. */+#define TMR_ERROR_GEN2_PROTOCOL_MEMORY_OVERRUN_BAD_PC TMR_ERROR_CODE(0x423)+/**Internal reader error. Contact support. */+#define TMR_ERROR_GEN2_PROTOCOL_MEMORY_LOCKED TMR_ERROR_CODE(0x424)+/**Authentication failed with specified key. */+#define TMR_ERROR_GEN2_PROTOCOL_V2_AUTHEN_FAILED TMR_ERROR_CODE(0x425)+/** Untrace operation failed. */+#define TMR_ERROR_GEN2_PROTOCOL_V2_UNTRACE_FAILED TMR_ERROR_CODE(0x426)+/**Internal reader error. Contact support. */+#define TMR_ERROR_GEN2_PROTOCOL_INSUFFICIENT_POWER TMR_ERROR_CODE(0x42b)+/**Internal reader error. Contact support. */+#define TMR_ERROR_GEN2_PROTOCOL_NON_SPECIFIC_ERROR TMR_ERROR_CODE(0x42f)+/**Internal reader error. Contact support. */ +#define TMR_ERROR_GEN2_PROTOCOL_UNKNOWN_ERROR TMR_ERROR_CODE(0x430)+/**A command was received to set a frequency outside the specified range. */+#define TMR_ERROR_AHAL_INVALID_FREQ TMR_ERROR_CODE(0x500)+/**With LBT enabled an attempt was made to set the frequency to an occupied channel. */+#define TMR_ERROR_AHAL_CHANNEL_OCCUPIED TMR_ERROR_CODE(0x501)+/**Checking antenna status while CW is on is not allowed. */+#define TMR_ERROR_AHAL_TRANSMITTER_ON TMR_ERROR_CODE(0x502)+/** Antenna not detected during pre-transmit safety test. */+#define TMR_ERROR_ANTENNA_NOT_CONNECTED TMR_ERROR_CODE(0x503)+/**Reader temperature outside safe range. */+#define TMR_ERROR_TEMPERATURE_EXCEED_LIMITS TMR_ERROR_CODE(0x504)+/** Excess power detected at transmitter port, usually due to antenna tuning mismatch. */+#define TMR_ERROR_HIGH_RETURN_LOSS TMR_ERROR_CODE(0x505)+#define TMR_ERROR_INVALID_ANTENNA_CONFIG TMR_ERROR_CODE(0x507)+/**Asked for more tags than were available in the buffer. */+#define TMR_ERROR_TAG_ID_BUFFER_NOT_ENOUGH_TAGS_AVAILABLE TMR_ERROR_CODE(0x600)+/**Too many tags are in buffer. Remove some with Get Tag ID Buffer or Clear Tag ID Buffer. */+#define TMR_ERROR_TAG_ID_BUFFER_FULL TMR_ERROR_CODE(0x601)+/**Internal error -- reader is trying to insert a duplicate tag record. Contact support. */+#define TMR_ERROR_TAG_ID_BUFFER_REPEATED_TAG_ID TMR_ERROR_CODE(0x602)+/**Asked for tags than a single transaction can handle. */+#define TMR_ERROR_TAG_ID_BUFFER_NUM_TAG_TOO_LARGE TMR_ERROR_CODE(0x603)+/**Blocked response to get additional data from host. */+#define TMR_ERROR_TAG_ID_BUFFER_AUTH_REQUEST TMR_ERROR_CODE(0x604)+/**Internal reader error. Contact support. */+#define TMR_ERROR_SYSTEM_UNKNOWN_ERROR TMR_ERROR_CODE(0x7f00)+/**Internal reader error. Contact support. */+#define TMR_ERROR_TM_ASSERT_FAILED TMR_ERROR_CODE(0x7f01)++#define TMR_ERROR_COMM(x) TMR_STATUS_MAKE(TMR_ERROR_TYPE_COMM, (x))+#define TMR_ERROR_IS_COMM(x) (TMR_ERROR_TYPE_COMM == TMR_STATUS_GET_TYPE(x))+#define TMR_ERROR_COMM_ERRNO(x) TMR_ERROR_COMM(0x8000 | (x))+#define TMR_ERROR_COMM_IS_ERRNO(x) (0x8000 == (TMR_STATUS_GET_VALUE(x) & 0x8000))+#define TMR_ERROR_COMM_GET_ERRNO(x) (TMR_STATUS_GET_VALUE(x) & 0x7fff)+#define TMR_ERROR_TIMEOUT TMR_ERROR_COMM(1)+#define TMR_ERROR_NO_HOST TMR_ERROR_COMM(2)+#define TMR_ERROR_LLRP TMR_ERROR_COMM(3)+#define TMR_ERROR_PARSE TMR_ERROR_COMM(4)+#define TMR_ERROR_DEVICE_RESET TMR_ERROR_COMM(5)+#define TMR_ERROR_CRC_ERROR TMR_ERROR_COMM(6)++#define TMR_ERROR_MISC(x) TMR_STATUS_MAKE(TMR_ERROR_TYPE_MISC, (x))+#define TMR_ERROR_INVALID TMR_ERROR_MISC(1)+#define TMR_ERROR_UNIMPLEMENTED TMR_ERROR_MISC(2)+#define TMR_ERROR_UNSUPPORTED TMR_ERROR_MISC(3)+#define TMR_ERROR_NO_ANTENNA TMR_ERROR_MISC(4)+#define TMR_ERROR_READONLY TMR_ERROR_MISC(5)+#define TMR_ERROR_TOO_BIG TMR_ERROR_MISC(6)+#define TMR_ERROR_NO_THREADS TMR_ERROR_MISC(7)+#define TMR_ERROR_NO_TAGS TMR_ERROR_MISC(8)+#define TMR_ERROR_NOT_FOUND TMR_ERROR_MISC(9)+#define TMR_ERROR_FIRMWARE_FORMAT TMR_ERROR_MISC(10)+#define TMR_ERROR_TRYAGAIN TMR_ERROR_MISC(11)+#define TMR_ERROR_OUT_OF_MEMORY TMR_ERROR_MISC(12)+#define TMR_ERROR_INVALID_WRITE_MODE TMR_ERROR_MISC(13)+#define TMR_ERROR_ILLEGAL_VALUE TMR_ERROR_MISC(14)+#define TMR_ERROR_END_OF_READING TMR_ERROR_MISC(15)+#define TMR_ERROR_UNSUPPORTED_READER_TYPE TMR_ERROR_MISC(16)+#define TMR_ERROR_BUFFER_OVERFLOW TMR_ERROR_MISC(17)+#define TMR_ERROR_LOADSAVE_CONFIG TMR_ERROR_MISC(18)+#define TMR_ERROR_AUTOREAD_ENABLED TMR_ERROR_MISC(19)+#define TMR_ERROR_FIRMWARE_UPDATE_ON_AUTOREAD TMR_ERROR_MISC(20)+#define TMR_ERROR_TIMESTAMP_NULL TMR_ERROR_MISC(21)++/* LLRP related errors */+#define TMR_ERROR_LLRP_SPECIFIC(x) TMR_STATUS_MAKE(TMR_ERROR_TYPE_LLRP, (x))+#define TMR_ERROR_IS_LLRP_SPECIFIC(x) (TMR_ERROR_TYPE_LLRP == TMR_STATUS_GET_TYPE(x))+#define TMR_ERROR_LLRP_GETTYPEREGISTRY TMR_ERROR_LLRP_SPECIFIC(1)+#define TMR_ERROR_LLRP_CONNECTIONFAILED TMR_ERROR_LLRP_SPECIFIC(2)+#define TMR_ERROR_LLRP_SENDIO_ERROR TMR_ERROR_LLRP_SPECIFIC(3)+#define TMR_ERROR_LLRP_RECEIVEIO_ERROR TMR_ERROR_LLRP_SPECIFIC(4)+#define TMR_ERROR_LLRP_RECEIVE_TIMEOUT TMR_ERROR_LLRP_SPECIFIC(5)+#define TMR_ERROR_LLRP_MSG_PARSE_ERROR TMR_ERROR_LLRP_SPECIFIC(6)+#define TMR_ERROR_LLRP_ALREADY_CONNECTED TMR_ERROR_LLRP_SPECIFIC(7)+#define TMR_ERROR_LLRP_INVALID_RFMODE TMR_ERROR_LLRP_SPECIFIC(8)+#define TMR_ERROR_LLRP_UNDEFINED_VALUE TMR_ERROR_LLRP_SPECIFIC(9)+#define TMR_ERROR_LLRP_READER_ERROR TMR_ERROR_LLRP_SPECIFIC(10)+#define TMR_ERROR_LLRP_READER_CONNECTION_LOST TMR_ERROR_LLRP_SPECIFIC(11)+#define TMR_ERROR_LLRP_CLIENT_CONNECTION_EXISTS TMR_ERROR_LLRP_SPECIFIC(12)++#ifdef TMR_ENABLE_ERROR_STRINGS+const char *TMR_strerror(TMR_Status status);+#endif++#ifdef __cplusplus+}+#endif++#endif /* _TMR_STATUS_H */
+ cbits/api/tmr_strerror.c view
@@ -0,0 +1,296 @@+/**+ * @file tmr_strerror.c+ * @brief Mercury API - status code to string conversion+ * @author Nathan Williams+ * @date 10/23/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 <stdio.h>+#include <string.h>++#include "tm_reader.h"++#if defined(TMR_ENABLE_ERROR_STRINGS)++const char *+TMR_strerror(TMR_Status status)+{+ return TMR_strerr(NULL, status);+}++const char *+TMR_strerr(TMR_Reader *reader, TMR_Status status)+{++ if (TMR_ERROR_IS_COMM(status) && TMR_ERROR_COMM_IS_ERRNO(status))+ {+#ifdef TMR_USE_STRERROR+ return strerror(TMR_ERROR_COMM_GET_ERRNO(status));+#else+ return "Error";+#endif + }++#ifdef TMR_ENABLE_LLRP_READER+ if (TMR_ERROR_IS_LLRP_SPECIFIC(status))+ {+ switch (status)+ {+ case TMR_ERROR_LLRP_MSG_PARSE_ERROR:+ return "Error parsing LLRP message";+ case TMR_ERROR_LLRP_ALREADY_CONNECTED:+ return "Already connected to reader";+ case TMR_ERROR_LLRP_INVALID_RFMODE:+ return "Specified RF Mode operation is not supported";+ case TMR_ERROR_LLRP_UNDEFINED_VALUE:+ return "Undefined Value";+ case TMR_ERROR_LLRP_READER_ERROR:+ return "LLRP reader unknown error";+ case TMR_ERROR_LLRP_READER_CONNECTION_LOST:+ return "LLRP reader connection lost";+ case TMR_ERROR_LLRP_GETTYPEREGISTRY:+ return "LLRP Reader GetTypeRegistry Failed";+ case TMR_ERROR_LLRP_CONNECTIONFAILED:+ return "LLRP Reader Connection attempt is failed";+ case TMR_ERROR_LLRP_CLIENT_CONNECTION_EXISTS:+ return "LLRP Reader Connection attempt is failed, A Client initiated connection already exists";+ case TMR_ERROR_LLRP_SENDIO_ERROR:+ return "LLRP Reader Send Messages failed";+ case TMR_ERROR_LLRP_RECEIVEIO_ERROR:+ return "LLRP Reader Receive Messages failed";+ case TMR_ERROR_LLRP_RECEIVE_TIMEOUT:+ return "LLRP Reader Receive Messages Timeout";+ default:+ {+ if (NULL == reader)+ return "Unknown error: Reader reference lost";+ else+ return reader->u.llrpReader.errMsg;+ }+ }+ }+#endif++ switch (status)+ {+ case TMR_ERROR_MSG_WRONG_NUMBER_OF_DATA:+ return "Message command length is incorrect";+ case TMR_ERROR_INVALID_OPCODE:+ return "Invalid command opcode";+ case TMR_ERROR_UNIMPLEMENTED_OPCODE:+ return "Unimplemented opcode";+ case TMR_ERROR_MSG_POWER_TOO_HIGH:+ return "Command attempted to set power above maximum";+ case TMR_ERROR_MSG_INVALID_FREQ_RECEIVED:+ return "Command attempted to set an unsupported frequency";+ case TMR_ERROR_MSG_INVALID_PARAMETER_VALUE:+ return "Parameter to command is invalid";+ case TMR_ERROR_MSG_POWER_TOO_LOW:+ return "Command attempted to set power below minimum";+ case TMR_ERROR_UNIMPLEMENTED_FEATURE:+ return "Unimplemented feature";+ case TMR_ERROR_INVALID_BAUD_RATE:+ return "Invalid baud rate";+ case TMR_ERROR_INVALID_REGION:+ return "Invalid region";+ case TMR_ERROR_INVALID_LICENSE_KEY:+ return "The license key code received is invalid";+ case TMR_ERROR_BL_INVALID_IMAGE_CRC:+ return "Application image failed CRC check";+ case TMR_ERROR_BL_INVALID_APP_END_ADDR:+ return "Application image failed data check";+ case TMR_ERROR_FLASH_BAD_ERASE_PASSWORD:+ return "Incorrect password to erase flash sector";+ case TMR_ERROR_FLASH_BAD_WRITE_PASSWORD:+ return "Incorrect password to write to flash sector";+ case TMR_ERROR_FLASH_UNDEFINED_SECTOR:+ return "Internal error in flash";+ case TMR_ERROR_FLASH_ILLEGAL_SECTOR:+ return "Incorrect password to erase or write to flash sector";+ case TMR_ERROR_FLASH_WRITE_TO_NON_ERASED_AREA:+ return "Area of flash to write to is not erased";+ case TMR_ERROR_FLASH_WRITE_TO_ILLEGAL_SECTOR:+ return "Flash write attempted to cross sector boundary";+ case TMR_ERROR_FLASH_VERIFY_FAILED:+ return "Flash verify failed";+ case TMR_ERROR_NO_TAGS_FOUND:+ return "No tags found";+ case TMR_ERROR_NO_PROTOCOL_DEFINED:+ return "Protocol not set";+ case TMR_ERROR_INVALID_PROTOCOL_SPECIFIED:+ return "Specified protocol not supported";+ case TMR_ERROR_WRITE_PASSED_LOCK_FAILED:+ return "Lock failed after write operation";+ case TMR_ERROR_PROTOCOL_NO_DATA_READ:+ return "No data could be read from a tag";+ case TMR_ERROR_AFE_NOT_ON:+ return "AFE not on - reader not sufficiently configured";+ case TMR_ERROR_PROTOCOL_WRITE_FAILED:+ return "Tag write operation failed";+ case TMR_ERROR_NOT_IMPLEMENTED_FOR_THIS_PROTOCOL:+ return "Operation not supported for this protocol";+ case TMR_ERROR_PROTOCOL_INVALID_WRITE_DATA:+ return "Tag ID supplied in write operation is incorrect";+ case TMR_ERROR_PROTOCOL_INVALID_ADDRESS:+ return "Invalid address in tag address space";+ case TMR_ERROR_GENERAL_TAG_ERROR:+ return "General tag error";+ case TMR_ERROR_DATA_TOO_LARGE:+ return "Size specified in read tag data command is too large";+ case TMR_ERROR_PROTOCOL_INVALID_KILL_PASSWORD:+ return "Kill password is not correct";+ case TMR_ERROR_PROTOCOL_KILL_FAILED:+ return "Kill failed";+ case TMR_ERROR_PROTOCOL_BIT_DECODING_FAILED:+ return "Bit decoding failed";+ case TMR_ERROR_PROTOCOL_INVALID_EPC:+ return "Invalid EPC provided";+ case TMR_ERROR_PROTOCOL_INVALID_NUM_DATA:+ return "Invalid amount of data provided";+ case TMR_ERROR_GEN2_PROTOCOL_OTHER_ERROR:+ return "Other Gen2 error";+ case TMR_ERROR_GEN2_PROTOCOL_MEMORY_OVERRUN_BAD_PC:+ return "Gen2 memory overrun - bad PC";+ case TMR_ERROR_GEN2_PROTOCOL_MEMORY_LOCKED:+ return "Gen2 memory locked";+ case TMR_ERROR_GEN2_PROTOCOL_INSUFFICIENT_POWER:+ return "Gen2 tag has insufficent power for operation";+ case TMR_ERROR_GEN2_PROTOCOL_NON_SPECIFIC_ERROR:+ return "Gen2 nonspecific error";+ case TMR_ERROR_GEN2_PROTOCOL_UNKNOWN_ERROR:+ return "Gen2 unknown error";+ case TMR_ERROR_GEN2_PROTOCOL_V2_AUTHEN_FAILED:+ return "Authentication failed with specified key.";+ case TMR_ERROR_GEN2_PROTOCOL_V2_UNTRACE_FAILED:+ return "Untrace operation failed.";+ case TMR_ERROR_AHAL_INVALID_FREQ:+ return "Invalid frequency";+ case TMR_ERROR_AHAL_CHANNEL_OCCUPIED:+ return "Channel occupied";+ case TMR_ERROR_AHAL_TRANSMITTER_ON:+ return "Transmitter already on";+ case TMR_ERROR_ANTENNA_NOT_CONNECTED:+ return "Antenna not connected";+ case TMR_ERROR_TEMPERATURE_EXCEED_LIMITS:+ return "Reader temperature too high";+ case TMR_ERROR_HIGH_RETURN_LOSS:+ return "High return loss detected, RF ended to avoid damage";+ case TMR_ERROR_INVALID_ANTENNA_CONFIG:+ return "Invalid antenna configuration";+ case TMR_ERROR_TAG_ID_BUFFER_NOT_ENOUGH_TAGS_AVAILABLE:+ return "Not enough tag IDs in buffer";+ case TMR_ERROR_TAG_ID_BUFFER_FULL:+ return "Tag ID buffer full";+ case TMR_ERROR_TAG_ID_BUFFER_REPEATED_TAG_ID:+ return "Tag ID buffer repeated tag ID";+ case TMR_ERROR_TAG_ID_BUFFER_NUM_TAG_TOO_LARGE:+ return "Number of tags too large";+ case TMR_ERROR_SYSTEM_UNKNOWN_ERROR:+ return "Unknown system error";+ case TMR_ERROR_TM_ASSERT_FAILED:+ {+ if (NULL == reader)+ {+ return "Assertion failed";+ }+ else+ {+ return reader->u.serialReader.errMsg;+ }+ }+ case TMR_ERROR_BUFFER_OVERFLOW:+ return "Buffer overflow";+ case TMR_ERROR_TIMEOUT:+ return "Timeout";+ case TMR_ERROR_NO_HOST:+ return "No matching host found";+ case TMR_ERROR_LLRP:+ return "LLRP error";+ case TMR_ERROR_PARSE:+ return "Error parsing device response";+ case TMR_ERROR_DEVICE_RESET:+ return "Device was reset externally";+ case TMR_ERROR_CRC_ERROR:+ return "CRC Error";+ case TMR_ERROR_INVALID:+ return "Invalid argument";+ case TMR_ERROR_UNIMPLEMENTED:+ return "Unimplemented operation";+ case TMR_ERROR_NO_ANTENNA:+ return "No antenna or invalid antenna";+ case TMR_ERROR_READONLY:+ return "Value is read-only";+ case TMR_ERROR_TOO_BIG:+ return "Value too big";+ case TMR_ERROR_NO_THREADS:+ return "Thread initialization failed";+ case TMR_ERROR_NO_TAGS:+ return "No tags to be retrieved";+ case TMR_ERROR_NOT_FOUND:+ return "Key not found";+ case TMR_ERROR_FIRMWARE_FORMAT:+ return "Size or format of firmware image is incorrect";+ case TMR_ERROR_TRYAGAIN:+ return "Temporary error, try again";+ case TMR_ERROR_OUT_OF_MEMORY:+ return "Out of memory";+ case TMR_ERROR_UNSUPPORTED:+ return "Unsupported operation";+ case TMR_ERROR_INVALID_WRITE_MODE:+ return "Invalid write mode";+ case TMR_ERROR_ILLEGAL_VALUE:+ return "Illegal value";+ case TMR_ERROR_UNSUPPORTED_READER_TYPE:+ return "Unsupported reader type";+ case TMR_ERROR_AUTOREAD_ENABLED:+ return "Autonomous mode is enabled on reader. Please disable it";+ case TMR_ERROR_FIRMWARE_UPDATE_ON_AUTOREAD:+ return "Firmware update is successful. Autonomous mode is already enabled on reader";+ case TMR_ERROR_TIMESTAMP_NULL:+ return "Timestamp cannot be null";++ default:+ {+ if (NULL == reader)+ return "Unknown error: Reader reference lost";+ else+ {+#ifdef TMR_ENABLE_LLRP_READER+ if (TMR_READER_TYPE_LLRP == reader->readerType)+ {+ return reader->u.llrpReader.errMsg;+ }+ else+#endif+ {+ return reader->u.serialReader.errMsg;+ }+ }+ }+ }+}++#endif /* defined(TMR_ENABLE_ERROR_STRINGS) */
+ cbits/api/tmr_tag_auth.h view
@@ -0,0 +1,79 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_TAG_AUTH_H+#define _TMR_TAG_AUTH_H+/**+ * @file tmr_tag_auth.h+ * @brief Mercury API - Tag Authentication Interface+ * @author Brian Fiegel+ * @date 4/18/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.+ */+#ifdef __cplusplus+extern "C" {+#endif++#include "tmr_gen2.h"++/* + * RFID Authentication structures+ */+typedef enum TMR_AuthType+{+ TMR_AUTH_TYPE_GEN2_PASSWORD = 0,+ TMR_AUTH_TYPE_GEN2_DENATRAN_IAV_WRITE_CREDENTIALS = 1,+ TMR_AUTH_TYPE_GEN2_DENATRAN_IAV_WRITE_SEC_CREDENTIALS = 2,+} TMR_AuthType;++/**+ * Authentication data for RFID tag protocols.+ */+typedef struct TMR_TagAuthentication+{+ /**+ * The type of authentication data.+ * Indicates which member of the union is valid.+ */+ TMR_AuthType type;+ union+ {+ /** Gen2 authentication data */+ TMR_GEN2_Password gen2Password;+ /** Gen2 Denatran IAV write credential */+ TMR_GEN2_DENATRAN_IAV_WriteCredentials writeCreds;+ TMR_GEN2_DENATRAN_IAV_WriteSecCredentials writeSecCreds;+ } u;+} TMR_TagAuthentication;++TMR_Status TMR_TA_init_gen2(TMR_TagAuthentication *auth,+ TMR_GEN2_Password password);++TMR_Status TMR_TA_init_gen2_Denatran_IAV_writeCredentials(TMR_TagAuthentication *auth, uint8_t idLength, uint8_t* tafId, uint8_t len,+ uint8_t *data);+TMR_Status TMR_TA_init_gen2_Denatran_IAV_writeSecCredentials(TMR_TagAuthentication *auth, uint8_t dataLength, uint8_t* data, uint8_t len,+ uint8_t *credentials);+#ifdef __cplusplus+}+#endif++#endif /* _TMR_TAG_AUTH_H_ */
+ cbits/api/tmr_tag_data.h view
@@ -0,0 +1,186 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_TAG_DATA_H+#define _TMR_TAG_DATA_H+/**+ * @file tmr_tag_data.h + * @brief Mercury API - Tag and tag read data structures+ * @author Brian Fiegel+ * @date 5/7/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 "tmr_tag_protocol.h"+#include "tmr_gen2.h"++#ifdef __cplusplus+extern "C" {+#endif++#define TMR_MAX_EPC_BYTE_COUNT (62)++/**+ * A structure to represent RFID tags.+ * @ingroup filter+ */+typedef struct TMR_TagData+{+ /** Tag EPC */+ uint8_t epc[TMR_MAX_EPC_BYTE_COUNT];+ /** Protocol of the tag */+ TMR_TagProtocol protocol;+ /** Length of the tag's EPC in bytes */+ uint8_t epcByteCount;+ /** Tag CRC */+ uint16_t crc;+ /** Protocol-specific tag information */+ union+ {+ /** Gen2-specific tag information */+ TMR_GEN2_TagData gen2;+ }u;+} TMR_TagData;+ +/**+ * Convert a hexadecimal string into an array of bytes. The string may+ * optionally include a "0x" prefix, which will be ignored. + *+ * @param hex The hexadecimal string to convert.+ * @param[out] bytes The array to store the converted bytes.+ * @param size The length of the byte array to store into.+ * @param[out] convertLen The number of bytes written to the array, or @c NULL.+ * + * @test If hex string is empty, *bytes should not be altered.+ * @test *convertLen is set to the correct value.+ * @test Function works when convertLen is @c NULL.+ * @test Specific values: @c "00", @c "0000", @c "ffff", @c "0xffff", @c "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabb".+ */+TMR_Status TMR_hexToBytes(const char *hex, uint8_t *bytes, uint32_t size, + uint32_t *convertLen);++/**+ * Convert an array of bytes, such as a tag EPC, into a hexadecimal string.+ *+ * @param bytes The byte array to convert.+ * @param size The length of the byte array to convert.+ * @param[out] hex The converted hexadecimal string, null-terminated.+ *+ * @test If size is 0, *hex should point to an empty string.+ */+void TMR_bytesToHex(const uint8_t *bytes, uint32_t size, char *hex);++/**+ * Defines the constants that may be combined to form the metadata+ * bitmask argument to the TMR_SR_cmdReadTagSingle,+ * TMR_SR_cmdReadTagData, and TMR_SR_cmdGetTagBuffer methods.+ */+typedef enum TMR_TRD_MetadataFlag+{+ TMR_TRD_METADATA_FLAG_NONE = 0x0000,+ TMR_TRD_METADATA_FLAG_READCOUNT = 0x0001,+ TMR_TRD_METADATA_FLAG_RSSI = 0x0002,+ TMR_TRD_METADATA_FLAG_ANTENNAID = 0x0004,+ TMR_TRD_METADATA_FLAG_FREQUENCY = 0x0008,+ TMR_TRD_METADATA_FLAG_TIMESTAMP = 0x0010,+ TMR_TRD_METADATA_FLAG_PHASE = 0x0020,+ TMR_TRD_METADATA_FLAG_PROTOCOL = 0x0040,+ TMR_TRD_METADATA_FLAG_DATA = 0x0080,+ TMR_TRD_METADATA_FLAG_GPIO_STATUS = 0x0100,+ TMR_TRD_METADATA_FLAG_ALL = + (TMR_TRD_METADATA_FLAG_READCOUNT |+ TMR_TRD_METADATA_FLAG_RSSI |+ TMR_TRD_METADATA_FLAG_ANTENNAID |+ TMR_TRD_METADATA_FLAG_FREQUENCY |+ TMR_TRD_METADATA_FLAG_TIMESTAMP |+ TMR_TRD_METADATA_FLAG_PHASE |+ TMR_TRD_METADATA_FLAG_PROTOCOL |+ TMR_TRD_METADATA_FLAG_DATA |+ TMR_TRD_METADATA_FLAG_GPIO_STATUS)+} TMR_TRD_MetadataFlag;++/**+ * A class to represent a read of an RFID tag. Provides access to the+ TMR_TRD_METADATA_FLAG_FREQUENCY tag structure and the metadata of the read event, such as the time+ * of the read, the antenna that read the tag, and the number of times+ * the tag was seen by the air protocol.+ */+typedef struct TMR_TagReadData+{+ /** The tag that was read */+ TMR_TagData tag;+ /** The set of metadata items below that are valid */+ uint16_t metadataFlags;+ /** Tag response phase */+ uint16_t phase;+ /** Antenna where the tag was read */+ uint8_t antenna;+ /** State of GPIO pins at the moment of the tag read */ + TMR_GpioPin gpio[16];+ /** the actual number of available gpio pins on module*/+ uint8_t gpioCount;+ /** Number of times the tag was read */+ uint32_t readCount;+ /** Strength of the signal received from the tag */+ int32_t rssi;+ /** RF carrier frequency the tag was read with */+ uint32_t frequency;+ /** Absolute time of the read (32 least-significant bits), in milliseconds since 1/1/1970 UTC */+ uint32_t timestampLow;+ /** Absolute time of the read (32 most-significant bits), in milliseconds since 1/1/1970 UTC */+ uint32_t timestampHigh;+ /** Data read from the tag */+ TMR_uint8List data;+ /** Read EPC bank data bytes */+ TMR_uint8List epcMemData;+ /** Read TID bank data bytes */+ TMR_uint8List tidMemData;+ /** Read USER bank data bytes */+ TMR_uint8List userMemData;+ /** Read RESERVED bank data bytes */+ TMR_uint8List reservedMemData;+ /** [PRIVATE] Relative time of the read within the read interval, in microseconds (for internal use only,+ * this value is used to calculate timestampLow and timestampHigh)+ **/+ bool isAsyncRead;+ uint32_t dspMicros;+#if TMR_MAX_EMBEDDED_DATA_LENGTH+ /** Preallocated storage for data */+ uint8_t _dataList[TMR_MAX_EMBEDDED_DATA_LENGTH];+ uint8_t _epcMemDataList[TMR_MAX_EMBEDDED_DATA_LENGTH];+ uint8_t _tidMemDataList[TMR_MAX_EMBEDDED_DATA_LENGTH];+ uint8_t _userMemDataList[TMR_MAX_EMBEDDED_DATA_LENGTH];+ uint8_t _reservedMemDataList[TMR_MAX_EMBEDDED_DATA_LENGTH];+#endif + /** Reader instance, to keep track of tag reads */+ TMR_Reader *reader;+} TMR_TagReadData;++TMR_Status TMR_TRD_init(TMR_TagReadData *trd);+TMR_Status TMR_TRD_init_data(TMR_TagReadData *trd, uint16_t size, uint8_t *buf);+TMR_Status TMR_TRD_MEMBANK_init_data(TMR_uint8List *data, uint16_t size, uint8_t *buf);++#ifdef __cplusplus+}+#endif++#endif /* __TAG_DATA_H */
+ cbits/api/tmr_tag_lock_action.h view
@@ -0,0 +1,77 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_TAG_LOCK_ACTION_H+#define _TMR_TAG_LOCK_ACTION_H+/**+ * @file tmr_tag_lock_action.h+ * @brief Mercury API - Tag Lock Action Interface+ * @author Brian Fiegel+ * @date 4/18/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.+ */+#ifdef __cplusplus+extern "C" {+#endif++#include "tmr_gen2.h"+#include "tmr_iso180006b.h"++/**+ * Types of RFID Tag Locking Structures+ */+typedef enum TMR_TagLockActionType+{+ TMR_LOCK_ACTION_TYPE_GEN2_LOCK_ACTION = 0,+ TMR_LOCK_ACTION_TYPE_ISO180006B_LOCK_ACTION = 1+} TMR_TagLockActionType;++/**+ * Tag locking structure+ */+typedef struct TMR_TagLockAction+{+ /** + * Type of the included locking structure. + * Indicates which member of the union is valid.+ */+ TMR_TagLockActionType type;+ union+ {+ /** Gen2 locking data */+ TMR_GEN2_LockAction gen2LockAction;+ /** ISO180006B locking data */+ TMR_IS0180006B_LockAction iso180006bLockAction;+ } u;+}TMR_TagLockAction;++TMR_Status TMR_TLA_init_gen2(TMR_TagLockAction *lockAction, uint16_t mask,+ uint16_t action);++TMR_Status TMR_TLA_init_ISO180006B(TMR_TagLockAction *lockAction,+ uint8_t address);++#ifdef __cplusplus+}+#endif++#endif /* _TMR_TAG_LOCK_ACTION_H_ */
+ cbits/api/tmr_tag_protocol.h view
@@ -0,0 +1,70 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_TAG_PROTOCOL_H+#define _TMR_TAG_PROTOCOL_H+/**+ * @file tmr_tag_protocol.h+ * @brief Mercury API - Tag Protocols+ * @author Brian Fiegel+ * @date 4/18/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.+ */+#ifdef __cplusplus+extern "C" {+#endif++#include "tmr_gen2.h"+#include "tmr_iso180006b.h"+#include "tmr_ipx.h"++/**+ * RFID Tag Protocols+ */+typedef enum TMR_TagProtocol +{+ TMR_TAG_PROTOCOL_NONE = 0x00,+ TMR_TAG_PROTOCOL_ISO180006B = 0x03,+ TMR_TAG_PROTOCOL_GEN2 = 0x05,+ TMR_TAG_PROTOCOL_ISO180006B_UCODE = 0x06, + TMR_TAG_PROTOCOL_IPX64 = 0x07,+ TMR_TAG_PROTOCOL_IPX256 = 0x08,+ TMR_TAG_PROTOCOL_ATA = 0x1D,+} TMR_TagProtocol;++/** A list of TMR_Protocol values */+typedef struct TMR_TagProtocolList+{+ /** The array of values */+ TMR_TagProtocol *list;+ /** The number of entries there is space for in the array */+ uint8_t max;+ /** The number of entries in the list - may be larger than max, indicating truncated data. */+ uint8_t len;+} TMR_TagProtocolList;++#ifdef __cplusplus+}+#endif+++#endif /* _TMR_TAG_PROTOCOL_H_ */
+ cbits/api/tmr_tagop.h view
@@ -0,0 +1,1734 @@+#ifndef _TMR_TAGOP_H+#define _TMR_TAGOP_H+/** + * @file tmr_tagop.h+ * @brief Mercury API - Tag Operations Interface+ * @author Nathan Williams+ * @date 1/8/2010+ */++/*+ * 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 "tmr_tag_auth.h"+#include "osdep.h"++#ifdef __cplusplus+extern "C" {+#endif++/** The type of a tag operation structure */+typedef enum TMR_TagOpType+{+ /** Gen2 EPC write */+ TMR_TAGOP_GEN2_WRITETAG,+ /** Gen2 memory read */+ TMR_TAGOP_GEN2_READDATA,+ /** Gen2 memory write */+ TMR_TAGOP_GEN2_WRITEDATA,+ /** Gen2 memory lock/unlock */+ TMR_TAGOP_GEN2_LOCK,+ /** Gen2 tag kill */+ TMR_TAGOP_GEN2_KILL,+ /** Gen2 tag block write */+ TMR_TAGOP_GEN2_BLOCKWRITE,+ /** Gen2 tag block permalock */+ TMR_TAGOP_GEN2_BLOCKPERMALOCK,+ /** Gen2 tag block erase */+ TMR_TAGOP_GEN2_BLOCKERASE,+ /** Higgs2 Partial Load Image */+ TMR_TAGOP_GEN2_ALIEN_HIGGS2_PARTIALLOADIMAGE,+ /** Higgs2 Full Load Image */+ TMR_TAGOP_GEN2_ALIEN_HIGGS2_FULLLOADIMAGE,+ /** Higgs3 Fast Load Image */+ TMR_TAGOP_GEN2_ALIEN_HIGGS3_FASTLOADIMAGE,+ /** Higgs3 Load Image */+ TMR_TAGOP_GEN2_ALIEN_HIGGS3_LOADIMAGE,+ /** Higgs3 Block Read Lock */+ TMR_TAGOP_GEN2_ALIEN_HIGGS3_BLOCKREADLOCK,++ /** NXP set read protect */+ TMR_TAGOP_GEN2_NXP_SETREADPROTECT,+ /** NXP reset read protect */+ TMR_TAGOP_GEN2_NXP_RESETREADPROTECT,+ /** NXP Change EAS */+ TMR_TAGOP_GEN2_NXP_CHANGEEAS,+ /** NXP EAS Alarm */+ TMR_TAGOP_GEN2_NXP_EASALARM,+ /** NXP Calibrate */+ TMR_TAGOP_GEN2_NXP_CALIBRATE,+ /** NXP ChangeConfig */+ TMR_TAGOP_GEN2_NXP_CHANGECONFIG,++/** NXP AES Gen2v2 untraceable operations */+ TMR_TAGOP_GEN2_NXP_UNTRACEABLE,+ /** NXP AES Gen2v2 Authenticate operations */+ TMR_TAGOP_GEN2_NXP_AUTHENTICATE,+ /** NXP AES Gen2v2 ReadBuffer operations */+ TMR_TAGOP_GEN2_NXP_READBUFFER,+++ /** Monza4 QT Read/Write*/+ TMR_TAGOP_GEN2_IMPINJ_MONZA4_QTREADWRITE,++ /** ISO180006B memory read */+ TMR_TAGOP_ISO180006B_READDATA,+ /** ISO180006B memory write */+ TMR_TAGOP_ISO180006B_WRITEDATA,+ /** ISO180006B memory lock/unlock */+ TMR_TAGOP_ISO180006B_LOCK,+ /** ISO180006B tag kill */+ /** Gen2 Secure read */+ TMR_TAGOP_GEN2_SECURE_READDATA,++ /** Gen2 IAVDenatran ActivateSecureMode - PA Protocol */+ TMR_TAGOP_GEN2_DENATRAN_IAV_ACTIVATESECUREMODE,+ /** Gen2 IAVDenatran Authenticate OBU - PA Protocol */+ TMR_TAGOP_GEN2_DENATRAN_IAV_AUTHENTICATEOBU,+ /** Gen2 IAVDenatran GEN2_ACTIVATE_SINIAV_MODE - G0 Protocol */+ TMR_TAGOP_GEN2_ACTIVATE_SINIAV_MODE,+ /** Gen2 IAVDenatran GEN2_OBU_AUTH_ID - G0 Protocol */+ TMR_TAGOP_GEN2_OBU_AUTH_ID,+ /** Gen2 IAVDenatran GEN2_AUTHENTICATE_OBU_FULL_PASS1 - G0 Protocol */+ TMR_TAGOP_GEN2_AUTHENTICATE_OBU_FULL_PASS1,+ /** Gen2 IAVDenatran GEN2_AUTHENTICATE_OBU_FULL_PASS2 - G0 Protocol */+ TMR_TAGOP_GEN2_AUTHENTICATE_OBU_FULL_PASS2,+ /** Gen2 IAVDenatran GEN2_OBU_READ_FROM_MEM_MAP - G0 Protocol */+ TMR_TAGOP_GEN2_OBU_READ_FROM_MEM_MAP,+ /** Gen2 IAVDenatran GEN2_OBU_WRITE_TO_MEM_MAP - G0 Protocol */+ TMR_TAGOP_GEN2_OBU_WRITE_TO_MEM_MAP,+ /** Gen2 IAVDenatran GET_TOKEN_ID - G0 Protocol */+ TMR_TAGOP_GEN2_DENATRAN_IAV_GET_TOKEN_ID,+ /** Gen2 IAVDenatran AUTHENTICATE_OBU_FULL_PASS */+ TMR_TAGOP_GEN2_DENATRAN_IAV_AUTHENTICATE_OBU_FULL_PASS,+ /** Gen2 IAVDenatran Read Sec - IP63 protocol */+ TMR_TAGOP_GEN2_DENATRAN_IAV_READ_SEC,+ /** Gen2 IAVDenatran Write Sec - IP63 protocol */+ TMR_TAGOP_GEN2_DENATRAN_IAV_WRITE_SEC,+ /** Gen2 IAVDenatran GEN2_G0_PA_OBU_AUTHENTICATE_ID - ( PA + G0 ) Protocol */+ TMR_TAGOP_GEN2_DENATRAN_IAV_G0_PA_OBU_AUTHENTICATE_ID,+ + /** Gen2 Ids get sensor type */+ TMR_TAGOP_GEN2_IDS_SL900A_GETSENSOR,+ /** Gen2 Ids get log state */+ TMR_TAGOP_GEN2_IDS_SL900A_GETLOGSTATE,+ /** Gen2 Ids set log mode */+ TMR_TAGOP_GEN2_IDS_SL900A_SETLOGMODE,+ /** Gen2 Ids end log */+ TMR_TAGOP_GEN2_IDS_SL900A_ENDLOG,+ /** Gen2 Ids Initialize */+ TMR_TAGOP_GEN2_IDS_SL900A_INITIALIZE,+ /** Gen2 Ids Fifo Status */+ TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOSTATUS,+ /** Gen2 Ids Fifo Read */+ TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOREAD,+ /** Gen2 Ids Fifo write */+ TMR_TAGOP_GEN2_IDS_SL900A_ACCESSFIFOWRITE,+ /** Gen2 Ids Starrt Log */+ TMR_TAGOP_GEN2_IDS_SL900A_STARTLOG,+ /** Gen2 Ids GetCalibrationData */+ TMR_TAGOP_GEN2_IDS_SL900A_GETCALIBRATIONDATA,+ /** Gen2 Ids SetCalibration */+ TMR_TAGOP_GEN2_IDS_SL900A_SETCALIBRATIONDATA,+ /** Gen2 Ids SetSfeParameters */+ TMR_TAGOP_GEN2_IDS_SL900A_SETSFEPARAMETERS,+ /** Gen2 Ids GetMeasurmentSetup */+ TMR_TAGOP_GEN2_IDS_SL900A_GETMEASUREMENTSETUP,+ /** Gen2 Ids GetBattery Level */+ TMR_TAGOP_GEN2_IDS_SL900A_GETBATTERYLEVEL,+ /** Gen2 Ids SetLogLimits */+ TMR_TAGOP_GEN2_IDS_SL900A_SETLOGLIMITS,+ /** Gen2 Ids SetShelfLife */+ TMR_TAGOP_GEN2_IDS_SL900A_SETSHELFLIFE,+ /** Set IDS Password */+ TMR_TAGOP_GEN2_IDS_SL900A_SETPASSWORD,+++ /** List of tag operations */+ TMR_TAGOP_LIST+} TMR_TagOpType;++/** The type of Gen2 Secure operation */+typedef enum SecureTagType+{+ GEN2_EMBEDDED_SECURE_DEFAULT = 0x00,+ /* Alien Higgs 3 secure access */+ GEN2_EMBEDDED_SECURE_HIGGS3_ACCESS = (1 << 1),+ /* Monza 4 secure access */+ GEN2_EMBEDDED_SECURE_MONZA4_ACCESS = (1 << 2)+}SecureTagType;+ +/* The type of Gen2 IAVDenatranCmdEnum */+typedef enum IAVDenatranSecureTagOpType+{+ /* Activate Secure Mode - PA Protocol */+ GEN2_ACTIVATE_SECURE_MODE = 0x00,+ /* Authenticate OBU - PA Protocol */+ GEN2_AUTHENTICATE_OBU = 0x01,+ /* Activate Siniav Mode OBU - G0 Protocol */+ GEN2_ACTIVATE_SINIAV_MODE = 0x02,+ /* Authenticate OBU ID - G0 Protocol */+ GEN2_OBU_AUTH_ID = 0x03,+ /* Authenticate OBU FullPass1 - G0 Protocol */+ GEN2_AUTHENTICATE_OBU_FULL_PASS1 = 0x04,+ /* Authenticate OBU FullPass2 - G0 Protocol */+ GEN2_AUTHENTICATE_OBU_FULL_PASS2 = 0x05,+ /* Read From Mem - G0 Protocol */+ GEN2_OBU_READ_FROM_MEM_MAP = 0x06,+ /* Write to Mem - G0 Protocol */+ GEN2_OBU_WRITE_TO_MEM_MAP = 0x07,+ /* Authenticate OBU FullPass2 - G0 Protocol */+ GEN2_AUTHENTICATE_OBU_FULL_PASS = 0x08,+ /* Get token ID - Go Protocol */+ GEN2_GET_TOKEN_ID = 0x09,+ /* Read Sec - IP63 Protocol */+ GEN2_READ_SEC = 0x0A,+ /* Write Sec - IP63 Protocol */+ GEN2_WRITE_SEC = 0x0B,+ /* Pa G0 - (PA + G0) Protocol */+ GEN2_PA_G0_AUTHENTICATE = 0x0C,+}IAVDenatranSecureTagOpType;++/* The type of Gen2 secure password */+typedef enum SecurePasswordType+{+ /* Gen2 password type */+ TMR_SECURE_GEN2_PASSWORD = 0x01,+ /* Look up table password */+ TMR_SECURE_GEN2_LOOKUP_TABLE_PASSWORD = 0x02+}SecurePasswordType;++/* The fild type of calibration data that user can modify */+typedef enum CalibrationParameter+{+ /* AD1 lower voltage reference - coarse */+ TMR_GEN2_IDS_SL900A_CALIBRATION_COARSE1,+ /* AD2 lower voltage reference - coarse */+ TMR_GEN2_IDS_SL900A_CALIBRATION_COARSE2,+ /* Switches the lower AD voltage reference to ground */+ TMR_GEN2_IDS_SL900A_CALIBRATION_GNDSWITCH,+ /* POR voltage level for 1.5V system */+ TMR_GEN2_IDS_SL900A_CALIBRATION_SELP12,+ /* RTC oscillator calibration */+ TMR_GEN2_IDS_SL900A_CALIBRATION_DF,+ /* Controlled battery supply for external sensor - the battery voltage is connected to the EXC pin */+ TMR_GEN2_IDS_SL900A_CALIBRATION_SWEXTEN,+ /* POR voltage level for 3V system */+ TMR_GEN2_IDS_SL900A_CALIBRATION_SELP22,+ /* Voltage level interrupt level for external sensor -- ratiometric */+ TMR_GEN2_IDS_SL900A_CALIBRATION_IRLEV,+ /* Excitate for resistive sensors without DC */+ TMR_GEN2_IDS_SL900A_CALIBRATION_EXCRES,+}CalibrationParameter;++/* The field type of sfe parameters that user can modify */+typedef enum SfeParameter+{+ /* External sensor 2 range */+ TMR_GEN2_IDS_SL900A_SFE_RANG,+ /* External sensor 1 range */+ TMR_GEN2_IDS_SL900A_SFE_SETI,+ /* External sensor 1 type */+ TMR_GEN2_IDS_SL900A_SFE_EXT1,+ /* External sensor 2 type */+ TMR_GEN2_IDS_SL900A_SFE_EXT2,+ /* Use preset range */+ TMR_GEN2_IDS_SL900A_SFE_AUTORANGEDISABLE,+ /* Sensor used in limit check */+ TMR_GEN2_IDS_SL900A_SFE_VERIFYSENSORID,+}SfeParameter;++typedef struct TMR_TagOp_GEN2_NXP_Tam1Authentication+{+ uint8_t Authentication;+ uint8_t CSI;+ uint8_t keyID;+ uint8_t KeyLength;+ uint8_t IchallengeLength;+ TMR_uint8List Key;+ TMR_uint8List Ichallenge;+} TMR_TagOp_GEN2_NXP_Tam1Authentication;++typedef struct TMR_TagOp_GEN2_NXP_Tam2Authentication+{+ TMR_TagOp_GEN2_NXP_Tam1Authentication tam1Auth;+ uint16_t Offset;+ uint8_t ProtMode;+ uint8_t BlockCount;+ TMR_NXP_Profile profile;+} TMR_TagOp_GEN2_NXP_Tam2Authentication;++typedef enum TMR_GEN2_UNTRACEABLE_AuthType+{+ /* Tag exposes EPC memory */+ UNTRACEABLE_WITH_AUTHENTICATION = 0,+ /*Tag untraceably hides EPC memory above that*/+ UNTRACEABLE_WITH_ACCESS = 1++}TMR_GEN2_UNTRACEABLE_AuthType;+typedef struct TMR_TagOp_GEN2_NXP_UNTRACEABLE_Authentication+{ + TMR_GEN2_UNTRACEABLE_AuthType authType;+ TMR_TagOp_GEN2_NXP_Tam1Authentication tam1Auth;+ TMR_GEN2_Password accessPassword;++}TMR_TagOp_GEN2_NXP_UNTRACEABLE_Authentication;++typedef struct TMR_TagOp_GEN2_NXP_Untraceable+{+ TMR_TagOp_GEN2_NXP_UNTRACEABLE_Authentication auth; + TMR_GEN2_UNTRACEABLE_Epc epc;+ int32_t epcLength;+ TMR_GEN2_UNTRACEABLE_Tid tid;+ TMR_GEN2_UNTRACEABLE_UserMemory userMemory;+ TMR_GEN2_UNTRACEABLE_Range range;+ uint8_t subCommand;++} TMR_TagOp_GEN2_NXP_Untraceable;++typedef enum TMR_GEN2_AUTHENTICATE_Type+{+ TAM1_AUTHENTICATION,+ TAM2_AUTHENTICATION+}TMR_GEN2_AUTHENTICATE_Type;++typedef struct TMR_TagOp_GEN2_NXP_Authenticate+{+ TMR_GEN2_AUTHENTICATE_Type type;+ TMR_TagOp_GEN2_NXP_Tam1Authentication tam1Auth;+ TMR_TagOp_GEN2_NXP_Tam2Authentication tam2Auth;+ uint8_t subCommand;+}TMR_TagOp_GEN2_NXP_Authenticate;++typedef struct TMR_TagOp_GEN2_NXP_Readbuffer+{+ uint16_t wordPointer;+ uint16_t bitCount;+ TMR_TagOp_GEN2_NXP_Authenticate authenticate;++}TMR_TagOp_GEN2_NXP_Readbuffer;++/** Parameters of a Gen2 EPC write operation */+typedef struct TMR_TagOp_GEN2_WriteTag+{+ /** Tag EPC */+ TMR_TagData* epcptr;+} TMR_TagOp_GEN2_WriteTag;++/** Parameters of a Gen2 memory read operation */+typedef struct TMR_TagOp_GEN2_ReadData+{+ /** Gen2 memory bank to read from */+ TMR_GEN2_Bank bank;+ /** Word address to start reading at */+ uint32_t wordAddress;+ /** Number of words to read */+ uint8_t len;+} TMR_TagOp_GEN2_ReadData;++/** Parameters of Gen2 Secure operation */++/* Parameters of SecurePassWordLookup Table */+typedef struct SecurePasswordLookup+{+ /* used in case Gen2 passWord */+ TMR_TagAuthentication gen2PassWord;++ /* used in case of password look table */+ /* Number of bits used to address the AP list (MSB byte - byte 4) */+ uint8_t secureAddressLength;+ /* EPC word offset (Next MSB byte - byte 3) */+ uint8_t secureAddressOffset;+ /* User flash offset, starting from 0x0000 (LSB 2 bytes) */+ uint16_t secureFlashOffset;+} SecurePasswordLookup;++typedef struct TMR_TagOp_GEN2_SecureReadData+{+ /** Gen2 read operation */+ TMR_TagOp_GEN2_ReadData readData;++ /** type of Gen2 Secure operation*/+ /* Options to select Alien Higgs 3 secure access and Monza 4 secure access */+ SecureTagType type;+ /* option to select Gen2 password or look up table password */+ SecurePasswordType passwordType;+ /* Options to specify the password */+ SecurePasswordLookup password;+ } TMR_TagOp_GEN2_SecureReadData;++/** Parameters of a Gen2 memory write operation */+typedef struct TMR_TagOp_GEN2_WriteData+{+ /** Gen2 memory bank to write to */+ TMR_GEN2_Bank bank;+ /** Word address to start writing at */+ uint32_t wordAddress;+ /** Data to write */+ TMR_uint16List data;+} TMR_TagOp_GEN2_WriteData;++/** Parameters of a Gen2 memory lock/unlock operation */+typedef struct TMR_TagOp_GEN2_Lock+{ + /** Bitmask indicating which lock bits to change */+ uint16_t mask;+ /** New values of each bit specified in the mask */+ uint16_t action;+ /** Access Password to use to lock the tag*/+ TMR_GEN2_Password accessPassword;+} TMR_TagOp_GEN2_Lock;++/** Parameters of a Gen2 tag kill operation */+typedef struct TMR_TagOp_GEN2_Kill+{+ /** Kill password to use to kill the tag */+ TMR_GEN2_Password password;+} TMR_TagOp_GEN2_Kill;++/** Parameters of a Gen2 tag Block Write operation */+typedef struct TMR_TagOp_GEN2_BlockWrite+{+ /** Gen2 memory bank to write to */+ TMR_GEN2_Bank bank; + /** The word address to start writing to */+ uint32_t wordPtr; + /** The data to write */+ TMR_uint16List data; +}TMR_TagOp_GEN2_BlockWrite;++/** Parameters of a Gen2 tag Block PermaLock operation */+typedef struct TMR_TagOp_GEN2_BlockPermaLock+{+ /** Read lock status or write it? */+ uint8_t readLock; + /** Gen2 memory bank to lock */+ TMR_GEN2_Bank bank; + /** The starting word address to lock */+ uint32_t blockPtr;+ /** Mask: Which blocks to lock? */+ TMR_uint16List mask;+}TMR_TagOp_GEN2_BlockPermaLock;++/** Parameters of a Gen2 tag Block Erase operation */+typedef struct TMR_TagOp_GEN2_BlockErase+{+ /** Gen2 memory bank to erase */+ TMR_GEN2_Bank bank;+ /** The starting word address for block erase */+ uint32_t wordPtr;+ /** Number of words to erase */+ uint8_t wordCount;+} TMR_TagOp_GEN2_BlockErase;++/** Parameters of a Gen2 memory lock/unlock operation */+typedef struct TMR_TagOp_ISO180006B_Lock+{ + /** The memory address of the byte to lock */+ uint8_t address;+} TMR_TagOp_ISO180006B_Lock;++/** Parameters of an ISO180006B memory read operation */+typedef struct TMR_TagOp_ISO180006B_ReadData+{+ /** Byte address to start reading at */+ uint8_t byteAddress;+ /** Number of bytes to read */+ uint8_t len;+} TMR_TagOp_ISO180006B_ReadData;++/** Parameters of an ISO180006B memory write operation */+typedef struct TMR_TagOp_ISO180006B_WriteData+{+ /** Byte address to start writing at */+ uint8_t byteAddress;+ /** Data to write */+ TMR_uint8List data;+} TMR_TagOp_ISO180006B_WriteData;++/**+ * Tagops for Gen2 custom commands+ **/++/** Parameters for Alien Higgs2, Partial Load Image command*/+typedef struct TMR_TagOp_GEN2_Alien_Higgs2_PartialLoadImage+{+ /** Kill password to write to the tag */+ TMR_GEN2_Password killPassword;+ /** Access password to write to the tag */+ TMR_GEN2_Password accessPassword;+ /** Tag EPC to write to the tag*/+ TMR_TagData* epcptr;+} TMR_TagOp_GEN2_Alien_Higgs2_PartialLoadImage;++/** Parameters for Alien Higgs2, Full Load Image command*/+typedef struct TMR_TagOp_GEN2_Alien_Higgs2_FullLoadImage+{+ /** Kill password to write to the tag */+ TMR_GEN2_Password killPassword;+ /** Access password to write to the tag */+ TMR_GEN2_Password accessPassword;+ /** Lock Bits */+ uint16_t lockBits;+ /** PC word */+ uint16_t pcWord;+ /** Tag EPC to write to the tag*/+ TMR_TagData* epcptr;+} TMR_TagOp_GEN2_Alien_Higgs2_FullLoadImage;++/** Parameters for Alien Higgs3, Fast Load Image command*/+typedef struct TMR_TagOp_GEN2_Alien_Higgs3_FastLoadImage+{+ /** Access password used to write to the tag */+ TMR_GEN2_Password currentAccessPassword;+ /** Kill password to write to the tag */+ TMR_GEN2_Password killPassword;+ /** Access password to write to the tag */+ TMR_GEN2_Password accessPassword;+ /** PC word */+ uint16_t pcWord;+ /** Tag EPC to write to the tag*/+ TMR_TagData* epcptr;+} TMR_TagOp_GEN2_Alien_Higgs3_FastLoadImage;+++/** Parameters for Alien Higgs3, Load Image command*/+typedef struct TMR_TagOp_GEN2_Alien_Higgs3_LoadImage+{+ /** Access password used to write to the tag */+ TMR_GEN2_Password currentAccessPassword;+ /** Kill password to write to the tag */+ TMR_GEN2_Password killPassword;+ /** Access password to write to the tag */+ TMR_GEN2_Password accessPassword;+ /** PC word */+ uint16_t pcWord;+ /** Tag EPC and user data to write to the tag (76 bytes)*/+ TMR_uint8List *epcAndUserData;+} TMR_TagOp_GEN2_Alien_Higgs3_LoadImage;++/** Parameters for Alien Higgs3, Block Read Lock command*/+typedef struct TMR_TagOp_GEN2_Alien_Higgs3_BlockReadLock+{+ /** Access password to use to write to the tag, in case if the tag is already locked */+ TMR_GEN2_Password accessPassword;+ /** A bitmask of bits to lock */+ uint8_t lockBits;+} TMR_TagOp_GEN2_Alien_Higgs3_BlockReadLock;++/** Parameters for NXP, Set Read Protect command */+typedef struct TMR_TagOp_GEN2_NXP_SetReadProtect+{+ /** Access password to use to write to the tag */+ TMR_GEN2_Password accessPassword;+}TMR_TagOp_GEN2_NXP_SetReadProtect;++/** Parameters for NXP, Reset Read Protect Command*/+typedef struct TMR_TagOp_GEN2_NXP_ResetReadProtect+{+ /** Access password to use to write to the tag */+ TMR_GEN2_Password accessPassword;+} TMR_TagOp_GEN2_NXP_ResetReadProtect;++/** Parameters for NXP, Change EAS Command*/+typedef struct TMR_TagOp_GEN2_NXP_ChangeEAS+{+ /** Access password to use to write to the tag */+ TMR_GEN2_Password accessPassword;+ /** Reset or set EAS bit */+ bool reset;+} TMR_TagOp_GEN2_NXP_ChangeEAS;++/** Parameters for NXP, EAS alarm command */+typedef struct TMR_TagOp_GEN2_NXP_EASAlarm+{+ /** Gen2 divide ratio to use */+ TMR_GEN2_DivideRatio dr;+ /** Gen2 M parameter to use */+ TMR_GEN2_TagEncoding m;+ /** Gen2 TrExt value to use */+ TMR_GEN2_TrExt trExt; +} TMR_TagOp_GEN2_NXP_EASAlarm;++/** Parameters for NXP, Calibration command */+typedef struct TMR_TagOp_GEN2_NXP_Calibrate+{+ /** Access password to use to write to the tag */+ TMR_GEN2_Password accessPassword;+} TMR_TagOp_GEN2_NXP_Calibrate;++/** Parameters for NXP, Change Config command */+typedef struct TMR_TagOp_GEN2_NXP_ChangeConfig+{+ /** Access password to use to write to the tag */+ TMR_GEN2_Password accessPassword;+ /** ConfigWord to write to the tag*/+ TMR_NXP_ConfigWord configWord;+}TMR_TagOp_GEN2_NXP_ChangeConfig;++/** Parameters for NXP, Change Config command */+typedef struct TMR_TagOp_GEN2_Impinj_Monza4_QTReadWrite+{+ /** Access password to use to write to the tag */+ TMR_GEN2_Password accessPassword;+ /** Control Byte to write to the tag*/+ TMR_Monza4_ControlByte controlByte;+ /** Payload */+ TMR_Monza4_Payload payload; +}TMR_TagOp_GEN2_Impinj_Monza4_QTReadWrite;+ +/** Parameters for IAV, ActivateSecureMode command */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_Activate_Secure_Mode+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+}TMR_TagOp_GEN2_Denatran_IAV_Activate_Secure_Mode;++/** Parameters for IAV, AuthenticateOBU command */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_Authenticate_OBU+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+}TMR_TagOp_GEN2_Denatran_IAV_Authenticate_OBU;++/** Parameters for IAV, Activate_Siniav_Mode command - G0 Protocol */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_Activate_Siniav_Mode+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+ /* token desc */+ bool isTokenDesc;+ /* 64 bits of token data */+ uint8_t token[8];+}TMR_TagOp_GEN2_Denatran_IAV_Activate_Siniav_Mode;++/** Parameters for IAV, OBU_Auth_ID command - G0 Protocol */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_ID+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+}TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_ID;++/** Parameters for IAV, OBU_Auth_Full_Pass1 command - G0 Protocol */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass1+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+}TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass1;++/** Parameters for IAV, OBU_Auth_Full_Pass2 command - G0 Protocol */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass2+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+}TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass2;++/** Parameters for IAV, OBU_ReadFromMemMap command - G0 Protocol */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_OBU_ReadFromMemMap+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+ /* address to be read from USER bank */+ uint16_t readPtr;+}TMR_TagOp_GEN2_Denatran_IAV_OBU_ReadFromMemMap;++/** Parameters for IAV, read sec command - IP63 Protocol */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_Read_Sec+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+ /* address to be read from USER bank */+ uint16_t readPtr;+}TMR_TagOp_GEN2_Denatran_IAV_Read_Sec;++/** Parameters for IAV, OBU_WriteToMemMap command - G0 Protocol */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_OBU_WriteToMemMap+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+ /* Pointer to the USER data */+ uint16_t writePtr;+ /* data to be written */+ uint16_t wordData;+ /* Tag ID */+ uint8_t* tagIdentification;+ /* Credentials written word */+ uint8_t* dataBuf; +}TMR_TagOp_GEN2_Denatran_IAV_OBU_WriteToMemMap;++/** Parameters for IAV, write sec command - IP63 Protocol */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_Write_Sec+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+ /* data words */+ uint8_t* dataWords;+ /* Credentials written word */+ uint8_t* dataBuf;+}TMR_TagOp_GEN2_Denatran_IAV_Write_Sec;++/** Parameters for IAV, Get Token ID command */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_Get_Token_Id+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+}TMR_TagOp_GEN2_Denatran_IAV_Get_Token_Id;++/** Parameters for IAV, Authenticate OBU Full Pass */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+}TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass;++/** Parameters for IAV, G0_PA_OBU_Auth_ID */+typedef struct TMR_TagOp_GEN2_Denatran_IAV_G0_PA_OBU_Auth_ID+{+ /* Enum for IAV tagoperation */+ IAVDenatranSecureTagOpType mode;+ /* RFU field */+ uint8_t payload;+}TMR_TagOp_GEN2_Denatran_IAV_G0_PA_OBU_Auth_ID;++/* Forward declaration for the benefit of TMR_TagOp_List */+typedef struct TMR_TagOp TMR_TagOp;++/** List of tag operations */+typedef struct TMR_TagOp_List+{+ /** Array of pointers to tag operations*/+ TMR_TagOp **list;+ /** Number of tag operations in list */+ uint16_t len;+} TMR_TagOp_List;++/** Sub-class for Gen2 Alien Higgs2 custom tag extensions */+typedef struct TMR_TagOp_GEN2_Alien_Higgs2+{+ union+ {+ TMR_TagOp_GEN2_Alien_Higgs2_PartialLoadImage partialLoadImage;+ TMR_TagOp_GEN2_Alien_Higgs2_FullLoadImage fullLoadImage;+ } u;+}TMR_TagOp_GEN2_Alien_Higgs2;++/** Sub-class for Gen2 Alien Higgs3 custom tag extensions */+typedef struct TMR_TagOp_GEN2_Alien_Higgs3+{+ union+ {+ TMR_TagOp_GEN2_Alien_Higgs3_FastLoadImage fastLoadImage;+ TMR_TagOp_GEN2_Alien_Higgs3_LoadImage loadImage;+ TMR_TagOp_GEN2_Alien_Higgs3_BlockReadLock blockReadLock;+ } u;+}TMR_TagOp_GEN2_Alien_Higgs3;++/** Sub-class for Gen2 Alien custom tag extensions */+typedef struct TMR_TagOp_GEN2_Alien+{+ union+ {+ TMR_TagOp_GEN2_Alien_Higgs2 higgs2;+ TMR_TagOp_GEN2_Alien_Higgs3 higgs3;+ } u;+}TMR_TagOp_GEN2_Alien;++/** Sub-class for Gen2 NXP custom tag extensions */+typedef struct TMR_TagOp_GEN2_NXP+{+ union+ {+ TMR_TagOp_GEN2_NXP_SetReadProtect setReadProtect;+ TMR_TagOp_GEN2_NXP_ResetReadProtect resetReadProtect;+ TMR_TagOp_GEN2_NXP_ChangeEAS changeEAS;+ TMR_TagOp_GEN2_NXP_EASAlarm EASAlarm;+ TMR_TagOp_GEN2_NXP_Calibrate calibrate;+ TMR_TagOp_GEN2_NXP_ChangeConfig changeConfig;+ TMR_TagOp_GEN2_NXP_Untraceable untraceable;+ TMR_TagOp_GEN2_NXP_Authenticate authenticate;+ TMR_TagOp_GEN2_NXP_Readbuffer readBuffer;+ }u;+}TMR_TagOp_GEN2_NXP;++/** Sub-class for Gen2 Impinj Monza4 custom tag extensions */+typedef struct TMR_TagOp_GEN2_Impinj_Monza4+{+ union+ {+ TMR_TagOp_GEN2_Impinj_Monza4_QTReadWrite qtReadWrite;+ } u;+}TMR_TagOp_GEN2_Impinj_Monza4;++/** Sub-class for Gen2 Impinj custom tag extensions */+typedef struct TMR_TagOp_GEN2_Impinj+{+ union+ {+ TMR_TagOp_GEN2_Impinj_Monza4 monza4;+ } u;+}TMR_TagOp_GEN2_Impinj;++/** Sub-class for Gen2 IavDenatran custom tag extensions */+typedef struct TMR_TagOp_GEN2_Denatran+{+ union+ {+ TMR_TagOp_GEN2_Denatran_IAV_Activate_Secure_Mode secureMode;+ TMR_TagOp_GEN2_Denatran_IAV_Authenticate_OBU authenticateOBU;+ TMR_TagOp_GEN2_Denatran_IAV_Activate_Siniav_Mode activateSiniavMode;+ TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_ID obuAuthId;+ TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass1 obuAuthFullPass1;+ TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass2 obuAuthFullPass2;+ TMR_TagOp_GEN2_Denatran_IAV_OBU_ReadFromMemMap obuReadFromMemMap;+ TMR_TagOp_GEN2_Denatran_IAV_OBU_WriteToMemMap obuWriteToMemMap;+ TMR_TagOp_GEN2_Denatran_IAV_Get_Token_Id getTokenId;+ TMR_TagOp_GEN2_Denatran_IAV_Read_Sec readSec;+ TMR_TagOp_GEN2_Denatran_IAV_Write_Sec writeSec;+ TMR_TagOp_GEN2_Denatran_IAV_OBU_Auth_Full_Pass obuAuthFullPass;+ TMR_TagOp_GEN2_Denatran_IAV_G0_PA_OBU_Auth_ID g0paobuauthid;+ } u;+}TMR_TagOp_GEN2_Denatran;++/** Sensor type for IDS Sl900A chip */+typedef enum Sensor+{+ /* SL900A sensor type values */+ TMR_GEN2_IDS_SL900A_SENSOR_TEMP = 0x00,+ TMR_GEN2_IDS_SL900A_SENSOR_EXT1 = 0x01,+ TMR_GEN2_IDS_SL900A_SENSOR_EXT2 = 0x02,+ TMR_GEN2_IDS_SL900A_SENSOR_BATTV = 0x03,+}Sensor;++/** SL900A password access level values */+typedef enum PasswordLevel+{+ /* No access to any protected area */+ TMR_GEN2_IDS_SL900A_PASSWORD_NOT_ALLOWED = 0x00,+ /* System area access */+ TMR_GEN2_IDS_SL900A_PASSWORD_SYSTEM = 0x01,+ /* Application area access */+ TMR_GEN2_IDS_SL900A_PASSWORD_APPLICATION = 0x02,+ /* Measurement area access */+ TMR_GEN2_IDS_SL900A_PASSWORD_MEASUREMENT = 0x03,+}PasswordLevel;++/** SL900A Data log format selection */+typedef enum LoggingForm+{+ /* Dense Logging */+ TMR_GEN2_IDS_SL900A_LOGGINGFORM_DENSE = 0x00,+ /* Log values outside specified limits */+ TMR_GEN2_IDS_SL900A_LOGGINGFORM_OUTOFLIMITS = 0x01,+ /* Log values at limit crossing points */+ TMR_GEN2_IDS_SL900A_LOGGINGFORM_LIMITSCROSSING = 0x03,+ /* Trigger log on EXT1 input */+ TMR_GEN2_IDS_SL900A_LOGGINGFORM_IRQ1 = 0x05,+ /* Trigger log on EXT2 input */+ TMR_GEN2_IDS_SL900A_LOGGINGFORM_IRQ2 = 0x06,+ /* Trigger log on EXT1 and EXT2 input */+ TMR_GEN2_IDS_SL900A_LOGGINGFORM_IRQ1IRQ2 = 0x07,+}LoggingForm;++/** SL900A Data log memory-full behavior */+typedef enum DelayMode+{+ /* Start logging after delay time */+ TMR_GEN2_IDS_SL900A_DELAYMODE_TIMER = 0x00,+ /* Start logging on external input */+ TMR_GEN2_IDS_SL900A_DELAYMODE_EXTSWITCH = 0x01,+}DelayMode;++/** SL900A Logging memory-full behavior */+typedef enum StorageRule+{+ /* Stop logging when memory fills */+ TMR_GEN2_IDS_SL900A_STORAGERULE_NORMAL = 0x00,+ /* Roll around (circular buffer) when memory fills */+ TMR_GEN2_IDS_SL900A_STORAGERULE_ROLLING = 0x01,+}StorageRule;++/** Sub-Class for BatterType, re-check or default */+typedef enum BatteryType+{+ /* Default */+ TMR_GEN2_IDS_SL900A_BATTERYTYPE_CHECK = 0x00,+ /* Application requested for the re-check of battery type */+ TMR_GEN2_IDS_SL900A_BATTERYTYPE_RECHECK = 0x01,+}BatteryType;++/** Sub-Class for Raw 9 or 21-bit Get Log State reply */+typedef struct LimitCounter+{+ /* Number of times selected sensor has gone beyond extreme lower limit */+ uint8_t extremeLower;+ /* Number of times selected sensor has gone beyond lower limit */+ uint8_t lower;+ /* Number of times selected sensor has gone beyond upper limit */+ uint8_t upper;+ /* Number of times selected sensor has gone beyond extreme upper limit */+ uint8_t extremeUpper;+}LimitCounter;++/** Sub-Class for specifying 40 bit LogLimits Value */+typedef struct LogLimits+{+ /* Specifying the extreme lower limit */+ uint16_t extremeLower;+ /* Specifying the lower limit */+ uint16_t lower;+ /* Specifying the upper limit */+ uint16_t upper;+ /* Specifying the extreme upper limit */+ uint16_t extremeUpper;+}LogLimits;++/** Sub-class for SystemStatus reply object */+typedef struct SystemStatus+{+ /* Measurement Address Pointer */+ uint16_t MeasurementAddressPointer;+ /* Number of memory replacements */+ uint8_t NumMemReplacements;+ /* Number of measurements */+ uint16_t NumMeasurements;+ /* Active */+ bool Active;+}SystemStatus;++/** Sub-Class for Log Status Flags */+typedef struct StatusFlags+{+ /* Logging active */+ bool Active;+ /* Measurement area full */+ bool Full;+ /* Measurement overwritten */+ bool Overwritten;+ /* A/D error occurred */+ bool ADError;+ /* Low battery */+ bool LowBattery;+ /* Shelf life low error */+ bool ShelfLifeLow;+ /* Shelf life high error */+ bool ShelfLifeHigh;+ /* ShelfLifeExpired */+ bool ShelfLifeExpired;+}StatusFlags;+/** Sub-class for get log state value reply */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_LogState+{+ /* Number of excursions beyond set limits */+ LimitCounter limitCount;+ /* Logging system status */+ SystemStatus statStatus;+ /* Logging status flags */+ StatusFlags statFlag;+}TMR_TagOp_GEN2_IDS_SL900A_LogState;++/** Sub-Class for Get Sensor Value reply */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_SensorReading+{+ /* Raw 16-bit response from GetSensorValue command */+ uint16_t reply;+ /* Raw sensor reply */+ uint16_t Raw;+ /* Did A/D conversion error occur? */+ bool ADError;+ /* 5-bit Range/Limit value */+ uint8_t RangeLimit;+ /* 10-bit Sensor value */+ uint16_t Value;+}TMR_TagOp_GEN2_IDS_SL900A_SensorReading;++/** Sub-Class for Get Battery Level Reply */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_BatteryLevelReading+{+ /* Raw 16-bit response from GetBatteryLevel command */+ uint16_t reply;+ /* Did A/D conversion error occur? */+ bool ADError;+ /* 1-bit Battery Type */+ uint8_t BatteryType;+ /* 10-bit Battery Level value */+ uint16_t Value;+}TMR_TagOp_GEN2_IDS_SL900A_BatteryLevelReading;++/** Sub-class for SL900A Log Mode Data */+typedef struct LogModeData+{+ /* Raw 8-bit response from Measurement Setup Data command */+ uint8_t Raw;+ /* Logging Format */+ LoggingForm Form;+ /* Log Memory-Full Behavior */+ StorageRule Storage;+ /* Enable log for EXT1 external sensor */+ bool Ext1Enable;+ /* Enable log for EXT2 external sensor */+ bool Ext2Enable;+ /* Enable log for temperature sensor */+ bool TempEnable;+ /* Enable log for battery sensor */+ bool BattEnable;+}LogModeData;++/** Sub-class for Calibration Data */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_CalibrationData+{+ /* Raw 56-bit Calibration data value */+ uint64_t raw;+ /* AD1 lower voltage reference - fine - DO NOT MODIFY */+ uint8_t Ad1;+ /* AD1 lower voltage reference - coarse */+ uint8_t Coarse1;+ /* AD2 lower voltage reference - fine - DO NOT MODIFY */+ uint8_t Ad2;+ /* AD2 lower voltage reference - coarse */+ uint8_t Coarse2;+ /* Switches the lower AD voltage reference to ground */+ bool GndSwitch;+ /* POR voltage level for 1.5V system */+ uint8_t Selp12;+ /* Main reference voltage calibration -- DO NOT MODIFY */+ uint8_t Adf;+ /* RTC oscillator calibration */+ uint8_t Df;+ /* Controlled battery supply for external sensor - the battery voltage is connected to the EXC pin */+ bool SwExtEn;+ /* POR voltage level for 3V system */+ uint8_t Selp22;+ /* Voltage level interrupt level for external sensor -- ratiometric */+ uint8_t Irlev;+ /* Main system clock oscillator calibration -- DO NOT MODIFY */+ uint8_t RingCal;+ /* Temperature conversion offset calibration -- DO NOT MODIFY */+ uint8_t OffInt;+ /* Bandgap voltage temperature coefficient calibration -- DO NOT MODIFY */+ uint8_t Reftc;+ /* Excitate for resistive sensors without DC */+ bool ExcRes;+ /* Reserved for Future Use */+ uint8_t RFU;+ /* Specifyes the field user can modify */+ CalibrationParameter type;+}TMR_TagOp_GEN2_IDS_SL900A_CalibrationData;++/** Sub-class to specify Sensor Front End Parameters */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_SfeParameters+{+ /* Raw 16-bit SFE parameters value */+ uint16_t raw;+ /* External sensor 2 range */+ uint8_t Rang;+ /* External sensor 1 range */+ uint8_t Seti;+ /** + * External sensor 1 type+ * 00 -- linear resistive sensor+ * 01 -- high impedance input (voltage follower), bridge+ * 10 -- capacitive sensor with DC+ * 11 -- capacitive or resistive sensor without DC+ */+ uint8_t Ext1;+ /**+ * External sensor 2 type+ * 00 -- linear conductive sensor+ * 01 -- high impedance input (voltage follower), bridge+ */+ uint8_t Ext2;+ /* Use preset range */+ bool AutorangeDisable;+ /**+ * Sensor used in limit check+ * 00 - first selected sensor+ * 01 -- second selected sensor+ * 10 -- third selected sensor+ * 11 -- fourth selected sensor+ */+ uint8_t VerifySensorID;+ /* specifies the type of field user want to modufy */+ SfeParameter type;+}TMR_TagOp_GEN2_IDS_SL900A_SfeParameters;++/** Sub-Class to Combination Calibration Data / SFE Parameters object */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_CalSfe+{+ /* Calibration Data */+ TMR_TagOp_GEN2_IDS_SL900A_CalibrationData Cal;+ /* Sensor Front End Parameters */+ TMR_TagOp_GEN2_IDS_SL900A_SfeParameters Sfe;+}TMR_TagOp_GEN2_IDS_SL900A_CalSfe;++/**Sub-Class to spcify fifo source */+typedef enum FifoSource+{+ /* Data from SPI */+ TMR_GEN2_IDS_SL900A_FIFOSOURCE_SPI = 0x00,+ /* Data from RFID */+ TMR_GEN2_IDS_SL900A_FIFOSOURCE_RFID = 0x01,+}FifoSource;+/** Sub-Class for Get status fifo reply */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_FifoStatus+{+ /* Raw 8-bit response from AccessFifo Status command */+ uint8_t raw;+ /* FIFO Busy bit */+ bool fifoBusy;+ /* Data Ready bit */+ bool dataReady;+ /* No Data bit */+ bool noData;+ /* Data Source bit (SPI, RFID) */+ FifoSource source;+ /* Number of valid bytes in FIFO register */+ uint8_t numValidBytes;+}TMR_TagOp_GEN2_IDS_SL900A_FifoStatus;++/** Sub-Class for specifying SL900A application data */+typedef struct ApplicationData+{+ /* Raw 16-bit protocol value */+ uint16_t raw;+ /* Number of user bank memory words to reserve for non-logging purposes */+ uint16_t NumberOfWords;+ /* Broken word pointer */+ uint8_t BrokenWordPointer;+}ApplicationData;++/** Sub-Class for Gen2 Ids Sl900A coustom tag extension */+typedef struct TMR_TagOP_GEN2_IDS_SL900A+{+ /* SL900A sensor type values */+ Sensor sensortype;+ /* SL900A password access level values */+ PasswordLevel level;+ /* Data log format selection */+ LoggingForm dataLog;+ /* Data log memory-full behavior */+ DelayMode mode;+ /* Logging memory-full behavior */+ StorageRule rule;+}TMR_TagOP_GEN2_IDS_SL900A;++/** Sub- class for Ids Sl900A sensor */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_GetSensorValue+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+}TMR_TagOp_GEN2_IDS_SL900A_GetSensorValue;++/** Sub-class for IDs SL900A get log state */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_GetLogState+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+}TMR_TagOp_GEN2_IDS_SL900A_GetLogState;++/** Sub-Class for IDS SL900A set log mode */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_SetLogMode+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /*Enable log for EXT1 external sensor */+ bool Ext1Enable;+ /* Enable log for EXT2 external sensor */+ bool Ext2Enable;+ /* Enable log for temperature sensor */+ bool TempEnable;+ /* Enable log for battery sensor */+ bool BattEnable;+ /* Time (seconds) between log readings */+ uint16_t LogInterval;+}TMR_TagOp_GEN2_IDS_SL900A_SetLogMode;++/** Sub-Class for Gen2 end log command*/+typedef struct TMR_TagOp_GEN2_IDS_SL900A_EndLog+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+}TMR_TagOp_GEN2_IDS_SL900A_EndLog;++/** Sub-Class for DelayTime */+typedef struct Delay+{+ /* Raw 16-bit protocol value */+ uint16_t raw;+ /* Logging start mode */+ DelayMode Mode;+ /* Logging timer delay value (units of 512 seconds) */+ uint16_t Time;+ /* Trigger log on both timer and external interrupts */+ bool IrqTimerEnable;+}Delay;++/** Sub-Classs for ShelfLife Block 0 */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock0+{+ /* raw value of block0 */+ uint32_t raw;+ /* Tmax */+ uint8_t Tmax;+ /* Tmin */+ uint8_t Tmin;+ /* Tstd */+ uint8_t Tstd;+ /* Ea */+ uint8_t Ea;+}TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock0;++/** Sub-Class for ShelfLife Block 1 */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock1+{+ /* raw value for block 1 */+ uint32_t raw;+ /* SLinit */+ uint16_t SLinit;+ /* Tint */+ uint16_t Tint;+ /* SensorID */+ uint8_t sensorID;+ /* Enable negative shelf life */+ bool enableNegative;+ /* Shelf life algorithem enable */+ bool algorithmEnable;+ /* RFU bytes */+ uint8_t rfu;+}TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock1;++/** Sub-class for GetMeasurmentSetUp command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_MeasurementSetupData+{+ /* Raw 16 byte response from Measurement Setup Data command */+ uint8_t Raw[16];+ /* LogLimits Data */+ LogLimits loglimit;+ /* Log Mode Data */+ LogModeData logModeData;+ /* Delay Data */+ Delay delyTime;+ /* Application Data */+ ApplicationData addData;+ /* Time (seconds) between log readings */+ uint16_t logInterval;+ /* Start Time */+ TMR_TimeStructure startTime;+}TMR_TagOp_GEN2_IDS_SL900A_MeasurementSetupData;++/** Sub-Class for GEN2 initialize command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_Initialize+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Logging memory configuration */+ ApplicationData applicationData;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /* Delay time */+ Delay delayTime;+}TMR_TagOp_GEN2_IDS_SL900A_Initialize;++/** Sub-Class for specifying AccessFifo operation */+typedef enum AccessFifoOperation+{+ /* Read from FIFO */+ TMR_GEN2_IDS_SL900A_ACCESSFIFO_READ = 0x80,+ /* Write to FIFO */+ TMR_GEN2_IDS_SL900A_ACCESSFIFO_WRITE = 0xA0,+ /* Get FIFO status */+ TMR_GEN2_IDS_SL900A_ACCESSFIFO_STATUS = 0xC0,+}AccessFifoOperation;++/** Sub-Class for Gen2 Ids AccessFifo command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_AccessFifo+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /* specify the operation do be done on fifo */+ AccessFifoOperation operation;+}TMR_TagOp_GEN2_IDS_SL900A_AccessFifo;++/** Sub-Class for Gen2 Ids accessFifo write command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_AccessFifoWrite+{+ TMR_TagOp_GEN2_IDS_SL900A_AccessFifo write;+ /* Bytes to write to FIFO */+ TMR_uint8List *payLoad;+}TMR_TagOp_GEN2_IDS_SL900A_AccessFifoWrite;++/** Sub-Class for Gen2 Ids accessFifo read command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_AccessFifoRead+{+ TMR_TagOp_GEN2_IDS_SL900A_AccessFifo read;+ /* Number of bytes to read from FIFO */+ uint8_t length;+}TMR_TagOp_GEN2_IDS_SL900A_AccessFifoRead;++/** Sub-Class for Gen2 Ids accessFifo status command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_AccessFifoStatus+{+ TMR_TagOp_GEN2_IDS_SL900A_AccessFifo status;+}TMR_TagOp_GEN2_IDS_SL900A_AccessFifoStatus;++/** Sub-Class for Gen2 StartLog command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_StartLog+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /* Time to initialize log timestamp counter with */+ uint32_t startTime; +}TMR_TagOp_GEN2_IDS_SL900A_StartLog;++/** Sub-Class for Gen2 IDS GetCalibrationData command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_GetCalibrationData+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+}TMR_TagOp_GEN2_IDS_SL900A_GetCalibrationData;++/** Sub-Class for Gen2 IDS SetCalibrationData command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_SetCalibrationData+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /* Calibration parameters */+ TMR_TagOp_GEN2_IDS_SL900A_CalibrationData cal; +}TMR_TagOp_GEN2_IDS_SL900A_SetCalibrationData;++/** Sub-class for Gen2 Ids SetSfeParameters command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_SetSfeParameters+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /* Sfe Parameters */+ TMR_TagOp_GEN2_IDS_SL900A_SfeParameters *sfe;+}TMR_TagOp_GEN2_IDS_SL900A_SetSfeParameters;++/** Sub-class for Gen2 Ids GetMeasurementSetup command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_GetMeasurementSetup+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+}TMR_TagOp_GEN2_IDS_SL900A_GetMeasurementSetup;++/** Sub-class for Gen2 Ids GetBatteryLevel command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_GetBatteryLevel+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /* enum BatterType, re-check or default */+ BatteryType batteryType;+}TMR_TagOp_GEN2_IDS_SL900A_GetBatteryLevel;++/** Sub-Class for Gen2 Ids SetLogLimits Command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_SetLogLimits+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /* Specify the Log Limits */+ LogLimits limit;+}TMR_TagOp_GEN2_IDS_SL900A_SetLogLimits;++/** Sub-Class for Gen2 Ids SetShelfLife Command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_SetShelfLife+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /* Specify the ShelfLifeBlock0 */+ TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock0 *shelfLifeBlock0;+ /* Specify the ShelfLifeBlock1 */+ TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock1 *shelfLifeBlock1;+}TMR_TagOp_GEN2_IDS_SL900A_SetShelfLife;++/** Sub-Class for Gen2 Ids SetPassword Command */+typedef struct TMR_TagOp_GEN2_IDS_SL900A_SetPassword+{+ TMR_TagOP_GEN2_IDS_SL900A sl900A;+ /* Custom Command Code */+ uint8_t CommandCode;+ /* Gen2 access password */+ uint32_t AccessPassword;+ /* IDS SL900A Password */+ uint32_t Password;+ /* New Passwordlevel */+ PasswordLevel NewPasswordLevel;+ /* New password */+ uint32_t NewPassword;+}TMR_TagOp_GEN2_IDS_SL900A_SetPassword;++/** Sub-class for Gen2 Ids parameters */+typedef struct TMR_TagOP_GEN2_IDS+{+ union+ {+ TMR_TagOp_GEN2_IDS_SL900A_GetSensorValue sensor;+ TMR_TagOp_GEN2_IDS_SL900A_GetLogState getLog;+ TMR_TagOp_GEN2_IDS_SL900A_SetLogMode setLogMode;+ TMR_TagOp_GEN2_IDS_SL900A_EndLog endLog;+ TMR_TagOp_GEN2_IDS_SL900A_Initialize initialize;+ TMR_TagOp_GEN2_IDS_SL900A_AccessFifoRead accessFifoRead;+ TMR_TagOp_GEN2_IDS_SL900A_AccessFifoWrite accessFifoWrite;+ TMR_TagOp_GEN2_IDS_SL900A_AccessFifoStatus accessFifoStatus;+ TMR_TagOp_GEN2_IDS_SL900A_StartLog startLog;+ TMR_TagOp_GEN2_IDS_SL900A_GetCalibrationData calibrationData;+ TMR_TagOp_GEN2_IDS_SL900A_SetCalibrationData setCalibration;+ TMR_TagOp_GEN2_IDS_SL900A_SetSfeParameters setSfeParameters;+ TMR_TagOp_GEN2_IDS_SL900A_GetMeasurementSetup measurementSetup;+ TMR_TagOp_GEN2_IDS_SL900A_GetBatteryLevel batteryLevel;+ TMR_TagOp_GEN2_IDS_SL900A_SetLogLimits setLogLimit;+ TMR_TagOp_GEN2_IDS_SL900A_SetShelfLife setShelfLife;+ TMR_TagOp_GEN2_IDS_SL900A_SetPassword setPassword;+ + }u;+}TMR_TagOP_GEN2_IDS;+/** Sub-class for Gen2 custom tagops */+typedef struct TMR_TagOp_GEN2_Custom+{+ TMR_SR_GEN2_SiliconType chipType;+ union+ {+ TMR_TagOp_GEN2_Alien alien;+ TMR_TagOp_GEN2_NXP nxp;+ TMR_TagOp_GEN2_Impinj impinj;+ TMR_TagOP_GEN2_IDS ids;+ TMR_TagOp_GEN2_Denatran IavDenatran;+ } u;+}TMR_TagOp_GEN2_Custom;++/** Sub-class for ISO180006B tagops */+typedef struct TMR_TagOp_ISO180006B+{+ union+ {+ TMR_TagOp_ISO180006B_Lock lock;+ TMR_TagOp_ISO180006B_WriteData writeData;+ TMR_TagOp_ISO180006B_ReadData readData;+ } u;+}TMR_TagOp_ISO180006B;++/** Sub-class for Gen2 standard tagops */+typedef struct TMR_TagOp_GEN2+{+ union+ {+ TMR_TagOp_GEN2_WriteTag writeTag;+ TMR_TagOp_GEN2_WriteData writeData;+ TMR_TagOp_GEN2_ReadData readData;+ TMR_TagOp_GEN2_SecureReadData secureReadData;+ TMR_TagOp_GEN2_Lock lock;+ TMR_TagOp_GEN2_Kill kill;+ TMR_TagOp_GEN2_BlockWrite blockWrite;+ TMR_TagOp_GEN2_BlockPermaLock blockPermaLock;+ TMR_TagOp_GEN2_BlockErase blockErase;+ TMR_TagOp_GEN2_Custom custom;+ } u;+}TMR_TagOp_GEN2;++/** Tag operation data structure */+struct TMR_TagOp+{+ TMR_TagOpType type;+ union+ {+ TMR_TagOp_GEN2 gen2;+ TMR_TagOp_ISO180006B iso180006b;+ TMR_TagOp_List list;+ } u;+};++TMR_Status TMR_TagOp_init_GEN2_WriteTag(TMR_TagOp *tagop, TMR_TagData* epc);+TMR_Status TMR_TagOp_init_GEN2_ReadData(TMR_TagOp *tagop, TMR_GEN2_Bank bank,+ uint32_t wordAddress, uint8_t len);+TMR_Status TMR_TagOp_init_GEN2_SecureReadData(TMR_TagOp *tagop, TMR_GEN2_Bank bank, uint32_t wordAddress,+ uint8_t len, uint8_t type, uint8_t passwordType);+TMR_Status TMR_TagOp_init_GEN2_SecurePassWord(TMR_TagOp *tagop, uint8_t passwordType, uint32_t gen2PassWord,+ uint8_t addressLength, uint8_t addressOffset, uint16_t flashOffset);+TMR_Status TMR_TagOp_init_GEN2_WriteData(TMR_TagOp *tagop, TMR_GEN2_Bank bank,+ uint32_t wordAddress,+ TMR_uint16List *data);+TMR_Status TMR_TagOp_init_GEN2_Lock(TMR_TagOp *tagop, uint16_t mask,+ uint16_t action, TMR_GEN2_Password accessPassword);+TMR_Status TMR_TagOp_init_GEN2_Kill(TMR_TagOp *tagop,+ TMR_GEN2_Password killPassword);+TMR_Status TMR_TagOp_init_GEN2_BlockWrite(TMR_TagOp *tagop, TMR_GEN2_Bank bank, uint32_t wordPtr, TMR_uint16List *data);+TMR_Status TMR_TagOp_init_GEN2_BlockPermaLock(TMR_TagOp *tagop, uint8_t readLock, TMR_GEN2_Bank bank, uint32_t blockPtr, TMR_uint16List* mask);+TMR_Status TMR_TagOp_init_GEN2_BlockErase(TMR_TagOp *tagop, TMR_GEN2_Bank bank, uint32_t wordPtr, uint8_t wordCount);++TMR_Status TMR_TagOp_init_ISO180006B_ReadData(TMR_TagOp *tagop, uint8_t byteAddress, uint8_t len);+TMR_Status TMR_TagOp_init_ISO180006B_WriteData(TMR_TagOp *tagop, uint8_t byteAddress, TMR_uint8List *data);+TMR_Status TMR_TagOp_init_ISO180006B_Lock(TMR_TagOp *tagop, uint8_t address);+TMR_Status TMR_TagOp_init_GEN2_Alien_Higgs2_PartialLoadImage(TMR_TagOp *tagop, TMR_GEN2_Password killPassword,+ TMR_GEN2_Password accessPassword, TMR_TagData *epc);+TMR_Status TMR_TagOp_init_GEN2_Alien_Higgs2_FullLoadImage(TMR_TagOp *tagop, TMR_GEN2_Password killPassword,+ TMR_GEN2_Password accessPassword, uint16_t lockBits, + uint16_t pcWord, TMR_TagData *epc);+TMR_Status TMR_TagOp_init_GEN2_Alien_Higgs3_FastLoadImage(TMR_TagOp *tagop, TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, + uint16_t pcWord, TMR_TagData *epc);+TMR_Status TMR_TagOp_init_GEN2_Alien_Higgs3_LoadImage(TMR_TagOp *tagop, TMR_GEN2_Password currentAccessPassword,+ TMR_GEN2_Password accessPassword, TMR_GEN2_Password killPassword, + uint16_t pcWord, TMR_uint8List *epcAndUserData);+TMR_Status TMR_TagOp_init_GEN2_Alien_Higgs3_BlockReadLock(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, uint8_t lockBits);++TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_SetReadProtect(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword);+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_SetReadProtect(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword);++TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_ResetReadProtect(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword);+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_ResetReadProtect(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword);++TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_ChangeEAS(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, bool resetEAS);+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_ChangeEAS(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, bool resetEAS);++TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_EASAlarm(TMR_TagOp *tagop, TMR_GEN2_DivideRatio dr, TMR_GEN2_TagEncoding m, TMR_GEN2_TrExt trExt);+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_EASAlarm(TMR_TagOp *tagop, TMR_GEN2_DivideRatio dr, TMR_GEN2_TagEncoding m, TMR_GEN2_TrExt trExt);++TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_Calibrate(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword);+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_Calibrate(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword);++TMR_Status TMR_TagOp_init_GEN2_NXP_G2I_ChangeConfig(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, TMR_NXP_ConfigWord configWord);+TMR_Status TMR_TagOp_init_GEN2_NXP_G2X_ChangeConfig(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, TMR_NXP_ConfigWord configWord);+TMR_Status TMR_TagOp_init_GEN2_NXP_AES_Untraceable(TMR_TagOp *tagop,TMR_GEN2_UNTRACEABLE_Epc epc, int epclen , TMR_GEN2_UNTRACEABLE_Tid tid,+ TMR_GEN2_UNTRACEABLE_UserMemory user, TMR_GEN2_UNTRACEABLE_Range range, TMR_TagOp_GEN2_NXP_Untraceable *auth);+TMR_Status TMR_TagOp_init_GEN2_NXP_AES_Authenticate(TMR_TagOp *tagop, TMR_TagOp_GEN2_NXP_Authenticate *authenticate);+TMR_Status TMR_TagOp_init_GEN2_NXP_AES_ReadBuffer(TMR_TagOp *tagop, uint16_t wordPointer, uint16_t bitCount, TMR_TagOp_GEN2_NXP_Readbuffer *readbuffer);+TMR_Status TMR_TagOp_init_GEN2_NXP_AES_Tam1authentication(TMR_TagOp_GEN2_NXP_Tam1Authentication *auth, TMR_NXP_KeyId keyid, TMR_uint8List *key, + TMR_uint8List *ichallenge ,bool sendRawData );+TMR_Status TMR_TagOp_init_GEN2_NXP_AES_Tam2authentication(TMR_TagOp_GEN2_NXP_Tam2Authentication *auth, TMR_NXP_KeyId keyid, TMR_uint8List *key, + TMR_uint8List *ichallenge, TMR_NXP_Profile profile, uint16_t Offset,uint8_t blockCount,bool sendRawData);++TMR_Status TMR_TagOp_init_GEN2_Impinj_Monza4_QTReadWrite(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ TMR_Monza4_ControlByte controlByte, TMR_Monza4_Payload payload);++TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_Activate_Secure_Mode(TMR_TagOp *tagop, uint8_t rfuByte);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_Authenticate_OBU(TMR_TagOp *tagop, uint8_t rfuByte);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_Activate_Siniav_Mode(TMR_TagOp *tagop, uint8_t rfuByte, TMR_uint8List *data);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_OBU_Auth_ID(TMR_TagOp *tagop, uint8_t rfuByte);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_OBU_Auth_Full_Pass1(TMR_TagOp *tagop, uint8_t rfuByte);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_OBU_Auth_Full_Pass2(TMR_TagOp *tagop, uint8_t rfuByte);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_OBU_ReadFromMemMap(TMR_TagOp *tagop, uint8_t rfuByte, uint16_t wordAddress);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_OBU_WriteToMemMap(TMR_TagOp *tagop, uint8_t rfuByte, uint16_t wordAddress, uint16_t word, uint8_t* tagID, uint8_t* data);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_GetTokenId(TMR_TagOp *tagop);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_OBU_Auth_Full_Pass(TMR_TagOp *tagop, uint8_t payload);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_ReadSec(TMR_TagOp *tagop, uint8_t payload, uint16_t wordAddress);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_WriteSec(TMR_TagOp *tagop, uint8_t payload, uint8_t* data, uint8_t* credentials);+TMR_Status TMR_TagOp_init_GEN2_Denatran_IAV_G0_PA_OBU_Auth(TMR_TagOp *tagop, uint8_t rfuByte);++TMR_Status +TMR_init_GEN2_NXP_G2I_ConfigWord(TMR_NXP_ConfigWord *configWord);++TMR_Status+TMR_init_GEN2_Impinj_Monza4_ControlByte(TMR_Monza4_ControlByte *controlByte);++TMR_Status+TMR_init_GEN2_Impinj_Monza4_Payload(TMR_Monza4_Payload *payload);++TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetSensorValue(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, Sensor type);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetCalibrationData(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel leveli, uint32_t password);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetLogLimit(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, + PasswordLevel level, uint32_t password, LogLimits *logLimits);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetCalibrationData(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level, + uint32_t password, TMR_TagOp_GEN2_IDS_SL900A_CalibrationData *data);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetSfeParameters(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level, + uint32_t password, TMR_TagOp_GEN2_IDS_SL900A_SfeParameters *data);+TMR_Status+TMR_init_GEN2_IDS_SL900A_SensorReading(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_SensorReading *sensor);++TMR_Status+TMR_init_GEN2_IDS_SL900A_BatteryLevelReading(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_BatteryLevelReading *battery);++TMR_Status+TMR_init_GEN2_IDS_SL900A_MeasurementSetupData(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_MeasurementSetupData *measurment);++TMR_Status+TMR_init_GEN2_IDS_SL900A_CalSfe(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_CalSfe *calSfe);++TMR_Status+TMR_init_GEN2_IDS_SL900A_CalibrationData(uint8_t byte[7], TMR_TagOp_GEN2_IDS_SL900A_CalibrationData *cal);++TMR_Status+TMR_update_GEN2_IDS_SL900A_CalibrationData(TMR_TagOp_GEN2_IDS_SL900A_CalibrationData *cal);++TMR_Status+TMR_update_GEN2_IDS_SL900A_SfeParameters(TMR_TagOp_GEN2_IDS_SL900A_SfeParameters *sfe);++TMR_Status+TMR_init_GEN2_IDS_SL900A_SfeParameters(uint8_t byte[2], TMR_TagOp_GEN2_IDS_SL900A_SfeParameters *sfe);++TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetLogState(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password);++TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetLogMode(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password, LoggingForm form, StorageRule rule, bool Ext1Enable,+ bool Ext2Enable, bool TempEnable, bool BattEnable, uint16_t LogInterval);++TMR_Status+TMR_init_GEN2_IDS_SL900A_LogState(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_LogState *log);++TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_Initialize(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password, uint8_t delayMode, uint16_t delayTime, bool timeEnable,+ uint16_t numberOfWords, uint8_t BrokenWordPointer);++TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_EndLog(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_AccessFifoStatus(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level ,uint32_t password);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_AccessFifoRead(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password, uint8_t readLength);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_AccessFifoWrite(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, TMR_uint8List *payLoad);+TMR_Status+TMR_init_GEN2_IDS_SL900A_FifoStatus(TMR_uint8List *reply, TMR_TagOp_GEN2_IDS_SL900A_FifoStatus *status);++TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_StartLog(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, TMR_TimeStructure *timestamp);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetMeasurementSetup(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password);++TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetPassword(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password, PasswordLevel newPasswordLevel, uint32_t newPassword);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_GetBatteryLevel(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword,+ PasswordLevel level, uint32_t password, BatteryType type);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_ShelfLifeBlock0(TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock0 *block0,+ uint8_t tmax, uint8_t Tmin, uint8_t tstd, uint8_t Ea);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_ShelfLifeBlock1(TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock1 *block1,+ uint16_t slinit, uint16_t tint, uint8_t sensorid,+ bool negative, bool algorithm);+TMR_Status+TMR_TagOp_init_GEN2_IDS_SL900A_SetShelfLife(TMR_TagOp *tagop, TMR_GEN2_Password accessPassword, PasswordLevel level,+ uint32_t password, TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock0 *block0,+ TMR_TagOp_GEN2_IDS_SL900A_ShelfLifeBlock1 *block1);+TMR_Status+TMR_GEN2_init_BapParams(TMR_GEN2_Bap *bapVal, int32_t powerUpDelayUs, int32_t freqHopOfftimeUs);+#ifdef __cplusplus+}+#endif++#endif /* _TMR_TAGOP_H */
+ cbits/api/tmr_types.h view
@@ -0,0 +1,121 @@+/* ex: set tabstop=2 shiftwidth=2 expandtab cindent: */+#ifndef _TMR_TYPES_H+#define _TMR_TYPES_H+/**+ * @file tmr_types.h+ * @brief Mercury API - General data type definitions+ * @author Nathan Williams+ * @date 10/20/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.+ */++#ifdef WINCE+#include <stdint_win32.h>+#else+#include <stdint.h>+#endif+#include <stdbool.h>++#ifdef __cplusplus+extern "C" {+#endif++/** Internal string representation with known storage size */+typedef struct TMR_String+{+ /** The null-terminated string value */+ char *value;+ /** The allocated number of bytes pointed to */+ uint16_t max;+} TMR_String;++/** List of uint8_t values */+typedef struct TMR_uint8List+{+ /** The array of values */+ uint8_t *list;+ /** The number of entries there is space for in the array */+ uint16_t max;+ /** The number of entries in the list - may be larger than max, indicating truncated data. */+ uint16_t len;+} TMR_uint8List;++/** List of uint16_t values */+typedef struct TMR_uint16List+{+ /** The array of values */+ uint16_t *list;+ /** The number of entries there is space for in the array */+ uint16_t max;+ /** The number of entries in the list - may be larger than max, indicating truncated data. */+ uint16_t len;+} TMR_uint16List;++/** List of uint32_t values */+typedef struct TMR_uint32List+{+ /** The array of values */+ uint32_t *list;+ /** The number of entries there is space for in the array */+ uint16_t max;+ /** The number of entries in the list - may be larger than max, indicating truncated data. */+ uint16_t len;+} TMR_uint32List;++/** List of int8_t values */+typedef struct TMR_int8List+{+ /** The array of values */+ int8_t *list;+ /** The number of entries there is space for the array */+ int8_t max;+ /** The number of entries in the list - may be larger than max, indicating truncated data. */+ int8_t len;+}TMR_int8List;++/**+ * Function callback used to obtain firmware data during a firmware+ * load operation. TMR_firmwareLoad will call this repeatedly to+ * obtain data to send to the reader. A buffer of a specified size+ * will be passed in; the callback is free to place less than that+ * amount of data in the buffer, provided that size is modified+ * accordingly. When the end of the firmware image has been reached,+ * the callback should return false. ++ * @see TMR_memoryProvider and TMR_fileProvider for pre-existing+ * callbacks to load firmware from system memory or from a file.+ * + * @param cookie Arbitrary data passed to the callback.+ * @param[in] size Pointer to amount of space in the buffer.+ * @param[out] Points to number of bytes stored in the buffer.+ * @param[out] data Buffer of bytes of firmware image.+ * @return true if there is more data to load+ */+typedef bool (*TMR_FirmwareDataProvider)(void *cookie, uint16_t *size, uint8_t *data);++#ifdef __cplusplus+}+#endif++#endif /* _TMR_TYPES_H */
+ cbits/api/tmr_utils.c view
@@ -0,0 +1,233 @@+/**+ * @file tmr_utils.c+ * @brief Mercury API - utility functions+ * @author Nathan Williams+ * @date 12/10/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 <stddef.h>+#include <string.h>++#include "osdep.h"+#include "tmr_types.h"+#include "tmr_utils.h"++#ifndef TMR_USE_HOST_C_LIBRARY++void *+tm_memcpy(void *dest, const void *src, size_t n)+{+ const uint8_t *u8src;+ uint8_t *u8dest;++ u8dest = dest;+ u8src = src;++ while (0 != n)+ {+ *u8dest = *u8src;+ u8dest++;+ u8src++;+ n--;+ }++ return dest;+}++char *+tm_strcpy(char *dest, const char *src)+{+ char *ptr, val;++ ptr = dest;++ do+ {+ val = *src;+ *ptr = val;+ ptr++;+ src++;+ } + while ('\0' != val);++ return dest;+}++char *+tm_strchr(const char *s, int c)+{+ const char *ptr;++ for (ptr = s; *ptr != '\0'; ptr++)+ {+ if (*ptr == c)+ {+ return (char *)ptr;+ }+ }++ return NULL;+}++#endif /* TMR_USE_HOST_C_LIBRARY */++int+tm_strcasecmp(const char *s1, const char *s2)+{+ char v1, v2;+ int diff;++ do+ {+ v1 = *s1;+ if (v1 >= 'a' && v1 <= 'z')+ v1 -= 'a' - 'A';+ v2 = *s2;+ if (v2 >= 'a' && v2 <= 'z')+ v2 -= 'a' - 'A';+ s1++;+ s2++;+ }+ while (v1 == v2 && '\0' != v1 && '\0' != v2);++ diff = v1 - v2;+ if (diff < 0)+ return -1;+ else if (diff > 0)+ return 1;+ else+ return 0;+}++/* Get a high/low timestamp pair, being careful not to get one value+ * before a wraparound and the other one after, which would lead to+ * 50-day time jumps forward or backwards. (high<<32)|low is in milliseconds.+ */+void+tm_gettime_consistent(uint32_t *high, uint32_t *low)+{+ uint32_t tmpHigh;++ *high = tmr_gettime_high();+ *low = tmr_gettime_low();+ tmpHigh = tmr_gettime_high();++ if (tmpHigh != *high)+ {+ *high = tmpHigh;+ *low = tmr_gettime_low();+ }+}++/* Find the time difference from start to end, allowing for end having+ * wrapped around UINT32_MAX and back to zero.+ */+uint32_t+tm_time_subtract(uint32_t end, uint32_t start)+{+ if (end >= start)+ return end - start;+ else+ return (UINT32_MAX - start) + end;+}++/** Minimum number of bytes required to hold a given number of bits.+ *+ * @param bitCount number of bits to hold+ * @return Minimum length of bytes that can contain that many bits+ */+int tm_u8s_per_bits(int bitCount) +{+ return ((0<bitCount) ?((((bitCount)-1)>>3)+1) :0);+}++void+TMR_stringCopy(TMR_String *dest, const char *src, int len)+{+ if (dest->max - 1 < len)+ {+ len = dest->max - 1;+ }+ if (dest->max > 0)+ {+ memcpy(dest->value, src, len);+ dest->value[len] = '\0';+ }+}++uint64_t+TMR_makeBitMask(int offset, int length)+{+ uint64_t mask;++ mask = 0;+ mask = ~mask;+ mask <<= length;+ mask = ~mask;++ mask <<= offset;++ return mask;+}++uint32_t+TMR_byteArrayToInt(uint8_t data[], int offset)+{+ uint32_t value = 0;+ int count;++ for( count = 0; count < 4; count++)+ {+ value <<= 8;+ value ^= (data[count + offset] & 0x000000FF);+ }+ return value;+}++uint16_t+TMR_byteArrayToShort(uint8_t data[], int offset)+{+ uint16_t value = 0;+ int hi, lo;+ hi = (uint16_t) (data[offset++]) << 8;+ lo = (uint16_t) (data[offset++]);+ value = (uint16_t)(hi | lo);++ return value;+}++uint64_t+TMR_byteArrayToLong(uint8_t data[], int offset)+{+ uint64_t value = 0;+ int i;+ for (i = 0; i < 8; i++)+ {+ value <<= 8;+ value ^= (uint64_t) (data[i + offset] & 0xff);+ }+ return value;+}+
+ cbits/api/tmr_utils.h view
@@ -0,0 +1,156 @@+#ifndef _TMR_UTILS_H+#define _TMR_UTILS_H++/**+ * @file tmr_utils.h+ * @brief Mercury API - generic utilities+ * @author Nathan Williams+ * @date 12/1/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.+ */++#ifdef WINCE+#include <stdint_win32.h>+#else+#include <stdint.h>+#endif+#include <stddef.h>++#ifdef __cplusplus+extern "C" {+#endif++/* Macros for working with values embedded in uint8_t arrays (msg) */+/* Absolute-value get */+#define GETU8AT(msg, i) ( \+ ((msg)[(i)]) )++#define GETU16AT(msg, i) ( \+ ((uint16_t)((msg)[(i) ]) << 8) | \+ ((msg)[(i)+1] << 0) )++#define GETS16AT(msg, i) ( \+ ((int16_t)((msg)[(i) ]) << 8) | \+ ((int16_t)((msg)[(i)+1]) << 0) )++#define GETU24AT(msg, i) ( \+ ((uint32_t)((msg)[(i) ]) << 16) | \+ ((uint32_t)((msg)[(i)+1]) << 8) | \+ ((msg)[(i)+2] << 0) )++#define GETU32AT(msg, i) ( \+ ((uint32_t)((msg)[(i) ]) << 24) | \+ ((uint32_t)((msg)[(i)+1]) << 16) | \+ ((uint32_t)((msg)[(i)+2]) << 8) | \+ ((msg)[(i)+3] << 0) )++/* Get and update index to next position */+#define GETU8(msg, i) ((msg)[(i)++])+#define GETU16(msg, i) (i+=2, GETU16AT((msg), i-2))+#define GETU24(msg, i) (i+=3, GETU24AT((msg), i-3))+#define GETU32(msg, i) (i+=4, GETU32AT((msg), i-4))++/* Set and update index to next position */+#define SETU8(msg, i, u8val) do { \+ (msg)[(i)++] = (u8val) & 0xff; \+} while (0)++#define SETU16(msg, i, u16val) do { \+ uint16_t _tmp = (u16val); \+ (msg)[(i)++] =(uint8_t) (_tmp >> 8) & 0xff; \+ (msg)[(i)++] =(uint8_t)(_tmp >> 0) & 0xff; \+} while (0)++#define SETS16(msg, i, s16val) do { \+ int16_t _tmp = (s16val); \+ (msg)[(i)++] =(int8_t) (_tmp >> 8) & 0xff; \+ (msg)[(i)++] =(int8_t)(_tmp >> 0) & 0xff; \+} while (0)++#define SETU32(msg, i, u32val) do { \+ uint32_t _tmp = (u32val); \+ (msg)[(i)++] = (uint8_t)(_tmp >> 24) & 0xff; \+ (msg)[(i)++] = (uint8_t)(_tmp >> 16) & 0xff; \+ (msg)[(i)++] = (uint8_t)(_tmp >> 8) & 0xff; \+ (msg)[(i)++] = (uint8_t)(_tmp >> 0) & 0xff; \+} while (0)++#define SETS32(msg, i, s32val) do { \+ int32_t _tmp = (s32val); \+ (msg)[(i)++] = (int8_t)(_tmp >> 24) & 0xff; \+ (msg)[(i)++] = (int8_t)(_tmp >> 16) & 0xff; \+ (msg)[(i)++] = (int8_t)(_tmp >> 8) & 0xff; \+ (msg)[(i)++] = (int8_t)(_tmp >> 0) & 0xff; \+} while (0)++/* Append a value to our list structures, which have both+ * a allocated-space value (max) and a length-of-underlying-list+ * value (len). Len can exceed max, which indicates to the caller+ * that there was not enough space in the passed-in list structure+ * to store the entire list.+ */+#define LISTAPPEND(l, value) do { \+ (l)->len++; \+ if ((l)->len <= (l)->max) \+ (l)->list[(l)->len - 1] = (value); \+} while (0)+++/* Macros for working with large bitmasks made up of arrays of uint32_t */+#define BITGET(array, number) (((array)[(number)/32] >> ((number)&31)) & 1)+#define BITSET(array, number) ((array)[(number)/32] |= ((uint32_t)1 << ((number)&31)))+#define BITCLR(array, number) ((array)[(number)/32] &= ~((uint32_t)1 << ((number)&31)))++#define numberof(x) (sizeof((x))/sizeof((x)[0]))++#ifndef TMR_USE_HOST_C_LIBRARY+void *tm_memcpy(void *dest, const void *src, size_t n);+char *tm_strcpy(char *dest, const char *src);+char *tm_strchr(const char *s, int c);++#undef memcpy+#undef strcpy+#undef strchr++#define memcpy tm_memcpy+#define strcpy tm_strcpy+#define strchr tm_strchr+#endif++int tm_strcasecmp(const char *s1, const char *s2);+#define strcasecmp tm_strcasecmp++void tm_gettime_consistent(uint32_t *high, uint32_t *low);+uint32_t tm_time_subtract(uint32_t end, uint32_t start);+int tm_u8s_per_bits(int bitCount);+void TMR_stringCopy(TMR_String *dest, const char *src, int len);+uint64_t TMR_makeBitMask(int offset, int lenght);+uint32_t TMR_byteArrayToInt(uint8_t data[], int offset);+uint16_t TMR_byteArrayToShort(uint8_t data[], int offset);+uint64_t TMR_byteArrayToLong(uint8_t data[], int offset);+#ifdef __cplusplus+}+#endif++#endif /* _TMR_UTILS_H */
+ cbits/glue/glue.c view
@@ -0,0 +1,340 @@+#define _GNU_SOURCE++#include <locale.h>+#include <stdbool.h>+#include <stdlib.h>+#include <string.h>+#include <time.h>+#ifndef _WIN32+#include <xlocale.h>+#endif+#include <HsFFI.h>++#include "glue.h"+#include "serial_reader_imp.h"++static TMR_Status free_transport_listener (TMR_Reader *reader,+ TransportListenerEtc *listener,+ TransportListenerEtc **prev)+{+ TMR_Status stat;++ stat = TMR_removeTransportListener (reader, &listener->block);+ free (listener->key);+ hs_free_fun_ptr (listener->funPtr);+ *prev = listener->next;+ free (listener);++ return stat;+}++static void free_all_transport_listeners (ReaderEtc *reader)+{+ while (reader->transportListeners) {+ free_transport_listener (&reader->reader,+ reader->transportListeners,+ &reader->transportListeners);+ }+}++/* These wrapper functions have at least two purposes:+ * 1) Check whether the reader has been destroyed+ * 2) Many of the reader methods are actually macros, so wrapping+ * them in a real function makes it possible to call them+ * from Haskell.+ *+ * Some of the wrapper functions also perform additional actions to+ * make calling from Haskell easier.+ */++TMR_Status c_TMR_create (ReaderEtc *reader, const char *deviceUri)+{+ reader->transportListeners = NULL;+ reader->readPlan = NULL;+ reader->destroyed = false;+ strcpy (reader->uri, deviceUri);+ return TMR_create (&reader->reader, deviceUri);+}++TMR_Status c_TMR_connect (ReaderEtc *reader)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else+ return TMR_connect (&reader->reader);+}++TMR_Status c_TMR_destroy (ReaderEtc *reader)+{+ if (reader->destroyed) {+ return ERROR_ALREADY_DESTROYED;+ } else {+ TMR_Status status;++ free_all_transport_listeners (reader);+ status = TMR_destroy (&reader->reader);+ free (reader->readPlan);+ reader->destroyed = true;+ return status;+ }+}++TMR_Status c_TMR_read (ReaderEtc *reader, uint32_t timeoutMs, int32_t *tagCount)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else+ return TMR_read (&reader->reader, timeoutMs, tagCount);+}++TMR_Status c_TMR_hasMoreTags (ReaderEtc *reader)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else+ return TMR_hasMoreTags (&reader->reader);+}++TMR_Status c_TMR_getNextTag (ReaderEtc *reader, TMR_TagReadData *tagData)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else+ return TMR_getNextTag (&reader->reader, tagData);+}++TMR_Status c_TMR_executeTagOp (ReaderEtc *reader,+ TMR_TagOp *tagop,+ TMR_TagFilter *filter,+ TMR_uint8List *data)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else+ return TMR_executeTagOp (&reader->reader, tagop, filter, data);+}++TMR_Status c_TMR_gpoSet (ReaderEtc *reader,+ uint8_t count,+ const TMR_GpioPin state[])+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else+ return TMR_gpoSet (&reader->reader, count, state);+}++TMR_Status c_TMR_gpiGet (ReaderEtc *reader,+ uint8_t *count,+ TMR_GpioPin state[])+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else+ return TMR_gpiGet (&reader->reader, count, state);+}++TMR_Status c_TMR_firmwareLoad (ReaderEtc *reader,+ uint8_t *firmwareStart,+ uint32_t firmwareSize)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else {+ TMR_memoryCookie cookie;+ cookie.firmwareStart = firmwareStart;+ cookie.firmwareSize = firmwareSize;+ return TMR_firmwareLoad (&reader->reader, &cookie, TMR_memoryProvider);+ }+}++TMR_Status c_TMR_paramSet(ReaderEtc *reader,+ TMR_Param key,+ const void *value)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else {+ TMR_Status status;++ status = TMR_paramSet (&reader->reader, key, value);+ if (key == TMR_PARAM_READ_PLAN) {+ if (status == TMR_SUCCESS) {+ /* TMR_paramSet appears to only do a shallow copy of the+ * read plan, meaning that the internal pointers need to+ * stay pointing at valid memory. We handle this by+ * keeping ownership of the ReadPlanEtc, which includes+ * space for the lists to point at.+ *+ * When the read plan is set, we need to free the old+ * ReadPlanEtc, and keep a pointer to the new one.+ */+ free (reader->readPlan);+ reader->readPlan = (ReadPlanEtc *) value;+ }+ }++ return status;+ }+}++TMR_Status c_TMR_paramGet(ReaderEtc *reader, TMR_Param key, void *value)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else {+ /* TMR_PARAM_READ_PLAN appears to be write-only, so fulfill the+ * read from our cached copy. */+ if (key == TMR_PARAM_READ_PLAN) {+ TMR_ReadPlan *rp;++ rp = (TMR_ReadPlan *) value;+ if (reader->readPlan) {+ /* Shallow copy the ReadPlan, although the pointers will+ * still point at parts of the cached ReadPlanEtc. */+ *rp = reader->readPlan->plan;+ } else {+ /* No cached read plan, which means it's initialized to+ * the default. */+ c_default_read_plan (rp);+ }++ return TMR_SUCCESS;+ } else {+ return TMR_paramGet (&reader->reader, key, value);+ }+ }+}++TMR_Status c_TMR_reboot (ReaderEtc *reader)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else+ return TMR_reboot (&reader->reader);+}++void c_default_read_plan (TMR_ReadPlan *rp)+{+ /* This should match the call to TMR_RP_init_simple() in+ * TMR_reader_init_internal() in tm_reader.c. */+ TMR_RP_init_simple (rp, 0, NULL, TMR_TAG_PROTOCOL_GEN2, 1);+}++TMR_Status c_TMR_paramList (ReaderEtc *reader, TMR_Param *keys, uint32_t *len)+{+ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;+ else+ return TMR_paramList (&reader->reader, keys, len);+}++/* takes ownership of func and unique */+TMR_Status c_TMR_addTransportListener (ReaderEtc *reader,+ TMR_TransportListener func,+ char *unique)+{+ TransportListenerEtc *listener;++ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;++ listener = (TransportListenerEtc *) malloc (sizeof (TransportListenerEtc));+ if (! listener)+ return TMR_ERROR_OUT_OF_MEMORY;++ listener->block.listener = func;+ listener->block.cookie = NULL;+ listener->key = unique;+ listener->funPtr = (HsFunPtr) func;+ listener->next = reader->transportListeners;+ reader->transportListeners = listener;++ return TMR_addTransportListener (&reader->reader, &listener->block);+}++TMR_Status c_TMR_removeTransportListener (ReaderEtc *reader,+ const char *unique)+{+ TransportListenerEtc *listener, **prev;++ if (reader->destroyed)+ return ERROR_ALREADY_DESTROYED;++ prev = &reader->transportListeners;+ for (listener = reader->transportListeners;+ listener != NULL;+ prev = &listener->next, listener = listener->next) {+ if (0 == strcmp (unique, listener->key))+ return free_transport_listener (&reader->reader, listener, prev);+ }++ return TMR_ERROR_INVALID;+}++const char *c_TMR_strerr (ReaderEtc *reader, TMR_Status status)+{+ TMR_Reader *tmr;++ if (reader && !reader->destroyed)+ tmr = &reader->reader;+ else+ tmr = NULL;++ switch (status) {+ case ERROR_ALREADY_DESTROYED:+ return "Attempt to use reader after it was destroyed";+ default:+ return TMR_strerr (tmr, status);+ }+}++void *c_new_c_locale (void)+{+ /* We need to call tzset once before calling localtime_r, and this seems+ * like a good place to do it. */+ tzset();+#ifdef _WIN32+ /* Unused on Windows, so value doesn't matter, but can't be NULL. */+ return (void*) 1;+#else+ /* Allocate a new locale. We only do this once, so it's okay+ * that it leaks. */+ return (void *) newlocale(LC_ALL_MASK, "C", (locale_t) 0);+#endif+}++int c_format_time (char *buf,+ size_t len,+ const char *fmt,+ time_t seconds,+ bool local,+ void *locale)+{+ time_t t;+ struct tm stm, *stmp;++ t = seconds;+#ifdef _WIN32+ if (local)+ stmp = localtime (&t);+ else+ stmp = gmtime (&t);+#else+ if (local)+ stmp = localtime_r (&t, &stm);+ else+ stmp = gmtime_r (&t, &stm);+#endif++ if (! stmp)+ return -1;+#ifdef _WIN32+ if (0 == strftime (buf, len, fmt, stmp))+ return -1;+#else+ if (0 == strftime_l (buf, len, fmt, stmp, (locale_t) locale))+ return -1;+#endif+ return 0;+}
+ cbits/glue/glue.h view
@@ -0,0 +1,141 @@+#ifndef GLUE_H+#define GLUE_H++#include <stdbool.h>+#include <time.h>+#include <HsFFI.h>++#include "tm_reader.h"++/** An error which originates from the Haskell binding, not the underlying C library. */+#define ERROR_TYPE_BINDING 127L++#define ERROR_BINDING(x) TMR_STATUS_MAKE(ERROR_TYPE_BINDING, (x))++/** Attempt to use reader after it was destroyed. */+#define ERROR_ALREADY_DESTROYED ERROR_BINDING(1)++typedef struct TransportListenerEtc TransportListenerEtc;+typedef struct ReaderEtc ReaderEtc;+typedef struct List16 List16;+typedef struct List8 List8;+typedef struct ReadPlanEtc ReadPlanEtc;+typedef struct TagOpEtc TagOpEtc;+typedef struct TagFilterEtc TagFilterEtc;++struct ReaderEtc {+ TMR_Reader reader;+ TransportListenerEtc *transportListeners;+ ReadPlanEtc *readPlan;+ bool destroyed;+ char uri[1]; // must be last+};++struct TransportListenerEtc {+ TMR_TransportListenerBlock block;+ char *key;+ HsFunPtr funPtr;+ struct TransportListenerEtc *next;+};++/* Has the same storage layout as the various TMR_*List structs+ * which use a 16-bit length, such as:+ * TMR_uint8List+ * TMR_uint16List+ * TMR_uint32List+ * TMR_StatsPerAntennaValuesList+ * Can also be used for TMR_String, if you ignore len.+ */+struct List16 {+ /** The array of values */+ void *list;+ /** The number of entries there is space for in the array */+ uint16_t max;+ /** The number of entries in the list - may be larger than max, indicating truncated data. */+ uint16_t len;+};++/* Has the same storage layout as the various TMR_*List structs+ * which use an 8-bit length, such as:+ * TMR_int8List+ * TMR_RegionList+ * TMR_TagProtocolList+ */+struct List8 {+ /** The array of values */+ void *list;+ /** The number of entries there is space for in the array */+ uint8_t max;+ /** The number of entries in the list - may be larger than max, indicating truncated data. */+ uint8_t len;+};++#define GLUE_MAX_MASK TMR_MAX_EMBEDDED_DATA_LENGTH++struct TagFilterEtc {+ TMR_TagFilter filter;+ uint8_t mask[GLUE_MAX_MASK];+};++#define GLUE_MAX_DATA16 TMR_MAX_EMBEDDED_DATA_LENGTH++struct TagOpEtc {+ TMR_TagOp tagop;+ union {+ TMR_TagData epc;+ uint16_t data16[GLUE_MAX_DATA16];+ } u;+};++#define GLUE_MAX_ANTENNAS TMR_SR_MAX_ANTENNA_PORTS+#define GLUE_MAX_GPIPORTS 16++struct ReadPlanEtc {+ TMR_ReadPlan plan;+ uint8_t antennas[GLUE_MAX_ANTENNAS];+ uint8_t gpiPorts[GLUE_MAX_GPIPORTS];+ TagFilterEtc filter;+ TagOpEtc tagop;+};++TMR_Status c_TMR_create (ReaderEtc *reader, const char *deviceUri);+TMR_Status c_TMR_connect (ReaderEtc *reader);+TMR_Status c_TMR_destroy (ReaderEtc *reader);+TMR_Status c_TMR_read (ReaderEtc *reader, uint32_t timeoutMs, int32_t *tagCount);+TMR_Status c_TMR_hasMoreTags (ReaderEtc *reader);+TMR_Status c_TMR_getNextTag (ReaderEtc *reader, TMR_TagReadData *tagData);+TMR_Status c_TMR_executeTagOp (ReaderEtc *reader,+ TMR_TagOp *tagop,+ TMR_TagFilter *filter,+ TMR_uint8List *data);+TMR_Status c_TMR_gpoSet (ReaderEtc *reader,+ uint8_t count,+ const TMR_GpioPin state[]);+TMR_Status c_TMR_gpiGet (ReaderEtc *reader,+ uint8_t *count,+ TMR_GpioPin state[]);+TMR_Status c_TMR_firmwareLoad (ReaderEtc *reader,+ uint8_t *firmwareStart,+ uint32_t firmwareSize);+TMR_Status c_TMR_paramSet (ReaderEtc *reader,+ TMR_Param key,+ const void *value);+TMR_Status c_TMR_paramGet (ReaderEtc *reader, TMR_Param key, void *value);+TMR_Status c_TMR_reboot (ReaderEtc *reader);+void c_default_read_plan (TMR_ReadPlan *rp);+TMR_Status c_TMR_paramList (ReaderEtc *reader, TMR_Param *keys, uint32_t *len);+TMR_Status c_TMR_addTransportListener (ReaderEtc *reader,+ TMR_TransportListener func,+ char *unique);+TMR_Status c_TMR_removeTransportListener (ReaderEtc *reader,+ const char *unique);+const char *c_TMR_strerr (ReaderEtc *reader, TMR_Status status);+void *c_new_c_locale (void);+int c_format_time (char *buf,+ size_t len,+ const char *fmt,+ time_t seconds,+ bool local,+ void *locale);++#endif /* GLUE_H */
+ examples/ExampleUtil.hs view
@@ -0,0 +1,122 @@+{-# LANGUAGE OverloadedStrings #-}++module ExampleUtil+ ( createAndConnect+ , createConnectAndParams+ , optUri+ , optRegion+ , optPower+ , optListen+ ) where++import Control.Exception ( throw, try )+import Control.Monad ( when, void, forM_ )+import Data.Int ( Int32 )+import Data.Monoid ( (<>) )+import qualified Data.Text as T ( replicate, pack, length )+import qualified Data.Text.IO as T ( putStrLn )+import Options.Applicative+ ( Parser,+ value,+ switch,+ strOption,+ short,+ option,+ metavar,+ long,+ help,+ auto )+import qualified System.Hardware.MercuryApi as TMR+import qualified System.Hardware.MercuryApi.Params as TMR+import System.Exit ( exitFailure )+import System.Info ( os )+import System.IO ( stdout )++printRegionsAndFail :: TMR.Reader -> IO a+printRegionsAndFail rdr = do+ rgns <- TMR.paramGetRegionSupportedRegions rdr+ T.putStrLn "Region must be one of:"+ forM_ rgns $ \rgn -> do+ let dr = TMR.displayRegion rgn+ nSpaces = 6 - T.length dr+ spaces = T.replicate nSpaces " "+ T.putStrLn $ " " <> dr <> spaces <> TMR.displayRegionDescription rgn+ exitFailure++parseRegionOrFail :: TMR.Reader -> String -> IO TMR.Region+parseRegionOrFail rdr s =+ case TMR.parseRegion (T.pack s) of+ Nothing -> printRegionsAndFail rdr+ Just rgn -> return rgn++printPowerAndFail :: TMR.Reader -> IO a+printPowerAndFail rdr = do+ lo <- TMR.paramGetRadioPowerMin rdr+ hi <- TMR.paramGetRadioPowerMax rdr+ putStrLn $ "Power must be between " ++ show lo ++ " and " ++ show hi+ exitFailure++handleParamError :: TMR.Reader -> Either TMR.MercuryException () -> IO ()+handleParamError _ (Right _) = return ()+handleParamError rdr (Left err) = hpe (TMR.meStatus err)+ where hpe TMR.ERROR_INVALID_REGION = printRegionsAndFail rdr+ hpe TMR.ERROR_MSG_POWER_TOO_HIGH = printPowerAndFail rdr+ hpe TMR.ERROR_MSG_POWER_TOO_LOW = printPowerAndFail rdr+ hpe _ = throw err++createAndConnect :: String -> Bool -> IO TMR.Reader+createAndConnect uri listen = do+ rdr <- TMR.create $ T.pack uri+ when (listen) $ do+ listener <- TMR.opcodeListener stdout+ void $ TMR.addTransportListener rdr listener+ TMR.paramSetTransportTimeout rdr 10000+ TMR.connect rdr+ return rdr++createConnectAndParams :: String -> Bool -> String -> Int32 -> IO TMR.Reader+createConnectAndParams uri listen region power = do+ rdr <- createAndConnect uri listen+ rgn <- parseRegionOrFail rdr region+ eth <- try $ TMR.paramSetBasics rdr rgn power TMR.sparkFunAntennas+ handleParamError rdr eth+ TMR.paramSetTagReadDataRecordHighestRssi rdr True+ return rdr++defUri :: String+defUri = case os of+ "darwin" -> "tmr:///dev/cu.SLAB_USBtoUART"+ "mingw32" -> "tmr:///COM4"+ _ -> "tmr:///dev/ttyUSB0"++defRegion :: String+defRegion = "na2"++defPower :: Int32+defPower = 2300++optUri :: Parser String+optUri = strOption (long "uri" <>+ short 'u' <>+ metavar "URI" <>+ help ("Reader to connect to (default " ++ defUri ++ ")") <>+ value defUri)++optRegion :: Parser String+optRegion = strOption (long "region" <>+ short 'r' <>+ metavar "REGION" <>+ help ("Regulatory region (default " ++ defRegion ++ ")") <>+ value defRegion)++optPower :: Parser Int32+optPower = option auto (long "power" <>+ short 'p' <>+ metavar "CENTI-DBM" <>+ help ("Power level (0-2700, default " ++ show defPower ++ ")") <>+ value defPower)++optListen :: Parser Bool+optListen = switch (long "transport-listener" <>+ short 't' <>+ help "Print bytes sent on serial port")
+ examples/LICENSE-FOR-EXAMPLES view
@@ -0,0 +1,121 @@+Creative Commons Legal Code++CC0 1.0 Universal++ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED+ HEREUNDER.++Statement of Purpose++The laws of most jurisdictions throughout the world automatically confer+exclusive Copyright and Related Rights (defined below) upon the creator+and subsequent owner(s) (each and all, an "owner") of an original work of+authorship and/or a database (each, a "Work").++Certain owners wish to permanently relinquish those rights to a Work for+the purpose of contributing to a commons of creative, cultural and+scientific works ("Commons") that the public can reliably and without fear+of later claims of infringement build upon, modify, incorporate in other+works, reuse and redistribute as freely as possible in any form whatsoever+and for any purposes, including without limitation commercial purposes.+These owners may contribute to the Commons to promote the ideal of a free+culture and the further production of creative, cultural and scientific+works, or to gain reputation or greater distribution for their Work in+part through the use and efforts of others.++For these and/or other purposes and motivations, and without any+expectation of additional consideration or compensation, the person+associating CC0 with a Work (the "Affirmer"), to the extent that he or she+is an owner of Copyright and Related Rights in the Work, voluntarily+elects to apply CC0 to the Work and publicly distribute the Work under its+terms, with knowledge of his or her Copyright and Related Rights in the+Work and the meaning and intended legal effect of CC0 on those rights.++1. Copyright and Related Rights. A Work made available under CC0 may be+protected by copyright and related or neighboring rights ("Copyright and+Related Rights"). Copyright and Related Rights include, but are not+limited to, the following:++ i. the right to reproduce, adapt, distribute, perform, display,+ communicate, and translate a Work;+ ii. moral rights retained by the original author(s) and/or performer(s);+iii. publicity and privacy rights pertaining to a person's image or+ likeness depicted in a Work;+ iv. rights protecting against unfair competition in regards to a Work,+ subject to the limitations in paragraph 4(a), below;+ v. rights protecting the extraction, dissemination, use and reuse of data+ in a Work;+ vi. database rights (such as those arising under Directive 96/9/EC of the+ European Parliament and of the Council of 11 March 1996 on the legal+ protection of databases, and under any national implementation+ thereof, including any amended or successor version of such+ directive); and+vii. other similar, equivalent or corresponding rights throughout the+ world based on applicable law or treaty, and any national+ implementations thereof.++2. Waiver. To the greatest extent permitted by, but not in contravention+of, applicable law, Affirmer hereby overtly, fully, permanently,+irrevocably and unconditionally waives, abandons, and surrenders all of+Affirmer's Copyright and Related Rights and associated claims and causes+of action, whether now known or unknown (including existing as well as+future claims and causes of action), in the Work (i) in all territories+worldwide, (ii) for the maximum duration provided by applicable law or+treaty (including future time extensions), (iii) in any current or future+medium and for any number of copies, and (iv) for any purpose whatsoever,+including without limitation commercial, advertising or promotional+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each+member of the public at large and to the detriment of Affirmer's heirs and+successors, fully intending that such Waiver shall not be subject to+revocation, rescission, cancellation, termination, or any other legal or+equitable action to disrupt the quiet enjoyment of the Work by the public+as contemplated by Affirmer's express Statement of Purpose.++3. Public License Fallback. Should any part of the Waiver for any reason+be judged legally invalid or ineffective under applicable law, then the+Waiver shall be preserved to the maximum extent permitted taking into+account Affirmer's express Statement of Purpose. In addition, to the+extent the Waiver is so judged Affirmer hereby grants to each affected+person a royalty-free, non transferable, non sublicensable, non exclusive,+irrevocable and unconditional license to exercise Affirmer's Copyright and+Related Rights in the Work (i) in all territories worldwide, (ii) for the+maximum duration provided by applicable law or treaty (including future+time extensions), (iii) in any current or future medium and for any number+of copies, and (iv) for any purpose whatsoever, including without+limitation commercial, advertising or promotional purposes (the+"License"). The License shall be deemed effective as of the date CC0 was+applied by Affirmer to the Work. Should any part of the License for any+reason be judged legally invalid or ineffective under applicable law, such+partial invalidity or ineffectiveness shall not invalidate the remainder+of the License, and in such case Affirmer hereby affirms that he or she+will not (i) exercise any of his or her remaining Copyright and Related+Rights in the Work or (ii) assert any associated claims and causes of+action with respect to the Work, in either case contrary to Affirmer's+express Statement of Purpose.++4. Limitations and Disclaimers.++ a. No trademark or patent rights held by Affirmer are waived, abandoned,+ surrendered, licensed or otherwise affected by this document.+ b. Affirmer offers the Work as-is and makes no representations or+ warranties of any kind concerning the Work, express, implied,+ statutory or otherwise, including without limitation warranties of+ title, merchantability, fitness for a particular purpose, non+ infringement, or the absence of latent or other defects, accuracy, or+ the present or absence of errors, whether or not discoverable, all to+ the greatest extent permissible under applicable law.+ c. Affirmer disclaims responsibility for clearing rights of other persons+ that may apply to the Work or any use thereof, including without+ limitation any person's Copyright and Related Rights in the Work.+ Further, Affirmer disclaims responsibility for obtaining any necessary+ consents, permissions or other rights required for any use of the+ Work.+ d. Affirmer understands and acknowledges that Creative Commons is not a+ party to this document and has no duty or obligation with respect to+ this CC0 or use of the Work.
+ examples/tmr-firmware.hs view
@@ -0,0 +1,65 @@+{-# LANGUAGE OverloadedStrings #-}++import Control.Monad ( when )+import Data.Monoid ( (<>) )+import qualified Data.Text.IO as T ( putStrLn )+import Options.Applicative+ ( Applicative((<*>)),+ Parser,+ helper,+ execParser,+ str,+ progDesc,+ metavar,+ info,+ header,+ fullDesc,+ argument,+ (<$>),+ optional )+import qualified System.Hardware.MercuryApi as TMR+import System.Exit ( exitSuccess )++import ExampleUtil++data Opts = Opts+ { oUri :: String+ , oListen :: Bool+ , oFilename :: Maybe String+ }++opts :: Parser Opts+opts = Opts+ <$> optUri+ <*> optListen+ <*> optional (argument str (metavar "FILENAME"))++opts' = info (helper <*> opts)+ ( fullDesc <>+ progDesc ("If run without firmware file, just print current " +++ "firmware version. " +++ "Firmware file can be downloaded from: " +++ "http://www.thingmagic.com/index.php/download-nano-firmware") <>+ header "tmr-firmware - write a new firmware image to reader" )++printFwVers :: TMR.Reader -> IO ()+printFwVers rdr =+ TMR.paramGet rdr TMR.PARAM_VERSION_SOFTWARE >>= T.putStrLn++main = do+ o <- execParser opts'+ rdr <- createAndConnect (oUri o) (oListen o)++ putStr "Current firmware version: "+ printFwVers rdr++ when (oFilename o == Nothing) exitSuccess+ let (Just fwFile) = oFilename o++ putStrLn $ "Loading firmware image from " ++ fwFile+ TMR.firmwareLoadFile rdr fwFile++ putStr "New firmware version: "+ printFwVers rdr++ TMR.destroy rdr
+ examples/tmr-gpio.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE OverloadedStrings #-}++import Control.Concurrent ( threadDelay )+import Control.Exception ( finally )+import Control.Monad ( when )+import Data.Monoid ( (<>) )+import qualified Data.Text.IO as T ( putStrLn )+import Options.Applicative+ ( Alternative(many),+ Applicative((<*>)),+ Parser,+ helper,+ execParser,+ metavar,+ info,+ header,+ fullDesc,+ auto,+ argument,+ (<$>) )+import qualified System.Hardware.MercuryApi as TMR+import qualified System.Hardware.MercuryApi.Params as TMR++import ExampleUtil++data Opts = Opts+ { oUri :: String+ , oListen :: Bool+ , oGpos :: [TMR.PinNumber]+ }++opts :: Parser Opts+opts = Opts+ <$> optUri+ <*> optListen+ <*> many (argument auto (metavar "OUTPUTS..."))++opts' = info (helper <*> opts)+ ( fullDesc <>+ header "tmr-gpio - print GPIs and control GPOs" )++delayMillis :: Int+delayMillis = 100++mkPin :: TMR.PinNumber -> TMR.PinNumber -> TMR.GpioPin+mkPin highPin pin =+ TMR.GpioPin+ { TMR.gpId = pin+ , TMR.gpHigh = highPin == pin+ , TMR.gpOutput = True+ }++gpioLoop :: TMR.Reader -> [TMR.PinNumber] -> Integer -> [TMR.GpioPin] -> IO ()+gpioLoop rdr outPins millis oldPins = do+ pins <- TMR.gpiGet rdr+ when (pins /= oldPins) $ mapM_ T.putStrLn $ TMR.displayGpio pins+ when (not $ null outPins) $ do+ let oLen = length outPins+ pinNo = outPins !! fromIntegral ((millis `div` 1000) `mod` fromIntegral oLen)+ gpoPins = map (mkPin pinNo) outPins+ TMR.gpoSet rdr gpoPins+ threadDelay $ delayMillis * 1000+ gpioLoop rdr outPins (millis + fromIntegral delayMillis) pins++main = do+ o <- execParser opts'+ rdr <- createAndConnect (oUri o) (oListen o)++ -- set all the pins to input+ TMR.paramSetGpioInputList rdr [1..4]++ -- then set some to output+ let outPins = oGpos o+ TMR.paramSetGpioOutputList rdr outPins+ putStrLn $ "cycling among output pins " ++ show outPins++ -- now see which inputs are left+ inPins <- TMR.paramGetGpioInputList rdr+ putStrLn $ "listening on input pins " ++ show inPins++ gpioLoop rdr outPins 0 [] `finally` TMR.destroy rdr
+ examples/tmr-lock.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE OverloadedStrings #-}++import Control.Exception ( throw, try )+import Control.Monad ( when, void )+import Data.Int ( Int32 )+import Data.List ( maximumBy )+import Data.Monoid ( (<>) )+import Data.Ord ( comparing )+import qualified Data.Text.IO as T ( putStrLn )+import Options.Applicative+ ( Applicative((<*>)),+ Parser,+ helper,+ execParser,+ info,+ header,+ fullDesc,+ (<$>) )+import qualified System.Hardware.MercuryApi as TMR++import ExampleUtil++data Opts = Opts+ { oUri :: String+ , oRegion :: String+ , oPower :: Int32+ , oListen :: Bool+ }++opts :: Parser Opts+opts = Opts+ <$> optUri+ <*> optRegion+ <*> optPower+ <*> optListen++opts' = info (helper <*> opts)+ ( fullDesc <>+ header "tmr-lock - test that locking works" )++password :: TMR.GEN2_Password+password = 12345++main = do+ o <- execParser opts'++ rdr <- createConnectAndParams (oUri o) (oListen o) (oRegion o) (oPower o)++ tags <- TMR.read rdr 1000+ putStrLn $ "read " ++ show (length tags) ++ " tags"+ when (not $ null tags) $ do+ let trd = maximumBy (comparing TMR.trRssi) tags+ td = TMR.trTag trd+ epc = TMR.tdEpc td+ hex = TMR.bytesToHex epc++ T.putStrLn $ "writing password to <" <> hex <> ">"+ let epcFilt = TMR.TagFilterEPC td+ opWrite = TMR.TagOp_GEN2_WriteData+ { TMR.opBank = TMR.GEN2_BANK_RESERVED+ , TMR.opWordAddress = TMR.accessPasswordAddress+ , TMR.opData = TMR.passwordToWords password+ }+ TMR.executeTagOp rdr opWrite (Just epcFilt)++ T.putStrLn $ "locking <" <> hex <> ">"+ let opLock = TMR.TagOp_GEN2_Lock+ { TMR.opMask = [TMR.GEN2_LOCK_BITS_USER]+ , TMR.opAction = [TMR.GEN2_LOCK_BITS_USER]+ , TMR.opAccessPassword = password+ }+ TMR.executeTagOp rdr opLock (Just epcFilt)++ T.putStrLn $ "attempting to write user data to <" <> hex <> ">"+ let opWrite2 = TMR.TagOp_GEN2_WriteData+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opWordAddress = 0+ , TMR.opData = TMR.packBytesIntoWords "This should fail"+ }+ eth <- try $ TMR.executeTagOp rdr opWrite2 (Just epcFilt)+ case eth of+ Right _ ->+ T.putStrLn "Write succeeded, but it shouldn't have."+ Left err ->+ when (TMR.meStatus err /= TMR.ERROR_PROTOCOL_WRITE_FAILED &&+ TMR.meStatus err /= TMR.ERROR_PROTOCOL_BIT_DECODING_FAILED) $ throw err++ T.putStrLn $ "unlocking <" <> hex <> ">"+ let opUnlock = TMR.TagOp_GEN2_Lock+ { TMR.opMask = [TMR.GEN2_LOCK_BITS_USER]+ , TMR.opAction = []+ , TMR.opAccessPassword = password+ }+ void $ TMR.executeTagOp rdr opUnlock (Just epcFilt)++ TMR.destroy rdr
+ examples/tmr-params.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE OverloadedStrings #-}++import Control.Exception ( try )+import Control.Monad ( forM_ )+import Data.List ( sortBy )+import Data.Monoid ( (<>) )+import qualified Data.Text as T ( dropWhileEnd )+import qualified Data.Text.IO as T ( putStrLn, putStr )+import Options.Applicative+ ( Applicative((<*>)),+ Parser,+ helper,+ execParser,+ info,+ header,+ fullDesc,+ (<$>) )+import System.Console.ANSI+ ( SGR(Reset, SetColor),+ Color(Blue, Green, Red),+ ColorIntensity(Dull, Vivid),+ ConsoleLayer(Foreground),+ setSGR )+import qualified System.Hardware.MercuryApi as TMR+import qualified System.Hardware.MercuryApi.Params as TMR++import ExampleUtil++data Opts = Opts+ { oUri :: String+ , oListen :: Bool+ }++opts :: Parser Opts+opts = Opts+ <$> optUri+ <*> optListen++opts' = info (helper <*> opts)+ ( fullDesc <>+ header "tmr-params - print parameters" )++compareParams :: TMR.Param -> TMR.Param -> Ordering+compareParams p1 p2 =+ let n1 = TMR.paramName p1+ n2 = TMR.paramName p2+ b1 = T.dropWhileEnd (/= '/') n1+ b2 = T.dropWhileEnd (/= '/') n2+ in case b1 `compare` b2 of+ EQ -> n1 `compare` n2+ x -> x++main = do+ o <- execParser opts'+ T.putStrLn $ "API version: " <> TMR.apiVersion+ rdr <- createAndConnect (oUri o) (oListen o)++ params <- TMR.paramList rdr+ forM_ (sortBy compareParams params) $ \param -> do+ setSGR [SetColor Foreground Vivid Blue]+ putStr $ show param+ setSGR [Reset]+ T.putStrLn $ " - " <> TMR.paramName param+ let typ = TMR.displayParamType $ TMR.paramType param+ eth <- try $ TMR.paramGetString rdr param+ case eth of+ Left err -> do+ setSGR [SetColor Foreground Vivid Red]+ putStrLn $ " " ++ show (TMR.meStatus err)+ setSGR [Reset]+ Right txt -> do+ setSGR [SetColor Foreground Dull Green]+ T.putStr $ " " <> txt+ setSGR [Reset]+ T.putStr $ " :: " <> typ+ case TMR.paramUnits param of+ Nothing -> T.putStrLn ""+ Just units -> T.putStrLn $ " (" <> units <> ")"+ TMR.destroy rdr
+ examples/tmr-read.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE OverloadedStrings #-}++import Control.Monad ( when, forM_ )+import qualified Data.ByteString as B ( takeWhile, null )+import Data.Int ( Int32 )+import Data.List ( sortBy )+import Data.Monoid ( (<>) )+import Data.Ord ( comparing )+import qualified Data.Text as T ( Text, takeWhile, pack, null )+import qualified Data.Text.IO as T ( putStrLn )+import Options.Applicative+ ( Applicative((<*>)),+ Parser,+ helper,+ execParser,+ switch,+ short,+ long,+ info,+ help,+ header,+ fullDesc,+ (<$>) )+import System.Console.ANSI+ ( SGR(Reset, SetColor, SetConsoleIntensity),+ Color(Blue),+ ColorIntensity(Vivid),+ ConsoleIntensity(BoldIntensity),+ ConsoleLayer(Foreground),+ setSGR )+import qualified System.Hardware.MercuryApi as TMR+import Text.Printf ( printf )++import ExampleUtil++data Opts = Opts+ { oUri :: String+ , oRegion :: String+ , oPower :: Int32+ , oListen :: Bool+ , oLong :: Bool+ }++opts :: Parser Opts+opts = Opts+ <$> optUri+ <*> optRegion+ <*> optPower+ <*> optListen+ <*> switch (long "long" <>+ short 'l' <>+ help "Print lots of information per tag")++opts' = info (helper <*> opts)+ ( fullDesc <>+ header "tmr-read - read tags" )++readUser =+ TMR.TagOp_GEN2_ReadData+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opExtraBanks = []+ , TMR.opWordAddress = 0+ , TMR.opLen = 32+ }++putWithBold :: T.Text -> IO ()+putWithBold txt = do+ let bold = T.null $ T.takeWhile (== ' ') txt+ when bold $ setSGR [SetConsoleIntensity BoldIntensity]+ T.putStrLn txt+ when bold $ setSGR [Reset]++displayTag :: TMR.TagReadData -> T.Text+displayTag trd = strength <> " <" <> epc <> ">" <> user+ where+ strength = T.pack $ printf "%3d" (TMR.trRssi trd)+ epc = TMR.bytesToHex $ TMR.tdEpc $ TMR.trTag trd+ dat = TMR.trData trd+ user =+ if B.null dat+ then "" -- this means it failed to read the user data+ else T.pack $ ' ' : show (B.takeWhile (/= 0) dat)++main = do+ o <- execParser opts'++ rdr <- createConnectAndParams (oUri o) (oListen o) (oRegion o) (oPower o)+ TMR.paramSetReadPlanTagop rdr (Just readUser)++ tags <- TMR.read rdr 1000+ let tags' = reverse $ sortBy (comparing TMR.trRssi) tags+ setSGR [SetColor Foreground Vivid Blue]+ putStrLn $ "read " ++ show (length tags') ++ " tags"+ setSGR [Reset]+ if oLong o+ then mapM_ putWithBold (concatMap TMR.displayTagReadData tags')+ else forM_ tags' (T.putStrLn . displayTag)++ TMR.destroy rdr
+ examples/tmr-write.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE OverloadedStrings #-}++import Control.Monad ( when )+import qualified Data.ByteString as B ( snoc, pack )+import Data.Int ( Int32 )+import Data.List ( maximumBy )+import Data.Monoid ( (<>) )+import Data.Ord ( comparing )+import qualified Data.Text as T ( Text, pack )+import qualified Data.Text.Encoding as T ( encodeUtf8 )+import qualified Data.Text.IO as T ( putStrLn )+import Options.Applicative+ ( Applicative((<*>)),+ Parser,+ helper,+ execParser,+ switch,+ str,+ short,+ metavar,+ long,+ info,+ help,+ header,+ fullDesc,+ argument,+ (<$>) )+import System.Console.ANSI+ ( SGR(Reset, SetColor),+ Color(Green, Red),+ ColorIntensity(Vivid),+ ConsoleLayer(Foreground),+ setSGR )+import qualified System.Hardware.MercuryApi as TMR++import ExampleUtil++data Opts = Opts+ { oUri :: String+ , oRegion :: String+ , oPower :: Int32+ , oListen :: Bool+ , oRewrite :: Bool+ , oString :: String+ }++opts :: Parser Opts+opts = Opts+ <$> optUri+ <*> optRegion+ <*> optPower+ <*> optListen+ <*> switch (long "rewrite" <>+ short 'R' <>+ help "Write to a tag even if written before")+ <*> argument str (metavar "STRING")++opts' = info (helper <*> opts)+ ( fullDesc <>+ header "tmr-write - write a string to user data of tag" )++emptyUserDataFilter :: TMR.TagFilter+emptyUserDataFilter = TMR.mkFilterGen2 TMR.GEN2_BANK_USER 0 $ B.pack [0, 0]++printColor :: Color -> T.Text -> IO ()+printColor c txt = do+ setSGR [SetColor Foreground Vivid c]+ T.putStrLn txt+ setSGR [Reset]++main = do+ o <- execParser opts'++ rdr <- createConnectAndParams (oUri o) (oListen o) (oRegion o) (oPower o)+ when (not $ oRewrite o) $+ TMR.paramSetReadPlanFilter rdr (Just emptyUserDataFilter)++ tags <- TMR.read rdr 1000+ putStrLn $ "read " ++ show (length tags) ++ " tags"+ if null tags+ then do+ printColor Red "No tag found"+ else do+ let trd = maximumBy (comparing TMR.trRssi) tags+ td = TMR.trTag trd+ epc = TMR.tdEpc td+ hex = TMR.bytesToHex epc+ T.putStrLn $ "writing <" <> hex <> ">"+ let epcFilt = TMR.TagFilterEPC td+ txt = T.pack (oString o)+ words = TMR.packBytesIntoWords $ T.encodeUtf8 txt `B.snoc` 0+ opWrite = TMR.TagOp_GEN2_WriteData+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opWordAddress = 0+ , TMR.opData = words+ }+ TMR.executeTagOp rdr opWrite (Just epcFilt)+ printColor Green "Success!"++ TMR.destroy rdr
+ mercury-api.cabal view
@@ -0,0 +1,270 @@+-- Initial mercury-api.cabal generated by cabal init. For further+-- documentation, see http://haskell.org/cabal/users-guide/++-- The name of the package.+name: mercury-api++-- The package version. See the Haskell package versioning policy (PVP)+-- for standards guiding when and how versions should be incremented.+-- https://wiki.haskell.org/Package_versioning_policy+-- PVP summary: +-+------- breaking API changes+-- | | +----- non-breaking API additions+-- | | | +--- code changes with no API change+version: 0.1.0.0++-- A short (one-line) description of the package.+synopsis: Haskell binding to Mercury API for ThingMagic RFID readers++-- A longer description of the package.+description:+ This package is a Haskell binding to the \"Mercury API\" C API for+ ThingMagic RFID readers. It is especially geared toward the+ <https://www.sparkfun.com/products/14066 SparkFun Simultaneous RFID Reader>,+ which uses ThingMagic's M6e Nano module, but it should work with other+ ThingMagic readers. (Though currently, only support for serial readers+ is compiled in.) Most of the function and type names are the same as+ their counterparts in the C API, with the @TMR_@ prefix dropped. For more+ in-depth, language-independent documentation of Mercury API, see+ <http://www.thingmagic.com/images/Downloads/Docs/MercuryAPI_ProgrammerGuide_for_v1.27.3.pdf Mercury API Programmers Guide>.++-- The license under which the package is released.+license: MIT++-- The file containing the license text.+license-file: LICENSE++-- The package author(s).+author: Patrick Pelletier++-- An email address to which users can send suggestions, bug reports, and+-- patches.+maintainer: code@funwithsoftware.org++homepage: https://github.com/ppelleti/hs-mercury-api++bug-reports: https://github.com/ppelleti/hs-mercury-api/issues++-- A copyright notice.+copyright: © Patrick Pelletier, 2017++category: Hardware++build-type: Simple++-- Extra files to be distributed with the package, such as examples or a+-- README.+extra-source-files: ChangeLog.md+ , README.md+ , UPGRADING.md+ , examples/LICENSE-FOR-EXAMPLES+ , tests/*.result+ , tests/*.transport+ , cbits/api/*.h+ , cbits/api/patches/README.md+ , cbits/api/patches/*.patch+ , cbits/glue/glue.h++-- Constraint on the version of Cabal needed to build this package.+cabal-version: >=1.10++tested-with:+ GHC==7.6.3,+ GHC==7.8.4,+ GHC==7.10.3,+ GHC==8.0.2++source-repository head+ Type: git+ Location: https://github.com/ppelleti/hs-mercury-api.git+++library+ -- Modules exported by the library.+ exposed-modules: System.Hardware.MercuryApi+ , System.Hardware.MercuryApi.Params+ , System.Hardware.MercuryApi.Testing++ -- Modules included in this library but not exported.+ other-modules: System.Hardware.MercuryApi.Enums+ , System.Hardware.MercuryApi.Records+ , System.Hardware.MercuryApi.ParamValue++ -- LANGUAGE extensions used by modules in this package.+ -- other-extensions:++ -- Apparently these are supposed to be listed in dependency order,+ -- although the Cabal documentation doesn't breathe a word about it:+ -- https://ghc.haskell.org/trac/ghc/ticket/13786#comment:3+ --+ -- Furthermore, it appears that Cabal always puts conditional sources+ -- after unconditional sources, so in order to get the sources in the+ -- right order, they need to all be conditional, i. e. we have to list+ -- the sources twice, once for Windows and once for POSIX.+ if os(windows)+ c-sources: cbits/api/serial_transport_win32.c+ , cbits/api/osdep_win32.c+ , cbits/api/tmr_strerror.c+ , cbits/api/tmr_utils.c+ , cbits/api/tmr_param.c+ , cbits/api/hex_bytes.c+ , cbits/api/serial_reader_l3.c+ , cbits/api/serial_reader.c+ , cbits/api/tm_reader_async.c+ , cbits/api/tm_reader.c+ , cbits/glue/glue.c+ else+ c-sources: cbits/api/serial_transport_posix.c+ , cbits/api/osdep_posix.c+ , cbits/api/tmr_strerror.c+ , cbits/api/tmr_utils.c+ , cbits/api/tmr_param.c+ , cbits/api/hex_bytes.c+ , cbits/api/serial_reader_l3.c+ , cbits/api/serial_reader.c+ , cbits/api/tm_reader_async.c+ , cbits/api/tm_reader.c+ , cbits/glue/glue.c++ include-dirs: cbits/api+ , cbits/glue++ cc-options: -DTMR_ENABLE_SERIAL_READER_ONLY=1+ -DTMR_USE_HOST_C_LIBRARY=1++ -- Other library packages from which modules are imported.+ build-depends: base >= 4.6 && < 5+ , ansi-terminal >= 0.6.2.3 && < 0.7+ , bytestring >= 0.10.4 && < 0.11+ , clock >= 0.7.2 && < 0.8+ , hashable >= 1.2.4 && < 1.3+ , text >= 1.2 && < 1.3+ , unordered-containers >= 0.2.7.1 && < 0.3++ -- Directories containing source files.+ hs-source-dirs: src++ -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.+ build-tools: hsc2hs++ -- Base language which the package is written in.+ default-language: Haskell2010+++executable tmr-params+ main-is: tmr-params.hs+ other-modules: ExampleUtil+ build-depends: base >= 4.6 && < 5+ , ansi-terminal >= 0.6.2.3 && < 0.7+ , bytestring >= 0.10.4 && < 0.11+ , mercury-api+ , optparse-applicative >= 0.13 && < 0.14+ , text >= 1.2 && < 1.3+ hs-source-dirs: examples+ default-language: Haskell2010+ ghc-options: -threaded+++executable tmr-firmware+ main-is: tmr-firmware.hs+ other-modules: ExampleUtil+ build-depends: base >= 4.6 && < 5+ , bytestring >= 0.10.4 && < 0.11+ , mercury-api+ , optparse-applicative >= 0.13 && < 0.14+ , text >= 1.2 && < 1.3+ hs-source-dirs: examples+ default-language: Haskell2010+ ghc-options: -threaded+++executable tmr-read+ main-is: tmr-read.hs+ other-modules: ExampleUtil+ build-depends: base >= 4.6 && < 5+ , ansi-terminal >= 0.6.2.3 && < 0.7+ , bytestring >= 0.10.4 && < 0.11+ , mercury-api+ , optparse-applicative >= 0.13 && < 0.14+ , text >= 1.2 && < 1.3+ hs-source-dirs: examples+ default-language: Haskell2010+ ghc-options: -threaded+++executable tmr-write+ main-is: tmr-write.hs+ other-modules: ExampleUtil+ build-depends: base >= 4.6 && < 5+ , ansi-terminal >= 0.6.2.3 && < 0.7+ , bytestring >= 0.10.4 && < 0.11+ , mercury-api+ , optparse-applicative >= 0.13 && < 0.14+ , text >= 1.2 && < 1.3+ hs-source-dirs: examples+ default-language: Haskell2010+ ghc-options: -threaded+++executable tmr-lock+ main-is: tmr-lock.hs+ other-modules: ExampleUtil+ build-depends: base >= 4.6 && < 5+ , bytestring >= 0.10.4 && < 0.11+ , mercury-api+ , optparse-applicative >= 0.13 && < 0.14+ , text >= 1.2 && < 1.3+ hs-source-dirs: examples+ default-language: Haskell2010+ ghc-options: -threaded+++executable tmr-gpio+ main-is: tmr-gpio.hs+ other-modules: ExampleUtil+ build-depends: base >= 4.6 && < 5+ , bytestring >= 0.10.4 && < 0.11+ , mercury-api+ , optparse-applicative >= 0.13 && < 0.14+ , text >= 1.2 && < 1.3+ hs-source-dirs: examples+ default-language: Haskell2010+ ghc-options: -threaded+++test-suite replay+ type: exitcode-stdio-1.0+ main-is: replay.hs+ build-depends: base >= 4.6 && < 5+ , bytestring >= 0.10.4 && < 0.11+ , directory >= 1.2.2 && < 1.4+ , mercury-api+ , optparse-applicative >= 0.13 && < 0.14+ , text >= 1.2 && < 1.3+ hs-source-dirs: tests+ default-language: Haskell2010+ ghc-options: -threaded+++test-suite unit+ type: exitcode-stdio-1.0+ main-is: unit.hs+ build-depends: base >= 4.6 && < 5+ , bytestring >= 0.10.4 && < 0.11+ , HUnit >= 1.5 && < 1.7+ , mercury-api+ , text >= 1.2 && < 1.3+ hs-source-dirs: tests+ default-language: Haskell2010+ ghc-options: -threaded+++test-suite param-test+ type: exitcode-stdio-1.0+ main-is: param-test.hs+ build-depends: base >= 4.6 && < 5+ , HUnit >= 1.5 && < 1.7+ , mercury-api+ , text >= 1.2 && < 1.3+ hs-source-dirs: tests+ default-language: Haskell2010+ ghc-options: -threaded
+ src/System/Hardware/MercuryApi.hs view
@@ -0,0 +1,1048 @@+{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable, OverloadedStrings, BangPatterns #-}+{-|+Module : System.Hardware.MercuryApi+Description : Control ThingMagic RFID readers+Copyright : © Patrick Pelletier, 2017+License : MIT+Maintainer : code@funwithsoftware.org+Portability : POSIX, Windows++This module is a Haskell binding to the \"Mercury API\" C API for+ThingMagic RFID readers. It is especially geared toward the+<https://www.sparkfun.com/products/14066 SparkFun Simultaneous RFID Reader>,+which uses ThingMagic's M6e Nano module, but it should work with other+ThingMagic readers. (Though currently, only support for serial readers+is compiled in.) Most of the function and type names are the same as+their counterparts in the C API, with the @TMR_@ prefix dropped. For more+in-depth, language-independent documentation of Mercury API, see+<http://www.thingmagic.com/images/Downloads/Docs/MercuryAPI_ProgrammerGuide_for_v1.27.3.pdf Mercury API Programmers Guide>.++This module is intended to be imported @qualified@, e. g.++> import qualified System.Hardware.MercuryApi as TMR+-}++module System.Hardware.MercuryApi+ ( -- * Reader+ create+ , connect+ , read+ , executeTagOp+ , reboot+ , destroy+ , withReader+ -- ** Parameters+ -- | Although 'paramGet' and 'paramSet' are very flexible, they only+ -- check that the parameter type is correct at runtime. You may+ -- prefer to use the functions in "System.Hardware.MercuryApi.Params",+ -- which ensure the correct type at compile time.+ , paramList+ , paramGet+ , paramSet+ , paramSetBasics+ , paramSetReadPlanFilter+ , paramSetReadPlanTagop+ -- ** Listeners+ -- | Transport listeners can be used to monitor the raw serial data+ -- going to and from the reader, for debugging purposes. A listener+ -- that prints the data to a 'Handle' is available from 'hexListener'+ -- or 'opcodeListener'.+ , addTransportListener+ , removeTransportListener+ -- ** GPIO+ -- | The M6e Nano has 4 GPIO pins that can be controlled by software,+ -- numbered 1-4. On the+ -- <https://www.sparkfun.com/products/14066 SparkFun Simultaneous RFID Reader>,+ -- GPIO 1 is available on the GPIO1 pin, and GPIOs 2, 3, and 4 are available+ -- on the LV2, LV3, and LV4 pins. The GPIO1 pin is 5V, but+ -- <https://learn.sparkfun.com/tutorials/simultaneous-rfid-tag-reader-hookup-guide/hardware-overview the LV pins are 3.3V only>.+ -- To configure GPIOs as inputs or outputs, use 'PARAM_GPIO_INPUTLIST'+ -- and 'PARAM_GPIO_OUTPUTLIST'.+ , gpiGet+ , gpoSet+ -- ** Firmware+ -- | Firmware for the M6e Nano can be obtained+ -- <http://www.thingmagic.com/index.php/download-nano-firmware here>.+ , firmwareLoad+ , firmwareLoadFile+ -- * Utility functions+ -- ** Listeners+ , hexListener+ , opcodeListener+ -- ** Data helpers+ , packBytesIntoWords+ , passwordToWords+ , mkFilterGen2+ -- ** Parameters+ , paramName+ , paramID+ , paramType+ , paramUnits+ -- ** Hex conversion+ , bytesToHex+ , bytesToHexWithSpaces+ , hexToBytes+ -- ** Display+ -- | Some functions to format data in a more human-friendly+ -- format than 'show'.+ , displayTimestamp+ , displayLocalTimestamp+ , displayData+ , displayGpio+ , displayTagData+ , displayTagReadData+ , displayParamType+ , displayRegion+ , displayRegionDescription+ , parseRegion+ -- * Constants+ , apiVersion+ , sparkFunAntennas+ , defaultReadPlan+ , killPasswordAddress+ , accessPasswordAddress+ -- * Types+ -- ** Opaque types+ , Reader+ , ParamValue+ , TransportListenerId+ -- ** Typedefs+ , TransportListener+ , PinNumber+ , AntennaPort+ , GEN2_Password+ , MillisecondsSinceEpoch+ -- ** Records+ , MercuryException (..)+ , ReadPlan (..)+ , TagOp (..)+ , TagFilter (..)+ , FilterOn (..)+ , TagReadData (..)+ , GpioPin (..)+ , TagData (..)+ , GEN2_TagData (..)+ , ReadWrite (..)+ -- ** Enums+ , StatusType (..)+ , Status (..)+ , Param (..)+ , ParamType (..)+ , Region (..)+ , TagProtocol (..)+ , MetadataFlag (..)+ , GEN2_Bank (..)+ , GEN2_LockBits (..)+ , GEN2_WriteMode (..)+ , PowerMode (..)+ , TransportDirection (..)+ ) where++import Prelude hiding (read)++import Control.Applicative ( (<$>) )+-- IOException is needed here so that Haddock can link to it+import Control.Exception ( Exception, IOException, throwIO, try, bracket )+import Control.Monad ( when )+import qualified Data.ByteString as B+import qualified Data.HashMap.Strict as H+import Data.IORef ( IORef, newIORef, atomicModifyIORef' )+import Data.List ( intercalate )+import Data.Monoid ( (<>) )+import qualified Data.Text as T+import qualified Data.Text.IO as T ( hPutStrLn )+import Data.Typeable ( Typeable )+import Data.Word ( Word8, Word16, Word32 )+import Foreign+ ( Int32,+ Ptr,+ FunPtr,+ ForeignPtr,+ nullPtr,+ withForeignPtr,+ Storable(peek, poke),+ Bits((.&.), (.|.), bit, shiftL, shiftR, testBit),+ castPtr,+ mallocForeignPtrBytes,+ addForeignPtrFinalizer,+ with,+ toBool,+ withArrayLen,+ peekArray,+ allocaArray,+ allocaBytes,+ alloca )+import Foreign.C+ ( CStringLen,+ CString,+ CInt(..),+ CTime(..),+ CSize(..),+ Errno(..),+ withCAString,+ newCAString,+ throwErrnoIfNull,+ errnoToIOError )+import Text.Printf ( printf )+import System.Clock+ ( TimeSpec(nsec, sec), Clock(Monotonic), getTime )+import System.Console.ANSI+ ( SGR(Reset, SetColor),+ ConsoleLayer(Foreground),+ ColorIntensity(Vivid),+ Color(Cyan, Magenta),+ hSupportsANSI,+ hSetSGR )+import System.IO ( Handle, hFlush )+import qualified System.IO.Unsafe as U ( unsafePerformIO )+import Text.Read (readMaybe)++import System.Hardware.MercuryApi.Enums+import System.Hardware.MercuryApi.Records+import System.Hardware.MercuryApi.ParamValue++-- | An opaque type which represents a connection to an RFID reader.+-- Note that @Reader@ is not threadsafe, so if you want to use a+-- @Reader@ from more than one thread, you will need to implement+-- your own locking.+newtype Reader = Reader (ForeignPtr ReaderEtc)++type RawStatus = Word32+type RawType = Word32++type RawTransportListener =+ CBool -> Word32 -> Ptr Word8 -> Word32 -> Ptr () -> IO ()++-- | The direction of data travel. Passed to 'TransportListener'.+data TransportDirection = Rx -- ^ Receive+ | Tx -- ^ Transmit+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++-- | A function which can be installed via 'addTransportListener'+-- to be called every time Mercury API sends or receives data on+-- the serial port.+type TransportListener = TransportDirection -- ^ Direction of data transmission+ -> B.ByteString -- ^ Binary data sent or received+ -> Word32 -- ^ Timeout+ -> IO ()++-- | An opaque type which can be passed to 'removeTransportListener'+-- to remove a transport listener.+newtype TransportListenerId = TransportListenerId Integer deriving (Eq)++newtype Locale = Locale ()++-- Many of these need to be safe because they could call back+-- into Haskell via the transport listener. (Or via the custom+-- transport we use for testing.)++foreign import ccall safe "glue.h c_TMR_create"+ c_TMR_create :: Ptr ReaderEtc+ -> CString+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_connect"+ c_TMR_connect :: Ptr ReaderEtc+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_destroy"+ c_TMR_destroy :: Ptr ReaderEtc+ -> IO RawStatus++foreign import ccall unsafe "glue.h &c_TMR_destroy"+ p_TMR_destroy :: FunPtr (Ptr ReaderEtc -> IO ())++foreign import ccall safe "glue.h c_TMR_read"+ c_TMR_read :: Ptr ReaderEtc+ -> Word32+ -> Ptr Word32+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_hasMoreTags"+ c_TMR_hasMoreTags :: Ptr ReaderEtc+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_getNextTag"+ c_TMR_getNextTag :: Ptr ReaderEtc+ -> Ptr TagReadData+ -> IO RawStatus++foreign import ccall unsafe "tmr_tag_data.h TMR_TRD_init"+ c_TMR_TRD_init :: Ptr TagReadData+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_executeTagOp"+ c_TMR_executeTagOp :: Ptr ReaderEtc+ -> Ptr TagOp+ -> Ptr TagFilter+ -> Ptr List16+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_gpoSet"+ c_TMR_gpoSet :: Ptr ReaderEtc+ -> Word8+ -> Ptr GpioPin+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_gpiGet"+ c_TMR_gpiGet :: Ptr ReaderEtc+ -> Ptr Word8+ -> Ptr GpioPin+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_firmwareLoad"+ c_TMR_firmwareLoad :: Ptr ReaderEtc+ -> Ptr Word8+ -> Word32+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_paramSet"+ c_TMR_paramSet :: Ptr ReaderEtc+ -> RawParam+ -> Ptr ()+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_paramGet"+ c_TMR_paramGet :: Ptr ReaderEtc+ -> RawParam+ -> Ptr ()+ -> IO RawStatus++foreign import ccall safe "glue.h c_TMR_reboot"+ c_TMR_reboot :: Ptr ReaderEtc+ -> IO RawStatus++foreign import ccall unsafe "glue.h c_default_read_plan"+ c_default_read_plan :: Ptr ReadPlan+ -> IO ()++foreign import ccall safe "glue.h c_TMR_paramList"+ c_TMR_paramList :: Ptr ReaderEtc+ -> Ptr RawParam+ -> Ptr Word32+ -> IO RawStatus++foreign import ccall "wrapper"+ wrapTransportListener :: RawTransportListener+ -> IO (FunPtr RawTransportListener)++-- takes ownership of the FunPtr and the CString+foreign import ccall unsafe "glue.h c_TMR_addTransportListener"+ c_TMR_addTransportListener :: Ptr ReaderEtc+ -> FunPtr RawTransportListener+ -> CString+ -> IO RawStatus++foreign import ccall unsafe "glue.h c_TMR_removeTransportListener"+ c_TMR_removeTransportListener :: Ptr ReaderEtc+ -> CString+ -> IO RawStatus++foreign import ccall unsafe "glue.h c_TMR_strerr"+ c_TMR_strerr :: Ptr ReaderEtc+ -> RawStatus+ -> IO CString++-- This is a pure function, because it returns a string literal+foreign import ccall unsafe "tm_reader.h TMR_paramName"+ c_TMR_paramName :: RawParam+ -> CString++foreign import ccall unsafe "tmr_tag_data.h TMR_hexToBytes"+ c_TMR_hexToBytes :: CString+ -> Ptr Word8+ -> Word32+ -> Ptr Word32+ -> IO RawStatus++foreign import ccall unsafe "tmr_tag_data.h TMR_bytesToHex"+ c_TMR_bytesToHex :: Ptr Word8+ -> Word32+ -> CString+ -> IO ()++foreign import ccall unsafe "glue.h c_new_c_locale"+ c_new_c_locale :: IO (Ptr Locale)++foreign import ccall unsafe "glue.h c_format_time"+ c_format_time :: CString+ -> CSize+ -> CString+ -> CTime+ -> CBool+ -> Ptr Locale+ -> IO CInt++-- | Represents any error that can occur in a MercuryApi call,+-- except for those which can be represented by 'IOException'.+data MercuryException =+ MercuryException+ { meStatusType :: StatusType -- ^ general category of error+ , meStatus :: Status -- ^ the specific error+ , meMessage :: T.Text -- ^ the error message+ , meLocation :: T.Text -- ^ function where the error occurred+ , meParam :: T.Text -- ^ more information, such as the parameter+ -- in 'paramGet' or 'paramSet'+ , meUri :: T.Text -- ^ URI of the reader+ }+ deriving (Eq, Ord, Show, Read, Typeable)++instance Exception MercuryException++statusGetType :: RawStatus -> RawType+statusGetType stat = stat `shiftR` 24++errnoBit :: Int+errnoBit = 15++statusIsErrno :: StatusType -> RawStatus -> Bool+statusIsErrno ERROR_TYPE_COMM rstat = rstat `testBit` errnoBit+statusIsErrno _ _ = False++statusGetErrno :: RawStatus -> Errno+statusGetErrno rstat = Errno $ fromIntegral $ rstat .&. (bit errnoBit - 1)++checkStatus' :: Ptr ReaderEtc+ -> RawStatus+ -> T.Text+ -> T.Text+ -> IO T.Text+ -> IO ()+checkStatus' rdr rstat loc param getUri = do+ let t = toStatusType $ statusGetType rstat+ stat = toStatus rstat+ case t of+ SUCCESS_TYPE -> return ()+ _ -> do+ uri <- getUri+ if statusIsErrno t rstat+ then do+ let errno = statusGetErrno rstat+ ioe = errnoToIOError (T.unpack loc) errno Nothing+ (Just $ T.unpack uri)+ throwIO ioe+ else do+ cstr <- c_TMR_strerr rdr rstat+ msg <- textFromCString cstr+ let exc = MercuryException+ { meStatusType = t+ , meStatus = stat+ , meMessage = msg+ , meLocation = loc+ , meParam = param+ , meUri = uri+ }+ throwIO exc++checkStatus :: Ptr ReaderEtc -> RawStatus -> T.Text -> T.Text -> IO ()+checkStatus rdr rstat loc param =+ checkStatus' rdr rstat loc param (textFromCString $ uriPtr rdr)++uniqueCounter :: IORef Integer+{-# NOINLINE uniqueCounter #-}+uniqueCounter = U.unsafePerformIO $ newIORef 0++newUnique :: IO Integer+newUnique = atomicModifyIORef' uniqueCounter f+ where f x = (x + 1, x)++castToCStringLen :: Integral a => a -> Ptr Word8 -> CStringLen+castToCStringLen len ptr = (castPtr ptr, fromIntegral len)++paramPairs :: [(Param, T.Text)]+paramPairs = map f [minBound..maxBound]+ where+ f p = (p, U.unsafePerformIO $ textFromCString $ c_TMR_paramName $ fromParam p)++paramMap :: H.HashMap Param T.Text+paramMap = H.fromList paramPairs++paramMapReverse :: H.HashMap T.Text Param+paramMapReverse = H.fromList $ map swap paramPairs+ where swap (x, y) = (y, x)++-- | Return the string name (e. g. \"\/reader\/read\/plan\")+-- corresponding to a 'Param'.+paramName :: Param -> T.Text+paramName p = paramMap H.! p -- all possible keys are in the map, so can't fail++-- | Return the 'Param' corresponding to a string name+-- (e. g. \"\/reader\/read\/plan\"). Returns 'PARAM_NONE' if no such+-- parameter exists.+paramID :: T.Text -> Param+paramID name = H.lookupDefault PARAM_NONE name paramMapReverse++-- | Create a new 'Reader' with the specified URI. The reader is+-- not contacted at this point. On Mac OS X, be sure to use the+-- serial device that starts with @cu.@, not the one that starts with+-- @tty.@.+create :: T.Text -- ^ a reader URI, such as @tmr:\/\/\/dev\/ttyUSB0@ on Linux,+ -- @tmr:\/\/\/dev\/cu.SLAB_USBtoUART@ on Mac OS X, or+ -- @tmr:\/\/\/COM4@ on Windows.+ -> IO Reader+create deviceUri = do+ B.useAsCStringLen (textToBS deviceUri) $ \(cs, len) -> do+ fp <- mallocForeignPtrBytes (sizeofReaderEtc + len)+ withForeignPtr fp $ \p -> do+ status <- c_TMR_create p cs+ checkStatus' p status "create" "" (return deviceUri)+ addForeignPtrFinalizer p_TMR_destroy fp+ return $ Reader fp++withReaderEtc :: Reader+ -> T.Text+ -> T.Text+ -> (Ptr ReaderEtc -> IO RawStatus)+ -> IO ()+withReaderEtc (Reader fp) location param func = do+ withForeignPtr fp $ \p -> do+ status <- func p+ checkStatus p status location param++-- | Establishes the connection to the reader at the URI specified in+-- the 'create' call. The existence of a reader at the address is+-- verified and the reader is brought into a state appropriate for+-- performing RF operations.+connect :: Reader -> IO ()+connect rdr = withReaderEtc rdr "connect" "" c_TMR_connect++-- | Closes the connection to the reader and releases any resources+-- that have been consumed by the reader structure. Any further+-- operations performed on the reader will fail with+-- 'ERROR_ALREADY_DESTROYED'. On finalization of the 'Reader',+-- 'destroy' will be called automatically if it has not already been called.+destroy :: Reader -> IO ()+destroy rdr = withReaderEtc rdr "destroy" "" c_TMR_destroy++-- | Create a new 'Reader' with the specified URI, pass it to the given+-- computation, and destroy it when the computation exits.+withReader :: T.Text -- ^ a reader URI, such as @tmr:\/\/\/dev\/ttyUSB0@ on+ -- Linux, @tmr:\/\/\/dev\/cu.SLAB_USBtoUART@ on Mac OS X,+ -- or @tmr:\/\/\/COM4@ on Windows.+ -> (Reader -> IO a) -- ^ computation to run with Reader+ -> IO a+withReader uri = bracket (create uri) destroy++hasMoreTags :: Ptr CBool -> Ptr ReaderEtc -> IO RawStatus+hasMoreTags boolPtr rdrPtr = do+ status <- c_TMR_hasMoreTags rdrPtr+ let (moreTags, status') = case toStatus status of+ ERROR_NO_TAGS -> (cFalse, 0)+ _ -> (cTrue, status)+ poke boolPtr moreTags+ return status'++tShow :: Show a => a -> T.Text+tShow = T.pack . show++readLoop :: Reader+ -> Word32+ -> Ptr TagReadData+ -> Ptr CBool+ -> Int+ -> [TagReadData]+ -> IO [TagReadData]+readLoop rdr tagCount trdPtr boolPtr !tagNum !trds = do+ let tagNum' = tagNum + 1+ progress = "(" <> tShow tagNum' <> " of " <> tShow tagCount <> ")"+ withReaderEtc rdr "read"+ ("hasMoreTags " <> progress)+ (hasMoreTags boolPtr)+ moreTags <- toBool' <$> peek boolPtr+ if moreTags+ then do+ c_TMR_TRD_init trdPtr -- ignore return value because it is always success+ withReaderEtc rdr "read" ("getNextTag " <> progress)+ $ \p -> c_TMR_getNextTag p trdPtr+ trd <- peek trdPtr+ readLoop rdr tagCount trdPtr boolPtr tagNum' (trd : trds)+ else do+ return $ reverse trds++-- | Search for tags for a fixed duration. Follows the 'ReadPlan'+-- stored in 'PARAM_READ_PLAN'.+read :: Reader -- ^ The reader being operated on+ -> Word32 -- ^ The number of milliseconds to search for tags+ -> IO [TagReadData]+read rdr timeoutMs = do+ alloca $ \tagCountPtr -> do+ withReaderEtc rdr "read" "" $ \p -> c_TMR_read p timeoutMs tagCountPtr+ tagCount <- peek tagCountPtr+ alloca $ \trdPtr -> alloca $+ \boolPtr -> readLoop rdr tagCount trdPtr boolPtr 0 []++-- | Directly executes a 'TagOp' command.+-- Operates on the first tag found, with applicable tag filtering.+-- The call returns immediately after finding one tag+-- and operating on it, unless the command timeout expires first.+-- The operation is performed on the antenna specified in the+-- 'PARAM_TAGOP_ANTENNA' parameter.+-- 'PARAM_TAGOP_PROTOCOL' specifies the protocol to be used.+-- Some TagOps return data, while others will just return an+-- empty 'B.ByteString'.+executeTagOp :: Reader -> TagOp -> Maybe TagFilter -> IO B.ByteString+executeTagOp rdr tagOp tagFilter = alloca $ \pOp -> alloca $ \pFilt -> do+ eth1 <- try $ poke pOp tagOp+ case eth1 of+ Left err -> throwPE rdr err "executeTagOp" "tagop"+ Right _ -> return ()+ pFilt' <- case tagFilter of+ Nothing -> return nullPtr+ Just tf -> do+ eth2 <- try $ poke pFilt tf+ case eth2 of+ Left err -> throwPE rdr err "executeTagOp" "filter"+ Right _ -> return pFilt+ results <- getList16 $ \pList -> do+ withReaderEtc rdr "executeTagOp" (tagOpName tagOp) $ \pRdr -> do+ c_TMR_executeTagOp pRdr pOp pFilt' (castPtr pList)+ return $ B.pack results++-- | Set the state of some GPO pins.+gpoSet :: Reader -> [GpioPin] -> IO ()+gpoSet rdr gpios = do+ withArrayLen gpios $ \len gpioPtr -> do+ eth <- try $ castLen "[GpioPin]" len+ case eth of+ Left err -> throwPE rdr err "gpoSet" ""+ Right len' -> do+ withReaderEtc rdr "gpoSet" "" $ \pRdr -> do+ c_TMR_gpoSet pRdr len' gpioPtr++-- | Get the state of all GPI pins.+gpiGet :: Reader -> IO [GpioPin]+gpiGet rdr = do+ let maxLen = maxBound+ with maxLen $ \lenPtr -> do+ allocaArray (fromIntegral maxLen) $ \gpioPtr -> do+ withReaderEtc rdr "gpiGet" "" $ \pRdr -> do+ c_TMR_gpiGet pRdr lenPtr gpioPtr+ len <- peek lenPtr+ peekArray (fromIntegral len) gpioPtr++-- | Attempts to install firmware on the reader, then restart and reinitialize.+firmwareLoad :: Reader -- ^ The reader being operated on+ -> B.ByteString -- ^ The binary firmware image to install+ -> IO ()+firmwareLoad = firmwareLoad' ""++firmwareLoad' :: T.Text -> Reader -> B.ByteString -> IO ()+firmwareLoad' filename rdr firmware = do+ B.useAsCStringLen firmware $ \(fwPtr, fwLen) -> do+ withReaderEtc rdr "firmwareLoad" filename $+ \p -> c_TMR_firmwareLoad p (castPtr fwPtr) (fromIntegral fwLen)++-- | Like 'firmwareLoad', but loads firmware from a file.+-- (e. g. @NanoFW-1.7.1.2.sim@)+firmwareLoadFile :: Reader -- ^ The reader being operated on+ -> FilePath -- ^ Name of file containing firmware image+ -> IO ()+firmwareLoadFile rdr filename = do+ firmware <- B.readFile filename+ firmwareLoad' (T.pack filename) rdr firmware++throwPE :: Reader -> ParamException -> T.Text -> T.Text -> IO a+throwPE (Reader fp) (ParamException statusType status msg) loc param = do+ uri <- withForeignPtr fp (textFromCString . uriPtr)+ throwIO $ MercuryException+ { meStatusType = statusType+ , meStatus = status+ , meMessage = msg+ , meLocation = loc+ , meParam = param+ , meUri = uri+ }++unimplementedParam :: ParamException+unimplementedParam =+ ParamException ERROR_TYPE_BINDING ERROR_UNIMPLEMENTED_PARAM+ "The given parameter is not yet implemented in the Haskell binding."++invalidParam :: ParamType -> ParamType -> ParamException+invalidParam expected actual =+ ParamException ERROR_TYPE_BINDING ERROR_INVALID_PARAM_TYPE+ ( "Expected " <> displayParamType expected <>+ " but got " <> displayParamType actual )++-- | Sets the value of a reader parameter. Throws 'MercuryException'+-- with a 'meStatus' of 'ERROR_INVALID_PARAM_TYPE' if the parameter value+-- is not of the correct type (sadly, this is only checked at runtime) or+-- 'ERROR_UNIMPLEMENTED_PARAM' if the parameter has not yet been implemented+-- in the Haskell binding. Can also propagate errors from the C API, such+-- as 'ERROR_UNSUPPORTED' or 'ERROR_READONLY'.+paramSet :: ParamValue a => Reader -> Param -> a -> IO ()+paramSet rdr param value = do+ let pt = paramType param+ pt' = pType value+ rp = fromParam param+ pName = T.pack $ show param+ when (pt == ParamTypeUnimplemented) $+ throwPE rdr unimplementedParam "paramSet" pName+ when (pt /= pt') $+ throwPE rdr (invalidParam pt pt') "paramSet" pName+ eth <- try $ pSet value $ \pp -> withReaderEtc rdr "paramSet" pName $+ \p -> c_TMR_paramSet p rp pp+ case eth of+ Left err -> throwPE rdr err "paramSet" pName+ Right _ -> return ()++withReturnType :: (a -> IO a) -> IO a+withReturnType f = f undefined++-- | Gets the value of a reader parameter. Throws 'MercuryException'+-- with a 'meStatus' of 'ERROR_INVALID_PARAM_TYPE' if the parameter value+-- is not of the correct type (sadly, this is only checked at runtime) or+-- 'ERROR_UNIMPLEMENTED_PARAM' if the parameter has not yet been implemented+-- in the Haskell binding. Can also propagate errors from the C API, such+-- as 'ERROR_UNSUPPORTED'.+paramGet :: ParamValue a => Reader -> Param -> IO a+paramGet rdr param = withReturnType $ \returnType -> do+ let pt = paramType param+ pt' = pType returnType+ rp = fromParam param+ pName = T.pack $ show param+ when (pt == ParamTypeUnimplemented) $+ throwPE rdr unimplementedParam "paramGet" pName+ when (pt /= pt') $+ throwPE rdr (invalidParam pt pt') "paramGet" pName+ pGet $ \pp -> withReaderEtc rdr "paramGet" pName $+ \p -> c_TMR_paramGet p rp pp++-- | Convenience function to set some of the most essential parameters.+-- The specified 'Region' is written into 'PARAM_REGION_ID'.+-- The specified power level is written into 'PARAM_RADIO_READPOWER'+-- and 'PARAM_RADIO_WRITEPOWER'. The specified antenna list is+-- written into the 'rpAntennas' field of 'PARAM_READ_PLAN', and the first+-- antenna in the list is written into 'PARAM_TAGOP_ANTENNA'. For the+-- <https://www.sparkfun.com/products/14066 SparkFun Simultaneous RFID Reader>,+-- the antenna list should be 'sparkFunAntennas', and if powering the reader+-- off USB, the power level should be 500+-- (<https://learn.sparkfun.com/tutorials/simultaneous-rfid-tag-reader-hookup-guide/power-supply-considerations 5 dBm>).+-- (Higher power levels can be used with a separate power supply.)+paramSetBasics :: Reader -- ^ The reader being operated on+ -> Region -- ^ The region+ -> Int32 -- ^ Power in centi-dBm+ -> [AntennaPort] -- ^ Antenna list+ -> IO ()+paramSetBasics rdr rgn pwr ant = do+ paramSet rdr PARAM_REGION_ID rgn+ paramSet rdr PARAM_RADIO_READPOWER pwr+ paramSet rdr PARAM_RADIO_WRITEPOWER pwr+ plan <- paramGet rdr PARAM_READ_PLAN+ paramSet rdr PARAM_READ_PLAN plan { rpAntennas = ant }+ when (not $ null ant) $ paramSet rdr PARAM_TAGOP_ANTENNA (head ant)++-- | Sets the 'rpFilter' field of the 'PARAM_READ_PLAN' parameter,+-- while leaving the rest of the read plan unchanged.+paramSetReadPlanFilter :: Reader -> Maybe TagFilter -> IO ()+paramSetReadPlanFilter rdr filt = do+ plan <- paramGet rdr PARAM_READ_PLAN+ paramSet rdr PARAM_READ_PLAN plan { rpFilter = filt }++-- | Sets the 'rpTagop' field of the 'PARAM_READ_PLAN' parameter,+-- while leaving the rest of the read plan unchanged.+paramSetReadPlanTagop :: Reader -> Maybe TagOp -> IO ()+paramSetReadPlanTagop rdr op = do+ plan <- paramGet rdr PARAM_READ_PLAN+ paramSet rdr PARAM_READ_PLAN plan { rpTagop = op }++-- | The read plan that the reader starts out with by default.+-- This has reasonable settings for most things, except for the+-- antennas, which need to be set. (e. g. set 'rpAntennas' to+-- 'sparkFunAntennas')+defaultReadPlan :: ReadPlan+defaultReadPlan = U.unsafePerformIO $ do+ alloca $ \p -> do+ c_default_read_plan p+ peek p++-- | The constant @[1]@, which is the correct value for 'rpAntennas'+-- when using the+-- <http://sparkfun.com/products/14066 SparkFun Simultaneous RFID Reader>.+sparkFunAntennas :: [AntennaPort]+sparkFunAntennas = [1]++-- | Reboot the reader+reboot :: Reader -> IO ()+reboot rdr = withReaderEtc rdr "reboot" "" c_TMR_reboot++-- | Get a list of parameters supported by the reader.+paramList :: Reader -> IO [Param]+paramList rdr = do+ let maxParams = paramMax + 1+ alloca $ \nParams -> do+ poke nParams (fromIntegral maxParams)+ allocaArray (fromIntegral maxParams) $ \params -> do+ withReaderEtc rdr "paramList" "" $ \p -> c_TMR_paramList p params nParams+ actual <- peek nParams+ result <- peekArray (min (fromIntegral actual) (fromIntegral maxParams)) params+ return $ map toParam result++txToDirection :: Bool -> TransportDirection+txToDirection True = Tx+txToDirection False = Rx++callTransportListener :: TransportListener -> RawTransportListener+callTransportListener listener tx dataLen dataPtr timeout _ = do+ bs <- B.packCStringLen (castToCStringLen dataLen dataPtr)+ listener (txToDirection $ toBool tx) bs timeout++-- | Add a listener to the list of functions that will be called for+-- each message sent to or recieved from the reader.+addTransportListener :: Reader -- ^ The reader to operate on.+ -> TransportListener -- ^ The listener to call.+ -> IO TransportListenerId -- ^ A unique identifier which+ -- can be used to remove the+ -- listener later.+addTransportListener rdr listener = do+ unique <- newUnique+ funPtr <- wrapTransportListener (callTransportListener listener)+ cs <- newCAString (show unique)+ withReaderEtc rdr "addTransportListener" "" $+ \p -> c_TMR_addTransportListener p funPtr cs+ return (TransportListenerId unique)++-- | Remove a listener from the list of functions that will be called+-- for each message sent to or recieved from the reader.+removeTransportListener :: Reader -- ^ The reader to operate on.+ -> TransportListenerId -- ^ The return value of a call+ -- to 'addTransportListener'.+ -> IO ()+removeTransportListener rdr (TransportListenerId unique) = do+ withCAString (show unique) $ \cs -> do+ withReaderEtc rdr "removeTransportListener" "" $+ \p -> c_TMR_removeTransportListener p cs++-- | Given a 'Handle', returns a 'TransportListener' which prints+-- transport data to that handle in hex. If the handle is a terminal,+-- prints transmitted data in magenta and received data in cyan.+hexListener :: Handle -> IO TransportListener+hexListener h = do+ useColor <- hSupportsANSI h+ return (listenerImpl h useColor False)++-- | Identical to 'hexListener', but also prints the opcode of each packet,+-- and a timestamp. (The timestamp is relative to an arbitrary point in+-- time, so is only useful for computing differences between timestamps.)+opcodeListener :: Handle -> IO TransportListener+opcodeListener h = do+ useColor <- hSupportsANSI h+ return (listenerImpl h useColor True)++listenerImpl :: Handle -> Bool -> Bool -> TransportListener+listenerImpl h useColor printOpcode dir dat _ = do+ setColors useColor [SetColor Foreground Vivid (color dir)]+ opc <- if printOpcode+ then opcodeAndTime dat+ else return []+ mapM_ (T.hPutStrLn h) $ lstn opc (prefix dir)+ setColors useColor [Reset]+ flushColor useColor+ where+ setColors False _ = return ()+ setColors True sgr = hSetSGR h sgr+ flushColor False = return ()+ flushColor True = hFlush h+ prefix Tx = "Sending: "+ prefix Rx = "Received:"+ color Tx = Magenta+ color Rx = Cyan+ lstn opc pfx =+ zipWith T.append (pfx : repeat " ") (opc ++ displayData dat)++extractOpcode :: B.ByteString -> T.Text+extractOpcode bs+ | B.length bs < 3 = "too short"+ | otherwise = opcodeName (bs `B.index` 2)++opcodeAndTime :: B.ByteString -> IO [T.Text]+opcodeAndTime bs = do+ now <- getTime Monotonic+ let opcode = extractOpcode bs+ tm = printf "%d.%09d" (sec now) (nsec now)+ return [pad 30 opcode <> T.pack tm]++-- | Convert a hexadecimal string (without spaces) into a+-- 'B.ByteString'. The hex string may optionally include a "0x"+-- prefix, which will be ignored. If the input cannot be parsed as a+-- hex string, returns 'Nothing'.+hexToBytes :: T.Text -> Maybe B.ByteString+hexToBytes hex = U.unsafePerformIO $ do+ let hexBs = textToBS hex+ hexLen = B.length hexBs+ bufLen = 1 + (hexLen `div` 2)+ alloca $ \pLen -> allocaBytes bufLen $ \buf -> B.useAsCString hexBs $ \cs -> do+ status <- c_TMR_hexToBytes cs buf (fromIntegral bufLen) pLen+ outLen <- peek pLen+ if (status == 0)+ then Just <$> B.packCStringLen (castPtr buf, fromIntegral outLen)+ else return Nothing++-- | Convert a 'B.ByteString', such as a tag EPC, into a hexadecimal string.+bytesToHex :: B.ByteString -> T.Text+bytesToHex bytes = U.unsafePerformIO $ do+ let bytesLen = B.length bytes+ bufLen = 1 + bytesLen * 2+ allocaBytes bufLen $ \buf -> B.useAsCString bytes $ \cs -> do+ c_TMR_bytesToHex (castPtr cs) (fromIntegral bytesLen) buf+ textFromBS <$> B.packCString buf++-- | Like 'bytesToHex', but with a space between each byte.+bytesToHexWithSpaces :: B.ByteString -> T.Text+bytesToHexWithSpaces = T.pack . intercalate " " . map (printf "%02x") . B.unpack++pad :: Int -> T.Text -> T.Text+pad x t = t <> T.replicate (x - T.length t) " "++-- | Format a 'B.ByteString' as 16 bytes per line, with both hex and ascii+-- on the line.+displayData :: B.ByteString -> [T.Text]+displayData bytes+ | B.null bytes = []+ | otherwise =+ let (bs1, bs2) = B.splitAt 16 bytes+ (bs1a, bs1b) = B.splitAt 8 bs1+ dotify x = if x < 0x20 || x >= 0x7f then 0x2e else x+ hex = map (pad 25 . bytesToHexWithSpaces) [bs1a, bs1b]+ ascii = B.map dotify bs1+ txt = T.concat $ hex ++ ["|", textFromBS ascii, "|"]+ in txt : displayData bs2++displayByteString :: B.ByteString -> T.Text+displayByteString bs =+ "<" <> bytesToHex bs <> "> (" <> T.pack (show $ B.length bs) <> " bytes)"++-- | Convert a 'TagData' to a human-readable list of lines.+displayTagData :: TagData -> [T.Text]+displayTagData td =+ concat+ [ [ "TagData"+ , " epc = " <> displayByteString (tdEpc td)+ , " protocol = " <> tShow (tdProtocol td)+ , " crc = " <> T.pack (printf "0x%04x" $ tdCrc td)+ ]+ , case tdGen2 td of+ Nothing -> []+ Just gen2 -> [" gen2.pc = " <> displayByteString (g2Pc gen2)]+ ]++indent :: [T.Text] -> [T.Text]+indent = map (" " <>)++cLocale :: Ptr Locale+{-# NOINLINE cLocale #-}+cLocale = U.unsafePerformIO $ throwErrnoIfNull "newlocale" c_new_c_locale++formatTimestamp :: MillisecondsSinceEpoch -> CBool -> String -> IO T.Text+formatTimestamp t local z = do+ let (seconds, millis) = t `divMod` 1000+ fmt = "%Y-%m-%dT%H:%M:%S" ++ printf ".%03d" millis ++ z+ bufSize = 80+ withCAString fmt $ \cFmt -> allocaBytes bufSize $ \buf -> do+ ret <- c_format_time buf (fromIntegral bufSize) cFmt+ (CTime $ fromIntegral seconds) local cLocale+ if ret < 0+ then return $ T.pack $ printf "%d.%03d" seconds millis+ else textFromCString buf++-- | Convert a timestamp into+-- <https://en.wikipedia.org/wiki/ISO_8601 ISO 8601> format in UTC.+displayTimestamp :: MillisecondsSinceEpoch -- ^ milliseconds since 1\/1\/1970 UTC+ -> T.Text+displayTimestamp t = U.unsafePerformIO $ formatTimestamp t cFalse "Z"++-- | Convert a timestamp into <https://en.wikipedia.org/wiki/ISO_8601 ISO 8601>+-- format in the local timezone.+displayLocalTimestamp :: MillisecondsSinceEpoch -- ^ milliseconds since 1\/1\/1970 UTC+ -> IO T.Text+displayLocalTimestamp t = formatTimestamp t cTrue "%z"++-- | Convert a list of 'GpioPin' to a human-readable list of lines.+displayGpio :: [GpioPin] -> [T.Text]+displayGpio gpios = "Gpio" : map dispGpio gpios+ where+ dispGpio gpio = " pin " <> tShow (gpId gpio) <>+ (if (gpHigh gpio) then " high" else " low ") <>+ (if (gpOutput gpio) then " output" else " input")++-- | Convert a 'TagReadData' to a human-readable list of lines.+displayTagReadData :: TagReadData -> [T.Text]+displayTagReadData trd =+ concat+ [ [ "TagReadData" ]+ , indent (displayTagData $ trTag trd)+ , [ " metadataFlags = " <> T.intercalate "|" (map fl $ trMetadataFlags trd)+ , " phase = " <> tShow (trPhase trd)+ , " antenna = " <> tShow (trAntenna trd)+ ]+ , indent (displayGpio $ trGpio trd)+ , [ " readCount = " <> tShow (trReadCount trd)+ , " rssi = " <> tShow (trRssi trd)+ , " frequency = " <> tShow (trFrequency trd)+ , " timestamp = " <> displayTimestamp (trTimestamp trd)+ ]+ , dat "data" (trData trd)+ , dat "epcMemData" (trEpcMemData trd)+ , dat "tidMemData" (trTidMemData trd)+ , dat "userMemData" (trUserMemData trd)+ , dat "reservedMemData" (trReservedMemData trd)+ ]+ where+ nDrop = T.length "METADATA_FLAG_"+ fl = T.drop nDrop . tShow+ dat name bs =+ if B.null bs+ then []+ else indent ((name <> ": " <> T.pack (show $ B.length bs) <> " bytes")+ : indent (displayData bs))++regionPrefix :: T.Text+regionPrefix = "REGION_"++-- | Like 'show' for 'Region', but in lower case and without the+-- @REGION_@ prefix.+displayRegion :: Region -> T.Text+displayRegion = T.toLower . T.pack . drop (T.length regionPrefix) . show++-- | Like 'readMaybe' for 'Region', but case-insenstive and without the+-- @REGION_@ prefix.+parseRegion :: T.Text -> Maybe Region+parseRegion = readMaybe . T.unpack . T.toUpper . T.append regionPrefix++-- | Convert a 'B.ByteString' into a list of 'Word16', in big-endian+-- order. Padded with 0 if the number of bytes is odd.+packBytesIntoWords :: B.ByteString -> [Word16]+packBytesIntoWords bs = pbw (B.unpack bs)+ where pbw [] = []+ pbw [x] = [pk x 0]+ pbw (x1:x2:xs) = pk x1 x2 : pbw xs+ pk x1 x2 = (fromIntegral x1 `shiftL` 8) .|. fromIntegral x2++-- | Split a password into two 16-bit words, suitable for writing+-- into reserved memory.+passwordToWords :: GEN2_Password -> [Word16]+passwordToWords pwd = map fromIntegral [pwd `shiftR` 16, pwd .&. 0xffff]++-- | Create a 'TagFilterGen2' with the most common settings+mkFilterGen2 :: GEN2_Bank -- ^ The bank to filter on+ -> Word32 -- ^ The location (in bits) at which to begin+ -- comparing the mask+ -> B.ByteString -- ^ The mask value to compare with the specified+ -- region of tag memory+ -> TagFilter+mkFilterGen2 bank bitPointer mask =+ TagFilterGen2+ { tfInvert = False+ , tfFilterOn = FilterOnBank bank+ , tfBitPointer = bitPointer+ , tfMaskBitLength = fromIntegral $ 8 * B.length mask+ , tfMask = mask+ }++-- | Word address of kill password in reserved memory.+killPasswordAddress :: Word32+killPasswordAddress = 0++-- | Word address of access password in reserved memory.+accessPasswordAddress :: Word32+accessPasswordAddress = 2
+ src/System/Hardware/MercuryApi/Enums.hsc view
@@ -0,0 +1,967 @@+-- Automatically generated by util/generate-tmr-hsc.pl+{-# LANGUAGE OverloadedStrings, FlexibleInstances, DeriveDataTypeable #-}+module System.Hardware.MercuryApi.Enums where++import Data.Hashable ( Hashable(..) )+import Data.Int ( Int8, Int16, Int32 )+import Data.Monoid ( (<>) )+import Data.Text (Text)+import qualified Data.Text as T ( pack )+import Data.Word ( Word8, Word16, Word32 )+import Text.Printf ( printf )++#include <tm_reader.h>+#include <serial_reader_imp.h>+#include <glue.h>++-- | Indicates a general category of error.+data StatusType =+ SUCCESS_TYPE+ | ERROR_TYPE_COMM+ | ERROR_TYPE_CODE+ | ERROR_TYPE_MISC+ | ERROR_TYPE_LLRP+ | ERROR_TYPE_BINDING -- ^ An error which originates from the Haskell binding, not the underlying C library.+ | ERROR_TYPE_UNKNOWN -- ^ Not a recognized status type+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++toStatusType :: Word32 -> StatusType+toStatusType #{const TMR_SUCCESS_TYPE} = SUCCESS_TYPE+toStatusType #{const TMR_ERROR_TYPE_COMM} = ERROR_TYPE_COMM+toStatusType #{const TMR_ERROR_TYPE_CODE} = ERROR_TYPE_CODE+toStatusType #{const TMR_ERROR_TYPE_MISC} = ERROR_TYPE_MISC+toStatusType #{const TMR_ERROR_TYPE_LLRP} = ERROR_TYPE_LLRP+toStatusType #{const ERROR_TYPE_BINDING} = ERROR_TYPE_BINDING+toStatusType _ = ERROR_TYPE_UNKNOWN++-- | A specific error encountered by the C API or the Haskell binding.+data Status =+ SUCCESS -- ^ Success! (Never thrown in an exception)+ | ERROR_MSG_WRONG_NUMBER_OF_DATA -- ^ Invalid number of arguments+ | ERROR_INVALID_OPCODE -- ^ Command opcode not recognized.+ | ERROR_UNIMPLEMENTED_OPCODE -- ^ Command opcode recognized, but is not supported.+ | ERROR_MSG_POWER_TOO_HIGH -- ^ Requested power setting is above the allowed maximum.+ | ERROR_MSG_INVALID_FREQ_RECEIVED -- ^ Requested frequency is outside the allowed range.+ | ERROR_MSG_INVALID_PARAMETER_VALUE -- ^ Parameter value is outside the allowed range.+ | ERROR_MSG_POWER_TOO_LOW -- ^ Requested power setting is below the allowed minimum.+ | ERROR_UNIMPLEMENTED_FEATURE -- ^ Command not supported.+ | ERROR_INVALID_BAUD_RATE -- ^ Requested serial speed is not supported.+ | ERROR_INVALID_REGION -- ^ Region is not supported.+ | ERROR_INVALID_LICENSE_KEY -- ^ License key code is invalid+ | ERROR_BL_INVALID_IMAGE_CRC -- ^ Firmware is corrupt: Checksum doesn\'t match content.+ | ERROR_BL_INVALID_APP_END_ADDR -- ^ Serial protocol status code for this exception.+ | ERROR_FLASH_BAD_ERASE_PASSWORD -- ^ Internal reader error. Contact support.+ | ERROR_FLASH_BAD_WRITE_PASSWORD -- ^ Internal reader error. Contact support.+ | ERROR_FLASH_UNDEFINED_SECTOR -- ^ Internal reader error. Contact support.+ | ERROR_FLASH_ILLEGAL_SECTOR -- ^ Internal reader error. Contact support.+ | ERROR_FLASH_WRITE_TO_NON_ERASED_AREA -- ^ Internal reader error. Contact support.+ | ERROR_FLASH_WRITE_TO_ILLEGAL_SECTOR -- ^ Internal reader error. Contact support.+ | ERROR_FLASH_VERIFY_FAILED -- ^ Internal reader error. Contact support.+ | ERROR_NO_TAGS_FOUND -- ^ Reader was asked to find tags, but none were detected.+ | ERROR_NO_PROTOCOL_DEFINED -- ^ RFID protocol has not been configured.+ | ERROR_INVALID_PROTOCOL_SPECIFIED -- ^ Requested RFID protocol is not recognized.+ | ERROR_WRITE_PASSED_LOCK_FAILED -- ^ Lock failed after write operation+ | ERROR_PROTOCOL_NO_DATA_READ -- ^ Tag data was requested, but could not be read.+ | ERROR_AFE_NOT_ON -- ^ AFE not on - reader not sufficiently configured+ | ERROR_PROTOCOL_WRITE_FAILED -- ^ Write to tag failed.+ | ERROR_NOT_IMPLEMENTED_FOR_THIS_PROTOCOL -- ^ Command is not supported in the current RFID protocol.+ | ERROR_PROTOCOL_INVALID_WRITE_DATA -- ^ Data does not conform to protocol standards.+ | ERROR_PROTOCOL_INVALID_ADDRESS -- ^ Requested data address is outside the valid range.+ | ERROR_GENERAL_TAG_ERROR -- ^ Unknown error during RFID operation.+ | ERROR_DATA_TOO_LARGE -- ^ Read Tag Data was asked for more data than it supports.+ | ERROR_PROTOCOL_INVALID_KILL_PASSWORD -- ^ Incorrect password was provided to Kill Tag.+ | ERROR_PROTOCOL_KILL_FAILED -- ^ Kill failed for unknown reason.+ | ERROR_PROTOCOL_BIT_DECODING_FAILED -- ^ Internal reader error. Contact support.+ | ERROR_PROTOCOL_INVALID_EPC -- ^ Internal reader error. Contact support.+ | ERROR_PROTOCOL_INVALID_NUM_DATA -- ^ Internal reader error. Contact support.+ | ERROR_GEN2_PROTOCOL_OTHER_ERROR -- ^ Internal reader error. Contact support.+ | ERROR_GEN2_PROTOCOL_MEMORY_OVERRUN_BAD_PC -- ^ Internal reader error. Contact support.+ | ERROR_GEN2_PROTOCOL_MEMORY_LOCKED -- ^ Internal reader error. Contact support.+ | ERROR_GEN2_PROTOCOL_V2_AUTHEN_FAILED -- ^ Authentication failed with specified key.+ | ERROR_GEN2_PROTOCOL_V2_UNTRACE_FAILED -- ^ Untrace operation failed.+ | ERROR_GEN2_PROTOCOL_INSUFFICIENT_POWER -- ^ Internal reader error. Contact support.+ | ERROR_GEN2_PROTOCOL_NON_SPECIFIC_ERROR -- ^ Internal reader error. Contact support.+ | ERROR_GEN2_PROTOCOL_UNKNOWN_ERROR -- ^ Internal reader error. Contact support.+ | ERROR_AHAL_INVALID_FREQ -- ^ A command was received to set a frequency outside the specified range.+ | ERROR_AHAL_CHANNEL_OCCUPIED -- ^ With LBT enabled an attempt was made to set the frequency to an occupied channel.+ | ERROR_AHAL_TRANSMITTER_ON -- ^ Checking antenna status while CW is on is not allowed.+ | ERROR_ANTENNA_NOT_CONNECTED -- ^ Antenna not detected during pre-transmit safety test.+ | ERROR_TEMPERATURE_EXCEED_LIMITS -- ^ Reader temperature outside safe range.+ | ERROR_HIGH_RETURN_LOSS -- ^ Excess power detected at transmitter port, usually due to antenna tuning mismatch.+ | ERROR_INVALID_ANTENNA_CONFIG -- ^ Invalid antenna configuration+ | ERROR_TAG_ID_BUFFER_NOT_ENOUGH_TAGS_AVAILABLE -- ^ Asked for more tags than were available in the buffer.+ | ERROR_TAG_ID_BUFFER_FULL -- ^ Too many tags are in buffer. Remove some with Get Tag ID Buffer or Clear Tag ID Buffer.+ | ERROR_TAG_ID_BUFFER_REPEATED_TAG_ID -- ^ Internal error -- reader is trying to insert a duplicate tag record. Contact support.+ | ERROR_TAG_ID_BUFFER_NUM_TAG_TOO_LARGE -- ^ Asked for tags than a single transaction can handle.+ | ERROR_TAG_ID_BUFFER_AUTH_REQUEST -- ^ Blocked response to get additional data from host.+ | ERROR_SYSTEM_UNKNOWN_ERROR -- ^ Internal reader error. Contact support.+ | ERROR_TM_ASSERT_FAILED -- ^ Internal reader error. Contact support.+ | ERROR_TIMEOUT -- ^ Timeout+ | ERROR_NO_HOST -- ^ No matching host found+ | ERROR_LLRP -- ^ LLRP error+ | ERROR_PARSE -- ^ Error parsing device response+ | ERROR_DEVICE_RESET -- ^ Device was reset externally+ | ERROR_CRC_ERROR -- ^ CRC Error+ | ERROR_INVALID -- ^ Invalid argument+ | ERROR_UNIMPLEMENTED -- ^ Unimplemented operation+ | ERROR_UNSUPPORTED -- ^ Unsupported operation+ | ERROR_NO_ANTENNA -- ^ No antenna or invalid antenna+ | ERROR_READONLY -- ^ Value is read-only+ | ERROR_TOO_BIG -- ^ Value too big+ | ERROR_NO_THREADS -- ^ Thread initialization failed+ | ERROR_NO_TAGS -- ^ No tags to be retrieved+ | ERROR_NOT_FOUND -- ^ Key not found+ | ERROR_FIRMWARE_FORMAT -- ^ Size or format of firmware image is incorrect+ | ERROR_TRYAGAIN -- ^ Temporary error, try again+ | ERROR_OUT_OF_MEMORY -- ^ Out of memory+ | ERROR_INVALID_WRITE_MODE -- ^ Invalid write mode+ | ERROR_ILLEGAL_VALUE -- ^ Illegal value+ | ERROR_END_OF_READING+ | ERROR_UNSUPPORTED_READER_TYPE -- ^ Unsupported reader type+ | ERROR_BUFFER_OVERFLOW -- ^ Buffer overflow+ | ERROR_LOADSAVE_CONFIG+ | ERROR_AUTOREAD_ENABLED -- ^ Autonomous mode is enabled on reader. Please disable it+ | ERROR_FIRMWARE_UPDATE_ON_AUTOREAD -- ^ Firmware update is successful. Autonomous mode is already enabled on reader+ | ERROR_TIMESTAMP_NULL -- ^ Timestamp cannot be null+ | ERROR_LLRP_GETTYPEREGISTRY -- ^ LLRP Reader GetTypeRegistry Failed+ | ERROR_LLRP_CONNECTIONFAILED -- ^ LLRP Reader Connection attempt is failed+ | ERROR_LLRP_SENDIO_ERROR -- ^ LLRP Reader Send Messages failed+ | ERROR_LLRP_RECEIVEIO_ERROR -- ^ LLRP Reader Receive Messages failed+ | ERROR_LLRP_RECEIVE_TIMEOUT -- ^ LLRP Reader Receive Messages Timeout+ | ERROR_LLRP_MSG_PARSE_ERROR -- ^ Error parsing LLRP message+ | ERROR_LLRP_ALREADY_CONNECTED -- ^ Already connected to reader+ | ERROR_LLRP_INVALID_RFMODE -- ^ Specified RF Mode operation is not supported+ | ERROR_LLRP_UNDEFINED_VALUE -- ^ Undefined Value+ | ERROR_LLRP_READER_ERROR -- ^ LLRP reader unknown error+ | ERROR_LLRP_READER_CONNECTION_LOST -- ^ LLRP reader connection lost+ | ERROR_LLRP_CLIENT_CONNECTION_EXISTS -- ^ LLRP Reader Connection attempt is failed, A Client initiated connection already exists+ | ERROR_ALREADY_DESTROYED -- ^ Attempt to use reader after it was destroyed.+ | ERROR_INVALID_PARAM_TYPE -- ^ The parameter value was not of the type expected.+ | ERROR_UNIMPLEMENTED_PARAM -- ^ The given parameter is not yet implemented in the Haskell binding.+ | ERROR_UNKNOWN Word32 -- ^ C API returned an unrecognized status code+ deriving (Eq, Ord, Show, Read)++toStatus :: Word32 -> Status+toStatus #{const TMR_SUCCESS} = SUCCESS+toStatus #{const TMR_ERROR_MSG_WRONG_NUMBER_OF_DATA} = ERROR_MSG_WRONG_NUMBER_OF_DATA+toStatus #{const TMR_ERROR_INVALID_OPCODE} = ERROR_INVALID_OPCODE+toStatus #{const TMR_ERROR_UNIMPLEMENTED_OPCODE} = ERROR_UNIMPLEMENTED_OPCODE+toStatus #{const TMR_ERROR_MSG_POWER_TOO_HIGH} = ERROR_MSG_POWER_TOO_HIGH+toStatus #{const TMR_ERROR_MSG_INVALID_FREQ_RECEIVED} = ERROR_MSG_INVALID_FREQ_RECEIVED+toStatus #{const TMR_ERROR_MSG_INVALID_PARAMETER_VALUE} = ERROR_MSG_INVALID_PARAMETER_VALUE+toStatus #{const TMR_ERROR_MSG_POWER_TOO_LOW} = ERROR_MSG_POWER_TOO_LOW+toStatus #{const TMR_ERROR_UNIMPLEMENTED_FEATURE} = ERROR_UNIMPLEMENTED_FEATURE+toStatus #{const TMR_ERROR_INVALID_BAUD_RATE} = ERROR_INVALID_BAUD_RATE+toStatus #{const TMR_ERROR_INVALID_REGION} = ERROR_INVALID_REGION+toStatus #{const TMR_ERROR_INVALID_LICENSE_KEY} = ERROR_INVALID_LICENSE_KEY+toStatus #{const TMR_ERROR_BL_INVALID_IMAGE_CRC} = ERROR_BL_INVALID_IMAGE_CRC+toStatus #{const TMR_ERROR_BL_INVALID_APP_END_ADDR} = ERROR_BL_INVALID_APP_END_ADDR+toStatus #{const TMR_ERROR_FLASH_BAD_ERASE_PASSWORD} = ERROR_FLASH_BAD_ERASE_PASSWORD+toStatus #{const TMR_ERROR_FLASH_BAD_WRITE_PASSWORD} = ERROR_FLASH_BAD_WRITE_PASSWORD+toStatus #{const TMR_ERROR_FLASH_UNDEFINED_SECTOR} = ERROR_FLASH_UNDEFINED_SECTOR+toStatus #{const TMR_ERROR_FLASH_ILLEGAL_SECTOR} = ERROR_FLASH_ILLEGAL_SECTOR+toStatus #{const TMR_ERROR_FLASH_WRITE_TO_NON_ERASED_AREA} = ERROR_FLASH_WRITE_TO_NON_ERASED_AREA+toStatus #{const TMR_ERROR_FLASH_WRITE_TO_ILLEGAL_SECTOR} = ERROR_FLASH_WRITE_TO_ILLEGAL_SECTOR+toStatus #{const TMR_ERROR_FLASH_VERIFY_FAILED} = ERROR_FLASH_VERIFY_FAILED+toStatus #{const TMR_ERROR_NO_TAGS_FOUND} = ERROR_NO_TAGS_FOUND+toStatus #{const TMR_ERROR_NO_PROTOCOL_DEFINED} = ERROR_NO_PROTOCOL_DEFINED+toStatus #{const TMR_ERROR_INVALID_PROTOCOL_SPECIFIED} = ERROR_INVALID_PROTOCOL_SPECIFIED+toStatus #{const TMR_ERROR_WRITE_PASSED_LOCK_FAILED} = ERROR_WRITE_PASSED_LOCK_FAILED+toStatus #{const TMR_ERROR_PROTOCOL_NO_DATA_READ} = ERROR_PROTOCOL_NO_DATA_READ+toStatus #{const TMR_ERROR_AFE_NOT_ON} = ERROR_AFE_NOT_ON+toStatus #{const TMR_ERROR_PROTOCOL_WRITE_FAILED} = ERROR_PROTOCOL_WRITE_FAILED+toStatus #{const TMR_ERROR_NOT_IMPLEMENTED_FOR_THIS_PROTOCOL} = ERROR_NOT_IMPLEMENTED_FOR_THIS_PROTOCOL+toStatus #{const TMR_ERROR_PROTOCOL_INVALID_WRITE_DATA} = ERROR_PROTOCOL_INVALID_WRITE_DATA+toStatus #{const TMR_ERROR_PROTOCOL_INVALID_ADDRESS} = ERROR_PROTOCOL_INVALID_ADDRESS+toStatus #{const TMR_ERROR_GENERAL_TAG_ERROR} = ERROR_GENERAL_TAG_ERROR+toStatus #{const TMR_ERROR_DATA_TOO_LARGE} = ERROR_DATA_TOO_LARGE+toStatus #{const TMR_ERROR_PROTOCOL_INVALID_KILL_PASSWORD} = ERROR_PROTOCOL_INVALID_KILL_PASSWORD+toStatus #{const TMR_ERROR_PROTOCOL_KILL_FAILED} = ERROR_PROTOCOL_KILL_FAILED+toStatus #{const TMR_ERROR_PROTOCOL_BIT_DECODING_FAILED} = ERROR_PROTOCOL_BIT_DECODING_FAILED+toStatus #{const TMR_ERROR_PROTOCOL_INVALID_EPC} = ERROR_PROTOCOL_INVALID_EPC+toStatus #{const TMR_ERROR_PROTOCOL_INVALID_NUM_DATA} = ERROR_PROTOCOL_INVALID_NUM_DATA+toStatus #{const TMR_ERROR_GEN2_PROTOCOL_OTHER_ERROR} = ERROR_GEN2_PROTOCOL_OTHER_ERROR+toStatus #{const TMR_ERROR_GEN2_PROTOCOL_MEMORY_OVERRUN_BAD_PC} = ERROR_GEN2_PROTOCOL_MEMORY_OVERRUN_BAD_PC+toStatus #{const TMR_ERROR_GEN2_PROTOCOL_MEMORY_LOCKED} = ERROR_GEN2_PROTOCOL_MEMORY_LOCKED+toStatus #{const TMR_ERROR_GEN2_PROTOCOL_V2_AUTHEN_FAILED} = ERROR_GEN2_PROTOCOL_V2_AUTHEN_FAILED+toStatus #{const TMR_ERROR_GEN2_PROTOCOL_V2_UNTRACE_FAILED} = ERROR_GEN2_PROTOCOL_V2_UNTRACE_FAILED+toStatus #{const TMR_ERROR_GEN2_PROTOCOL_INSUFFICIENT_POWER} = ERROR_GEN2_PROTOCOL_INSUFFICIENT_POWER+toStatus #{const TMR_ERROR_GEN2_PROTOCOL_NON_SPECIFIC_ERROR} = ERROR_GEN2_PROTOCOL_NON_SPECIFIC_ERROR+toStatus #{const TMR_ERROR_GEN2_PROTOCOL_UNKNOWN_ERROR} = ERROR_GEN2_PROTOCOL_UNKNOWN_ERROR+toStatus #{const TMR_ERROR_AHAL_INVALID_FREQ} = ERROR_AHAL_INVALID_FREQ+toStatus #{const TMR_ERROR_AHAL_CHANNEL_OCCUPIED} = ERROR_AHAL_CHANNEL_OCCUPIED+toStatus #{const TMR_ERROR_AHAL_TRANSMITTER_ON} = ERROR_AHAL_TRANSMITTER_ON+toStatus #{const TMR_ERROR_ANTENNA_NOT_CONNECTED} = ERROR_ANTENNA_NOT_CONNECTED+toStatus #{const TMR_ERROR_TEMPERATURE_EXCEED_LIMITS} = ERROR_TEMPERATURE_EXCEED_LIMITS+toStatus #{const TMR_ERROR_HIGH_RETURN_LOSS} = ERROR_HIGH_RETURN_LOSS+toStatus #{const TMR_ERROR_INVALID_ANTENNA_CONFIG} = ERROR_INVALID_ANTENNA_CONFIG+toStatus #{const TMR_ERROR_TAG_ID_BUFFER_NOT_ENOUGH_TAGS_AVAILABLE} = ERROR_TAG_ID_BUFFER_NOT_ENOUGH_TAGS_AVAILABLE+toStatus #{const TMR_ERROR_TAG_ID_BUFFER_FULL} = ERROR_TAG_ID_BUFFER_FULL+toStatus #{const TMR_ERROR_TAG_ID_BUFFER_REPEATED_TAG_ID} = ERROR_TAG_ID_BUFFER_REPEATED_TAG_ID+toStatus #{const TMR_ERROR_TAG_ID_BUFFER_NUM_TAG_TOO_LARGE} = ERROR_TAG_ID_BUFFER_NUM_TAG_TOO_LARGE+toStatus #{const TMR_ERROR_TAG_ID_BUFFER_AUTH_REQUEST} = ERROR_TAG_ID_BUFFER_AUTH_REQUEST+toStatus #{const TMR_ERROR_SYSTEM_UNKNOWN_ERROR} = ERROR_SYSTEM_UNKNOWN_ERROR+toStatus #{const TMR_ERROR_TM_ASSERT_FAILED} = ERROR_TM_ASSERT_FAILED+toStatus #{const TMR_ERROR_TIMEOUT} = ERROR_TIMEOUT+toStatus #{const TMR_ERROR_NO_HOST} = ERROR_NO_HOST+toStatus #{const TMR_ERROR_LLRP} = ERROR_LLRP+toStatus #{const TMR_ERROR_PARSE} = ERROR_PARSE+toStatus #{const TMR_ERROR_DEVICE_RESET} = ERROR_DEVICE_RESET+toStatus #{const TMR_ERROR_CRC_ERROR} = ERROR_CRC_ERROR+toStatus #{const TMR_ERROR_INVALID} = ERROR_INVALID+toStatus #{const TMR_ERROR_UNIMPLEMENTED} = ERROR_UNIMPLEMENTED+toStatus #{const TMR_ERROR_UNSUPPORTED} = ERROR_UNSUPPORTED+toStatus #{const TMR_ERROR_NO_ANTENNA} = ERROR_NO_ANTENNA+toStatus #{const TMR_ERROR_READONLY} = ERROR_READONLY+toStatus #{const TMR_ERROR_TOO_BIG} = ERROR_TOO_BIG+toStatus #{const TMR_ERROR_NO_THREADS} = ERROR_NO_THREADS+toStatus #{const TMR_ERROR_NO_TAGS} = ERROR_NO_TAGS+toStatus #{const TMR_ERROR_NOT_FOUND} = ERROR_NOT_FOUND+toStatus #{const TMR_ERROR_FIRMWARE_FORMAT} = ERROR_FIRMWARE_FORMAT+toStatus #{const TMR_ERROR_TRYAGAIN} = ERROR_TRYAGAIN+toStatus #{const TMR_ERROR_OUT_OF_MEMORY} = ERROR_OUT_OF_MEMORY+toStatus #{const TMR_ERROR_INVALID_WRITE_MODE} = ERROR_INVALID_WRITE_MODE+toStatus #{const TMR_ERROR_ILLEGAL_VALUE} = ERROR_ILLEGAL_VALUE+toStatus #{const TMR_ERROR_END_OF_READING} = ERROR_END_OF_READING+toStatus #{const TMR_ERROR_UNSUPPORTED_READER_TYPE} = ERROR_UNSUPPORTED_READER_TYPE+toStatus #{const TMR_ERROR_BUFFER_OVERFLOW} = ERROR_BUFFER_OVERFLOW+toStatus #{const TMR_ERROR_LOADSAVE_CONFIG} = ERROR_LOADSAVE_CONFIG+toStatus #{const TMR_ERROR_AUTOREAD_ENABLED} = ERROR_AUTOREAD_ENABLED+toStatus #{const TMR_ERROR_FIRMWARE_UPDATE_ON_AUTOREAD} = ERROR_FIRMWARE_UPDATE_ON_AUTOREAD+toStatus #{const TMR_ERROR_TIMESTAMP_NULL} = ERROR_TIMESTAMP_NULL+toStatus #{const TMR_ERROR_LLRP_GETTYPEREGISTRY} = ERROR_LLRP_GETTYPEREGISTRY+toStatus #{const TMR_ERROR_LLRP_CONNECTIONFAILED} = ERROR_LLRP_CONNECTIONFAILED+toStatus #{const TMR_ERROR_LLRP_SENDIO_ERROR} = ERROR_LLRP_SENDIO_ERROR+toStatus #{const TMR_ERROR_LLRP_RECEIVEIO_ERROR} = ERROR_LLRP_RECEIVEIO_ERROR+toStatus #{const TMR_ERROR_LLRP_RECEIVE_TIMEOUT} = ERROR_LLRP_RECEIVE_TIMEOUT+toStatus #{const TMR_ERROR_LLRP_MSG_PARSE_ERROR} = ERROR_LLRP_MSG_PARSE_ERROR+toStatus #{const TMR_ERROR_LLRP_ALREADY_CONNECTED} = ERROR_LLRP_ALREADY_CONNECTED+toStatus #{const TMR_ERROR_LLRP_INVALID_RFMODE} = ERROR_LLRP_INVALID_RFMODE+toStatus #{const TMR_ERROR_LLRP_UNDEFINED_VALUE} = ERROR_LLRP_UNDEFINED_VALUE+toStatus #{const TMR_ERROR_LLRP_READER_ERROR} = ERROR_LLRP_READER_ERROR+toStatus #{const TMR_ERROR_LLRP_READER_CONNECTION_LOST} = ERROR_LLRP_READER_CONNECTION_LOST+toStatus #{const TMR_ERROR_LLRP_CLIENT_CONNECTION_EXISTS} = ERROR_LLRP_CLIENT_CONNECTION_EXISTS+toStatus #{const ERROR_ALREADY_DESTROYED} = ERROR_ALREADY_DESTROYED+toStatus x = ERROR_UNKNOWN x++type RawRegion = #{type TMR_Region}++-- | RFID regulatory regions+data Region =+ REGION_NONE -- ^ Unspecified region+ | REGION_NA -- ^ North America+ | REGION_EU -- ^ European Union+ | REGION_KR -- ^ Korea+ | REGION_IN -- ^ India+ | REGION_JP -- ^ Japan+ | REGION_PRC -- ^ People\'s Republic of China+ | REGION_EU2 -- ^ European Union 2+ | REGION_EU3 -- ^ European Union 3+ | REGION_KR2 -- ^ Korea 2+ | REGION_PRC2 -- ^ People\'s Republic of China(840MHZ)+ | REGION_AU -- ^ Australia+ | REGION_NZ -- ^ New Zealand !!EXPERIMENTAL!!+ | REGION_NA2 -- ^ Reduced FCC region+ | REGION_NA3 -- ^ 5MHZ FCC band+ | REGION_IS -- ^ Israel+ | REGION_OPEN -- ^ Open+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++toRegion :: RawRegion -> Region+toRegion #{const TMR_REGION_NONE} = REGION_NONE+toRegion #{const TMR_REGION_NA} = REGION_NA+toRegion #{const TMR_REGION_EU} = REGION_EU+toRegion #{const TMR_REGION_KR} = REGION_KR+toRegion #{const TMR_REGION_IN} = REGION_IN+toRegion #{const TMR_REGION_JP} = REGION_JP+toRegion #{const TMR_REGION_PRC} = REGION_PRC+toRegion #{const TMR_REGION_EU2} = REGION_EU2+toRegion #{const TMR_REGION_EU3} = REGION_EU3+toRegion #{const TMR_REGION_KR2} = REGION_KR2+toRegion #{const TMR_REGION_PRC2} = REGION_PRC2+toRegion #{const TMR_REGION_AU} = REGION_AU+toRegion #{const TMR_REGION_NZ} = REGION_NZ+toRegion #{const TMR_REGION_NA2} = REGION_NA2+toRegion #{const TMR_REGION_NA3} = REGION_NA3+toRegion #{const TMR_REGION_IS} = REGION_IS+toRegion #{const TMR_REGION_OPEN} = REGION_OPEN+toRegion _ = REGION_NONE++fromRegion :: Region -> RawRegion+fromRegion REGION_NONE = #{const TMR_REGION_NONE}+fromRegion REGION_NA = #{const TMR_REGION_NA}+fromRegion REGION_EU = #{const TMR_REGION_EU}+fromRegion REGION_KR = #{const TMR_REGION_KR}+fromRegion REGION_IN = #{const TMR_REGION_IN}+fromRegion REGION_JP = #{const TMR_REGION_JP}+fromRegion REGION_PRC = #{const TMR_REGION_PRC}+fromRegion REGION_EU2 = #{const TMR_REGION_EU2}+fromRegion REGION_EU3 = #{const TMR_REGION_EU3}+fromRegion REGION_KR2 = #{const TMR_REGION_KR2}+fromRegion REGION_PRC2 = #{const TMR_REGION_PRC2}+fromRegion REGION_AU = #{const TMR_REGION_AU}+fromRegion REGION_NZ = #{const TMR_REGION_NZ}+fromRegion REGION_NA2 = #{const TMR_REGION_NA2}+fromRegion REGION_NA3 = #{const TMR_REGION_NA3}+fromRegion REGION_IS = #{const TMR_REGION_IS}+fromRegion REGION_OPEN = #{const TMR_REGION_OPEN}++-- | A description of the given region, useful for a user interface.+displayRegionDescription :: Region -> Text+displayRegionDescription REGION_NONE = "Unspecified region"+displayRegionDescription REGION_NA = "North America"+displayRegionDescription REGION_EU = "European Union"+displayRegionDescription REGION_KR = "Korea"+displayRegionDescription REGION_IN = "India"+displayRegionDescription REGION_JP = "Japan"+displayRegionDescription REGION_PRC = "People's Republic of China"+displayRegionDescription REGION_EU2 = "European Union 2"+displayRegionDescription REGION_EU3 = "European Union 3"+displayRegionDescription REGION_KR2 = "Korea 2"+displayRegionDescription REGION_PRC2 = "People's Republic of China(840MHZ)"+displayRegionDescription REGION_AU = "Australia"+displayRegionDescription REGION_NZ = "New Zealand !!EXPERIMENTAL!!"+displayRegionDescription REGION_NA2 = "Reduced FCC region"+displayRegionDescription REGION_NA3 = "5MHZ FCC band"+displayRegionDescription REGION_IS = "Israel"+displayRegionDescription REGION_OPEN = "Open"++type RawTagProtocol = #{type TMR_TagProtocol}++-- | The protocol used by an RFID tag. Only 'TAG_PROTOCOL_GEN2'+-- is supported by the M6e Nano, and therefore the Haskell+-- binding currently only supports that protocol.+data TagProtocol =+ TAG_PROTOCOL_NONE+ | TAG_PROTOCOL_ISO180006B+ | TAG_PROTOCOL_GEN2+ | TAG_PROTOCOL_ISO180006B_UCODE+ | TAG_PROTOCOL_IPX64+ | TAG_PROTOCOL_IPX256+ | TAG_PROTOCOL_ATA+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++toTagProtocol :: RawTagProtocol -> TagProtocol+toTagProtocol #{const TMR_TAG_PROTOCOL_NONE} = TAG_PROTOCOL_NONE+toTagProtocol #{const TMR_TAG_PROTOCOL_ISO180006B} = TAG_PROTOCOL_ISO180006B+toTagProtocol #{const TMR_TAG_PROTOCOL_GEN2} = TAG_PROTOCOL_GEN2+toTagProtocol #{const TMR_TAG_PROTOCOL_ISO180006B_UCODE} = TAG_PROTOCOL_ISO180006B_UCODE+toTagProtocol #{const TMR_TAG_PROTOCOL_IPX64} = TAG_PROTOCOL_IPX64+toTagProtocol #{const TMR_TAG_PROTOCOL_IPX256} = TAG_PROTOCOL_IPX256+toTagProtocol #{const TMR_TAG_PROTOCOL_ATA} = TAG_PROTOCOL_ATA+toTagProtocol _ = TAG_PROTOCOL_NONE++fromTagProtocol :: TagProtocol -> RawTagProtocol+fromTagProtocol TAG_PROTOCOL_NONE = #{const TMR_TAG_PROTOCOL_NONE}+fromTagProtocol TAG_PROTOCOL_ISO180006B = #{const TMR_TAG_PROTOCOL_ISO180006B}+fromTagProtocol TAG_PROTOCOL_GEN2 = #{const TMR_TAG_PROTOCOL_GEN2}+fromTagProtocol TAG_PROTOCOL_ISO180006B_UCODE = #{const TMR_TAG_PROTOCOL_ISO180006B_UCODE}+fromTagProtocol TAG_PROTOCOL_IPX64 = #{const TMR_TAG_PROTOCOL_IPX64}+fromTagProtocol TAG_PROTOCOL_IPX256 = #{const TMR_TAG_PROTOCOL_IPX256}+fromTagProtocol TAG_PROTOCOL_ATA = #{const TMR_TAG_PROTOCOL_ATA}++type RawMetadataFlag = #{type TMR_TRD_MetadataFlag}++-- | Various metadata parameters which can be requested+-- in 'PARAM_METADATAFLAG'.+data MetadataFlag =+ METADATA_FLAG_READCOUNT+ | METADATA_FLAG_RSSI+ | METADATA_FLAG_ANTENNAID+ | METADATA_FLAG_FREQUENCY+ | METADATA_FLAG_TIMESTAMP+ | METADATA_FLAG_PHASE+ | METADATA_FLAG_PROTOCOL+ | METADATA_FLAG_DATA+ | METADATA_FLAG_GPIO_STATUS+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++fromMetadataFlag :: MetadataFlag -> RawMetadataFlag+fromMetadataFlag METADATA_FLAG_READCOUNT = #{const TMR_TRD_METADATA_FLAG_READCOUNT}+fromMetadataFlag METADATA_FLAG_RSSI = #{const TMR_TRD_METADATA_FLAG_RSSI}+fromMetadataFlag METADATA_FLAG_ANTENNAID = #{const TMR_TRD_METADATA_FLAG_ANTENNAID}+fromMetadataFlag METADATA_FLAG_FREQUENCY = #{const TMR_TRD_METADATA_FLAG_FREQUENCY}+fromMetadataFlag METADATA_FLAG_TIMESTAMP = #{const TMR_TRD_METADATA_FLAG_TIMESTAMP}+fromMetadataFlag METADATA_FLAG_PHASE = #{const TMR_TRD_METADATA_FLAG_PHASE}+fromMetadataFlag METADATA_FLAG_PROTOCOL = #{const TMR_TRD_METADATA_FLAG_PROTOCOL}+fromMetadataFlag METADATA_FLAG_DATA = #{const TMR_TRD_METADATA_FLAG_DATA}+fromMetadataFlag METADATA_FLAG_GPIO_STATUS = #{const TMR_TRD_METADATA_FLAG_GPIO_STATUS}++type RawBank = #{type TMR_GEN2_Bank}++-- | Gen2 memory banks+data GEN2_Bank =+ GEN2_BANK_RESERVED -- ^ Reserved bank (kill and access passwords)+ | GEN2_BANK_EPC -- ^ EPC memory bank+ | GEN2_BANK_TID -- ^ TID memory bank+ | GEN2_BANK_USER -- ^ User memory bank+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++fromBank :: GEN2_Bank -> RawBank+fromBank GEN2_BANK_RESERVED = #{const TMR_GEN2_BANK_RESERVED}+fromBank GEN2_BANK_EPC = #{const TMR_GEN2_BANK_EPC}+fromBank GEN2_BANK_TID = #{const TMR_GEN2_BANK_TID}+fromBank GEN2_BANK_USER = #{const TMR_GEN2_BANK_USER}++toBank :: RawBank -> GEN2_Bank+toBank #{const TMR_GEN2_BANK_RESERVED} = GEN2_BANK_RESERVED+toBank #{const TMR_GEN2_BANK_EPC} = GEN2_BANK_EPC+toBank #{const TMR_GEN2_BANK_TID} = GEN2_BANK_TID+toBank #{const TMR_GEN2_BANK_USER} = GEN2_BANK_USER+toBank x = error $ "didn't expect bank to be " ++ show x++fromExtraBank :: GEN2_Bank -> RawBank+fromExtraBank GEN2_BANK_RESERVED = #{const TMR_GEN2_BANK_RESERVED_ENABLED}+fromExtraBank GEN2_BANK_EPC = #{const TMR_GEN2_BANK_EPC_ENABLED}+fromExtraBank GEN2_BANK_TID = #{const TMR_GEN2_BANK_TID_ENABLED}+fromExtraBank GEN2_BANK_USER = #{const TMR_GEN2_BANK_USER_ENABLED}++type RawLockBits = #{type TMR_GEN2_LockBits}++-- | Memory lock bits+data GEN2_LockBits =+ GEN2_LOCK_BITS_USER_PERM -- ^ User memory bank lock permalock bit+ | GEN2_LOCK_BITS_USER -- ^ User memory bank lock bit+ | GEN2_LOCK_BITS_TID_PERM -- ^ TID memory bank lock permalock bit+ | GEN2_LOCK_BITS_TID -- ^ TID memory bank lock bit+ | GEN2_LOCK_BITS_EPC_PERM -- ^ EPC memory bank lock permalock bit+ | GEN2_LOCK_BITS_EPC -- ^ EPC memory bank lock bit+ | GEN2_LOCK_BITS_ACCESS_PERM -- ^ Access password lock permalock bit+ | GEN2_LOCK_BITS_ACCESS -- ^ Access password lock bit+ | GEN2_LOCK_BITS_KILL_PERM -- ^ Kill password lock permalock bit+ | GEN2_LOCK_BITS_KILL -- ^ Kill password lock bit+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++fromLockBits :: GEN2_LockBits -> RawLockBits+fromLockBits GEN2_LOCK_BITS_USER_PERM = #{const TMR_GEN2_LOCK_BITS_USER_PERM}+fromLockBits GEN2_LOCK_BITS_USER = #{const TMR_GEN2_LOCK_BITS_USER}+fromLockBits GEN2_LOCK_BITS_TID_PERM = #{const TMR_GEN2_LOCK_BITS_TID_PERM}+fromLockBits GEN2_LOCK_BITS_TID = #{const TMR_GEN2_LOCK_BITS_TID}+fromLockBits GEN2_LOCK_BITS_EPC_PERM = #{const TMR_GEN2_LOCK_BITS_EPC_PERM}+fromLockBits GEN2_LOCK_BITS_EPC = #{const TMR_GEN2_LOCK_BITS_EPC}+fromLockBits GEN2_LOCK_BITS_ACCESS_PERM = #{const TMR_GEN2_LOCK_BITS_ACCESS_PERM}+fromLockBits GEN2_LOCK_BITS_ACCESS = #{const TMR_GEN2_LOCK_BITS_ACCESS}+fromLockBits GEN2_LOCK_BITS_KILL_PERM = #{const TMR_GEN2_LOCK_BITS_KILL_PERM}+fromLockBits GEN2_LOCK_BITS_KILL = #{const TMR_GEN2_LOCK_BITS_KILL}++opcodeName :: Word8 -> Text+opcodeName #{const TMR_SR_OPCODE_WRITE_FLASH} = "WRITE_FLASH"+opcodeName #{const TMR_SR_OPCODE_READ_FLASH} = "READ_FLASH"+opcodeName #{const TMR_SR_OPCODE_VERSION} = "VERSION"+opcodeName #{const TMR_SR_OPCODE_BOOT_FIRMWARE} = "BOOT_FIRMWARE"+opcodeName #{const TMR_SR_OPCODE_SET_BAUD_RATE} = "SET_BAUD_RATE"+opcodeName #{const TMR_SR_OPCODE_ERASE_FLASH} = "ERASE_FLASH"+opcodeName #{const TMR_SR_OPCODE_VERIFY_IMAGE_CRC} = "VERIFY_IMAGE_CRC"+opcodeName #{const TMR_SR_OPCODE_BOOT_BOOTLOADER} = "BOOT_BOOTLOADER"+opcodeName #{const TMR_SR_OPCODE_HW_VERSION} = "HW_VERSION"+opcodeName #{const TMR_SR_OPCODE_MODIFY_FLASH} = "MODIFY_FLASH"+opcodeName #{const TMR_SR_OPCODE_GET_DSP_SILICON_ID} = "GET_DSP_SILICON_ID"+opcodeName #{const TMR_SR_OPCODE_GET_CURRENT_PROGRAM} = "GET_CURRENT_PROGRAM"+opcodeName #{const TMR_SR_OPCODE_WRITE_FLASH_SECTOR} = "WRITE_FLASH_SECTOR"+opcodeName #{const TMR_SR_OPCODE_GET_SECTOR_SIZE} = "GET_SECTOR_SIZE"+opcodeName #{const TMR_SR_OPCODE_MODIFY_FLASH_SECTOR} = "MODIFY_FLASH_SECTOR"+opcodeName #{const TMR_SR_OPCODE_READ_TAG_ID_SINGLE} = "READ_TAG_ID_SINGLE"+opcodeName #{const TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE} = "READ_TAG_ID_MULTIPLE"+opcodeName #{const TMR_SR_OPCODE_WRITE_TAG_ID} = "WRITE_TAG_ID"+opcodeName #{const TMR_SR_OPCODE_WRITE_TAG_DATA} = "WRITE_TAG_DATA"+opcodeName #{const TMR_SR_OPCODE_LOCK_TAG} = "LOCK_TAG"+opcodeName #{const TMR_SR_OPCODE_KILL_TAG} = "KILL_TAG"+opcodeName #{const TMR_SR_OPCODE_READ_TAG_DATA} = "READ_TAG_DATA"+opcodeName #{const TMR_SR_OPCODE_GET_TAG_ID_BUFFER} = "GET_TAG_ID_BUFFER"+opcodeName #{const TMR_SR_OPCODE_CLEAR_TAG_ID_BUFFER} = "CLEAR_TAG_ID_BUFFER"+opcodeName #{const TMR_SR_OPCODE_WRITE_TAG_SPECIFIC} = "WRITE_TAG_SPECIFIC"+opcodeName #{const TMR_SR_OPCODE_ERASE_BLOCK_TAG_SPECIFIC} = "ERASE_BLOCK_TAG_SPECIFIC"+opcodeName #{const TMR_SR_OPCODE_MULTI_PROTOCOL_TAG_OP} = "MULTI_PROTOCOL_TAG_OP"+opcodeName #{const TMR_SR_OPCODE_GET_ANTENNA_PORT} = "GET_ANTENNA_PORT"+opcodeName #{const TMR_SR_OPCODE_GET_READ_TX_POWER} = "GET_READ_TX_POWER"+opcodeName #{const TMR_SR_OPCODE_GET_TAG_PROTOCOL} = "GET_TAG_PROTOCOL"+opcodeName #{const TMR_SR_OPCODE_GET_WRITE_TX_POWER} = "GET_WRITE_TX_POWER"+opcodeName #{const TMR_SR_OPCODE_GET_FREQ_HOP_TABLE} = "GET_FREQ_HOP_TABLE"+opcodeName #{const TMR_SR_OPCODE_GET_USER_GPIO_INPUTS} = "GET_USER_GPIO_INPUTS"+opcodeName #{const TMR_SR_OPCODE_GET_REGION} = "GET_REGION"+opcodeName #{const TMR_SR_OPCODE_GET_POWER_MODE} = "GET_POWER_MODE"+opcodeName #{const TMR_SR_OPCODE_GET_USER_MODE} = "GET_USER_MODE"+opcodeName #{const TMR_SR_OPCODE_GET_READER_OPTIONAL_PARAMS} = "GET_READER_OPTIONAL_PARAMS"+opcodeName #{const TMR_SR_OPCODE_GET_PROTOCOL_PARAM} = "GET_PROTOCOL_PARAM"+opcodeName #{const TMR_SR_OPCODE_GET_READER_STATS} = "GET_READER_STATS"+opcodeName #{const TMR_SR_OPCODE_GET_USER_PROFILE} = "GET_USER_PROFILE"+opcodeName #{const TMR_SR_OPCODE_GET_AVAILABLE_PROTOCOLS} = "GET_AVAILABLE_PROTOCOLS"+opcodeName #{const TMR_SR_OPCODE_GET_AVAILABLE_REGIONS} = "GET_AVAILABLE_REGIONS"+opcodeName #{const TMR_SR_OPCODE_GET_TEMPERATURE} = "GET_TEMPERATURE"+opcodeName #{const TMR_SR_OPCODE_SET_ANTENNA_PORT} = "SET_ANTENNA_PORT"+opcodeName #{const TMR_SR_OPCODE_SET_READ_TX_POWER} = "SET_READ_TX_POWER"+opcodeName #{const TMR_SR_OPCODE_SET_TAG_PROTOCOL} = "SET_TAG_PROTOCOL"+opcodeName #{const TMR_SR_OPCODE_SET_WRITE_TX_POWER} = "SET_WRITE_TX_POWER"+opcodeName #{const TMR_SR_OPCODE_SET_FREQ_HOP_TABLE} = "SET_FREQ_HOP_TABLE"+opcodeName #{const TMR_SR_OPCODE_SET_USER_GPIO_OUTPUTS} = "SET_USER_GPIO_OUTPUTS"+opcodeName #{const TMR_SR_OPCODE_SET_REGION} = "SET_REGION"+opcodeName #{const TMR_SR_OPCODE_SET_POWER_MODE} = "SET_POWER_MODE"+opcodeName #{const TMR_SR_OPCODE_SET_USER_MODE} = "SET_USER_MODE"+opcodeName #{const TMR_SR_OPCODE_SET_READER_OPTIONAL_PARAMS} = "SET_READER_OPTIONAL_PARAMS"+opcodeName #{const TMR_SR_OPCODE_SET_PROTOCOL_PARAM} = "SET_PROTOCOL_PARAM"+opcodeName #{const TMR_SR_OPCODE_SET_USER_PROFILE} = "SET_USER_PROFILE"+opcodeName #{const TMR_SR_OPCODE_SET_PROTOCOL_LICENSEKEY} = "SET_PROTOCOL_LICENSEKEY"+opcodeName #{const TMR_SR_OPCODE_SET_OPERATING_FREQ} = "SET_OPERATING_FREQ"+opcodeName #{const TMR_SR_OPCODE_TX_CW_SIGNAL} = "TX_CW_SIGNAL"+opcodeName x = "Unknown opcode " <> T.pack (printf "0x%02X" x)++type RawWriteMode = #{type TMR_GEN2_WriteMode}++-- | Whether to use word write or block write for+-- 'System.Hardware.MercuryApi.TagOp_GEN2_WriteData'.+data GEN2_WriteMode =+ GEN2_WORD_ONLY+ | GEN2_BLOCK_ONLY+ | GEN2_BLOCK_FALLBACK+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++fromWriteMode :: GEN2_WriteMode -> RawWriteMode+fromWriteMode GEN2_WORD_ONLY = #{const TMR_GEN2_WORD_ONLY}+fromWriteMode GEN2_BLOCK_ONLY = #{const TMR_GEN2_BLOCK_ONLY}+fromWriteMode GEN2_BLOCK_FALLBACK = #{const TMR_GEN2_BLOCK_FALLBACK}++toWriteMode :: RawWriteMode -> GEN2_WriteMode+toWriteMode #{const TMR_GEN2_WORD_ONLY} = GEN2_WORD_ONLY+toWriteMode #{const TMR_GEN2_BLOCK_ONLY} = GEN2_BLOCK_ONLY+toWriteMode #{const TMR_GEN2_BLOCK_FALLBACK} = GEN2_BLOCK_FALLBACK+toWriteMode x = error $ "didn't expect WriteMode to be " ++ show x++type RawPowerMode = #{type TMR_SR_PowerMode}++-- | Value for parameter 'PARAM_POWERMODE'. On the M6e Nano,+-- 'POWER_MODE_MINSAVE', 'POWER_MODE_MEDSAVE', and+-- 'POWER_MODE_MAXSAVE' are all the same.+data PowerMode =+ POWER_MODE_FULL+ | POWER_MODE_MINSAVE+ | POWER_MODE_MEDSAVE+ | POWER_MODE_MAXSAVE+ | POWER_MODE_SLEEP+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++fromPowerMode :: PowerMode -> RawPowerMode+fromPowerMode POWER_MODE_FULL = #{const TMR_SR_POWER_MODE_FULL}+fromPowerMode POWER_MODE_MINSAVE = #{const TMR_SR_POWER_MODE_MINSAVE}+fromPowerMode POWER_MODE_MEDSAVE = #{const TMR_SR_POWER_MODE_MEDSAVE}+fromPowerMode POWER_MODE_MAXSAVE = #{const TMR_SR_POWER_MODE_MAXSAVE}+fromPowerMode POWER_MODE_SLEEP = #{const TMR_SR_POWER_MODE_SLEEP}++toPowerMode :: RawPowerMode -> PowerMode+toPowerMode #{const TMR_SR_POWER_MODE_FULL} = POWER_MODE_FULL+toPowerMode #{const TMR_SR_POWER_MODE_MINSAVE} = POWER_MODE_MINSAVE+toPowerMode #{const TMR_SR_POWER_MODE_MEDSAVE} = POWER_MODE_MEDSAVE+toPowerMode #{const TMR_SR_POWER_MODE_MAXSAVE} = POWER_MODE_MAXSAVE+toPowerMode #{const TMR_SR_POWER_MODE_SLEEP} = POWER_MODE_SLEEP+toPowerMode x = error $ "didn't expect PowerMode to be " ++ show x++type RawParam = #{type TMR_Param}++-- | Reader parameters which you can get and set. The names+-- are the same as the names of the enum in the C API.+-- (Unfortunately, these do not correspond to the+-- \"path\"-style names in any systematic way.)+-- Each parameter is listed with its \"path\", and the+-- Haskell type which is used to store it. Some parameters+-- are also listed with the physical units the parameter+-- is in. Not all parameters are implemented in the Haskell+-- binding. Please file a Github issue if there is a parameter+-- you need which is not implemented.+data Param =+ PARAM_NONE -- ^ No such parameter - used as a return value from 'System.Hardware.MercuryApi.paramID'.+ | PARAM_BAUDRATE -- ^ @\/reader\/baudRate@ 'Word32'+ | PARAM_COMMANDTIMEOUT -- ^ @\/reader\/commandTimeout@ 'Word32' (milliseconds)+ | PARAM_CURRENTTIME -- ^ @\/reader\/currentTime@ (Not yet implemented)+ | PARAM_READER_DESCRIPTION -- ^ @\/reader\/description@ 'Text'+ | PARAM_EXTENDEDEPC -- ^ @\/reader\/extendedEpc@ 'Bool'+ | PARAM_READER_HOSTNAME -- ^ @\/reader\/hostname@ 'Text'+ | PARAM_LICENSE_KEY -- ^ @\/reader\/licenseKey@ ['Word8']+ | PARAM_LICENSED_FEATURES -- ^ @\/reader\/licensedFeatures@ ['Word8']+ | PARAM_METADATAFLAG -- ^ @\/reader\/metadataflags@ ['MetadataFlag']+ | PARAM_POWERMODE -- ^ @\/reader\/powerMode@ 'PowerMode'+ | PARAM_PROBEBAUDRATES -- ^ @\/reader\/probeBaudRates@ ['Word32']+ | PARAM_READER_STATISTICS -- ^ @\/reader\/statistics@ (Not yet implemented)+ | PARAM_READER_STATS -- ^ @\/reader\/stats@ (Not yet implemented)+ | PARAM_TRANSPORTTIMEOUT -- ^ @\/reader\/transportTimeout@ 'Word32' (milliseconds)+ | PARAM_URI -- ^ @\/reader\/uri@ 'Text' (read-only)+ | PARAM_USER_CONFIG -- ^ @\/reader\/userConfig@ (Not yet implemented)+ | PARAM_USERMODE -- ^ @\/reader\/userMode@ (Not yet implemented)+ | PARAM_ANTENNA_CHECKPORT -- ^ @\/reader\/antenna\/checkPort@ 'Bool'+ | PARAM_ANTENNA_CONNECTEDPORTLIST -- ^ @\/reader\/antenna\/connectedPortList@ ['Word8'], or typedef ['System.Hardware.MercuryApi.AntennaPort'] (read-only)+ | PARAM_ANTENNA_PORTLIST -- ^ @\/reader\/antenna\/portList@ ['Word8'], or typedef ['System.Hardware.MercuryApi.AntennaPort'] (read-only)+ | PARAM_ANTENNA_PORTSWITCHGPOS -- ^ @\/reader\/antenna\/portSwitchGpos@ ['Word8'], or typedef ['System.Hardware.MercuryApi.PinNumber']+ | PARAM_ANTENNA_RETURNLOSS -- ^ @\/reader\/antenna\/returnLoss@ (Not yet implemented)+ | PARAM_ANTENNA_SETTLINGTIMELIST -- ^ @\/reader\/antenna\/settlingTimeList@ (Not yet implemented)+ | PARAM_ANTENNA_TXRXMAP -- ^ @\/reader\/antenna\/txRxMap@ (Not yet implemented)+ | PARAM_GEN2_BLF -- ^ @\/reader\/gen2\/BLF@ (Not yet implemented)+ | PARAM_GEN2_ACCESSPASSWORD -- ^ @\/reader\/gen2\/accessPassword@ 'Word32', or typedef 'System.Hardware.MercuryApi.GEN2_Password'+ | PARAM_GEN2_BAP -- ^ @\/reader\/gen2\/bap@ (Not yet implemented)+ | PARAM_GEN2_PROTOCOLEXTENSION -- ^ @\/reader\/gen2\/protocolExtension@ (Not yet implemented)+ | PARAM_GEN2_Q -- ^ @\/reader\/gen2\/q@ (Not yet implemented)+ | PARAM_GEN2_SESSION -- ^ @\/reader\/gen2\/session@ (Not yet implemented)+ | PARAM_GEN2_TAGENCODING -- ^ @\/reader\/gen2\/tagEncoding@ (Not yet implemented)+ | PARAM_GEN2_TARGET -- ^ @\/reader\/gen2\/target@ (Not yet implemented)+ | PARAM_GEN2_TARI -- ^ @\/reader\/gen2\/tari@ (Not yet implemented)+ | PARAM_READER_WRITE_EARLY_EXIT -- ^ @\/reader\/gen2\/writeEarlyExit@ 'Bool'+ | PARAM_GEN2_WRITEMODE -- ^ @\/reader\/gen2\/writeMode@ 'GEN2_WriteMode'+ | PARAM_READER_WRITE_REPLY_TIMEOUT -- ^ @\/reader\/gen2\/writeReplyTimeout@ 'Word16' (microseconds)+ | PARAM_GPIO_INPUTLIST -- ^ @\/reader\/gpio\/inputList@ ['Word8'], or typedef ['System.Hardware.MercuryApi.PinNumber']+ | PARAM_GPIO_OUTPUTLIST -- ^ @\/reader\/gpio\/outputList@ ['Word8'], or typedef ['System.Hardware.MercuryApi.PinNumber']+ | PARAM_ISO180006B_BLF -- ^ @\/reader\/iso180006b\/BLF@ (Not yet implemented)+ | PARAM_ISO180006B_DELIMITER -- ^ @\/reader\/iso180006b\/delimiter@ (Not yet implemented)+ | PARAM_ISO180006B_MODULATION_DEPTH -- ^ @\/reader\/iso180006b\/modulationDepth@ (Not yet implemented)+ | PARAM_RADIO_ENABLEPOWERSAVE -- ^ @\/reader\/radio\/enablePowerSave@ 'Bool'+ | PARAM_RADIO_ENABLESJC -- ^ @\/reader\/radio\/enableSJC@ 'Bool'+ | PARAM_RADIO_PORTREADPOWERLIST -- ^ @\/reader\/radio\/portReadPowerList@ (Not yet implemented)+ | PARAM_RADIO_PORTWRITEPOWERLIST -- ^ @\/reader\/radio\/portWritePowerList@ (Not yet implemented)+ | PARAM_RADIO_POWERMAX -- ^ @\/reader\/radio\/powerMax@ 'Int16' (centi-dBm, read-only)+ | PARAM_RADIO_POWERMIN -- ^ @\/reader\/radio\/powerMin@ 'Int16' (centi-dBm, read-only)+ | PARAM_RADIO_READPOWER -- ^ @\/reader\/radio\/readPower@ 'Int32' (centi-dBm)+ | PARAM_RADIO_TEMPERATURE -- ^ @\/reader\/radio\/temperature@ 'Int8' (degrees C, read-only)+ | PARAM_RADIO_WRITEPOWER -- ^ @\/reader\/radio\/writePower@ 'Int32' (centi-dBm)+ | PARAM_READ_ASYNCOFFTIME -- ^ @\/reader\/read\/asyncOffTime@ 'Word32' (milliseconds)+ | PARAM_READ_ASYNCONTIME -- ^ @\/reader\/read\/asyncOnTime@ 'Word32' (milliseconds)+ | PARAM_READ_PLAN -- ^ @\/reader\/read\/plan@ 'System.Hardware.MercuryApi.ReadPlan'+ | PARAM_REGION_HOPTABLE -- ^ @\/reader\/region\/hopTable@ ['Word32'] (kHz)+ | PARAM_REGION_HOPTIME -- ^ @\/reader\/region\/hopTime@ 'Word32' (milliseconds)+ | PARAM_REGION_ID -- ^ @\/reader\/region\/id@ 'Region'+ | PARAM_REGION_SUPPORTEDREGIONS -- ^ @\/reader\/region\/supportedRegions@ ['Region'] (read-only)+ | PARAM_REGION_LBT_ENABLE -- ^ @\/reader\/region\/lbt\/enable@ 'Bool'+ | PARAM_READER_STATS_ENABLE -- ^ @\/reader\/stats\/enable@ (Not yet implemented)+ | PARAM_STATUS_ENABLE_ANTENNAREPORT -- ^ @\/reader\/status\/antennaEnable@ 'Bool'+ | PARAM_STATUS_ENABLE_FREQUENCYREPORT -- ^ @\/reader\/status\/frequencyEnable@ 'Bool'+ | PARAM_STATUS_ENABLE_TEMPERATUREREPORT -- ^ @\/reader\/status\/temperatureEnable@ 'Bool'+ | PARAM_TAGREADDATA_ENABLEREADFILTER -- ^ @\/reader\/tagReadData\/enableReadFilter@ 'Bool'+ | PARAM_TAGREADDATA_READFILTERTIMEOUT -- ^ @\/reader\/tagReadData\/readFilterTimeout@ 'Int32'+ | PARAM_TAGREADDATA_RECORDHIGHESTRSSI -- ^ @\/reader\/tagReadData\/recordHighestRssi@ 'Bool'+ | PARAM_TAGREADDATA_REPORTRSSIINDBM -- ^ @\/reader\/tagReadData\/reportRssiInDbm@ 'Bool'+ | PARAM_TAGREADATA_TAGOPFAILURECOUNT -- ^ @\/reader\/tagReadData\/tagopFailures@ 'Word16' (read-only)+ | PARAM_TAGREADATA_TAGOPSUCCESSCOUNT -- ^ @\/reader\/tagReadData\/tagopSuccesses@ 'Word16' (read-only)+ | PARAM_TAGREADDATA_UNIQUEBYANTENNA -- ^ @\/reader\/tagReadData\/uniqueByAntenna@ 'Bool'+ | PARAM_TAGREADDATA_UNIQUEBYDATA -- ^ @\/reader\/tagReadData\/uniqueByData@ 'Bool'+ | PARAM_TAGREADDATA_UNIQUEBYPROTOCOL -- ^ @\/reader\/tagReadData\/uniqueByProtocol@ 'Bool'+ | PARAM_TAGOP_ANTENNA -- ^ @\/reader\/tagop\/antenna@ 'Word8', or typedef 'System.Hardware.MercuryApi.AntennaPort'+ | PARAM_TAGOP_PROTOCOL -- ^ @\/reader\/tagop\/protocol@ 'TagProtocol'+ | PARAM_TRIGGER_READ_GPI -- ^ @\/reader\/trigger\/read\/Gpi@ ['Word8'], or typedef ['System.Hardware.MercuryApi.PinNumber']+ | PARAM_VERSION_HARDWARE -- ^ @\/reader\/version\/hardware@ 'Text' (read-only)+ | PARAM_VERSION_MODEL -- ^ @\/reader\/version\/model@ 'Text' (read-only)+ | PARAM_PRODUCT_GROUP -- ^ @\/reader\/version\/productGroup@ 'Text' (read-only)+ | PARAM_PRODUCT_GROUP_ID -- ^ @\/reader\/version\/productGroupID@ 'Word16' (read-only)+ | PARAM_PRODUCT_ID -- ^ @\/reader\/version\/productID@ 'Word16' (read-only)+ | PARAM_VERSION_SERIAL -- ^ @\/reader\/version\/serial@ 'Text'+ | PARAM_VERSION_SOFTWARE -- ^ @\/reader\/version\/software@ 'Text' (read-only)+ | PARAM_VERSION_SUPPORTEDPROTOCOLS -- ^ @\/reader\/version\/supportedProtocols@ ['TagProtocol'] (read-only)+ | PARAM_SELECTED_PROTOCOLS+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++instance Hashable Param where+ hash = fromEnum+ salt `hashWithSalt` p = salt `hashWithSalt` fromEnum p++toParam :: RawParam -> Param+toParam #{const TMR_PARAM_NONE} = PARAM_NONE+toParam #{const TMR_PARAM_BAUDRATE} = PARAM_BAUDRATE+toParam #{const TMR_PARAM_PROBEBAUDRATES} = PARAM_PROBEBAUDRATES+toParam #{const TMR_PARAM_COMMANDTIMEOUT} = PARAM_COMMANDTIMEOUT+toParam #{const TMR_PARAM_TRANSPORTTIMEOUT} = PARAM_TRANSPORTTIMEOUT+toParam #{const TMR_PARAM_POWERMODE} = PARAM_POWERMODE+toParam #{const TMR_PARAM_USERMODE} = PARAM_USERMODE+toParam #{const TMR_PARAM_ANTENNA_CHECKPORT} = PARAM_ANTENNA_CHECKPORT+toParam #{const TMR_PARAM_ANTENNA_PORTLIST} = PARAM_ANTENNA_PORTLIST+toParam #{const TMR_PARAM_ANTENNA_CONNECTEDPORTLIST} = PARAM_ANTENNA_CONNECTEDPORTLIST+toParam #{const TMR_PARAM_ANTENNA_PORTSWITCHGPOS} = PARAM_ANTENNA_PORTSWITCHGPOS+toParam #{const TMR_PARAM_ANTENNA_SETTLINGTIMELIST} = PARAM_ANTENNA_SETTLINGTIMELIST+toParam #{const TMR_PARAM_ANTENNA_RETURNLOSS} = PARAM_ANTENNA_RETURNLOSS+toParam #{const TMR_PARAM_ANTENNA_TXRXMAP} = PARAM_ANTENNA_TXRXMAP+toParam #{const TMR_PARAM_GPIO_INPUTLIST} = PARAM_GPIO_INPUTLIST+toParam #{const TMR_PARAM_GPIO_OUTPUTLIST} = PARAM_GPIO_OUTPUTLIST+toParam #{const TMR_PARAM_GEN2_ACCESSPASSWORD} = PARAM_GEN2_ACCESSPASSWORD+toParam #{const TMR_PARAM_GEN2_Q} = PARAM_GEN2_Q+toParam #{const TMR_PARAM_GEN2_TAGENCODING} = PARAM_GEN2_TAGENCODING+toParam #{const TMR_PARAM_GEN2_SESSION} = PARAM_GEN2_SESSION+toParam #{const TMR_PARAM_GEN2_TARGET} = PARAM_GEN2_TARGET+toParam #{const TMR_PARAM_GEN2_BLF} = PARAM_GEN2_BLF+toParam #{const TMR_PARAM_GEN2_TARI} = PARAM_GEN2_TARI+toParam #{const TMR_PARAM_GEN2_WRITEMODE} = PARAM_GEN2_WRITEMODE+toParam #{const TMR_PARAM_GEN2_BAP} = PARAM_GEN2_BAP+toParam #{const TMR_PARAM_GEN2_PROTOCOLEXTENSION} = PARAM_GEN2_PROTOCOLEXTENSION+toParam #{const TMR_PARAM_ISO180006B_BLF} = PARAM_ISO180006B_BLF+toParam #{const TMR_PARAM_ISO180006B_MODULATION_DEPTH} = PARAM_ISO180006B_MODULATION_DEPTH+toParam #{const TMR_PARAM_ISO180006B_DELIMITER} = PARAM_ISO180006B_DELIMITER+toParam #{const TMR_PARAM_READ_ASYNCOFFTIME} = PARAM_READ_ASYNCOFFTIME+toParam #{const TMR_PARAM_READ_ASYNCONTIME} = PARAM_READ_ASYNCONTIME+toParam #{const TMR_PARAM_READ_PLAN} = PARAM_READ_PLAN+toParam #{const TMR_PARAM_RADIO_ENABLEPOWERSAVE} = PARAM_RADIO_ENABLEPOWERSAVE+toParam #{const TMR_PARAM_RADIO_POWERMAX} = PARAM_RADIO_POWERMAX+toParam #{const TMR_PARAM_RADIO_POWERMIN} = PARAM_RADIO_POWERMIN+toParam #{const TMR_PARAM_RADIO_PORTREADPOWERLIST} = PARAM_RADIO_PORTREADPOWERLIST+toParam #{const TMR_PARAM_RADIO_PORTWRITEPOWERLIST} = PARAM_RADIO_PORTWRITEPOWERLIST+toParam #{const TMR_PARAM_RADIO_READPOWER} = PARAM_RADIO_READPOWER+toParam #{const TMR_PARAM_RADIO_WRITEPOWER} = PARAM_RADIO_WRITEPOWER+toParam #{const TMR_PARAM_RADIO_TEMPERATURE} = PARAM_RADIO_TEMPERATURE+toParam #{const TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI} = PARAM_TAGREADDATA_RECORDHIGHESTRSSI+toParam #{const TMR_PARAM_TAGREADDATA_REPORTRSSIINDBM} = PARAM_TAGREADDATA_REPORTRSSIINDBM+toParam #{const TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA} = PARAM_TAGREADDATA_UNIQUEBYANTENNA+toParam #{const TMR_PARAM_TAGREADDATA_UNIQUEBYDATA} = PARAM_TAGREADDATA_UNIQUEBYDATA+toParam #{const TMR_PARAM_TAGOP_ANTENNA} = PARAM_TAGOP_ANTENNA+toParam #{const TMR_PARAM_TAGOP_PROTOCOL} = PARAM_TAGOP_PROTOCOL+toParam #{const TMR_PARAM_VERSION_HARDWARE} = PARAM_VERSION_HARDWARE+toParam #{const TMR_PARAM_VERSION_SERIAL} = PARAM_VERSION_SERIAL+toParam #{const TMR_PARAM_VERSION_MODEL} = PARAM_VERSION_MODEL+toParam #{const TMR_PARAM_VERSION_SOFTWARE} = PARAM_VERSION_SOFTWARE+toParam #{const TMR_PARAM_VERSION_SUPPORTEDPROTOCOLS} = PARAM_VERSION_SUPPORTEDPROTOCOLS+toParam #{const TMR_PARAM_REGION_HOPTABLE} = PARAM_REGION_HOPTABLE+toParam #{const TMR_PARAM_REGION_HOPTIME} = PARAM_REGION_HOPTIME+toParam #{const TMR_PARAM_REGION_ID} = PARAM_REGION_ID+toParam #{const TMR_PARAM_REGION_SUPPORTEDREGIONS} = PARAM_REGION_SUPPORTEDREGIONS+toParam #{const TMR_PARAM_REGION_LBT_ENABLE} = PARAM_REGION_LBT_ENABLE+toParam #{const TMR_PARAM_LICENSE_KEY} = PARAM_LICENSE_KEY+toParam #{const TMR_PARAM_USER_CONFIG} = PARAM_USER_CONFIG+toParam #{const TMR_PARAM_RADIO_ENABLESJC} = PARAM_RADIO_ENABLESJC+toParam #{const TMR_PARAM_EXTENDEDEPC} = PARAM_EXTENDEDEPC+toParam #{const TMR_PARAM_READER_STATISTICS} = PARAM_READER_STATISTICS+toParam #{const TMR_PARAM_READER_STATS} = PARAM_READER_STATS+toParam #{const TMR_PARAM_URI} = PARAM_URI+toParam #{const TMR_PARAM_PRODUCT_GROUP_ID} = PARAM_PRODUCT_GROUP_ID+toParam #{const TMR_PARAM_PRODUCT_GROUP} = PARAM_PRODUCT_GROUP+toParam #{const TMR_PARAM_PRODUCT_ID} = PARAM_PRODUCT_ID+toParam #{const TMR_PARAM_TAGREADATA_TAGOPSUCCESSCOUNT} = PARAM_TAGREADATA_TAGOPSUCCESSCOUNT+toParam #{const TMR_PARAM_TAGREADATA_TAGOPFAILURECOUNT} = PARAM_TAGREADATA_TAGOPFAILURECOUNT+toParam #{const TMR_PARAM_STATUS_ENABLE_ANTENNAREPORT} = PARAM_STATUS_ENABLE_ANTENNAREPORT+toParam #{const TMR_PARAM_STATUS_ENABLE_FREQUENCYREPORT} = PARAM_STATUS_ENABLE_FREQUENCYREPORT+toParam #{const TMR_PARAM_STATUS_ENABLE_TEMPERATUREREPORT} = PARAM_STATUS_ENABLE_TEMPERATUREREPORT+toParam #{const TMR_PARAM_TAGREADDATA_ENABLEREADFILTER} = PARAM_TAGREADDATA_ENABLEREADFILTER+toParam #{const TMR_PARAM_TAGREADDATA_READFILTERTIMEOUT} = PARAM_TAGREADDATA_READFILTERTIMEOUT+toParam #{const TMR_PARAM_TAGREADDATA_UNIQUEBYPROTOCOL} = PARAM_TAGREADDATA_UNIQUEBYPROTOCOL+toParam #{const TMR_PARAM_READER_DESCRIPTION} = PARAM_READER_DESCRIPTION+toParam #{const TMR_PARAM_READER_HOSTNAME} = PARAM_READER_HOSTNAME+toParam #{const TMR_PARAM_CURRENTTIME} = PARAM_CURRENTTIME+toParam #{const TMR_PARAM_READER_WRITE_REPLY_TIMEOUT} = PARAM_READER_WRITE_REPLY_TIMEOUT+toParam #{const TMR_PARAM_READER_WRITE_EARLY_EXIT} = PARAM_READER_WRITE_EARLY_EXIT+toParam #{const TMR_PARAM_READER_STATS_ENABLE} = PARAM_READER_STATS_ENABLE+toParam #{const TMR_PARAM_TRIGGER_READ_GPI} = PARAM_TRIGGER_READ_GPI+toParam #{const TMR_PARAM_METADATAFLAG} = PARAM_METADATAFLAG+toParam #{const TMR_PARAM_LICENSED_FEATURES} = PARAM_LICENSED_FEATURES+toParam #{const TMR_PARAM_SELECTED_PROTOCOLS} = PARAM_SELECTED_PROTOCOLS+toParam _ = PARAM_NONE++fromParam :: Param -> RawParam+fromParam PARAM_NONE = #{const TMR_PARAM_NONE}+fromParam PARAM_BAUDRATE = #{const TMR_PARAM_BAUDRATE}+fromParam PARAM_PROBEBAUDRATES = #{const TMR_PARAM_PROBEBAUDRATES}+fromParam PARAM_COMMANDTIMEOUT = #{const TMR_PARAM_COMMANDTIMEOUT}+fromParam PARAM_TRANSPORTTIMEOUT = #{const TMR_PARAM_TRANSPORTTIMEOUT}+fromParam PARAM_POWERMODE = #{const TMR_PARAM_POWERMODE}+fromParam PARAM_USERMODE = #{const TMR_PARAM_USERMODE}+fromParam PARAM_ANTENNA_CHECKPORT = #{const TMR_PARAM_ANTENNA_CHECKPORT}+fromParam PARAM_ANTENNA_PORTLIST = #{const TMR_PARAM_ANTENNA_PORTLIST}+fromParam PARAM_ANTENNA_CONNECTEDPORTLIST = #{const TMR_PARAM_ANTENNA_CONNECTEDPORTLIST}+fromParam PARAM_ANTENNA_PORTSWITCHGPOS = #{const TMR_PARAM_ANTENNA_PORTSWITCHGPOS}+fromParam PARAM_ANTENNA_SETTLINGTIMELIST = #{const TMR_PARAM_ANTENNA_SETTLINGTIMELIST}+fromParam PARAM_ANTENNA_RETURNLOSS = #{const TMR_PARAM_ANTENNA_RETURNLOSS}+fromParam PARAM_ANTENNA_TXRXMAP = #{const TMR_PARAM_ANTENNA_TXRXMAP}+fromParam PARAM_GPIO_INPUTLIST = #{const TMR_PARAM_GPIO_INPUTLIST}+fromParam PARAM_GPIO_OUTPUTLIST = #{const TMR_PARAM_GPIO_OUTPUTLIST}+fromParam PARAM_GEN2_ACCESSPASSWORD = #{const TMR_PARAM_GEN2_ACCESSPASSWORD}+fromParam PARAM_GEN2_Q = #{const TMR_PARAM_GEN2_Q}+fromParam PARAM_GEN2_TAGENCODING = #{const TMR_PARAM_GEN2_TAGENCODING}+fromParam PARAM_GEN2_SESSION = #{const TMR_PARAM_GEN2_SESSION}+fromParam PARAM_GEN2_TARGET = #{const TMR_PARAM_GEN2_TARGET}+fromParam PARAM_GEN2_BLF = #{const TMR_PARAM_GEN2_BLF}+fromParam PARAM_GEN2_TARI = #{const TMR_PARAM_GEN2_TARI}+fromParam PARAM_GEN2_WRITEMODE = #{const TMR_PARAM_GEN2_WRITEMODE}+fromParam PARAM_GEN2_BAP = #{const TMR_PARAM_GEN2_BAP}+fromParam PARAM_GEN2_PROTOCOLEXTENSION = #{const TMR_PARAM_GEN2_PROTOCOLEXTENSION}+fromParam PARAM_ISO180006B_BLF = #{const TMR_PARAM_ISO180006B_BLF}+fromParam PARAM_ISO180006B_MODULATION_DEPTH = #{const TMR_PARAM_ISO180006B_MODULATION_DEPTH}+fromParam PARAM_ISO180006B_DELIMITER = #{const TMR_PARAM_ISO180006B_DELIMITER}+fromParam PARAM_READ_ASYNCOFFTIME = #{const TMR_PARAM_READ_ASYNCOFFTIME}+fromParam PARAM_READ_ASYNCONTIME = #{const TMR_PARAM_READ_ASYNCONTIME}+fromParam PARAM_READ_PLAN = #{const TMR_PARAM_READ_PLAN}+fromParam PARAM_RADIO_ENABLEPOWERSAVE = #{const TMR_PARAM_RADIO_ENABLEPOWERSAVE}+fromParam PARAM_RADIO_POWERMAX = #{const TMR_PARAM_RADIO_POWERMAX}+fromParam PARAM_RADIO_POWERMIN = #{const TMR_PARAM_RADIO_POWERMIN}+fromParam PARAM_RADIO_PORTREADPOWERLIST = #{const TMR_PARAM_RADIO_PORTREADPOWERLIST}+fromParam PARAM_RADIO_PORTWRITEPOWERLIST = #{const TMR_PARAM_RADIO_PORTWRITEPOWERLIST}+fromParam PARAM_RADIO_READPOWER = #{const TMR_PARAM_RADIO_READPOWER}+fromParam PARAM_RADIO_WRITEPOWER = #{const TMR_PARAM_RADIO_WRITEPOWER}+fromParam PARAM_RADIO_TEMPERATURE = #{const TMR_PARAM_RADIO_TEMPERATURE}+fromParam PARAM_TAGREADDATA_RECORDHIGHESTRSSI = #{const TMR_PARAM_TAGREADDATA_RECORDHIGHESTRSSI}+fromParam PARAM_TAGREADDATA_REPORTRSSIINDBM = #{const TMR_PARAM_TAGREADDATA_REPORTRSSIINDBM}+fromParam PARAM_TAGREADDATA_UNIQUEBYANTENNA = #{const TMR_PARAM_TAGREADDATA_UNIQUEBYANTENNA}+fromParam PARAM_TAGREADDATA_UNIQUEBYDATA = #{const TMR_PARAM_TAGREADDATA_UNIQUEBYDATA}+fromParam PARAM_TAGOP_ANTENNA = #{const TMR_PARAM_TAGOP_ANTENNA}+fromParam PARAM_TAGOP_PROTOCOL = #{const TMR_PARAM_TAGOP_PROTOCOL}+fromParam PARAM_VERSION_HARDWARE = #{const TMR_PARAM_VERSION_HARDWARE}+fromParam PARAM_VERSION_SERIAL = #{const TMR_PARAM_VERSION_SERIAL}+fromParam PARAM_VERSION_MODEL = #{const TMR_PARAM_VERSION_MODEL}+fromParam PARAM_VERSION_SOFTWARE = #{const TMR_PARAM_VERSION_SOFTWARE}+fromParam PARAM_VERSION_SUPPORTEDPROTOCOLS = #{const TMR_PARAM_VERSION_SUPPORTEDPROTOCOLS}+fromParam PARAM_REGION_HOPTABLE = #{const TMR_PARAM_REGION_HOPTABLE}+fromParam PARAM_REGION_HOPTIME = #{const TMR_PARAM_REGION_HOPTIME}+fromParam PARAM_REGION_ID = #{const TMR_PARAM_REGION_ID}+fromParam PARAM_REGION_SUPPORTEDREGIONS = #{const TMR_PARAM_REGION_SUPPORTEDREGIONS}+fromParam PARAM_REGION_LBT_ENABLE = #{const TMR_PARAM_REGION_LBT_ENABLE}+fromParam PARAM_LICENSE_KEY = #{const TMR_PARAM_LICENSE_KEY}+fromParam PARAM_USER_CONFIG = #{const TMR_PARAM_USER_CONFIG}+fromParam PARAM_RADIO_ENABLESJC = #{const TMR_PARAM_RADIO_ENABLESJC}+fromParam PARAM_EXTENDEDEPC = #{const TMR_PARAM_EXTENDEDEPC}+fromParam PARAM_READER_STATISTICS = #{const TMR_PARAM_READER_STATISTICS}+fromParam PARAM_READER_STATS = #{const TMR_PARAM_READER_STATS}+fromParam PARAM_URI = #{const TMR_PARAM_URI}+fromParam PARAM_PRODUCT_GROUP_ID = #{const TMR_PARAM_PRODUCT_GROUP_ID}+fromParam PARAM_PRODUCT_GROUP = #{const TMR_PARAM_PRODUCT_GROUP}+fromParam PARAM_PRODUCT_ID = #{const TMR_PARAM_PRODUCT_ID}+fromParam PARAM_TAGREADATA_TAGOPSUCCESSCOUNT = #{const TMR_PARAM_TAGREADATA_TAGOPSUCCESSCOUNT}+fromParam PARAM_TAGREADATA_TAGOPFAILURECOUNT = #{const TMR_PARAM_TAGREADATA_TAGOPFAILURECOUNT}+fromParam PARAM_STATUS_ENABLE_ANTENNAREPORT = #{const TMR_PARAM_STATUS_ENABLE_ANTENNAREPORT}+fromParam PARAM_STATUS_ENABLE_FREQUENCYREPORT = #{const TMR_PARAM_STATUS_ENABLE_FREQUENCYREPORT}+fromParam PARAM_STATUS_ENABLE_TEMPERATUREREPORT = #{const TMR_PARAM_STATUS_ENABLE_TEMPERATUREREPORT}+fromParam PARAM_TAGREADDATA_ENABLEREADFILTER = #{const TMR_PARAM_TAGREADDATA_ENABLEREADFILTER}+fromParam PARAM_TAGREADDATA_READFILTERTIMEOUT = #{const TMR_PARAM_TAGREADDATA_READFILTERTIMEOUT}+fromParam PARAM_TAGREADDATA_UNIQUEBYPROTOCOL = #{const TMR_PARAM_TAGREADDATA_UNIQUEBYPROTOCOL}+fromParam PARAM_READER_DESCRIPTION = #{const TMR_PARAM_READER_DESCRIPTION}+fromParam PARAM_READER_HOSTNAME = #{const TMR_PARAM_READER_HOSTNAME}+fromParam PARAM_CURRENTTIME = #{const TMR_PARAM_CURRENTTIME}+fromParam PARAM_READER_WRITE_REPLY_TIMEOUT = #{const TMR_PARAM_READER_WRITE_REPLY_TIMEOUT}+fromParam PARAM_READER_WRITE_EARLY_EXIT = #{const TMR_PARAM_READER_WRITE_EARLY_EXIT}+fromParam PARAM_READER_STATS_ENABLE = #{const TMR_PARAM_READER_STATS_ENABLE}+fromParam PARAM_TRIGGER_READ_GPI = #{const TMR_PARAM_TRIGGER_READ_GPI}+fromParam PARAM_METADATAFLAG = #{const TMR_PARAM_METADATAFLAG}+fromParam PARAM_LICENSED_FEATURES = #{const TMR_PARAM_LICENSED_FEATURES}+fromParam PARAM_SELECTED_PROTOCOLS = #{const TMR_PARAM_SELECTED_PROTOCOLS}++paramMax :: RawParam+paramMax = #{const TMR_PARAM_MAX}++-- | For parameters which are expressed in physical units,+-- returns a string describing the units. Returns 'Nothing'+-- for parameters which are not expressed in physical units.+-- This can be useful for displaying in a user interface,+-- for example.+paramUnits :: Param -> Maybe Text+paramUnits PARAM_COMMANDTIMEOUT = Just "milliseconds"+paramUnits PARAM_TRANSPORTTIMEOUT = Just "milliseconds"+paramUnits PARAM_GEN2_BLF = Just "kHz"+paramUnits PARAM_READ_ASYNCOFFTIME = Just "milliseconds"+paramUnits PARAM_READ_ASYNCONTIME = Just "milliseconds"+paramUnits PARAM_RADIO_POWERMAX = Just "centi-dBm"+paramUnits PARAM_RADIO_POWERMIN = Just "centi-dBm"+paramUnits PARAM_RADIO_PORTREADPOWERLIST = Just "centi-dBm"+paramUnits PARAM_RADIO_PORTWRITEPOWERLIST = Just "centi-dBm"+paramUnits PARAM_RADIO_READPOWER = Just "centi-dBm"+paramUnits PARAM_RADIO_WRITEPOWER = Just "centi-dBm"+paramUnits PARAM_RADIO_TEMPERATURE = Just "degrees C"+paramUnits PARAM_REGION_HOPTABLE = Just "kHz"+paramUnits PARAM_REGION_HOPTIME = Just "milliseconds"+paramUnits PARAM_READER_WRITE_REPLY_TIMEOUT = Just "microseconds"+paramUnits _ = Nothing++-- | The Haskell data type expected for a particular parameter.+data ParamType =+ ParamTypeBool+ | ParamTypeGEN2_WriteMode+ | ParamTypeInt16+ | ParamTypeInt32+ | ParamTypeInt8+ | ParamTypeMetadataFlagList+ | ParamTypePowerMode+ | ParamTypeReadPlan+ | ParamTypeRegion+ | ParamTypeRegionList+ | ParamTypeTagProtocol+ | ParamTypeTagProtocolList+ | ParamTypeText+ | ParamTypeWord16+ | ParamTypeWord32+ | ParamTypeWord32List+ | ParamTypeWord8+ | ParamTypeWord8List+ | ParamTypeUnimplemented+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++-- | Indicates the type expected for a given parameter.+paramType :: Param -> ParamType+paramType PARAM_BAUDRATE = ParamTypeWord32+paramType PARAM_PROBEBAUDRATES = ParamTypeWord32List+paramType PARAM_COMMANDTIMEOUT = ParamTypeWord32+paramType PARAM_TRANSPORTTIMEOUT = ParamTypeWord32+paramType PARAM_POWERMODE = ParamTypePowerMode+paramType PARAM_ANTENNA_CHECKPORT = ParamTypeBool+paramType PARAM_ANTENNA_PORTLIST = ParamTypeWord8List+paramType PARAM_ANTENNA_CONNECTEDPORTLIST = ParamTypeWord8List+paramType PARAM_ANTENNA_PORTSWITCHGPOS = ParamTypeWord8List+paramType PARAM_GPIO_INPUTLIST = ParamTypeWord8List+paramType PARAM_GPIO_OUTPUTLIST = ParamTypeWord8List+paramType PARAM_GEN2_ACCESSPASSWORD = ParamTypeWord32+paramType PARAM_GEN2_WRITEMODE = ParamTypeGEN2_WriteMode+paramType PARAM_READ_ASYNCOFFTIME = ParamTypeWord32+paramType PARAM_READ_ASYNCONTIME = ParamTypeWord32+paramType PARAM_READ_PLAN = ParamTypeReadPlan+paramType PARAM_RADIO_ENABLEPOWERSAVE = ParamTypeBool+paramType PARAM_RADIO_POWERMAX = ParamTypeInt16+paramType PARAM_RADIO_POWERMIN = ParamTypeInt16+paramType PARAM_RADIO_READPOWER = ParamTypeInt32+paramType PARAM_RADIO_WRITEPOWER = ParamTypeInt32+paramType PARAM_RADIO_TEMPERATURE = ParamTypeInt8+paramType PARAM_TAGREADDATA_RECORDHIGHESTRSSI = ParamTypeBool+paramType PARAM_TAGREADDATA_REPORTRSSIINDBM = ParamTypeBool+paramType PARAM_TAGREADDATA_UNIQUEBYANTENNA = ParamTypeBool+paramType PARAM_TAGREADDATA_UNIQUEBYDATA = ParamTypeBool+paramType PARAM_TAGOP_ANTENNA = ParamTypeWord8+paramType PARAM_TAGOP_PROTOCOL = ParamTypeTagProtocol+paramType PARAM_VERSION_HARDWARE = ParamTypeText+paramType PARAM_VERSION_SERIAL = ParamTypeText+paramType PARAM_VERSION_MODEL = ParamTypeText+paramType PARAM_VERSION_SOFTWARE = ParamTypeText+paramType PARAM_VERSION_SUPPORTEDPROTOCOLS = ParamTypeTagProtocolList+paramType PARAM_REGION_HOPTABLE = ParamTypeWord32List+paramType PARAM_REGION_HOPTIME = ParamTypeWord32+paramType PARAM_REGION_ID = ParamTypeRegion+paramType PARAM_REGION_SUPPORTEDREGIONS = ParamTypeRegionList+paramType PARAM_REGION_LBT_ENABLE = ParamTypeBool+paramType PARAM_LICENSE_KEY = ParamTypeWord8List+paramType PARAM_RADIO_ENABLESJC = ParamTypeBool+paramType PARAM_EXTENDEDEPC = ParamTypeBool+paramType PARAM_URI = ParamTypeText+paramType PARAM_PRODUCT_GROUP_ID = ParamTypeWord16+paramType PARAM_PRODUCT_GROUP = ParamTypeText+paramType PARAM_PRODUCT_ID = ParamTypeWord16+paramType PARAM_TAGREADATA_TAGOPSUCCESSCOUNT = ParamTypeWord16+paramType PARAM_TAGREADATA_TAGOPFAILURECOUNT = ParamTypeWord16+paramType PARAM_STATUS_ENABLE_ANTENNAREPORT = ParamTypeBool+paramType PARAM_STATUS_ENABLE_FREQUENCYREPORT = ParamTypeBool+paramType PARAM_STATUS_ENABLE_TEMPERATUREREPORT = ParamTypeBool+paramType PARAM_TAGREADDATA_ENABLEREADFILTER = ParamTypeBool+paramType PARAM_TAGREADDATA_READFILTERTIMEOUT = ParamTypeInt32+paramType PARAM_TAGREADDATA_UNIQUEBYPROTOCOL = ParamTypeBool+paramType PARAM_READER_DESCRIPTION = ParamTypeText+paramType PARAM_READER_HOSTNAME = ParamTypeText+paramType PARAM_READER_WRITE_REPLY_TIMEOUT = ParamTypeWord16+paramType PARAM_READER_WRITE_EARLY_EXIT = ParamTypeBool+paramType PARAM_TRIGGER_READ_GPI = ParamTypeWord8List+paramType PARAM_METADATAFLAG = ParamTypeMetadataFlagList+paramType PARAM_LICENSED_FEATURES = ParamTypeWord8List+paramType _ = ParamTypeUnimplemented++-- | A textual representation of the Haskell type corresponding+-- to a particular 'ParamType'.+displayParamType :: ParamType -> Text+displayParamType ParamTypeBool = "Bool"+displayParamType ParamTypeGEN2_WriteMode = "GEN2_WriteMode"+displayParamType ParamTypeInt16 = "Int16"+displayParamType ParamTypeInt32 = "Int32"+displayParamType ParamTypeInt8 = "Int8"+displayParamType ParamTypePowerMode = "PowerMode"+displayParamType ParamTypeReadPlan = "ReadPlan"+displayParamType ParamTypeRegion = "Region"+displayParamType ParamTypeTagProtocol = "TagProtocol"+displayParamType ParamTypeText = "Text"+displayParamType ParamTypeWord16 = "Word16"+displayParamType ParamTypeWord32 = "Word32"+displayParamType ParamTypeWord8 = "Word8"+displayParamType ParamTypeMetadataFlagList = "[MetadataFlag]"+displayParamType ParamTypeRegionList = "[Region]"+displayParamType ParamTypeTagProtocolList = "[TagProtocol]"+displayParamType ParamTypeWord32List = "[Word32]"+displayParamType ParamTypeWord8List = "[Word8]"+displayParamType _ = "(Not yet implemented)"
+ src/System/Hardware/MercuryApi/ParamValue.hs view
@@ -0,0 +1,145 @@+{-# LANGUAGE OverloadedStrings, FlexibleInstances, DeriveDataTypeable #-}+module System.Hardware.MercuryApi.ParamValue where++import Control.Applicative ( (<$>) )+import Control.Exception ( bracketOnError )+import qualified Data.ByteString as B ( useAsCString, length )+import Data.Text (Text)+import Data.Word ( Word8, Word16, Word32 )+import Foreign+ ( Int8,+ Int16,+ Int32,+ Ptr,+ Storable(peek, poke),+ castPtr,+ with,+ toBool,+ new,+ fromBool,+ free,+ allocaBytes,+ alloca )++import System.Hardware.MercuryApi.Enums+import System.Hardware.MercuryApi.Records++-- | A class for types which can be used as parameter values.+class ParamValue a where+ pType :: a -> ParamType+ pGet :: (Ptr () -> IO ()) -> IO a+ pSet :: a -> (Ptr () -> IO ()) -> IO ()++instance ParamValue Bool where+ pType _ = ParamTypeBool+ pGet f = alloca $ \p -> f (castPtr (p :: Ptr CBool)) >> toBool <$> peek p+ pSet x f = alloca $ \p -> poke p (fromBool x :: CBool) >> f (castPtr p)++instance ParamValue GEN2_WriteMode where+ pType _ = ParamTypeGEN2_WriteMode+ pGet f = alloca $ \p -> f (castPtr p) >> toWriteMode <$> peek p+ pSet x f = alloca $ \p -> poke p (fromWriteMode x) >> f (castPtr p)++instance ParamValue Int16 where+ pType _ = ParamTypeInt16+ pGet f = alloca $ \p -> f (castPtr p) >> peek p+ pSet x f = alloca $ \p -> poke p x >> f (castPtr p)++instance ParamValue Int32 where+ pType _ = ParamTypeInt32+ pGet f = alloca $ \p -> f (castPtr p) >> peek p+ pSet x f = alloca $ \p -> poke p x >> f (castPtr p)++instance ParamValue Int8 where+ pType _ = ParamTypeInt8+ pGet f = alloca $ \p -> f (castPtr p) >> peek p+ pSet x f = alloca $ \p -> poke p x >> f (castPtr p)++instance ParamValue PowerMode where+ pType _ = ParamTypePowerMode+ pGet f = alloca $ \p -> f (castPtr p) >> toPowerMode <$> peek p+ pSet x f = alloca $ \p -> poke p (fromPowerMode x) >> f (castPtr p)++instance ParamValue ReadPlan where+ pType _ = ParamTypeReadPlan+ pGet f = alloca $ \p -> f (castPtr p) >> peek p+ -- Unlike all the other cases, in this case we transfer ownership+ -- to the C code, which will free it later.+ pSet x f = bracketOnError (new x) free (f . castPtr)++instance ParamValue Region where+ pType _ = ParamTypeRegion+ pGet f = alloca $ \p -> f (castPtr p) >> toRegion <$> peek p+ pSet x f = alloca $ \p -> poke p (fromRegion x) >> f (castPtr p)++instance ParamValue TagProtocol where+ pType _ = ParamTypeTagProtocol+ pGet f = alloca $ \p -> f (castPtr p) >> toTagProtocol <$> peek p+ pSet x f = alloca $ \p -> poke p (fromTagProtocol x) >> f (castPtr p)++instance ParamValue Text where+ pType _ = ParamTypeText++ pGet f = do+ let maxLen = maxBound :: Word16+ allocaBytes (fromIntegral maxLen) $ \storage -> do+ let lst = List16+ { l16_list = castPtr storage+ , l16_max = maxLen+ , l16_len = 0 -- unused for TMR_String+ }+ with lst $ \p -> do+ f (castPtr p)+ textFromCString storage++ pSet x f = do+ let bs = textToBS x+ B.useAsCString bs $ \cs -> do+ len' <- castLen "Text" (1 + B.length bs)+ let lst = List16+ { l16_list = castPtr cs+ , l16_max = len'+ , l16_len = 0 -- unused for TMR_String+ }+ with lst $ \p -> f (castPtr p)++instance ParamValue Word16 where+ pType _ = ParamTypeWord16+ pGet f = alloca $ \p -> f (castPtr p) >> peek p+ pSet x f = alloca $ \p -> poke p x >> f (castPtr p)++instance ParamValue Word32 where+ pType _ = ParamTypeWord32+ pGet f = alloca $ \p -> f (castPtr p) >> peek p+ pSet x f = alloca $ \p -> poke p x >> f (castPtr p)++instance ParamValue Word8 where+ pType _ = ParamTypeWord8+ pGet f = alloca $ \p -> f (castPtr p) >> peek p+ pSet x f = alloca $ \p -> poke p x >> f (castPtr p)++instance ParamValue [MetadataFlag] where+ pType _ = ParamTypeMetadataFlagList+ pGet f = alloca $ \p -> f (castPtr p) >> unpackFlags <$> peek p+ pSet x f = alloca $ \p -> poke p (packFlags x) >> f (castPtr p)++instance ParamValue [Region] where+ pType _ = ParamTypeRegionList+ pGet f = map toRegion <$> getList8 f+ pSet x f = setList8 "[Region]" (map fromRegion x) f++instance ParamValue [TagProtocol] where+ pType _ = ParamTypeTagProtocolList+ pGet f = map toTagProtocol <$> getList8 f+ pSet x f = setList8 "[TagProtocol]" (map fromTagProtocol x) f++instance ParamValue [Word32] where+ pType _ = ParamTypeWord32List+ pGet = getList16+ pSet = setList16 "[Word32]"++instance ParamValue [Word8] where+ pType _ = ParamTypeWord8List+ pGet = getList16+ pSet = setList16 "[Word8]"+
+ src/System/Hardware/MercuryApi/Params.hs view
@@ -0,0 +1,613 @@+-- Automatically generated by util/generate-tmr-hsc.pl+{-|+Module : System.Hardware.MercuryApi.Params+Description : Type-safe parameter access+Copyright : © Patrick Pelletier, 2017+License : MIT+Maintainer : code@funwithsoftware.org+Portability : POSIX, Windows++Individual functions to get and set parameters. These are+type-checked at compile time, unlike 'paramGet' and 'paramSet',+which are type-checked at runtime.+-}+module System.Hardware.MercuryApi.Params+ ( -- * Type-safe getters and setters+ -- ** \/reader+ paramGetBaudRate+ , paramSetBaudRate+ , paramGetCommandTimeout+ , paramSetCommandTimeout+ , paramGetDescription+ , paramSetDescription+ , paramGetExtendedEpc+ , paramSetExtendedEpc+ , paramGetHostname+ , paramSetHostname+ , paramGetLicenseKey+ , paramSetLicenseKey+ , paramGetLicensedFeatures+ , paramSetLicensedFeatures+ , paramGetMetadataflags+ , paramSetMetadataflags+ , paramGetPowerMode+ , paramSetPowerMode+ , paramGetProbeBaudRates+ , paramSetProbeBaudRates+ , paramGetTransportTimeout+ , paramSetTransportTimeout+ , paramGetUri+ -- ** \/reader\/antenna+ , paramGetAntennaCheckPort+ , paramSetAntennaCheckPort+ , paramGetAntennaConnectedPortList+ , paramGetAntennaPortList+ , paramGetAntennaPortSwitchGpos+ , paramSetAntennaPortSwitchGpos+ -- ** \/reader\/gen2+ , paramGetGen2AccessPassword+ , paramSetGen2AccessPassword+ , paramGetGen2WriteEarlyExit+ , paramSetGen2WriteEarlyExit+ , paramGetGen2WriteMode+ , paramSetGen2WriteMode+ , paramGetGen2WriteReplyTimeout+ , paramSetGen2WriteReplyTimeout+ -- ** \/reader\/gpio+ , paramGetGpioInputList+ , paramSetGpioInputList+ , paramGetGpioOutputList+ , paramSetGpioOutputList+ -- ** \/reader\/radio+ , paramGetRadioEnablePowerSave+ , paramSetRadioEnablePowerSave+ , paramGetRadioEnableSJC+ , paramSetRadioEnableSJC+ , paramGetRadioPowerMax+ , paramGetRadioPowerMin+ , paramGetRadioReadPower+ , paramSetRadioReadPower+ , paramGetRadioTemperature+ , paramGetRadioWritePower+ , paramSetRadioWritePower+ -- ** \/reader\/read+ , paramGetReadAsyncOffTime+ , paramSetReadAsyncOffTime+ , paramGetReadAsyncOnTime+ , paramSetReadAsyncOnTime+ , paramGetReadPlan+ , paramSetReadPlan+ -- ** \/reader\/region+ , paramGetRegionHopTable+ , paramSetRegionHopTable+ , paramGetRegionHopTime+ , paramSetRegionHopTime+ , paramGetRegionId+ , paramSetRegionId+ , paramGetRegionSupportedRegions+ -- ** \/reader\/region\/lbt+ , paramGetRegionLbtEnable+ , paramSetRegionLbtEnable+ -- ** \/reader\/status+ , paramGetStatusAntennaEnable+ , paramSetStatusAntennaEnable+ , paramGetStatusFrequencyEnable+ , paramSetStatusFrequencyEnable+ , paramGetStatusTemperatureEnable+ , paramSetStatusTemperatureEnable+ -- ** \/reader\/tagReadData+ , paramGetTagReadDataEnableReadFilter+ , paramSetTagReadDataEnableReadFilter+ , paramGetTagReadDataReadFilterTimeout+ , paramSetTagReadDataReadFilterTimeout+ , paramGetTagReadDataRecordHighestRssi+ , paramSetTagReadDataRecordHighestRssi+ , paramGetTagReadDataReportRssiInDbm+ , paramSetTagReadDataReportRssiInDbm+ , paramGetTagReadDataTagopFailures+ , paramGetTagReadDataTagopSuccesses+ , paramGetTagReadDataUniqueByAntenna+ , paramSetTagReadDataUniqueByAntenna+ , paramGetTagReadDataUniqueByData+ , paramSetTagReadDataUniqueByData+ , paramGetTagReadDataUniqueByProtocol+ , paramSetTagReadDataUniqueByProtocol+ -- ** \/reader\/tagop+ , paramGetTagopAntenna+ , paramSetTagopAntenna+ , paramGetTagopProtocol+ , paramSetTagopProtocol+ -- ** \/reader\/trigger\/read+ , paramGetTriggerReadGpi+ , paramSetTriggerReadGpi+ -- ** \/reader\/version+ , paramGetVersionHardware+ , paramGetVersionModel+ , paramGetVersionProductGroup+ , paramGetVersionProductGroupID+ , paramGetVersionProductID+ , paramGetVersionSerial+ , paramSetVersionSerial+ , paramGetVersionSoftware+ , paramGetVersionSupportedProtocols+ -- * As strings+ , paramGetString+ , paramSetString+ ) where++import Control.Applicative ( (<$>) )+import Data.Int ( Int8, Int16, Int32 )+import Data.Text (Text)+import qualified Data.Text as T ( unpack, pack )+import Data.Word ( Word8, Word16, Word32 )++import System.Hardware.MercuryApi hiding (read)++-- | Set parameter 'PARAM_BAUDRATE' (@\/reader\/baudRate@)+paramSetBaudRate :: Reader -> Word32 -> IO ()+paramSetBaudRate rdr = paramSet rdr PARAM_BAUDRATE++-- | Get parameter 'PARAM_BAUDRATE' (@\/reader\/baudRate@)+paramGetBaudRate :: Reader -> IO Word32+paramGetBaudRate rdr = paramGet rdr PARAM_BAUDRATE++-- | Set parameter 'PARAM_PROBEBAUDRATES' (@\/reader\/probeBaudRates@)+paramSetProbeBaudRates :: Reader -> [Word32] -> IO ()+paramSetProbeBaudRates rdr = paramSet rdr PARAM_PROBEBAUDRATES++-- | Get parameter 'PARAM_PROBEBAUDRATES' (@\/reader\/probeBaudRates@)+paramGetProbeBaudRates :: Reader -> IO [Word32]+paramGetProbeBaudRates rdr = paramGet rdr PARAM_PROBEBAUDRATES++-- | Set parameter 'PARAM_COMMANDTIMEOUT' (@\/reader\/commandTimeout@) (milliseconds)+paramSetCommandTimeout :: Reader -> Word32 -> IO ()+paramSetCommandTimeout rdr = paramSet rdr PARAM_COMMANDTIMEOUT++-- | Get parameter 'PARAM_COMMANDTIMEOUT' (@\/reader\/commandTimeout@) (milliseconds)+paramGetCommandTimeout :: Reader -> IO Word32+paramGetCommandTimeout rdr = paramGet rdr PARAM_COMMANDTIMEOUT++-- | Set parameter 'PARAM_TRANSPORTTIMEOUT' (@\/reader\/transportTimeout@) (milliseconds)+paramSetTransportTimeout :: Reader -> Word32 -> IO ()+paramSetTransportTimeout rdr = paramSet rdr PARAM_TRANSPORTTIMEOUT++-- | Get parameter 'PARAM_TRANSPORTTIMEOUT' (@\/reader\/transportTimeout@) (milliseconds)+paramGetTransportTimeout :: Reader -> IO Word32+paramGetTransportTimeout rdr = paramGet rdr PARAM_TRANSPORTTIMEOUT++-- | Set parameter 'PARAM_POWERMODE' (@\/reader\/powerMode@)+paramSetPowerMode :: Reader -> PowerMode -> IO ()+paramSetPowerMode rdr = paramSet rdr PARAM_POWERMODE++-- | Get parameter 'PARAM_POWERMODE' (@\/reader\/powerMode@)+paramGetPowerMode :: Reader -> IO PowerMode+paramGetPowerMode rdr = paramGet rdr PARAM_POWERMODE++-- | Set parameter 'PARAM_ANTENNA_CHECKPORT' (@\/reader\/antenna\/checkPort@)+paramSetAntennaCheckPort :: Reader -> Bool -> IO ()+paramSetAntennaCheckPort rdr = paramSet rdr PARAM_ANTENNA_CHECKPORT++-- | Get parameter 'PARAM_ANTENNA_CHECKPORT' (@\/reader\/antenna\/checkPort@)+paramGetAntennaCheckPort :: Reader -> IO Bool+paramGetAntennaCheckPort rdr = paramGet rdr PARAM_ANTENNA_CHECKPORT++-- | Get parameter 'PARAM_ANTENNA_PORTLIST' (@\/reader\/antenna\/portList@)+paramGetAntennaPortList :: Reader -> IO [AntennaPort]+paramGetAntennaPortList rdr = paramGet rdr PARAM_ANTENNA_PORTLIST++-- | Get parameter 'PARAM_ANTENNA_CONNECTEDPORTLIST' (@\/reader\/antenna\/connectedPortList@)+paramGetAntennaConnectedPortList :: Reader -> IO [AntennaPort]+paramGetAntennaConnectedPortList rdr = paramGet rdr PARAM_ANTENNA_CONNECTEDPORTLIST++-- | Set parameter 'PARAM_ANTENNA_PORTSWITCHGPOS' (@\/reader\/antenna\/portSwitchGpos@)+paramSetAntennaPortSwitchGpos :: Reader -> [PinNumber] -> IO ()+paramSetAntennaPortSwitchGpos rdr = paramSet rdr PARAM_ANTENNA_PORTSWITCHGPOS++-- | Get parameter 'PARAM_ANTENNA_PORTSWITCHGPOS' (@\/reader\/antenna\/portSwitchGpos@)+paramGetAntennaPortSwitchGpos :: Reader -> IO [PinNumber]+paramGetAntennaPortSwitchGpos rdr = paramGet rdr PARAM_ANTENNA_PORTSWITCHGPOS++-- | Set parameter 'PARAM_GPIO_INPUTLIST' (@\/reader\/gpio\/inputList@)+paramSetGpioInputList :: Reader -> [PinNumber] -> IO ()+paramSetGpioInputList rdr = paramSet rdr PARAM_GPIO_INPUTLIST++-- | Get parameter 'PARAM_GPIO_INPUTLIST' (@\/reader\/gpio\/inputList@)+paramGetGpioInputList :: Reader -> IO [PinNumber]+paramGetGpioInputList rdr = paramGet rdr PARAM_GPIO_INPUTLIST++-- | Set parameter 'PARAM_GPIO_OUTPUTLIST' (@\/reader\/gpio\/outputList@)+paramSetGpioOutputList :: Reader -> [PinNumber] -> IO ()+paramSetGpioOutputList rdr = paramSet rdr PARAM_GPIO_OUTPUTLIST++-- | Get parameter 'PARAM_GPIO_OUTPUTLIST' (@\/reader\/gpio\/outputList@)+paramGetGpioOutputList :: Reader -> IO [PinNumber]+paramGetGpioOutputList rdr = paramGet rdr PARAM_GPIO_OUTPUTLIST++-- | Set parameter 'PARAM_GEN2_ACCESSPASSWORD' (@\/reader\/gen2\/accessPassword@)+paramSetGen2AccessPassword :: Reader -> GEN2_Password -> IO ()+paramSetGen2AccessPassword rdr = paramSet rdr PARAM_GEN2_ACCESSPASSWORD++-- | Get parameter 'PARAM_GEN2_ACCESSPASSWORD' (@\/reader\/gen2\/accessPassword@)+paramGetGen2AccessPassword :: Reader -> IO GEN2_Password+paramGetGen2AccessPassword rdr = paramGet rdr PARAM_GEN2_ACCESSPASSWORD++-- | Set parameter 'PARAM_GEN2_WRITEMODE' (@\/reader\/gen2\/writeMode@)+paramSetGen2WriteMode :: Reader -> GEN2_WriteMode -> IO ()+paramSetGen2WriteMode rdr = paramSet rdr PARAM_GEN2_WRITEMODE++-- | Get parameter 'PARAM_GEN2_WRITEMODE' (@\/reader\/gen2\/writeMode@)+paramGetGen2WriteMode :: Reader -> IO GEN2_WriteMode+paramGetGen2WriteMode rdr = paramGet rdr PARAM_GEN2_WRITEMODE++-- | Set parameter 'PARAM_READ_ASYNCOFFTIME' (@\/reader\/read\/asyncOffTime@) (milliseconds)+paramSetReadAsyncOffTime :: Reader -> Word32 -> IO ()+paramSetReadAsyncOffTime rdr = paramSet rdr PARAM_READ_ASYNCOFFTIME++-- | Get parameter 'PARAM_READ_ASYNCOFFTIME' (@\/reader\/read\/asyncOffTime@) (milliseconds)+paramGetReadAsyncOffTime :: Reader -> IO Word32+paramGetReadAsyncOffTime rdr = paramGet rdr PARAM_READ_ASYNCOFFTIME++-- | Set parameter 'PARAM_READ_ASYNCONTIME' (@\/reader\/read\/asyncOnTime@) (milliseconds)+paramSetReadAsyncOnTime :: Reader -> Word32 -> IO ()+paramSetReadAsyncOnTime rdr = paramSet rdr PARAM_READ_ASYNCONTIME++-- | Get parameter 'PARAM_READ_ASYNCONTIME' (@\/reader\/read\/asyncOnTime@) (milliseconds)+paramGetReadAsyncOnTime :: Reader -> IO Word32+paramGetReadAsyncOnTime rdr = paramGet rdr PARAM_READ_ASYNCONTIME++-- | Set parameter 'PARAM_READ_PLAN' (@\/reader\/read\/plan@)+paramSetReadPlan :: Reader -> ReadPlan -> IO ()+paramSetReadPlan rdr = paramSet rdr PARAM_READ_PLAN++-- | Get parameter 'PARAM_READ_PLAN' (@\/reader\/read\/plan@)+paramGetReadPlan :: Reader -> IO ReadPlan+paramGetReadPlan rdr = paramGet rdr PARAM_READ_PLAN++-- | Set parameter 'PARAM_RADIO_ENABLEPOWERSAVE' (@\/reader\/radio\/enablePowerSave@)+paramSetRadioEnablePowerSave :: Reader -> Bool -> IO ()+paramSetRadioEnablePowerSave rdr = paramSet rdr PARAM_RADIO_ENABLEPOWERSAVE++-- | Get parameter 'PARAM_RADIO_ENABLEPOWERSAVE' (@\/reader\/radio\/enablePowerSave@)+paramGetRadioEnablePowerSave :: Reader -> IO Bool+paramGetRadioEnablePowerSave rdr = paramGet rdr PARAM_RADIO_ENABLEPOWERSAVE++-- | Get parameter 'PARAM_RADIO_POWERMAX' (@\/reader\/radio\/powerMax@) (centi-dBm)+paramGetRadioPowerMax :: Reader -> IO Int16+paramGetRadioPowerMax rdr = paramGet rdr PARAM_RADIO_POWERMAX++-- | Get parameter 'PARAM_RADIO_POWERMIN' (@\/reader\/radio\/powerMin@) (centi-dBm)+paramGetRadioPowerMin :: Reader -> IO Int16+paramGetRadioPowerMin rdr = paramGet rdr PARAM_RADIO_POWERMIN++-- | Set parameter 'PARAM_RADIO_READPOWER' (@\/reader\/radio\/readPower@) (centi-dBm)+paramSetRadioReadPower :: Reader -> Int32 -> IO ()+paramSetRadioReadPower rdr = paramSet rdr PARAM_RADIO_READPOWER++-- | Get parameter 'PARAM_RADIO_READPOWER' (@\/reader\/radio\/readPower@) (centi-dBm)+paramGetRadioReadPower :: Reader -> IO Int32+paramGetRadioReadPower rdr = paramGet rdr PARAM_RADIO_READPOWER++-- | Set parameter 'PARAM_RADIO_WRITEPOWER' (@\/reader\/radio\/writePower@) (centi-dBm)+paramSetRadioWritePower :: Reader -> Int32 -> IO ()+paramSetRadioWritePower rdr = paramSet rdr PARAM_RADIO_WRITEPOWER++-- | Get parameter 'PARAM_RADIO_WRITEPOWER' (@\/reader\/radio\/writePower@) (centi-dBm)+paramGetRadioWritePower :: Reader -> IO Int32+paramGetRadioWritePower rdr = paramGet rdr PARAM_RADIO_WRITEPOWER++-- | Get parameter 'PARAM_RADIO_TEMPERATURE' (@\/reader\/radio\/temperature@) (degrees C)+paramGetRadioTemperature :: Reader -> IO Int8+paramGetRadioTemperature rdr = paramGet rdr PARAM_RADIO_TEMPERATURE++-- | Set parameter 'PARAM_TAGREADDATA_RECORDHIGHESTRSSI' (@\/reader\/tagReadData\/recordHighestRssi@)+paramSetTagReadDataRecordHighestRssi :: Reader -> Bool -> IO ()+paramSetTagReadDataRecordHighestRssi rdr = paramSet rdr PARAM_TAGREADDATA_RECORDHIGHESTRSSI++-- | Get parameter 'PARAM_TAGREADDATA_RECORDHIGHESTRSSI' (@\/reader\/tagReadData\/recordHighestRssi@)+paramGetTagReadDataRecordHighestRssi :: Reader -> IO Bool+paramGetTagReadDataRecordHighestRssi rdr = paramGet rdr PARAM_TAGREADDATA_RECORDHIGHESTRSSI++-- | Set parameter 'PARAM_TAGREADDATA_REPORTRSSIINDBM' (@\/reader\/tagReadData\/reportRssiInDbm@)+paramSetTagReadDataReportRssiInDbm :: Reader -> Bool -> IO ()+paramSetTagReadDataReportRssiInDbm rdr = paramSet rdr PARAM_TAGREADDATA_REPORTRSSIINDBM++-- | Get parameter 'PARAM_TAGREADDATA_REPORTRSSIINDBM' (@\/reader\/tagReadData\/reportRssiInDbm@)+paramGetTagReadDataReportRssiInDbm :: Reader -> IO Bool+paramGetTagReadDataReportRssiInDbm rdr = paramGet rdr PARAM_TAGREADDATA_REPORTRSSIINDBM++-- | Set parameter 'PARAM_TAGREADDATA_UNIQUEBYANTENNA' (@\/reader\/tagReadData\/uniqueByAntenna@)+paramSetTagReadDataUniqueByAntenna :: Reader -> Bool -> IO ()+paramSetTagReadDataUniqueByAntenna rdr = paramSet rdr PARAM_TAGREADDATA_UNIQUEBYANTENNA++-- | Get parameter 'PARAM_TAGREADDATA_UNIQUEBYANTENNA' (@\/reader\/tagReadData\/uniqueByAntenna@)+paramGetTagReadDataUniqueByAntenna :: Reader -> IO Bool+paramGetTagReadDataUniqueByAntenna rdr = paramGet rdr PARAM_TAGREADDATA_UNIQUEBYANTENNA++-- | Set parameter 'PARAM_TAGREADDATA_UNIQUEBYDATA' (@\/reader\/tagReadData\/uniqueByData@)+paramSetTagReadDataUniqueByData :: Reader -> Bool -> IO ()+paramSetTagReadDataUniqueByData rdr = paramSet rdr PARAM_TAGREADDATA_UNIQUEBYDATA++-- | Get parameter 'PARAM_TAGREADDATA_UNIQUEBYDATA' (@\/reader\/tagReadData\/uniqueByData@)+paramGetTagReadDataUniqueByData :: Reader -> IO Bool+paramGetTagReadDataUniqueByData rdr = paramGet rdr PARAM_TAGREADDATA_UNIQUEBYDATA++-- | Set parameter 'PARAM_TAGOP_ANTENNA' (@\/reader\/tagop\/antenna@)+paramSetTagopAntenna :: Reader -> AntennaPort -> IO ()+paramSetTagopAntenna rdr = paramSet rdr PARAM_TAGOP_ANTENNA++-- | Get parameter 'PARAM_TAGOP_ANTENNA' (@\/reader\/tagop\/antenna@)+paramGetTagopAntenna :: Reader -> IO AntennaPort+paramGetTagopAntenna rdr = paramGet rdr PARAM_TAGOP_ANTENNA++-- | Set parameter 'PARAM_TAGOP_PROTOCOL' (@\/reader\/tagop\/protocol@)+paramSetTagopProtocol :: Reader -> TagProtocol -> IO ()+paramSetTagopProtocol rdr = paramSet rdr PARAM_TAGOP_PROTOCOL++-- | Get parameter 'PARAM_TAGOP_PROTOCOL' (@\/reader\/tagop\/protocol@)+paramGetTagopProtocol :: Reader -> IO TagProtocol+paramGetTagopProtocol rdr = paramGet rdr PARAM_TAGOP_PROTOCOL++-- | Get parameter 'PARAM_VERSION_HARDWARE' (@\/reader\/version\/hardware@)+paramGetVersionHardware :: Reader -> IO Text+paramGetVersionHardware rdr = paramGet rdr PARAM_VERSION_HARDWARE++-- | Set parameter 'PARAM_VERSION_SERIAL' (@\/reader\/version\/serial@)+paramSetVersionSerial :: Reader -> Text -> IO ()+paramSetVersionSerial rdr = paramSet rdr PARAM_VERSION_SERIAL++-- | Get parameter 'PARAM_VERSION_SERIAL' (@\/reader\/version\/serial@)+paramGetVersionSerial :: Reader -> IO Text+paramGetVersionSerial rdr = paramGet rdr PARAM_VERSION_SERIAL++-- | Get parameter 'PARAM_VERSION_MODEL' (@\/reader\/version\/model@)+paramGetVersionModel :: Reader -> IO Text+paramGetVersionModel rdr = paramGet rdr PARAM_VERSION_MODEL++-- | Get parameter 'PARAM_VERSION_SOFTWARE' (@\/reader\/version\/software@)+paramGetVersionSoftware :: Reader -> IO Text+paramGetVersionSoftware rdr = paramGet rdr PARAM_VERSION_SOFTWARE++-- | Get parameter 'PARAM_VERSION_SUPPORTEDPROTOCOLS' (@\/reader\/version\/supportedProtocols@)+paramGetVersionSupportedProtocols :: Reader -> IO [TagProtocol]+paramGetVersionSupportedProtocols rdr = paramGet rdr PARAM_VERSION_SUPPORTEDPROTOCOLS++-- | Set parameter 'PARAM_REGION_HOPTABLE' (@\/reader\/region\/hopTable@) (kHz)+paramSetRegionHopTable :: Reader -> [Word32] -> IO ()+paramSetRegionHopTable rdr = paramSet rdr PARAM_REGION_HOPTABLE++-- | Get parameter 'PARAM_REGION_HOPTABLE' (@\/reader\/region\/hopTable@) (kHz)+paramGetRegionHopTable :: Reader -> IO [Word32]+paramGetRegionHopTable rdr = paramGet rdr PARAM_REGION_HOPTABLE++-- | Set parameter 'PARAM_REGION_HOPTIME' (@\/reader\/region\/hopTime@) (milliseconds)+paramSetRegionHopTime :: Reader -> Word32 -> IO ()+paramSetRegionHopTime rdr = paramSet rdr PARAM_REGION_HOPTIME++-- | Get parameter 'PARAM_REGION_HOPTIME' (@\/reader\/region\/hopTime@) (milliseconds)+paramGetRegionHopTime :: Reader -> IO Word32+paramGetRegionHopTime rdr = paramGet rdr PARAM_REGION_HOPTIME++-- | Set parameter 'PARAM_REGION_ID' (@\/reader\/region\/id@)+paramSetRegionId :: Reader -> Region -> IO ()+paramSetRegionId rdr = paramSet rdr PARAM_REGION_ID++-- | Get parameter 'PARAM_REGION_ID' (@\/reader\/region\/id@)+paramGetRegionId :: Reader -> IO Region+paramGetRegionId rdr = paramGet rdr PARAM_REGION_ID++-- | Get parameter 'PARAM_REGION_SUPPORTEDREGIONS' (@\/reader\/region\/supportedRegions@)+paramGetRegionSupportedRegions :: Reader -> IO [Region]+paramGetRegionSupportedRegions rdr = paramGet rdr PARAM_REGION_SUPPORTEDREGIONS++-- | Set parameter 'PARAM_REGION_LBT_ENABLE' (@\/reader\/region\/lbt\/enable@)+paramSetRegionLbtEnable :: Reader -> Bool -> IO ()+paramSetRegionLbtEnable rdr = paramSet rdr PARAM_REGION_LBT_ENABLE++-- | Get parameter 'PARAM_REGION_LBT_ENABLE' (@\/reader\/region\/lbt\/enable@)+paramGetRegionLbtEnable :: Reader -> IO Bool+paramGetRegionLbtEnable rdr = paramGet rdr PARAM_REGION_LBT_ENABLE++-- | Set parameter 'PARAM_LICENSE_KEY' (@\/reader\/licenseKey@)+paramSetLicenseKey :: Reader -> [Word8] -> IO ()+paramSetLicenseKey rdr = paramSet rdr PARAM_LICENSE_KEY++-- | Get parameter 'PARAM_LICENSE_KEY' (@\/reader\/licenseKey@)+paramGetLicenseKey :: Reader -> IO [Word8]+paramGetLicenseKey rdr = paramGet rdr PARAM_LICENSE_KEY++-- | Set parameter 'PARAM_RADIO_ENABLESJC' (@\/reader\/radio\/enableSJC@)+paramSetRadioEnableSJC :: Reader -> Bool -> IO ()+paramSetRadioEnableSJC rdr = paramSet rdr PARAM_RADIO_ENABLESJC++-- | Get parameter 'PARAM_RADIO_ENABLESJC' (@\/reader\/radio\/enableSJC@)+paramGetRadioEnableSJC :: Reader -> IO Bool+paramGetRadioEnableSJC rdr = paramGet rdr PARAM_RADIO_ENABLESJC++-- | Set parameter 'PARAM_EXTENDEDEPC' (@\/reader\/extendedEpc@)+paramSetExtendedEpc :: Reader -> Bool -> IO ()+paramSetExtendedEpc rdr = paramSet rdr PARAM_EXTENDEDEPC++-- | Get parameter 'PARAM_EXTENDEDEPC' (@\/reader\/extendedEpc@)+paramGetExtendedEpc :: Reader -> IO Bool+paramGetExtendedEpc rdr = paramGet rdr PARAM_EXTENDEDEPC++-- | Get parameter 'PARAM_URI' (@\/reader\/uri@)+paramGetUri :: Reader -> IO Text+paramGetUri rdr = paramGet rdr PARAM_URI++-- | Get parameter 'PARAM_PRODUCT_GROUP_ID' (@\/reader\/version\/productGroupID@)+paramGetVersionProductGroupID :: Reader -> IO Word16+paramGetVersionProductGroupID rdr = paramGet rdr PARAM_PRODUCT_GROUP_ID++-- | Get parameter 'PARAM_PRODUCT_GROUP' (@\/reader\/version\/productGroup@)+paramGetVersionProductGroup :: Reader -> IO Text+paramGetVersionProductGroup rdr = paramGet rdr PARAM_PRODUCT_GROUP++-- | Get parameter 'PARAM_PRODUCT_ID' (@\/reader\/version\/productID@)+paramGetVersionProductID :: Reader -> IO Word16+paramGetVersionProductID rdr = paramGet rdr PARAM_PRODUCT_ID++-- | Get parameter 'PARAM_TAGREADATA_TAGOPSUCCESSCOUNT' (@\/reader\/tagReadData\/tagopSuccesses@)+paramGetTagReadDataTagopSuccesses :: Reader -> IO Word16+paramGetTagReadDataTagopSuccesses rdr = paramGet rdr PARAM_TAGREADATA_TAGOPSUCCESSCOUNT++-- | Get parameter 'PARAM_TAGREADATA_TAGOPFAILURECOUNT' (@\/reader\/tagReadData\/tagopFailures@)+paramGetTagReadDataTagopFailures :: Reader -> IO Word16+paramGetTagReadDataTagopFailures rdr = paramGet rdr PARAM_TAGREADATA_TAGOPFAILURECOUNT++-- | Set parameter 'PARAM_STATUS_ENABLE_ANTENNAREPORT' (@\/reader\/status\/antennaEnable@)+paramSetStatusAntennaEnable :: Reader -> Bool -> IO ()+paramSetStatusAntennaEnable rdr = paramSet rdr PARAM_STATUS_ENABLE_ANTENNAREPORT++-- | Get parameter 'PARAM_STATUS_ENABLE_ANTENNAREPORT' (@\/reader\/status\/antennaEnable@)+paramGetStatusAntennaEnable :: Reader -> IO Bool+paramGetStatusAntennaEnable rdr = paramGet rdr PARAM_STATUS_ENABLE_ANTENNAREPORT++-- | Set parameter 'PARAM_STATUS_ENABLE_FREQUENCYREPORT' (@\/reader\/status\/frequencyEnable@)+paramSetStatusFrequencyEnable :: Reader -> Bool -> IO ()+paramSetStatusFrequencyEnable rdr = paramSet rdr PARAM_STATUS_ENABLE_FREQUENCYREPORT++-- | Get parameter 'PARAM_STATUS_ENABLE_FREQUENCYREPORT' (@\/reader\/status\/frequencyEnable@)+paramGetStatusFrequencyEnable :: Reader -> IO Bool+paramGetStatusFrequencyEnable rdr = paramGet rdr PARAM_STATUS_ENABLE_FREQUENCYREPORT++-- | Set parameter 'PARAM_STATUS_ENABLE_TEMPERATUREREPORT' (@\/reader\/status\/temperatureEnable@)+paramSetStatusTemperatureEnable :: Reader -> Bool -> IO ()+paramSetStatusTemperatureEnable rdr = paramSet rdr PARAM_STATUS_ENABLE_TEMPERATUREREPORT++-- | Get parameter 'PARAM_STATUS_ENABLE_TEMPERATUREREPORT' (@\/reader\/status\/temperatureEnable@)+paramGetStatusTemperatureEnable :: Reader -> IO Bool+paramGetStatusTemperatureEnable rdr = paramGet rdr PARAM_STATUS_ENABLE_TEMPERATUREREPORT++-- | Set parameter 'PARAM_TAGREADDATA_ENABLEREADFILTER' (@\/reader\/tagReadData\/enableReadFilter@)+paramSetTagReadDataEnableReadFilter :: Reader -> Bool -> IO ()+paramSetTagReadDataEnableReadFilter rdr = paramSet rdr PARAM_TAGREADDATA_ENABLEREADFILTER++-- | Get parameter 'PARAM_TAGREADDATA_ENABLEREADFILTER' (@\/reader\/tagReadData\/enableReadFilter@)+paramGetTagReadDataEnableReadFilter :: Reader -> IO Bool+paramGetTagReadDataEnableReadFilter rdr = paramGet rdr PARAM_TAGREADDATA_ENABLEREADFILTER++-- | Set parameter 'PARAM_TAGREADDATA_READFILTERTIMEOUT' (@\/reader\/tagReadData\/readFilterTimeout@)+paramSetTagReadDataReadFilterTimeout :: Reader -> Int32 -> IO ()+paramSetTagReadDataReadFilterTimeout rdr = paramSet rdr PARAM_TAGREADDATA_READFILTERTIMEOUT++-- | Get parameter 'PARAM_TAGREADDATA_READFILTERTIMEOUT' (@\/reader\/tagReadData\/readFilterTimeout@)+paramGetTagReadDataReadFilterTimeout :: Reader -> IO Int32+paramGetTagReadDataReadFilterTimeout rdr = paramGet rdr PARAM_TAGREADDATA_READFILTERTIMEOUT++-- | Set parameter 'PARAM_TAGREADDATA_UNIQUEBYPROTOCOL' (@\/reader\/tagReadData\/uniqueByProtocol@)+paramSetTagReadDataUniqueByProtocol :: Reader -> Bool -> IO ()+paramSetTagReadDataUniqueByProtocol rdr = paramSet rdr PARAM_TAGREADDATA_UNIQUEBYPROTOCOL++-- | Get parameter 'PARAM_TAGREADDATA_UNIQUEBYPROTOCOL' (@\/reader\/tagReadData\/uniqueByProtocol@)+paramGetTagReadDataUniqueByProtocol :: Reader -> IO Bool+paramGetTagReadDataUniqueByProtocol rdr = paramGet rdr PARAM_TAGREADDATA_UNIQUEBYPROTOCOL++-- | Set parameter 'PARAM_READER_DESCRIPTION' (@\/reader\/description@)+paramSetDescription :: Reader -> Text -> IO ()+paramSetDescription rdr = paramSet rdr PARAM_READER_DESCRIPTION++-- | Get parameter 'PARAM_READER_DESCRIPTION' (@\/reader\/description@)+paramGetDescription :: Reader -> IO Text+paramGetDescription rdr = paramGet rdr PARAM_READER_DESCRIPTION++-- | Set parameter 'PARAM_READER_HOSTNAME' (@\/reader\/hostname@)+paramSetHostname :: Reader -> Text -> IO ()+paramSetHostname rdr = paramSet rdr PARAM_READER_HOSTNAME++-- | Get parameter 'PARAM_READER_HOSTNAME' (@\/reader\/hostname@)+paramGetHostname :: Reader -> IO Text+paramGetHostname rdr = paramGet rdr PARAM_READER_HOSTNAME++-- | Set parameter 'PARAM_READER_WRITE_REPLY_TIMEOUT' (@\/reader\/gen2\/writeReplyTimeout@) (microseconds)+paramSetGen2WriteReplyTimeout :: Reader -> Word16 -> IO ()+paramSetGen2WriteReplyTimeout rdr = paramSet rdr PARAM_READER_WRITE_REPLY_TIMEOUT++-- | Get parameter 'PARAM_READER_WRITE_REPLY_TIMEOUT' (@\/reader\/gen2\/writeReplyTimeout@) (microseconds)+paramGetGen2WriteReplyTimeout :: Reader -> IO Word16+paramGetGen2WriteReplyTimeout rdr = paramGet rdr PARAM_READER_WRITE_REPLY_TIMEOUT++-- | Set parameter 'PARAM_READER_WRITE_EARLY_EXIT' (@\/reader\/gen2\/writeEarlyExit@)+paramSetGen2WriteEarlyExit :: Reader -> Bool -> IO ()+paramSetGen2WriteEarlyExit rdr = paramSet rdr PARAM_READER_WRITE_EARLY_EXIT++-- | Get parameter 'PARAM_READER_WRITE_EARLY_EXIT' (@\/reader\/gen2\/writeEarlyExit@)+paramGetGen2WriteEarlyExit :: Reader -> IO Bool+paramGetGen2WriteEarlyExit rdr = paramGet rdr PARAM_READER_WRITE_EARLY_EXIT++-- | Set parameter 'PARAM_TRIGGER_READ_GPI' (@\/reader\/trigger\/read\/Gpi@)+paramSetTriggerReadGpi :: Reader -> [PinNumber] -> IO ()+paramSetTriggerReadGpi rdr = paramSet rdr PARAM_TRIGGER_READ_GPI++-- | Get parameter 'PARAM_TRIGGER_READ_GPI' (@\/reader\/trigger\/read\/Gpi@)+paramGetTriggerReadGpi :: Reader -> IO [PinNumber]+paramGetTriggerReadGpi rdr = paramGet rdr PARAM_TRIGGER_READ_GPI++-- | Set parameter 'PARAM_METADATAFLAG' (@\/reader\/metadataflags@)+paramSetMetadataflags :: Reader -> [MetadataFlag] -> IO ()+paramSetMetadataflags rdr = paramSet rdr PARAM_METADATAFLAG++-- | Get parameter 'PARAM_METADATAFLAG' (@\/reader\/metadataflags@)+paramGetMetadataflags :: Reader -> IO [MetadataFlag]+paramGetMetadataflags rdr = paramGet rdr PARAM_METADATAFLAG++-- | Set parameter 'PARAM_LICENSED_FEATURES' (@\/reader\/licensedFeatures@)+paramSetLicensedFeatures :: Reader -> [Word8] -> IO ()+paramSetLicensedFeatures rdr = paramSet rdr PARAM_LICENSED_FEATURES++-- | Get parameter 'PARAM_LICENSED_FEATURES' (@\/reader\/licensedFeatures@)+paramGetLicensedFeatures :: Reader -> IO [Word8]+paramGetLicensedFeatures rdr = paramGet rdr PARAM_LICENSED_FEATURES++-- | Version of 'paramSet' which converts its argument from a+-- string to the proper type using 'read'.+paramSetString :: Reader -> Param -> Text -> IO ()+paramSetString rdr param txt = do+ let str = T.unpack txt+ case paramType param of+ ParamTypeBool -> paramSet rdr param (read str :: Bool)+ ParamTypeGEN2_WriteMode -> paramSet rdr param (read str :: GEN2_WriteMode)+ ParamTypeInt16 -> paramSet rdr param (read str :: Int16)+ ParamTypeInt32 -> paramSet rdr param (read str :: Int32)+ ParamTypeInt8 -> paramSet rdr param (read str :: Int8)+ ParamTypePowerMode -> paramSet rdr param (read str :: PowerMode)+ ParamTypeReadPlan -> paramSet rdr param (read str :: ReadPlan)+ ParamTypeRegion -> paramSet rdr param (read str :: Region)+ ParamTypeTagProtocol -> paramSet rdr param (read str :: TagProtocol)+ ParamTypeText -> paramSet rdr param (read str :: Text)+ ParamTypeWord16 -> paramSet rdr param (read str :: Word16)+ ParamTypeWord32 -> paramSet rdr param (read str :: Word32)+ ParamTypeWord8 -> paramSet rdr param (read str :: Word8)+ ParamTypeMetadataFlagList -> paramSet rdr param (read str :: [MetadataFlag])+ ParamTypeRegionList -> paramSet rdr param (read str :: [Region])+ ParamTypeTagProtocolList -> paramSet rdr param (read str :: [TagProtocol])+ ParamTypeWord32List -> paramSet rdr param (read str :: [Word32])+ ParamTypeWord8List -> paramSet rdr param (read str :: [Word8])+ _ -> paramSet rdr param (undefined :: Bool) -- force ERROR_UNIMPLEMENTED_PARAM++-- | Version of 'paramGet' which converts its result to a+-- string using 'show'.+paramGetString :: Reader -> Param -> IO Text+paramGetString rdr param =+ T.pack <$>+ case paramType param of+ ParamTypeBool -> show <$> (paramGet rdr param :: IO Bool)+ ParamTypeGEN2_WriteMode -> show <$> (paramGet rdr param :: IO GEN2_WriteMode)+ ParamTypeInt16 -> show <$> (paramGet rdr param :: IO Int16)+ ParamTypeInt32 -> show <$> (paramGet rdr param :: IO Int32)+ ParamTypeInt8 -> show <$> (paramGet rdr param :: IO Int8)+ ParamTypePowerMode -> show <$> (paramGet rdr param :: IO PowerMode)+ ParamTypeReadPlan -> show <$> (paramGet rdr param :: IO ReadPlan)+ ParamTypeRegion -> show <$> (paramGet rdr param :: IO Region)+ ParamTypeTagProtocol -> show <$> (paramGet rdr param :: IO TagProtocol)+ ParamTypeText -> show <$> (paramGet rdr param :: IO Text)+ ParamTypeWord16 -> show <$> (paramGet rdr param :: IO Word16)+ ParamTypeWord32 -> show <$> (paramGet rdr param :: IO Word32)+ ParamTypeWord8 -> show <$> (paramGet rdr param :: IO Word8)+ ParamTypeMetadataFlagList -> show <$> (paramGet rdr param :: IO [MetadataFlag])+ ParamTypeRegionList -> show <$> (paramGet rdr param :: IO [Region])+ ParamTypeTagProtocolList -> show <$> (paramGet rdr param :: IO [TagProtocol])+ ParamTypeWord32List -> show <$> (paramGet rdr param :: IO [Word32])+ ParamTypeWord8List -> show <$> (paramGet rdr param :: IO [Word8])+ _ -> show <$> (paramGet rdr param :: IO Bool) -- force ERROR_UNIMPLEMENTED_PARAM+
+ src/System/Hardware/MercuryApi/Records.hsc view
@@ -0,0 +1,828 @@+{-# LANGUAGE OverloadedStrings, FlexibleInstances, DeriveDataTypeable #-}+module System.Hardware.MercuryApi.Records where++import Control.Applicative ( Applicative((<*>)), (<$>) )+import Control.Exception ( Exception, throwIO )+import Data.ByteString (ByteString)+import qualified Data.ByteString as B+import Data.Maybe ( mapMaybe, fromMaybe )+import Data.Monoid ( (<>) )+import Data.Text (Text)+import qualified Data.Text as T ( pack )+import qualified Data.Text.Encoding as T+ ( encodeUtf8, decodeUtf8With )+import qualified Data.Text.Encoding.Error as T ( lenientDecode )+import Data.Typeable ( Typeable )+import Data.Word ( Word8, Word16, Word32, Word64 )+import Foreign+ ( Int32,+ Ptr,+ nullPtr,+ plusPtr,+ Storable(alignment, peek, peekByteOff, poke, pokeByteOff, sizeOf),+ Bits((.&.), (.|.), shiftL),+ castPtr,+ with,+ toBool,+ fromBool,+ withArrayLen,+ pokeArray,+ peekArray,+ copyArray,+ allocaArray )+import Foreign.C ( CString )++import System.Hardware.MercuryApi.Enums++#include <tm_reader.h>+#include <glue.h>+#include <stdbool.h>++-- | A GPIO pin number. On the M6e Nano, these are numbered 1-4.+type PinNumber = Word8++-- | An antenna number. On the+-- <https://www.sparkfun.com/products/14066 SparkFun Simultaneous RFID Reader>,+-- there is a single antenna with the number 1.+type AntennaPort = Word8++-- | A 32-bit password (access or kill) in the Gen2 protocol.+type GEN2_Password = Word32++-- | milliseconds since 1\/1\/1970 UTC+type MillisecondsSinceEpoch = Word64++-- | Version number of the Mercury API C library.+apiVersion :: Text+apiVersion = #{const_str TMR_VERSION}++type CBool = #{type bool}+newtype ReaderEtc = ReaderEtc ()++cFalse, cTrue :: CBool+cFalse = 0+cTrue = 1++toBool' :: CBool -> Bool+toBool' = toBool++fromBool' :: Bool -> CBool+fromBool' = fromBool++sizeofReaderEtc :: Int+sizeofReaderEtc = #{size ReaderEtc}++uriPtr :: Ptr ReaderEtc -> CString+uriPtr = #{ptr ReaderEtc, uri}++-- I'm not sure what encoding MercuryApi uses for its strings.+-- I'm guessing UTF-8 for now, but the encoding is encapsulated in+-- these two functions (textFromBS and textToBS) so it can be+-- easily changed.+textFromBS :: ByteString -> Text+textFromBS = T.decodeUtf8With T.lenientDecode++textToBS :: Text -> ByteString+textToBS = T.encodeUtf8++textFromCString :: CString -> IO Text+textFromCString cs = textFromBS <$> B.packCString cs++-- | Indicates whether to read or write the lock bits in+-- 'TagOp_GEN2_BlockPermaLock'.+data ReadWrite = Read !Int -- ^ number of words of lock bits to read+ | Write ![Word16] -- ^ lock bits to write+ deriving (Eq, Ord, Show, Read)++fromReadWrite :: ReadWrite -> (Word8, [Word16])+fromReadWrite (Read n) = (0, replicate n 0)+fromReadWrite (Write ws) = (1, ws)++toReadWrite :: (Word8, [Word16]) -> ReadWrite+toReadWrite (0, ws) = Read $ length ws+toReadWrite (1, ws) = Write ws+toReadWrite (x, _) = error $ "didn't expect ReadWrite to be " ++ show x++-- This exception is never seen by the user. It is caught+-- internally and turned into a MercuryException (with some added fields).+data ParamException = ParamException StatusType Status Text+ deriving (Eq, Ord, Show, Read, Typeable)++instance Exception ParamException++castLen' :: Integral a => a -> Text -> Int -> IO a+castLen' bound description x = do+ let tShow = T.pack . show+ maxLen = fromIntegral bound+ if x > maxLen+ then throwIO ( ParamException ERROR_TYPE_MISC ERROR_TOO_BIG $+ description <> " had length " <> tShow x <>+ " but maximum is " <> tShow maxLen )+ else return $ fromIntegral x++castLen :: (Integral a, Bounded a) => Text -> Int -> IO a+castLen = castLen' maxBound++-- | A ReadPlan record specifies the antennas, protocols, and filters+-- to use for a search (read).+--+-- Currently, only @SimpleReadPlan@ is supported.+data ReadPlan =+ SimpleReadPlan+ { rpWeight :: !Word32 -- ^ The relative weight of this read plan+ , rpEnableAutonomousRead :: !Bool -- ^ Option for Autonomous read+ , rpAntennas :: ![AntennaPort] -- ^ The list of antennas to read on+ , rpProtocol :: !TagProtocol -- ^ The protocol to use for reading+ , rpFilter :: !(Maybe TagFilter) -- ^ The filter to apply to reading+ , rpTagop :: !(Maybe TagOp) -- ^ The tag operation to apply to+ -- each read tag+ , rpUseFastSearch :: !Bool -- ^ Option to use the FastSearch+ , rpStopOnCount :: !(Maybe Word32) -- ^ Number of tags to be read+ , rpTriggerRead :: !(Maybe [Word8]) -- ^ The list of GPI ports which should+ -- be used to trigger the read+ } deriving (Eq, Ord, Show, Read)++antennasInfo :: Ptr ReadPlan -> (Ptr List16, Word16, Ptr Word8, Text)+antennasInfo rp =+ ( #{ptr ReadPlanEtc, plan.u.simple.antennas} rp+ , #{const GLUE_MAX_ANTENNAS}+ , #{ptr ReadPlanEtc, antennas} rp+ , "rpAntennas"+ )++gpiListInfo :: Ptr ReadPlan -> (Ptr List16, Word16, Ptr Word8, Text)+gpiListInfo rp =+ ( #{ptr ReadPlanEtc, plan.u.simple.triggerRead.gpiList} rp+ , #{const GLUE_MAX_GPIPORTS}+ , #{ptr ReadPlanEtc, gpiPorts} rp+ , "rpTriggerRead"+ )++readPlanTypeSimple :: #{type TMR_ReadPlanType}+readPlanTypeSimple = #{const TMR_READ_PLAN_TYPE_SIMPLE}++instance Storable ReadPlan where+ sizeOf _ = #{size ReadPlanEtc}+ alignment _ = 8++ poke p x = do+ #{poke ReadPlanEtc, plan.type} p readPlanTypeSimple+ #{poke ReadPlanEtc, plan.weight} p (rpWeight x)+ #{poke ReadPlanEtc, plan.enableAutonomousRead} p+ (fromBool' $ rpEnableAutonomousRead x)+ pokeList16 (antennasInfo p) (rpAntennas x)+ #{poke ReadPlanEtc, plan.u.simple.protocol} p+ (fromTagProtocol $ rpProtocol x)+ case rpFilter x of+ Nothing -> #{poke ReadPlanEtc, plan.u.simple.filter} p nullPtr+ Just f -> do+ #{poke ReadPlanEtc, filter} p f+ #{poke ReadPlanEtc, plan.u.simple.filter} p (#{ptr ReadPlanEtc, filter} p)+ case rpTagop x of+ Nothing -> #{poke ReadPlanEtc, plan.u.simple.tagop} p nullPtr+ Just op -> do+ #{poke ReadPlanEtc, tagop} p op+ #{poke ReadPlanEtc, plan.u.simple.tagop} p (#{ptr ReadPlanEtc, tagop} p)+ #{poke ReadPlanEtc, plan.u.simple.useFastSearch} p+ (fromBool' $ rpUseFastSearch x)+ let (stop, nTags) = case rpStopOnCount x of+ Nothing -> (cFalse, 0)+ Just n -> (cTrue, n)+ #{poke ReadPlanEtc, plan.u.simple.stopOnCount.stopNTriggerStatus} p stop+ #{poke ReadPlanEtc, plan.u.simple.stopOnCount.noOfTags} p nTags+ let (enable, ports) = case rpTriggerRead x of+ Nothing -> (cFalse, [])+ Just ps -> (cTrue, ps)+ #{poke ReadPlanEtc, plan.u.simple.triggerRead.enable} p enable+ pokeList16 (gpiListInfo p) ports++ peek p = do+ weight <- #{peek ReadPlanEtc, plan.weight} p+ enableAutonomousRead <- #{peek ReadPlanEtc, plan.enableAutonomousRead} p+ antennas <- peekList16 (antennasInfo p)+ protocol <- #{peek ReadPlanEtc, plan.u.simple.protocol} p+ fPtr <- #{peek ReadPlanEtc, plan.u.simple.filter} p+ filt <- if fPtr == nullPtr+ then return Nothing+ else Just <$> peek fPtr+ opPtr <- #{peek ReadPlanEtc, plan.u.simple.tagop} p+ op <- if opPtr == nullPtr+ then return Nothing+ else Just <$> peek opPtr+ useFastSearch <- #{peek ReadPlanEtc, plan.u.simple.useFastSearch} p+ stop <- #{peek ReadPlanEtc, plan.u.simple.stopOnCount.stopNTriggerStatus} p+ stopOnCount <- if toBool' stop+ then Just <$> #{peek ReadPlanEtc, plan.u.simple.stopOnCount.noOfTags} p+ else return Nothing+ enable <- #{peek ReadPlanEtc, plan.u.simple.triggerRead.enable} p+ triggerRead <- if toBool' enable+ then Just <$> peekList16 (gpiListInfo p)+ else return Nothing+ return $ SimpleReadPlan+ { rpWeight = weight+ , rpEnableAutonomousRead = toBool' enableAutonomousRead+ , rpAntennas = antennas+ , rpProtocol = toTagProtocol protocol+ , rpFilter = filt+ , rpTagop = op+ , rpUseFastSearch = toBool' useFastSearch+ , rpStopOnCount = stopOnCount+ , rpTriggerRead = triggerRead+ }++-- | Filter on EPC length, or on a Gen2 bank.+data FilterOn = FilterOnBank GEN2_Bank+ | FilterOnEpcLength+ deriving (Eq, Ord, Show, Read)++instance Storable FilterOn where+ sizeOf _ = #{size TMR_GEN2_Bank}+ alignment _ = 8++ poke p FilterOnEpcLength = do+ let p' = castPtr p :: Ptr RawBank+ poke p' #{const TMR_GEN2_EPC_LENGTH_FILTER}++ poke p (FilterOnBank bank) = do+ let p' = castPtr p :: Ptr RawBank+ poke p' (fromBank bank)++ peek p = do+ x <- peek (castPtr p)+ if x == #{const TMR_GEN2_EPC_LENGTH_FILTER}+ then return FilterOnEpcLength+ else return $ FilterOnBank $ toBank x++-- | Filter on EPC data, or on Gen2-specific information.+data TagFilter = TagFilterEPC TagData+ | TagFilterGen2+ { tfInvert :: !Bool -- ^ Whether to invert the+ -- selection (deselect tags+ -- that meet the comparison)+ , tfFilterOn :: !FilterOn -- ^ The memory bank in which+ -- to compare the mask+ , tfBitPointer :: !Word32 -- ^ The location (in bits) at+ -- which to begin comparing+ -- the mask+ , tfMaskBitLength :: !Word16 -- ^ The length (in bits) of+ -- the mask+ , tfMask :: !ByteString -- ^ The mask value to compare+ -- with the specified region+ -- of tag memory, MSB first+ }+ deriving (Eq, Ord, Show, Read)++instance Storable TagFilter where+ sizeOf _ = #{size TagFilterEtc}+ alignment _ = 8++ poke p (TagFilterEPC td) = do+ #{poke TagFilterEtc, filter.type} p+ (#{const TMR_FILTER_TYPE_TAG_DATA} :: #{type TMR_FilterType})+ #{poke TagFilterEtc, filter.u.tagData} p td++ poke p tf@(TagFilterGen2 {}) = do+ #{poke TagFilterEtc, filter.type} p+ (#{const TMR_FILTER_TYPE_GEN2_SELECT} :: #{type TMR_FilterType})+ #{poke TagFilterEtc, filter.u.gen2Select.invert} p (fromBool' $ tfInvert tf)+ #{poke TagFilterEtc, filter.u.gen2Select.bank} p (tfFilterOn tf)+ #{poke TagFilterEtc, filter.u.gen2Select.bitPointer} p (tfBitPointer tf)+ #{poke TagFilterEtc, filter.u.gen2Select.maskBitLength} p (tfMaskBitLength tf)+ let maskLenBytes = fromIntegral $ (tfMaskBitLength tf + 7) `div` 8+ origLen = B.length (tfMask tf)+ bs = if origLen < maskLenBytes+ then tfMask tf <> B.pack (replicate (maskLenBytes - origLen) 0)+ else tfMask tf+ B.useAsCStringLen bs $ \(cs, len) -> do+ len' <- castLen' #{const GLUE_MAX_MASK} "tfMask" len+ copyArray (#{ptr TagFilterEtc, mask} p) cs (fromIntegral len')+ #{poke TagFilterEtc, filter.u.gen2Select.mask} p (#{ptr TagFilterEtc, mask} p)++ peek p = do+ ft <- #{peek TagFilterEtc, filter.type} p :: IO #{type TMR_FilterType}+ case ft of+ #{const TMR_FILTER_TYPE_TAG_DATA} ->+ TagFilterEPC <$> #{peek TagFilterEtc, filter.u.tagData} p+ #{const TMR_FILTER_TYPE_GEN2_SELECT} ->+ TagFilterGen2+ <$> (toBool' <$> #{peek TagFilterEtc, filter.u.gen2Select.invert} p)+ <*> #{peek TagFilterEtc, filter.u.gen2Select.bank} p+ <*> #{peek TagFilterEtc, filter.u.gen2Select.bitPointer} p+ <*> #{peek TagFilterEtc, filter.u.gen2Select.maskBitLength} p+ <*> peekMask p++peekMask :: Ptr TagFilter -> IO ByteString+peekMask p = do+ bitLength <- #{peek TagFilterEtc, filter.u.gen2Select.maskBitLength} p :: IO Word32+ let len = fromIntegral $ (bitLength + 7) `div` 8+ maskPtr <- #{peek TagFilterEtc, filter.u.gen2Select.mask} p+ B.packCStringLen (maskPtr, len)++packBits :: Num b => (a -> b) -> [a] -> b+packBits from flags = sum $ map from flags++unpackBits :: (Bounded a, Enum a, Num b, Bits b) => (a -> b) -> b -> [a]+unpackBits from x = mapMaybe f [minBound..maxBound]+ where f flag = if (x .&. from flag) == 0+ then Nothing+ else Just flag++packFlags :: [MetadataFlag] -> RawMetadataFlag+packFlags = packBits fromMetadataFlag++unpackFlags :: RawMetadataFlag -> [MetadataFlag]+unpackFlags = unpackBits fromMetadataFlag++packFlags16 :: [MetadataFlag] -> Word16+packFlags16 = fromIntegral . packFlags++unpackFlags16 :: Word16 -> [MetadataFlag]+unpackFlags16 = unpackFlags . fromIntegral++packExtraBanks :: [GEN2_Bank] -> RawBank+packExtraBanks = packBits fromExtraBank++unpackExtraBanks :: RawBank -> [GEN2_Bank]+unpackExtraBanks = unpackBits fromExtraBank++packLockBits :: [GEN2_LockBits] -> RawLockBits+packLockBits = packBits fromLockBits++unpackLockBits :: RawLockBits -> [GEN2_LockBits]+unpackLockBits = unpackBits fromLockBits++packLockBits16 :: [GEN2_LockBits] -> Word16+packLockBits16 = fromIntegral . packLockBits++unpackLockBits16 :: Word16 -> [GEN2_LockBits]+unpackLockBits16 = unpackLockBits . fromIntegral++peekArrayAsByteString :: Ptr Word8 -> Ptr Word8 -> IO ByteString+peekArrayAsByteString arrayPtr lenPtr = do+ len <- peek lenPtr+ B.packCStringLen (castPtr arrayPtr, fromIntegral len)++pokeArrayAsByteString :: Text+ -> Word8+ -> Ptr Word8+ -> Ptr Word8+ -> ByteString+ -> IO ()+pokeArrayAsByteString desc maxLen arrayPtr lenPtr bs = do+ B.useAsCStringLen bs $ \(cs, len) -> do+ len' <- castLen' maxLen desc len+ copyArray arrayPtr (castPtr cs) (fromIntegral len')+ poke lenPtr len'++peekListAsByteString :: Ptr List16 -> IO ByteString+peekListAsByteString listPtr = do+ lst <- peek listPtr+ B.packCStringLen (castPtr $ l16_list lst, fromIntegral $ l16_len lst)++peekArrayAsList :: Storable a => Ptr a -> Ptr Word8 -> IO [a]+peekArrayAsList arrayPtr lenPtr = do+ len <- peek lenPtr+ peekArray (fromIntegral len) arrayPtr++peekListAsList :: Storable a => Ptr List16 -> Ptr a -> IO [a]+peekListAsList listPtr _ = do+ lst <- peek listPtr+ peekArray (fromIntegral $ l16_len lst) (castPtr $ l16_list lst)++pokeListAsList :: Storable a+ => Text+ -> Word16+ -> Ptr List16+ -> Ptr a+ -> [a]+ -> IO ()+pokeListAsList desc maxLen listPtr storage xs = do+ withArrayLen xs $ \len tmpPtr -> do+ len' <- castLen' maxLen desc len+ copyArray storage tmpPtr len+ let lst = List16+ { l16_list = castPtr storage+ , l16_max = maxLen+ , l16_len = len'+ }+ poke listPtr lst++peekMaybe :: (Storable a, Storable b)+ => (Ptr a -> IO a)+ -> (b -> Bool)+ -> Ptr a+ -> Ptr b+ -> IO (Maybe a)+peekMaybe oldPeek cond justP condP = do+ c <- peek condP+ if cond c+ then Just <$> oldPeek justP+ else return Nothing++pokeGen2TagData :: Ptr GEN2_TagData+ -> Ptr RawTagProtocol+ -> Maybe GEN2_TagData+ -> IO ()+pokeGen2TagData pGen2 _ mGen2 = do+ let gen2 = fromMaybe (GEN2_TagData B.empty) mGen2+ poke pGen2 gen2++peekSplit64 :: Ptr Word32 -> Ptr Word32 -> IO Word64+peekSplit64 pLow pHigh = do+ lo <- fromIntegral <$> peek pLow+ hi <- fromIntegral <$> peek pHigh+ return $ lo .|. (hi `shiftL` 32)++peekPtr :: Storable a => Ptr (Ptr a) -> Ptr a -> IO a+peekPtr pp _ = do+ p <- peek pp+ peek p++pokePtr :: Storable a => Ptr (Ptr a) -> Ptr a -> a -> IO ()+pokePtr pp p x = do+ poke p x+ poke pp p++pokeOr :: (Storable a, Bits a) => Ptr a -> a -> IO ()+pokeOr p x = do+ old <- peek p+ poke p (x .|. old)++data List16 =+ List16+ { l16_list :: !(Ptr ())+ , l16_max :: !(Word16)+ , l16_len :: !(Word16)+ }++instance Storable List16 where+ sizeOf _ = #{size List16}+ alignment _ = 8+ peek p = List16+ <$> #{peek List16, list} p+ <*> #{peek List16, max} p+ <*> #{peek List16, len} p+ poke p x = do+ #{poke List16, list} p (l16_list x)+ #{poke List16, max} p (l16_max x)+ #{poke List16, len} p (l16_len x)++getList16 :: Storable a => (Ptr () -> IO ()) -> IO [a]+getList16 f = do+ let maxLen = maxBound :: Word16+ allocaArray (fromIntegral maxLen) $ \storage -> do+ let lst = List16+ { l16_list = castPtr storage+ , l16_max = maxLen+ , l16_len = 0+ }+ with lst $ \p -> do+ f (castPtr p)+ lst' <- peek p+ peekArray (fromIntegral (l16_len lst')) storage++setList16 :: Storable a => Text -> [a] -> (Ptr () -> IO ()) -> IO ()+setList16 t x f = do+ withArrayLen x $ \len storage -> do+ len' <- castLen t len+ let lst = List16+ { l16_list = castPtr storage+ , l16_max = len'+ , l16_len = len'+ }+ with lst $ \p -> f (castPtr p)++pokeList16 :: Storable a => (Ptr List16, Word16, Ptr a, Text) -> [a] -> IO ()+pokeList16 (lp, maxLen, storage, name) ws = do+ len <- castLen' maxLen name (length ws)+ poke lp $ List16+ { l16_list = castPtr storage+ , l16_max = maxLen+ , l16_len = len+ }+ pokeArray storage ws++peekList16 :: Storable a => (Ptr List16, Word16, Ptr a, Text) -> IO [a]+peekList16 (lp, _, _, _) = do+ lst <- peek lp+ peekArray (fromIntegral $ l16_len lst) (castPtr $ l16_list lst)++data List8 =+ List8+ { l8_list :: !(Ptr ())+ , l8_max :: !(Word8)+ , l8_len :: !(Word8)+ }++instance Storable List8 where+ sizeOf _ = #{size List8}+ alignment _ = 8+ peek p = List8+ <$> #{peek List8, list} p+ <*> #{peek List8, max} p+ <*> #{peek List8, len} p+ poke p x = do+ #{poke List8, list} p (l8_list x)+ #{poke List8, max} p (l8_max x)+ #{poke List8, len} p (l8_len x)++getList8 :: Storable a => (Ptr () -> IO ()) -> IO [a]+getList8 f = do+ let maxLen = maxBound :: Word8+ allocaArray (fromIntegral maxLen) $ \storage -> do+ let lst = List8+ { l8_list = castPtr storage+ , l8_max = maxLen+ , l8_len = 0+ }+ with lst $ \p -> do+ f (castPtr p)+ lst' <- peek p+ peekArray (fromIntegral (l8_len lst')) storage++setList8 :: Storable a => Text -> [a] -> (Ptr () -> IO ()) -> IO ()+setList8 t x f = do+ withArrayLen x $ \len storage -> do+ len' <- castLen t len+ let lst = List8+ { l8_list = castPtr storage+ , l8_max = len'+ , l8_len = len'+ }+ with lst $ \p -> f (castPtr p)++pokeList8 :: Storable a => (Ptr List8, Word8, Ptr a, Text) -> [a] -> IO ()+pokeList8 (lp, maxLen, storage, name) ws = do+ len <- castLen' maxLen name (length ws)+ poke lp $ List8+ { l8_list = castPtr storage+ , l8_max = maxLen+ , l8_len = len+ }+ pokeArray storage ws++peekList8 :: Storable a => (Ptr List8, Word8, Ptr a, Text) -> IO [a]+peekList8 (lp, _, _, _) = do+ lst <- peek lp+ peekArray (fromIntegral $ l8_len lst) (castPtr $ l8_list lst)++-- | Gen2-specific per-tag data+newtype GEN2_TagData =+ GEN2_TagData+ { g2Pc :: ByteString -- ^ Tag PC+ } deriving (Eq, Ord, Show, Read)++instance Storable GEN2_TagData where+ sizeOf _ = #{size TMR_GEN2_TagData}+ alignment _ = 8++ peek p =+ GEN2_TagData+ <$> peekArrayAsByteString (#{ptr TMR_GEN2_TagData, pc} p) (#{ptr TMR_GEN2_TagData, pcByteCount} p)++ poke p x = do+ pokeArrayAsByteString "pc" #{const TMR_GEN2_MAX_PC_BYTE_COUNT} (#{ptr TMR_GEN2_TagData, pc} p) (#{ptr TMR_GEN2_TagData, pcByteCount} p) (g2Pc x)++-- | A record to represent RFID tags.+data TagData =+ TagData+ { tdEpc :: !ByteString -- ^ Tag EPC+ , tdProtocol :: !TagProtocol -- ^ Protocol of the tag+ , tdCrc :: !Word16 -- ^ Tag CRC+ , tdGen2 :: !(Maybe (GEN2_TagData)) -- ^ Gen2-specific tag information+ } deriving (Eq, Ord, Show, Read)++instance Storable TagData where+ sizeOf _ = #{size TMR_TagData}+ alignment _ = 8++ peek p =+ TagData+ <$> peekArrayAsByteString (#{ptr TMR_TagData, epc} p) (#{ptr TMR_TagData, epcByteCount} p)+ <*> (toTagProtocol <$> #{peek TMR_TagData, protocol} p)+ <*> #{peek TMR_TagData, crc} p+ <*> peekMaybe (peek) (== (#{const TMR_TAG_PROTOCOL_GEN2} :: RawTagProtocol)) (#{ptr TMR_TagData, u.gen2} p) (#{ptr TMR_TagData, protocol} p)++ poke p x = do+ pokeArrayAsByteString "epc" #{const TMR_MAX_EPC_BYTE_COUNT} (#{ptr TMR_TagData, epc} p) (#{ptr TMR_TagData, epcByteCount} p) (tdEpc x)+ #{poke TMR_TagData, protocol} p (fromTagProtocol $ tdProtocol x)+ #{poke TMR_TagData, crc} p (tdCrc x)+ pokeGen2TagData (#{ptr TMR_TagData, u.gen2} p) (#{ptr TMR_TagData, protocol} p) (tdGen2 x)++-- | The identity and state of a single GPIO pin.+data GpioPin =+ GpioPin+ { gpId :: !PinNumber -- ^ The ID number of the pin.+ , gpHigh :: !Bool -- ^ Whether the pin is in the high state.+ , gpOutput :: !Bool -- ^ The direction of the pin+ } deriving (Eq, Ord, Show, Read)++instance Storable GpioPin where+ sizeOf _ = #{size TMR_GpioPin}+ alignment _ = 8++ peek p =+ GpioPin+ <$> #{peek TMR_GpioPin, id} p+ <*> (toBool' <$> #{peek TMR_GpioPin, high} p)+ <*> (toBool' <$> #{peek TMR_GpioPin, output} p)++ poke p x = do+ #{poke TMR_GpioPin, id} p (gpId x)+ #{poke TMR_GpioPin, high} p (fromBool' $ gpHigh x)+ #{poke TMR_GpioPin, output} p (fromBool' $ gpOutput x)++-- | A record to represent a read of an RFID tag.+-- Provides access to the metadata of the read event,+-- such as the time of the read, the antenna that read the tag,+-- and the number of times the tag was seen by the air protocol.+data TagReadData =+ TagReadData+ { trTag :: !TagData -- ^ The tag that was read+ , trMetadataFlags :: ![MetadataFlag] -- ^ The set of metadata items below that are valid+ , trPhase :: !Word16 -- ^ Tag response phase+ , trAntenna :: !AntennaPort -- ^ Antenna where the tag was read+ , trGpio :: ![GpioPin] -- ^ State of GPIO pins at the moment of the tag read+ , trReadCount :: !Word32 -- ^ Number of times the tag was read+ , trRssi :: !Int32 -- ^ Strength of the signal received from the tag+ , trFrequency :: !Word32 -- ^ RF carrier frequency the tag was read with+ , trTimestamp :: !MillisecondsSinceEpoch -- ^ Absolute time of the read, in milliseconds since 1\/1\/1970 UTC+ , trData :: !ByteString -- ^ Data read from the tag+ , trEpcMemData :: !ByteString -- ^ Read EPC bank data bytes (Only if 'GEN2_BANK_EPC' is present in 'opExtraBanks')+ , trTidMemData :: !ByteString -- ^ Read TID bank data bytes (Only if 'GEN2_BANK_TID' is present in 'opExtraBanks')+ , trUserMemData :: !ByteString -- ^ Read USER bank data bytes (Only if 'GEN2_BANK_USER' is present in 'opExtraBanks')+ , trReservedMemData :: !ByteString -- ^ Read RESERVED bank data bytes (Only if 'GEN2_BANK_RESERVED' is present in 'opExtraBanks')+ } deriving (Eq, Ord, Show, Read)++instance Storable TagReadData where+ sizeOf _ = #{size TMR_TagReadData}+ alignment _ = 8++ peek p =+ TagReadData+ <$> #{peek TMR_TagReadData, tag} p+ <*> (unpackFlags16 <$> #{peek TMR_TagReadData, metadataFlags} p)+ <*> #{peek TMR_TagReadData, phase} p+ <*> #{peek TMR_TagReadData, antenna} p+ <*> peekArrayAsList (#{ptr TMR_TagReadData, gpio} p) (#{ptr TMR_TagReadData, gpioCount} p)+ <*> #{peek TMR_TagReadData, readCount} p+ <*> #{peek TMR_TagReadData, rssi} p+ <*> #{peek TMR_TagReadData, frequency} p+ <*> peekSplit64 (#{ptr TMR_TagReadData, timestampLow} p) (#{ptr TMR_TagReadData, timestampHigh} p)+ <*> peekListAsByteString (#{ptr TMR_TagReadData, data} p)+ <*> peekListAsByteString (#{ptr TMR_TagReadData, epcMemData} p)+ <*> peekListAsByteString (#{ptr TMR_TagReadData, tidMemData} p)+ <*> peekListAsByteString (#{ptr TMR_TagReadData, userMemData} p)+ <*> peekListAsByteString (#{ptr TMR_TagReadData, reservedMemData} p)++ poke p x = error "poke not implemented for TagReadData"++-- | An operation that can be performed on a tag. Can be used+-- as an argument to 'System.Hardware.MercuryApi.executeTagOp',+-- or can be embedded into a 'System.Hardware.MercuryApi.ReadPlan'.+-- (However, on the M6e Nano, only 'TagOp_GEN2_ReadData' may be+-- embedded in a 'System.Hardware.MercuryApi.ReadPlan'.)+data TagOp =+ TagOp_GEN2_ReadData+ { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on+ , opExtraBanks :: ![GEN2_Bank] -- ^ Additional Gen2 memory banks to read from (seems buggy, though; I\'ve had strange results with it)+ , opWordAddress :: !Word32 -- ^ Word address to start at+ , opLen :: !Word8 -- ^ Number of words to read+ }+ | TagOp_GEN2_WriteTag+ { opEpc :: !TagData -- ^ Tag EPC+ }+ | TagOp_GEN2_WriteData+ { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on+ , opWordAddress :: !Word32 -- ^ Word address to start at+ , opData :: ![Word16] -- ^ Data to write+ }+ | TagOp_GEN2_Lock+ { opMask :: ![GEN2_LockBits] -- ^ Bitmask indicating which lock bits to change+ , opAction :: ![GEN2_LockBits] -- ^ New values of each bit specified in the mask+ , opAccessPassword :: !GEN2_Password -- ^ Access Password to use to lock the tag+ }+ | TagOp_GEN2_Kill+ { opPassword :: !GEN2_Password -- ^ Kill password to use to kill the tag+ }+ | TagOp_GEN2_BlockWrite+ { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on+ , opWordPtr :: !Word32 -- ^ The word address to start at+ , opData :: ![Word16] -- ^ The data to write+ }+ | TagOp_GEN2_BlockErase+ { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on+ , opWordPtr :: !Word32 -- ^ The word address to start at+ , opWordCount :: !Word8 -- ^ Number of words to erase+ }+ | TagOp_GEN2_BlockPermaLock+ { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on+ , opBlockPtr :: !Word32 -- ^ The starting word address to lock+ , opReadWrite :: !ReadWrite -- ^ Read lock status or write it?+ }+ deriving (Eq, Ord, Show, Read)++instance Storable TagOp where+ sizeOf _ = #{size TagOpEtc}+ alignment _ = 8++ peek p = do+ x <- #{peek TagOpEtc, tagop.type} p :: IO #{type TMR_TagOpType}+ case x of+ #{const TMR_TAGOP_GEN2_READDATA} -> do+ TagOp_GEN2_ReadData+ <$> ((toBank . (.&. 3)) <$> #{peek TagOpEtc, tagop.u.gen2.u.readData.bank} p)+ <*> (unpackExtraBanks <$> #{peek TagOpEtc, tagop.u.gen2.u.readData.bank} p)+ <*> #{peek TagOpEtc, tagop.u.gen2.u.readData.wordAddress} p+ <*> #{peek TagOpEtc, tagop.u.gen2.u.readData.len} p+ #{const TMR_TAGOP_GEN2_WRITETAG} -> do+ TagOp_GEN2_WriteTag+ <$> peekPtr (#{ptr TagOpEtc, tagop.u.gen2.u.writeTag.epcptr} p) (#{ptr TagOpEtc, u.epc} p)+ #{const TMR_TAGOP_GEN2_WRITEDATA} -> do+ TagOp_GEN2_WriteData+ <$> ((toBank . (.&. 3)) <$> #{peek TagOpEtc, tagop.u.gen2.u.writeData.bank} p)+ <*> #{peek TagOpEtc, tagop.u.gen2.u.writeData.wordAddress} p+ <*> peekListAsList (#{ptr TagOpEtc, tagop.u.gen2.u.writeData.data} p) (#{ptr TagOpEtc, u.data16} p)+ #{const TMR_TAGOP_GEN2_LOCK} -> do+ TagOp_GEN2_Lock+ <$> (unpackLockBits16 <$> #{peek TagOpEtc, tagop.u.gen2.u.lock.mask} p)+ <*> (unpackLockBits16 <$> #{peek TagOpEtc, tagop.u.gen2.u.lock.action} p)+ <*> #{peek TagOpEtc, tagop.u.gen2.u.lock.accessPassword} p+ #{const TMR_TAGOP_GEN2_KILL} -> do+ TagOp_GEN2_Kill+ <$> #{peek TagOpEtc, tagop.u.gen2.u.kill.password} p+ #{const TMR_TAGOP_GEN2_BLOCKWRITE} -> do+ TagOp_GEN2_BlockWrite+ <$> ((toBank . (.&. 3)) <$> #{peek TagOpEtc, tagop.u.gen2.u.blockWrite.bank} p)+ <*> #{peek TagOpEtc, tagop.u.gen2.u.blockWrite.wordPtr} p+ <*> peekListAsList (#{ptr TagOpEtc, tagop.u.gen2.u.blockWrite.data} p) (#{ptr TagOpEtc, u.data16} p)+ #{const TMR_TAGOP_GEN2_BLOCKERASE} -> do+ TagOp_GEN2_BlockErase+ <$> ((toBank . (.&. 3)) <$> #{peek TagOpEtc, tagop.u.gen2.u.blockErase.bank} p)+ <*> #{peek TagOpEtc, tagop.u.gen2.u.blockErase.wordPtr} p+ <*> #{peek TagOpEtc, tagop.u.gen2.u.blockErase.wordCount} p+ #{const TMR_TAGOP_GEN2_BLOCKPERMALOCK} -> do+ rw <- #{peek TagOpEtc, tagop.u.gen2.u.blockPermaLock.readLock} p+ ws <- peekListAsList (#{ptr TagOpEtc, tagop.u.gen2.u.blockPermaLock.mask} p) (#{ptr TagOpEtc, u.data16} p)+ TagOp_GEN2_BlockPermaLock+ <$> ((toBank . (.&. 3)) <$> #{peek TagOpEtc, tagop.u.gen2.u.blockPermaLock.bank} p)+ <*> #{peek TagOpEtc, tagop.u.gen2.u.blockPermaLock.blockPtr} p+ <*> (return $ toReadWrite (rw, ws))++ poke p x@(TagOp_GEN2_ReadData {}) = do+ #{poke TagOpEtc, tagop.type} p (#{const TMR_TAGOP_GEN2_READDATA} :: #{type TMR_TagOpType})+ #{poke TagOpEtc, tagop.u.gen2.u.readData.bank} p (fromBank $ opBank x)+ pokeOr (#{ptr TagOpEtc, tagop.u.gen2.u.readData.bank} p) (packExtraBanks $ opExtraBanks x)+ #{poke TagOpEtc, tagop.u.gen2.u.readData.wordAddress} p (opWordAddress x)+ #{poke TagOpEtc, tagop.u.gen2.u.readData.len} p (opLen x)++ poke p x@(TagOp_GEN2_WriteTag {}) = do+ #{poke TagOpEtc, tagop.type} p (#{const TMR_TAGOP_GEN2_WRITETAG} :: #{type TMR_TagOpType})+ pokePtr (#{ptr TagOpEtc, tagop.u.gen2.u.writeTag.epcptr} p) (#{ptr TagOpEtc, u.epc} p) (opEpc x)++ poke p x@(TagOp_GEN2_WriteData {}) = do+ #{poke TagOpEtc, tagop.type} p (#{const TMR_TAGOP_GEN2_WRITEDATA} :: #{type TMR_TagOpType})+ #{poke TagOpEtc, tagop.u.gen2.u.writeData.bank} p (fromBank $ opBank x)+ #{poke TagOpEtc, tagop.u.gen2.u.writeData.wordAddress} p (opWordAddress x)+ pokeListAsList "data" #{const GLUE_MAX_DATA16} (#{ptr TagOpEtc, tagop.u.gen2.u.writeData.data} p) (#{ptr TagOpEtc, u.data16} p) (opData x)++ poke p x@(TagOp_GEN2_Lock {}) = do+ #{poke TagOpEtc, tagop.type} p (#{const TMR_TAGOP_GEN2_LOCK} :: #{type TMR_TagOpType})+ #{poke TagOpEtc, tagop.u.gen2.u.lock.mask} p (packLockBits16 $ opMask x)+ #{poke TagOpEtc, tagop.u.gen2.u.lock.action} p (packLockBits16 $ opAction x)+ #{poke TagOpEtc, tagop.u.gen2.u.lock.accessPassword} p (opAccessPassword x)++ poke p x@(TagOp_GEN2_Kill {}) = do+ #{poke TagOpEtc, tagop.type} p (#{const TMR_TAGOP_GEN2_KILL} :: #{type TMR_TagOpType})+ #{poke TagOpEtc, tagop.u.gen2.u.kill.password} p (opPassword x)++ poke p x@(TagOp_GEN2_BlockWrite {}) = do+ #{poke TagOpEtc, tagop.type} p (#{const TMR_TAGOP_GEN2_BLOCKWRITE} :: #{type TMR_TagOpType})+ #{poke TagOpEtc, tagop.u.gen2.u.blockWrite.bank} p (fromBank $ opBank x)+ #{poke TagOpEtc, tagop.u.gen2.u.blockWrite.wordPtr} p (opWordPtr x)+ pokeListAsList "data" #{const GLUE_MAX_DATA16} (#{ptr TagOpEtc, tagop.u.gen2.u.blockWrite.data} p) (#{ptr TagOpEtc, u.data16} p) (opData x)++ poke p x@(TagOp_GEN2_BlockErase {}) = do+ #{poke TagOpEtc, tagop.type} p (#{const TMR_TAGOP_GEN2_BLOCKERASE} :: #{type TMR_TagOpType})+ #{poke TagOpEtc, tagop.u.gen2.u.blockErase.bank} p (fromBank $ opBank x)+ #{poke TagOpEtc, tagop.u.gen2.u.blockErase.wordPtr} p (opWordPtr x)+ #{poke TagOpEtc, tagop.u.gen2.u.blockErase.wordCount} p (opWordCount x)++ poke p x@(TagOp_GEN2_BlockPermaLock {}) = do+ let (rw, ws) = fromReadWrite $ opReadWrite x+ #{poke TagOpEtc, tagop.type} p (#{const TMR_TAGOP_GEN2_BLOCKPERMALOCK} :: #{type TMR_TagOpType})+ #{poke TagOpEtc, tagop.u.gen2.u.blockPermaLock.readLock} p rw+ #{poke TagOpEtc, tagop.u.gen2.u.blockPermaLock.bank} p (fromBank $ opBank x)+ #{poke TagOpEtc, tagop.u.gen2.u.blockPermaLock.blockPtr} p (opBlockPtr x)+ pokeListAsList "mask" #{const GLUE_MAX_DATA16} (#{ptr TagOpEtc, tagop.u.gen2.u.blockPermaLock.mask} p) (#{ptr TagOpEtc, u.data16} p) ws++tagOpName :: TagOp -> Text+tagOpName TagOp_GEN2_ReadData {} = "TagOp_GEN2_ReadData"+tagOpName TagOp_GEN2_WriteTag {} = "TagOp_GEN2_WriteTag"+tagOpName TagOp_GEN2_WriteData {} = "TagOp_GEN2_WriteData"+tagOpName TagOp_GEN2_Lock {} = "TagOp_GEN2_Lock"+tagOpName TagOp_GEN2_Kill {} = "TagOp_GEN2_Kill"+tagOpName TagOp_GEN2_BlockWrite {} = "TagOp_GEN2_BlockWrite"+tagOpName TagOp_GEN2_BlockErase {} = "TagOp_GEN2_BlockErase"+tagOpName TagOp_GEN2_BlockPermaLock {} = "TagOp_GEN2_BlockPermaLock"+
+ src/System/Hardware/MercuryApi/Testing.hsc view
@@ -0,0 +1,320 @@+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_HADDOCK hide #-}+{-|+Module : System.Hardware.MercuryApi.Testing+Description : A serial transport for MercuryApi which replays data from a file+Copyright : © Patrick Pelletier, 2017+License : MIT+Maintainer : code@funwithsoftware.org++This module is not meant to be used by the end user. It exists for the+automated tests. It provides a handler for URIs of the form+test:///path/to/file, where the file is in the format produced by+'opcodeListener'. When Mercury API reads from the transport, the data+from a "Received:" line is returned. When Mercury API writes to the+transport, the data is compared to the data in the "Sending:" line.+If the data does not match, an error message is printed, and+TMR_ERROR_TIMEOUT is returned. (Timeout was chosen because it's the only+error that seems to be consistently propagated from the transport by+Mercury API.)+-}++module System.Hardware.MercuryApi.Testing+ ( registerTransportInit+ ) where++import Control.Applicative ( Applicative((<*>)), (<$>) )+import Control.Concurrent ( threadDelay )+import Control.Exception ( IOException, try )+import Control.Monad ( when )+import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as B8 ( unpack )+import Data.Char ( isDigit )+import Data.IORef ( IORef, writeIORef, readIORef, newIORef )+import Data.Monoid ( (<>) )+import qualified Data.Text as T+import qualified Data.Text.Encoding as T ( encodeUtf8 )+import qualified Data.Text.IO as T ( readFile, putStrLn )+import Data.Word ( Word8, Word32 )+import Foreign+ ( newStablePtr,+ Ptr,+ FunPtr,+ nullPtr,+ Storable(alignment, peek, peekByteOff, poke, pokeByteOff, sizeOf),+ freeStablePtr,+ deRefStablePtr,+ castStablePtrToPtr,+ castPtrToStablePtr,+ nullFunPtr,+ castPtr,+ copyArray )+import Foreign.C ( CString, withCAString, peekCAString )+import System.Info ( os )+import qualified System.IO.Unsafe as U ( unsafePerformIO )++import System.Hardware.MercuryApi hiding (read)++#include <tm_reader.h>+#include <glue.h>++type RawStatus = Word32++successStatus :: RawStatus+successStatus = #{const TMR_SUCCESS}++failureStatus :: RawStatus+failureStatus = #{const TMR_ERROR_TIMEOUT}++data SerialState =+ SerialState+ { ssFilename :: String+ , ssNext :: IORef [T.Text]+ , ssLeftover :: IORef B.ByteString+ , ssSendTime :: IORef Double+ }++data SerialTransport =+ SerialTransport+ { stCookie :: Ptr ()+ , stOpen :: FunPtr (Ptr SerialTransport -> IO RawStatus)+ , stSendBytes :: FunPtr (Ptr SerialTransport -> Word32 -> Ptr Word8 -> Word32 -> IO RawStatus)+ , stReceiveBytes :: FunPtr (Ptr SerialTransport -> Word32 -> Ptr Word32 -> Ptr Word8 -> Word32 -> IO RawStatus)+ , stSetBaudRate :: FunPtr (Ptr SerialTransport -> Word32 -> IO RawStatus)+ , stShutdown :: FunPtr (Ptr SerialTransport -> IO RawStatus)+ , stFlush :: FunPtr (Ptr SerialTransport -> IO RawStatus)+ }++instance Storable SerialTransport where+ sizeOf _ = #{size TMR_SR_SerialTransport}+ alignment _ = 8++ peek p =+ SerialTransport+ <$> #{peek TMR_SR_SerialTransport, cookie} p+ <*> #{peek TMR_SR_SerialTransport, open} p+ <*> #{peek TMR_SR_SerialTransport, sendBytes} p+ <*> #{peek TMR_SR_SerialTransport, receiveBytes} p+ <*> #{peek TMR_SR_SerialTransport, setBaudRate} p+ <*> #{peek TMR_SR_SerialTransport, shutdown} p+ <*> #{peek TMR_SR_SerialTransport, flush} p++ poke p x = do+ #{poke TMR_SR_SerialTransport, cookie} p (stCookie x)+ #{poke TMR_SR_SerialTransport, open} p (stOpen x)+ #{poke TMR_SR_SerialTransport, sendBytes} p (stSendBytes x)+ #{poke TMR_SR_SerialTransport, receiveBytes} p (stReceiveBytes x)+ #{poke TMR_SR_SerialTransport, setBaudRate} p (stSetBaudRate x)+ #{poke TMR_SR_SerialTransport, shutdown} p (stShutdown x)+ #{poke TMR_SR_SerialTransport, flush} p (stFlush x)++foreign import ccall "tm_reader.h TMR_setSerialTransport"+ c_TMR_setSerialTransport :: CString+ -> FunPtr (Ptr SerialTransport -> Ptr () -> CString -> IO RawStatus)+ -> IO RawStatus++foreign import ccall "wrapper"+ wrapOneArg :: (Ptr SerialTransport -> IO RawStatus)+ -> IO (FunPtr (Ptr SerialTransport -> IO RawStatus))++foreign import ccall "wrapper"+ wrapSendBytes :: (Ptr SerialTransport -> Word32 -> Ptr Word8 -> Word32 -> IO RawStatus)+ -> IO (FunPtr (Ptr SerialTransport -> Word32 -> Ptr Word8 -> Word32 -> IO RawStatus))++foreign import ccall "wrapper"+ wrapReceiveBytes :: (Ptr SerialTransport -> Word32 -> Ptr Word32 -> Ptr Word8 -> Word32 -> IO RawStatus)+ -> IO (FunPtr (Ptr SerialTransport -> Word32 -> Ptr Word32 -> Ptr Word8 -> Word32 -> IO RawStatus))++foreign import ccall "wrapper"+ wrapInit :: (Ptr SerialTransport -> Ptr () -> CString -> IO RawStatus)+ -> IO (FunPtr (Ptr SerialTransport -> Ptr () -> CString -> IO RawStatus))++funOpen :: FunPtr (Ptr SerialTransport -> IO RawStatus)+{-# NOINLINE funOpen #-}+funOpen = U.unsafePerformIO $ wrapOneArg testOpen++funSendBytes :: FunPtr (Ptr SerialTransport -> Word32 -> Ptr Word8 -> Word32 -> IO RawStatus)+{-# NOINLINE funSendBytes #-}+funSendBytes = U.unsafePerformIO $ wrapSendBytes testSendBytes++funReceiveBytes :: FunPtr (Ptr SerialTransport -> Word32 -> Ptr Word32 -> Ptr Word8 -> Word32 -> IO RawStatus)+{-# NOINLINE funReceiveBytes #-}+funReceiveBytes = U.unsafePerformIO $ wrapReceiveBytes testReceiveBytes++funShutdown :: FunPtr (Ptr SerialTransport -> IO RawStatus)+{-# NOINLINE funShutdown #-}+funShutdown = U.unsafePerformIO $ wrapOneArg testShutdown++funFlush :: FunPtr (Ptr SerialTransport -> IO RawStatus)+{-# NOINLINE funFlush #-}+funFlush = U.unsafePerformIO $ wrapOneArg testFlush++funTransportInit :: FunPtr (Ptr SerialTransport -> Ptr () -> CString -> IO RawStatus)+{-# NOINLINE funTransportInit #-}+funTransportInit = U.unsafePerformIO $ wrapInit testTransportInit++mkSerialTransport :: Ptr () -> SerialTransport+mkSerialTransport cookie =+ SerialTransport+ { stCookie = cookie+ , stOpen = funOpen+ , stSendBytes = funSendBytes+ , stReceiveBytes = funReceiveBytes+ , stSetBaudRate = nullFunPtr+ , stShutdown = funShutdown+ , stFlush = funFlush+ }++getState :: Ptr SerialTransport -> IO SerialState+getState p = do+ st <- peek p+ let stable = castPtrToStablePtr $ stCookie st+ deRefStablePtr stable++printIOException :: IOException -> IO ()+printIOException = print++testOpen :: Ptr SerialTransport -> IO RawStatus+testOpen p = do+ ss <- getState p+ eth <- try $ T.readFile (ssFilename ss)+ case eth of+ Left exc -> do+ printIOException exc+ return failureStatus+ Right txt -> do+ writeIORef (ssNext ss) (T.lines txt)+ return successStatus++parseTransportLine :: T.Text -> (Maybe TransportDirection, B.ByteString)+parseTransportLine txt =+ let txt' = T.takeWhile (/= '|') txt+ f d = if d == "Sending" then Tx else Rx+ (dir, mbs) = case T.splitOn ":" txt' of+ [x] -> (Nothing, hexToBytes $ T.filter (/= ' ') x)+ [d, x] -> (Just (f d),+ Just $ T.encodeUtf8 $ T.dropWhile (not . isDigit) x)+ _ -> (Nothing, Just "")+ in case mbs of+ Nothing -> (dir, "barf!")+ Just bs -> (dir, bs)++parseTransport :: [T.Text]+ -> Maybe (TransportDirection, B.ByteString, Double, [T.Text])+parseTransport [] = Nothing+parseTransport (t:ts) =+ let (Just dir, bs) = parseTransportLine t+ rest = takeWhile ((== Nothing) . fst) $ map parseTransportLine ts+ leftover = drop (length rest) ts+ bss = map snd rest+ tm = read $ B8.unpack bs+ in Just (dir, B.concat bss, tm, leftover)++takeNext :: SerialState -> IO (Maybe (TransportDirection, B.ByteString, Double))+takeNext ss = do+ let ref = ssNext ss+ ts <- readIORef ref+ let result = parseTransport ts+ case result of+ Nothing -> return Nothing+ Just (dir, bs, tm, ts') -> do+ writeIORef ref ts'+ return $ Just (dir, bs, tm)++testSendBytes :: Ptr SerialTransport+ -> Word32+ -> Ptr Word8+ -> Word32+ -> IO RawStatus+testSendBytes p len msg _ = do+ ss <- getState p+ nxt <- takeNext ss+ case nxt of+ Just (Tx, expected, tm) -> do+ writeIORef (ssSendTime ss) tm+ actual <- B.packCStringLen (castPtr msg, fromIntegral len)+ if actual == expected+ then return successStatus+ else do+ T.putStrLn ("expected <" <> bytesToHex expected <>+ ">, but got <" <> bytesToHex actual <> ">")+ return failureStatus+ x -> do+ putStrLn $ "expected Tx, but got " ++ show x+ return failureStatus++computeDelay :: Double -> Double -> Int+computeDelay oldTime newTime =+ -- convert seconds to microseconds, and add a fudge factor of 10%+ ceiling $ (newTime - oldTime) * 1.1e6++getNextBytes :: SerialState -> IO (Either RawStatus B.ByteString)+getNextBytes ss = do+ leftover <- readIORef (ssLeftover ss)+ if B.null leftover+ then do+ nxt <- takeNext ss+ case nxt of+ Just (Rx, bs, tm) -> do+ sendTime <- readIORef (ssSendTime ss)+ threadDelay $ computeDelay sendTime tm+ return $ Right bs+ x -> do+ putStrLn $ "expected Rx, but got " ++ show x+ return $ Left failureStatus+ else return $ Right leftover++testReceiveBytes :: Ptr SerialTransport+ -> Word32+ -> Ptr Word32+ -> Ptr Word8+ -> Word32+ -> IO RawStatus+testReceiveBytes p len returnLen msg _ = do+ ss <- getState p+ eth <- getNextBytes ss+ case eth of+ Left status -> return status+ Right bs -> do+ let (bs1, bs2) = B.splitAt (fromIntegral len) bs+ B.useAsCStringLen bs1 $ \(pChar, bsLen) -> do+ poke returnLen (fromIntegral len)+ copyArray msg (castPtr pChar) bsLen+ writeIORef (ssLeftover ss) bs2+ return successStatus++testFlush :: Ptr SerialTransport -> IO RawStatus+testFlush _ = return successStatus++testShutdown :: Ptr SerialTransport -> IO RawStatus+testShutdown p = do+ st <- peek p+ let stable = castPtrToStablePtr $ stCookie st+ freeStablePtr stable+ poke p st { stCookie = nullPtr }+ return successStatus++-- Somehow in Windows, we end up with an absolute path that+-- starts with "/C:", which doesn't work, so we need to strip+-- the leading slash.+hackPath :: String -> String -> String+hackPath "mingw32" = dropWhile (== '/')+hackPath _ = id++testTransportInit :: Ptr SerialTransport -> Ptr () -> CString -> IO RawStatus+testTransportInit p _ cstr = do+ fname <- hackPath os <$> peekCAString cstr+ ref <- newIORef []+ ref2 <- newIORef ""+ ref3 <- newIORef 0+ let ss = SerialState fname ref ref2 ref3+ stable <- newStablePtr ss+ let st = mkSerialTransport $ castStablePtrToPtr stable+ poke p st+ return successStatus++registerTransportInit :: IO ()+registerTransportInit = do+ withCAString "test" $ \name -> do+ status <- c_TMR_setSerialTransport name funTransportInit+ when (status /= successStatus) $ fail "TMR_setSerialTransport failed"
+ tests/blockErase.result view
@@ -0,0 +1,5 @@+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NULQ\134\SOH\a\SOH\135\ap\196\193", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 47646, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 18, trRssi = -44, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right ""+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NULQ\134\SOH\a\SOH\135\ap\196\193", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 47646, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 22, trRssi = -40, trFrequency = 918400, trTimestamp = 0, trData = "\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})
+ tests/blockErase.transport view
@@ -0,0 +1,118 @@+Sending: VERSION 1733450.679602521+ ff 00 03 1d 0c |.....|+Received:VERSION 1733450.684134700+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1733450.684657205+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1733450.686277606+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1733450.686375908+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1733450.688135301+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1733450.688284351+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1733450.690435237+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1733450.698289611+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1733450.700384916+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1733450.700490046+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1733450.702188454+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1733450.702288657+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1733450.704364082+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1733450.704576636+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1733450.706714766+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1733450.706873798+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1733450.709308529+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1733450.709501081+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1733450.711348767+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1733450.711558562+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1733450.713440798+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1733450.713578366+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1733450.715466506+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1733450.715640398+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1733450.717565537+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1733450.717697069+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1733450.719718857+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1733450.719880829+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1733450.722077569+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1733450.722247530+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1733450.723941906+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1733450.724084225+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1733450.726101108+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1733450.726243987+ ff 16 22 03 00 13 03 e8 00 00 00 00 00 00 00 00 |..".............|+ 40 00 01 02 03 04 05 06 07 8f 1e |@..........|+Received:READ_TAG_ID_MULTIPLE 1733451.734947047+ ff 07 22 00 00 03 00 13 00 00 00 01 65 8a |..".........e.|+Sending: GET_TAG_ID_BUFFER 1733451.735124397+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1733451.740349899+ ff 26 29 00 00 01 ff 00 01 12 d4 11 0e 13 e8 00 |.&).............|+ 00 03 07 00 ae 05 00 00 00 00 80 30 00 e2 00 51 |...........0...Q|+ 86 01 07 01 87 07 70 c4 c1 ba 1e 47 2c |......p....G,|+Sending: ERASE_BLOCK_TAG_SPECIFIC 1733451.740792941+ ff 1c 2e 03 e8 00 41 00 00 00 00 00 60 e2 00 51 |......A.....`..Q|+ 86 01 07 01 87 07 70 c4 c1 00 00 00 00 03 04 36 |......p........6|+ 2a |*|+Received:ERASE_BLOCK_TAG_SPECIFIC 1733451.774187155+ ff 00 2e 00 00 41 6c |.....Al|+Sending: GET_READER_STATS 1733451.774381812+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1733451.776784092+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1733451.776983355+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1733451.778708021+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1733451.778890524+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1733451.780914629+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1733451.781081920+ ff 11 22 00 00 17 03 e8 01 09 28 07 d0 00 03 00 |..".......(.....|+ 00 00 00 20 49 70 |... Ip|+Received:READ_TAG_ID_MULTIPLE 1733452.808667838+ ff 4d 22 00 00 00 00 17 00 00 00 01 01 28 00 16 |.M"..........(..|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 e4 bf |....|+Sending: GET_TAG_ID_BUFFER 1733452.809593767+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1733452.820884567+ ff 66 29 00 00 01 ff 00 01 16 d8 11 0e 03 80 00 |.f).............|+ 00 01 8f 00 ae 05 02 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 80 30 00 e2 00 51 |...........0...Q|+ 86 01 07 01 87 07 70 c4 c1 ba 1e 4b f7 |......p....K.|
+ tests/blockPermalockRead.result view
@@ -0,0 +1,3 @@+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\SOH\134\DLEP\178\ENQ", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 17157, tdGen2 = Just (GEN2_TagData {g2Pc = "4\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 29, trRssi = -36, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right "\NUL\NUL"
+ tests/blockPermalockRead.transport view
@@ -0,0 +1,86 @@+Sending: VERSION 1829051.749487169+ ff 00 03 1d 0c |.....|+Received:VERSION 1829051.754158098+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1829051.754732547+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1829051.756325310+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1829051.756433837+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1829051.758001346+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1829051.758097441+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1829051.760214239+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1829051.768183546+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1829051.770281602+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1829051.770397735+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1829051.772015315+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1829051.772120484+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1829051.774081569+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1829051.774218216+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1829051.776219065+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1829051.776383680+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1829051.778820450+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1829051.779002895+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1829051.780904919+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1829051.781086964+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1829051.782951692+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1829051.783084670+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1829051.784973813+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1829051.785227705+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1829051.787167999+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1829051.787303537+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1829051.789354238+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1829051.789507837+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1829051.791778681+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1829051.791937775+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1829051.793646752+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1829051.793796892+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1829051.795843593+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1829051.795998706+ ff 1a 22 03 00 13 03 e8 00 00 00 00 00 00 00 00 |..".............|+ 60 70 65 72 6d 61 6c 6f 63 6b 20 6d 65 0d 10 |`permalock me..|+Received:READ_TAG_ID_MULTIPLE 1829052.807263318+ ff 07 22 00 00 03 00 13 00 00 00 01 65 8a |..".........e.|+Sending: GET_TAG_ID_BUFFER 1829052.807500776+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1829052.813042126+ ff 26 29 00 00 01 ff 00 01 1d dc 11 0e 13 e8 00 |.&).............|+ 00 03 66 00 ae 05 00 00 00 00 80 34 00 e2 00 00 |..f........4....|+ 15 86 0e 01 86 10 50 b2 05 43 05 c6 5e |......P..C..^|+Sending: ERASE_BLOCK_TAG_SPECIFIC 1829052.816943258+ ff 1e 2e 03 e8 00 41 01 00 00 00 00 60 e2 00 00 |......A.....`...|+ 15 86 0e 01 86 10 50 b2 05 00 00 03 00 00 00 00 |......P.........|+ 01 66 1b |.f.|+Received:ERASE_BLOCK_TAG_SPECIFIC 1829052.840513132+ ff 04 2e 00 00 41 01 00 00 de 5f |.....A...._|
+ tests/blockPermalockWrite.result view
@@ -0,0 +1,38 @@+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\SOH\134\DLEP\178\ENQ", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 17157, tdGen2 = Just (GEN2_TagData {g2Pc = "4\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 29, trRssi = -36, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right ""+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Right ""+Right ""+Right ""+Right ""+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Right ""+Right ""+Right ""+Right ""+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Right ""+Right ""+Right ""+Right ""+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Right ""+Right ""+Right ""+Right ""+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\SOH\134\DLEP\178\ENQ", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 17157, tdGen2 = Just (GEN2_TagData {g2Pc = "4\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 22, trRssi = -34, trFrequency = 921600, trTimestamp = 0, trData = "permaloc\NUL\EOT\NUL\ENQ\NUL\ACK\NUL\a \NUL\f\NUL\r\NUL\SO\NUL\SI \NUL\DC4\NUL\NAK\NUL\SYN\NUL\ETB \NUL\FS\NUL\GS\NUL\RS\NUL\US", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right "\170\NUL"
+ tests/blockPermalockWrite.transport view
@@ -0,0 +1,284 @@+Sending: VERSION 1829749.010225401+ ff 00 03 1d 0c |.....|+Received:VERSION 1829749.013984210+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1829749.014793598+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1829749.016562806+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1829749.016810252+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1829749.018482575+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1829749.018608322+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1829749.020623429+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1829749.021754159+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1829749.023878015+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1829749.024026326+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1829749.025740344+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1829749.025881277+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1829749.027831871+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1829749.027988101+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1829749.029953161+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1829749.030069038+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1829749.032468987+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1829749.032668048+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1829749.034531357+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1829749.034720522+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1829749.036607567+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1829749.036735988+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1829749.038506907+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1829749.038650766+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1829749.040334163+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1829749.040436892+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1829749.042469035+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1829749.042628435+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1829749.044924815+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1829749.045087626+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1829749.046781026+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1829749.046931097+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1829749.048977941+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1829749.049135083+ ff 1a 22 03 00 13 03 e8 00 00 00 00 00 00 00 00 |..".............|+ 60 70 65 72 6d 61 6c 6f 63 6b 20 6d 65 0d 10 |`permalock me..|+Received:READ_TAG_ID_MULTIPLE 1829750.056628187+ ff 07 22 00 00 03 00 13 00 00 00 01 65 8a |..".........e.|+Sending: GET_TAG_ID_BUFFER 1829750.056804295+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1829750.062018018+ ff 26 29 00 00 01 ff 00 01 1d dc 11 0e 13 e8 00 |.&).............|+ 00 03 0b 00 ae 05 00 00 00 00 80 34 00 e2 00 00 |...........4....|+ 15 86 0e 01 86 10 50 b2 05 43 05 9e 57 |......P..C..W|+Sending: ERASE_BLOCK_TAG_SPECIFIC 1829750.065369420+ ff 20 2e 03 e8 00 41 01 00 00 00 00 60 e2 00 00 |. ....A.....`...|+ 15 86 0e 01 86 10 50 b2 05 00 01 03 00 00 00 00 |......P.........|+ 01 aa 00 60 1e |...`.|+Received:ERASE_BLOCK_TAG_SPECIFIC 1829750.112401542+ ff 00 2e 00 00 41 6c |.....Al|+Sending: WRITE_TAG_DATA 1829750.112821077+ ff 1b 24 03 e8 01 00 00 00 00 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 00 12 f7 |.........P......|+Received:WRITE_TAG_DATA 1829751.142148716+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829751.142397556+ ff 1b 24 03 e8 01 00 00 00 01 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 01 cc e9 |.........P......|+Received:WRITE_TAG_DATA 1829752.152142164+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829752.152418941+ ff 1b 24 03 e8 01 00 00 00 02 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 02 be ea |.........P......|+Received:WRITE_TAG_DATA 1829753.171222351+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829753.171502860+ ff 1b 24 03 e8 01 00 00 00 03 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 03 60 f4 |.........P....`.|+Received:WRITE_TAG_DATA 1829754.193508531+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829754.193796103+ ff 1b 24 03 e8 01 00 00 00 04 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 04 5a ec |.........P....Z.|+Received:WRITE_TAG_DATA 1829754.222549247+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829754.222738514+ ff 1b 24 03 e8 01 00 00 00 05 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 05 84 f2 |.........P......|+Received:WRITE_TAG_DATA 1829754.251609957+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829754.251872514+ ff 1b 24 03 e8 01 00 00 00 06 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 06 f6 f1 |.........P......|+Received:WRITE_TAG_DATA 1829754.280762468+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829754.281006941+ ff 1b 24 03 e8 01 00 00 00 07 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 07 28 ef |.........P....(.|+Received:WRITE_TAG_DATA 1829754.309970159+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829754.310172608+ ff 1b 24 03 e8 01 00 00 00 08 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 08 82 c1 |.........P......|+Received:WRITE_TAG_DATA 1829755.346791842+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829755.347092306+ ff 1b 24 03 e8 01 00 00 00 09 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 09 5c df |.........P....\.|+Received:WRITE_TAG_DATA 1829756.380042974+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829756.380287524+ ff 1b 24 03 e8 01 00 00 00 0a 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 0a 2e dc |.........P......|+Received:WRITE_TAG_DATA 1829757.407129848+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829757.407368360+ ff 1b 24 03 e8 01 00 00 00 0b 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 0b f0 c2 |.........P......|+Received:WRITE_TAG_DATA 1829758.440289154+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829758.440490255+ ff 1b 24 03 e8 01 00 00 00 0c 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 0c ca da |.........P......|+Received:WRITE_TAG_DATA 1829758.469259190+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829758.469522032+ ff 1b 24 03 e8 01 00 00 00 0d 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 0d 14 c4 |.........P......|+Received:WRITE_TAG_DATA 1829758.498531273+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829758.498805425+ ff 1b 24 03 e8 01 00 00 00 0e 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 0e 66 c7 |.........P....f.|+Received:WRITE_TAG_DATA 1829758.527733252+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829758.527982849+ ff 1b 24 03 e8 01 00 00 00 0f 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 0f b8 d9 |.........P......|+Received:WRITE_TAG_DATA 1829758.556692351+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829758.556900495+ ff 1b 24 03 e8 01 00 00 00 10 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 10 22 ba |.........P....".|+Received:WRITE_TAG_DATA 1829759.593563381+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829759.593731843+ ff 1b 24 03 e8 01 00 00 00 11 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 11 fc a4 |.........P......|+Received:WRITE_TAG_DATA 1829760.623955751+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829760.624235451+ ff 1b 24 03 e8 01 00 00 00 12 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 12 8e a7 |.........P......|+Received:WRITE_TAG_DATA 1829761.652961247+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829761.653243691+ ff 1b 24 03 e8 01 00 00 00 13 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 13 50 b9 |.........P....P.|+Received:WRITE_TAG_DATA 1829762.665276942+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829762.665494236+ ff 1b 24 03 e8 01 00 00 00 14 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 14 6a a1 |.........P....j.|+Received:WRITE_TAG_DATA 1829762.694120598+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829762.694383889+ ff 1b 24 03 e8 01 00 00 00 15 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 15 b4 bf |.........P......|+Received:WRITE_TAG_DATA 1829762.751451949+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829762.751713427+ ff 1b 24 03 e8 01 00 00 00 16 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 16 c6 bc |.........P......|+Received:WRITE_TAG_DATA 1829762.780199308+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829762.780457877+ ff 1b 24 03 e8 01 00 00 00 17 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 17 18 a2 |.........P......|+Received:WRITE_TAG_DATA 1829762.809239881+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829762.809503379+ ff 1b 24 03 e8 01 00 00 00 18 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 18 b2 8c |.........P......|+Received:WRITE_TAG_DATA 1829763.842151363+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829763.842308880+ ff 1b 24 03 e8 01 00 00 00 19 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 19 6c 92 |.........P....l.|+Received:WRITE_TAG_DATA 1829764.873162970+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829764.873443541+ ff 1b 24 03 e8 01 00 00 00 1a 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 1a 1e 91 |.........P......|+Received:WRITE_TAG_DATA 1829765.879579000+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829765.879851392+ ff 1b 24 03 e8 01 00 00 00 1b 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 1b c0 8f |.........P......|+Received:WRITE_TAG_DATA 1829766.888892450+ ff 00 24 04 06 e4 20 |..$... |+Sending: WRITE_TAG_DATA 1829766.889180097+ ff 1b 24 03 e8 01 00 00 00 1c 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 1c fa 97 |.........P......|+Received:WRITE_TAG_DATA 1829766.918023959+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829766.918292458+ ff 1b 24 03 e8 01 00 00 00 1d 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 1d 24 89 |.........P....$.|+Received:WRITE_TAG_DATA 1829766.946906138+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829766.947094131+ ff 1b 24 03 e8 01 00 00 00 1e 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 1e 56 8a |.........P....V.|+Received:WRITE_TAG_DATA 1829766.975771316+ ff 00 24 00 00 e0 26 |..$...&|+Sending: WRITE_TAG_DATA 1829766.976106491+ ff 1b 24 03 e8 01 00 00 00 1f 03 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 00 1f 88 94 |.........P......|+Received:WRITE_TAG_DATA 1829767.004705226+ ff 00 24 00 00 e0 26 |..$...&|+Sending: GET_READER_STATS 1829767.004898988+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1829767.007163224+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1829767.007420284+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1829767.009235148+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1829767.009451929+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1829767.011452983+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1829767.011619788+ ff 11 22 00 00 17 03 e8 01 09 28 07 d0 00 03 00 |..".......(.....|+ 00 00 00 20 49 70 |... Ip|+Received:READ_TAG_ID_MULTIPLE 1829768.032941727+ ff 4d 22 00 00 00 00 17 00 00 00 01 01 28 00 16 |.M"..........(..|+ 00 00 70 65 72 6d 61 6c 6f 63 00 04 00 05 00 06 |..permaloc......|+ 00 07 20 20 20 20 20 20 20 20 00 0c 00 0d 00 0e |.. ......|+ 00 0f 20 20 20 20 20 20 20 20 00 14 00 15 00 16 |.. ......|+ 00 17 20 20 20 20 20 20 20 20 00 1c 00 1d 00 1e |.. ......|+ 00 1f c4 38 |...8|+Sending: GET_TAG_ID_BUFFER 1829768.033538854+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1829768.044502944+ ff 66 29 00 00 01 ff 00 01 16 de 11 0e 10 00 00 |.f).............|+ 00 00 16 00 ae 05 02 00 70 65 72 6d 61 6c 6f 63 |........permaloc|+ 00 04 00 05 00 06 00 07 20 20 20 20 20 20 20 20 |........ |+ 00 0c 00 0d 00 0e 00 0f 20 20 20 20 20 20 20 20 |........ |+ 00 14 00 15 00 16 00 17 20 20 20 20 20 20 20 20 |........ |+ 00 1c 00 1d 00 1e 00 1f 00 00 80 34 00 e2 00 00 |...........4....|+ 15 86 0e 01 86 10 50 b2 05 43 05 90 67 |......P..C..g|+Sending: ERASE_BLOCK_TAG_SPECIFIC 1829768.045283520+ ff 1e 2e 03 e8 00 41 01 00 00 00 00 60 e2 00 00 |......A.....`...|+ 15 86 0e 01 86 10 50 b2 05 00 00 03 00 00 00 00 |......P.........|+ 01 66 1b |.f.|+Received:ERASE_BLOCK_TAG_SPECIFIC 1829768.068511562+ ff 04 2e 00 00 41 01 aa 00 74 5f |.....A...t_|
+ tests/blockWrite.result view
@@ -0,0 +1,5 @@+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NULQ\134\SOH\a\SOH\135\ap\196\193", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 47646, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 22, trRssi = -42, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right ""+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NULQ\134\SOH\a\SOH\135\ap\196\193", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 47646, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 21, trRssi = -40, trFrequency = 918400, trTimestamp = 0, trData = "\NUL\SOH\STX\ETX\EOT\ENQ\ACK\a\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL456789:;<=>?", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})
+ tests/blockWrite.transport view
@@ -0,0 +1,118 @@+Sending: VERSION 1733235.445865270+ ff 00 03 1d 0c |.....|+Received:VERSION 1733235.450593149+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1733235.451166815+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1733235.452792849+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1733235.452909508+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1733235.454483132+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1733235.454584834+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1733235.456720836+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1733235.464524663+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1733235.466891122+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1733235.467046237+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1733235.468960694+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1733235.469176660+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1733235.471205061+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1733235.471393661+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1733235.473331463+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1733235.473436213+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1733235.475652405+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1733235.475787800+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1733235.477440297+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1733235.477572174+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1733235.479231984+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1733235.479325942+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1733235.480974365+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1733235.481085977+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1733235.482945579+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1733235.483086775+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1733235.485124382+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1733235.485409960+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1733235.487718897+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1733235.487877132+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1733235.489434618+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1733235.489576531+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1733235.491653350+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1733235.491795994+ ff 10 22 03 00 13 03 e8 00 00 00 00 00 00 00 00 |..".............|+ 10 00 00 86 a3 |.....|+Received:READ_TAG_ID_MULTIPLE 1733236.497741270+ ff 07 22 00 00 03 00 13 00 00 00 01 65 8a |..".........e.|+Sending: GET_TAG_ID_BUFFER 1733236.498026395+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1733236.503600010+ ff 26 29 00 00 01 ff 00 01 16 d6 11 0e 13 e8 00 |.&).............|+ 00 03 29 00 ae 05 00 00 00 00 80 30 00 e2 00 51 |..)........0...Q|+ 86 01 07 01 87 07 70 c4 c1 ba 1e 08 aa |......p......|+Sending: WRITE_TAG_SPECIFIC 1733236.504361013+ ff 26 2d 03 e8 00 41 00 c7 00 00 00 00 60 e2 00 |.&-...A......`..|+ 51 86 01 07 01 87 07 70 c4 c1 00 03 00 00 00 00 |Q......p........|+ 04 00 01 02 03 04 05 06 07 f3 66 |..........f|+Received:WRITE_TAG_SPECIFIC 1733236.536904406+ ff 04 2d 00 00 00 41 00 c7 46 73 |..-...A..Fs|+Sending: GET_READER_STATS 1733236.537262949+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1733236.539475858+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1733236.539649148+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1733236.541393558+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1733236.541581880+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1733236.543666695+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1733236.543972909+ ff 11 22 00 00 17 03 e8 01 09 28 07 d0 00 03 00 |..".......(.....|+ 00 00 00 20 49 70 |... Ip|+Received:READ_TAG_ID_MULTIPLE 1733237.559689784+ ff 4d 22 00 00 00 00 17 00 00 00 01 01 28 00 15 |.M"..........(..|+ 00 00 00 01 02 03 04 05 06 07 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 34 35 36 37 38 39 3a 3b 3c 3d |......456789:;<=|+ 3e 3f 14 7a |>?.z|+Sending: GET_TAG_ID_BUFFER 1733237.560562427+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1733237.571772759+ ff 66 29 00 00 01 ff 00 01 15 d8 11 0e 03 80 00 |.f).............|+ 00 01 a1 00 ae 05 02 00 00 01 02 03 04 05 06 07 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 34 35 36 37 |............4567|+ 38 39 3a 3b 3c 3d 3e 3f 00 00 80 30 00 e2 00 51 |89:;<=>?...0...Q|+ 86 01 07 01 87 07 70 c4 c1 ba 1e 59 6d |......p....Ym|
+ tests/gpi.result view
@@ -0,0 +1,1 @@+Right [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = True, gpOutput = False}]
+ tests/gpi.transport view
@@ -0,0 +1,58 @@+Sending: VERSION 1618349.830532032+ ff 00 03 1d 0c |.....|+Received:VERSION 1618349.834088647+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1618349.834651661+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1618349.836219541+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1618349.836338063+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1618349.838107299+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1618349.838259128+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1618349.840405018+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1618349.841446339+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1618349.843738766+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1618349.843921112+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1618349.845804952+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1618349.845969838+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1618349.848073650+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1618349.848306062+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1618349.850482317+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1618349.850695273+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1618349.853152056+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_USER_GPIO_OUTPUTS 1618349.853335246+ ff 04 96 01 01 00 00 2d 68 |.......-h|+Received:SET_USER_GPIO_OUTPUTS 1618349.855303359+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618349.855484441+ ff 04 96 01 02 00 00 1d 0b |.........|+Received:SET_USER_GPIO_OUTPUTS 1618349.857372145+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618349.857457353+ ff 04 96 01 03 00 00 0d 2a |........*|+Received:SET_USER_GPIO_OUTPUTS 1618349.859481273+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618349.859607401+ ff 04 96 01 04 00 00 7d cd |.......}.|+Received:SET_USER_GPIO_OUTPUTS 1618349.861699382+ ff 00 96 00 00 67 bf |.....g.|+Sending: GET_USER_GPIO_INPUTS 1618349.861992903+ ff 01 66 01 ba bc |..f...|+Received:GET_USER_GPIO_INPUTS 1618349.864881787+ ff 0d 66 00 00 01 01 00 00 02 00 00 03 00 00 04 |..f.............|+ 00 01 64 46 |..dF|
+ tests/gpo.result view
+ tests/gpo.transport view
@@ -0,0 +1,117 @@+Sending: VERSION 1618318.942992850+ ff 00 03 1d 0c |.....|+Received:VERSION 1618318.946535066+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1618318.947020444+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1618318.948566726+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1618318.948717066+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1618318.950309705+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1618318.950404769+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1618318.952376555+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1618318.953236827+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1618318.955499201+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1618318.955666882+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1618318.957566645+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1618318.957735305+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1618318.959879076+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1618318.960104443+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1618318.962299514+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1618318.962561529+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1618318.965031538+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_USER_GPIO_OUTPUTS 1618318.965276377+ ff 04 96 01 01 01 00 2c 68 |.......,h|+Received:SET_USER_GPIO_OUTPUTS 1618318.967228964+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.967416136+ ff 04 96 01 02 01 00 1c 0b |.........|+Received:SET_USER_GPIO_OUTPUTS 1618318.969281000+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.969370599+ ff 04 96 01 03 01 00 0c 2a |........*|+Received:SET_USER_GPIO_OUTPUTS 1618318.971406485+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.971538137+ ff 04 96 01 04 01 00 7c cd |.......|.|+Received:SET_USER_GPIO_OUTPUTS 1618318.973585255+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.973773431+ ff 02 96 01 01 00 dc |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.975520311+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.975658272+ ff 02 96 02 00 03 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.977385363+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.977471678+ ff 02 96 03 00 02 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.979121138+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.979212246+ ff 02 96 04 00 05 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.981086248+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.981222933+ ff 02 96 01 00 00 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.983093686+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.983221881+ ff 02 96 02 01 03 dc |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.985118247+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.985257581+ ff 02 96 03 00 02 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.987180140+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.987332353+ ff 02 96 04 00 05 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.989201090+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.989345414+ ff 02 96 01 00 00 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.991214250+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.991343106+ ff 02 96 02 00 03 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.993198749+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.993376145+ ff 02 96 03 01 02 dc |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.995161980+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.995420491+ ff 02 96 04 00 05 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.997327262+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.997461552+ ff 02 96 01 00 00 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618318.999330677+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618318.999462362+ ff 02 96 02 00 03 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618319.001219823+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618319.001349635+ ff 02 96 03 00 02 dd |.......|+Received:SET_USER_GPIO_OUTPUTS 1618319.002983389+ ff 00 96 00 00 67 bf |.....g.|+Sending: SET_USER_GPIO_OUTPUTS 1618319.003060700+ ff 02 96 04 01 05 dc |.......|+Received:SET_USER_GPIO_OUTPUTS 1618319.004690734+ ff 00 96 00 00 67 bf |.....g.|
+ tests/kill.result view
@@ -0,0 +1,5 @@+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\SOH\134\DLEP\178\ENQ", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 17157, tdGen2 = Just (GEN2_TagData {g2Pc = "4\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 27, trRssi = -36, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right ""+Right ""+Right 0
+ tests/kill.transport view
@@ -0,0 +1,111 @@+Sending: VERSION 1831074.447420502+ ff 00 03 1d 0c |.....|+Received:VERSION 1831074.452022120+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1831074.452559544+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1831074.454340797+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1831074.454531231+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1831074.456343322+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1831074.456488564+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1831074.458682283+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1831074.466612730+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1831074.468769754+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1831074.468885509+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1831074.470567920+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1831074.470671618+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1831074.472597812+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1831074.472737097+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1831074.474854214+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1831074.475006893+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1831074.477456734+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1831074.477619146+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1831074.479492124+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1831074.479681964+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1831074.481432960+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1831074.481527235+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1831074.483390045+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1831074.483543623+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1831074.485442387+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1831074.485576255+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1831074.487606924+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1831074.487818404+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1831074.490136003+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1831074.490291027+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1831074.492017214+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1831074.492271773+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1831074.494357801+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1831074.494526919+ ff 1e 22 03 00 13 03 e8 00 00 00 00 00 00 00 00 |..".............|+ 80 70 65 72 6d 61 6c 6f 63 00 04 00 05 00 06 00 |.permaloc.......|+ 07 3b 60 |.;`|+Received:READ_TAG_ID_MULTIPLE 1831075.503599087+ ff 07 22 00 00 03 00 13 00 00 00 01 65 8a |..".........e.|+Sending: GET_TAG_ID_BUFFER 1831075.503916938+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1831075.509398749+ ff 26 29 00 00 01 ff 00 01 1b dc 11 0e 13 e8 00 |.&).............|+ 00 03 08 00 ae 05 00 00 00 00 80 34 00 e2 00 00 |...........4....|+ 15 86 0e 01 86 10 50 b2 05 43 05 f6 ff |......P..C...|+Sending: WRITE_TAG_DATA 1831075.513325167+ ff 1d 24 03 e8 01 00 00 00 00 00 00 00 00 00 60 |..$............`|+ e2 00 00 15 86 0e 01 86 10 50 b2 05 be ad ea d1 |.........P......|+ 15 be |..|+Received:WRITE_TAG_DATA 1831075.551566490+ ff 00 24 00 00 e0 26 |..$...&|+Sending: KILL_TAG 1831075.551883959+ ff 15 26 03 e8 01 be ad ea d1 00 60 e2 00 00 15 |..&........`....|+ 86 0e 01 86 10 50 b2 05 9f 2a |.....P...*|+Received:KILL_TAG 1831075.605610474+ ff 00 26 00 00 c0 64 |..&...d|+Sending: GET_READER_STATS 1831075.605904821+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1831075.608102121+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1831075.608299737+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1831075.610065410+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1831075.610229640+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1831075.612277145+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1831075.612456260+ ff 22 22 01 00 17 03 e8 00 00 00 00 60 e2 00 00 |."".........`...|+ 15 86 0e 01 86 10 50 b2 05 01 09 28 07 d0 00 03 |......P....(....|+ 00 00 00 00 20 88 da |.... ..|+Received:READ_TAG_ID_MULTIPLE 1831076.620853129+ ff 0d 22 04 00 01 00 17 00 00 00 00 01 28 00 00 |.."..........(..|+ 00 00 d8 88 |....|
+ tests/lock.result view
@@ -0,0 +1,7 @@+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NULQ\134\SOH\a\SOH\135\ap\196\193", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 47646, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 21, trRssi = -41, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right ""+Right ""+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_PROTOCOL_WRITE_FAILED, meMessage = "Tag write operation failed", meLocation = "executeTagOp", meParam = "TagOp_GEN2_WriteData", meUri = ""})+Right ""+Right ""
+ tests/lock.transport view
@@ -0,0 +1,109 @@+Sending: VERSION 1790605.584555826+ ff 00 03 1d 0c |.....|+Received:VERSION 1790605.588060962+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1790605.588579065+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1790605.590133584+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1790605.590279389+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1790605.591896715+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1790605.591990509+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1790605.593926208+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1790605.594787483+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1790605.597048243+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1790605.597237617+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1790605.599164222+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1790605.599333871+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1790605.601513969+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1790605.601889295+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1790605.604146998+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1790605.604339750+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1790605.606640416+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1790605.606780094+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1790605.608595882+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1790605.608799467+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1790605.610710783+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1790605.610861534+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1790605.612720664+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1790605.612904299+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1790605.614647207+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1790605.614754132+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1790605.616556454+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1790605.616652209+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1790605.618851953+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1790605.619014686+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1790605.620740423+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1790605.620890824+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1790605.622843141+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1790605.623000323+ ff 10 22 03 00 13 03 e8 00 00 00 00 00 00 00 00 |..".............|+ 10 00 00 86 a3 |.....|+Received:READ_TAG_ID_MULTIPLE 1790606.630500088+ ff 07 22 00 00 03 00 13 00 00 00 01 65 8a |..".........e.|+Sending: GET_TAG_ID_BUFFER 1790606.630747461+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1790606.636238404+ ff 26 29 00 00 01 ff 00 01 15 d7 11 0e 13 e8 00 |.&).............|+ 00 03 cd 00 ae 05 00 00 00 00 80 30 00 e2 00 51 |...........0...Q|+ 86 01 07 01 87 07 70 c4 c1 ba 1e db e1 |......p......|+Sending: WRITE_TAG_DATA 1790606.636934933+ ff 1d 24 03 e8 01 00 00 00 02 00 00 00 00 00 60 |..$............`|+ e2 00 51 86 01 07 01 87 07 70 c4 c1 00 00 30 39 |..Q......p....09|+ a7 0f |..|+Received:WRITE_TAG_DATA 1790606.677344468+ ff 00 24 00 00 e0 26 |..$...&|+Sending: LOCK_TAG 1790606.677604774+ ff 18 25 03 e8 01 00 00 30 39 00 02 00 02 60 e2 |..%.....09....`.|+ 00 51 86 01 07 01 87 07 70 c4 c1 eb 70 |.Q......p...p|+Received:LOCK_TAG 1790606.736355478+ ff 00 25 00 00 f0 07 |..%....|+Sending: WRITE_TAG_DATA 1790606.736556271+ ff 29 24 03 e8 01 00 00 00 00 03 00 00 00 00 60 |.)$............`|+ e2 00 51 86 01 07 01 87 07 70 c4 c1 54 68 69 73 |..Q......p..This|+ 20 73 68 6f 75 6c 64 20 66 61 69 6c dd 94 | should fail..|+Received:WRITE_TAG_DATA 1790607.750972661+ ff 00 24 04 06 e4 20 |..$... |+Sending: LOCK_TAG 1790607.751291468+ ff 18 25 03 e8 01 00 00 30 39 00 02 00 00 60 e2 |..%.....09....`.|+ 00 51 86 01 07 01 87 07 70 c4 c1 ed 9a |.Q......p....|+Received:LOCK_TAG 1790607.821038416+ ff 00 25 00 00 f0 07 |..%....|+Sending: WRITE_TAG_DATA 1790607.821243325+ ff 2d 24 03 e8 01 00 00 00 00 03 00 00 00 00 60 |.-$............`|+ e2 00 51 86 01 07 01 87 07 70 c4 c1 54 68 69 73 |..Q......p..This|+ 20 73 68 6f 75 6c 64 20 73 75 63 63 65 65 64 00 | should succeed.|+ 69 0c |i.|+Received:WRITE_TAG_DATA 1790607.950912849+ ff 00 24 00 00 e0 26 |..$...&|
+ tests/param-test.hs view
@@ -0,0 +1,832 @@+-- Automatically generated by util/generate-tmr-hsc.pl+{-# LANGUAGE OverloadedStrings #-}++import Test.HUnit ( Test(..), runTestTT, assertEqual )++import qualified System.Hardware.MercuryApi as TMR++main = runTestTT tests++testBaudRate :: Test+testBaudRate = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_BAUDRATE"+ "/reader/baudRate"+ (TMR.paramName TMR.PARAM_BAUDRATE)+ assertEqual "TMR.paramID \"/reader/baudRate\""+ TMR.PARAM_BAUDRATE+ (TMR.paramID "/reader/baudRate")++testProbeBaudRates :: Test+testProbeBaudRates = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_PROBEBAUDRATES"+ "/reader/probeBaudRates"+ (TMR.paramName TMR.PARAM_PROBEBAUDRATES)+ assertEqual "TMR.paramID \"/reader/probeBaudRates\""+ TMR.PARAM_PROBEBAUDRATES+ (TMR.paramID "/reader/probeBaudRates")++testCommandTimeout :: Test+testCommandTimeout = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_COMMANDTIMEOUT"+ "/reader/commandTimeout"+ (TMR.paramName TMR.PARAM_COMMANDTIMEOUT)+ assertEqual "TMR.paramID \"/reader/commandTimeout\""+ TMR.PARAM_COMMANDTIMEOUT+ (TMR.paramID "/reader/commandTimeout")++testTransportTimeout :: Test+testTransportTimeout = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TRANSPORTTIMEOUT"+ "/reader/transportTimeout"+ (TMR.paramName TMR.PARAM_TRANSPORTTIMEOUT)+ assertEqual "TMR.paramID \"/reader/transportTimeout\""+ TMR.PARAM_TRANSPORTTIMEOUT+ (TMR.paramID "/reader/transportTimeout")++testPowerMode :: Test+testPowerMode = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_POWERMODE"+ "/reader/powerMode"+ (TMR.paramName TMR.PARAM_POWERMODE)+ assertEqual "TMR.paramID \"/reader/powerMode\""+ TMR.PARAM_POWERMODE+ (TMR.paramID "/reader/powerMode")++testUserMode :: Test+testUserMode = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_USERMODE"+ "/reader/userMode"+ (TMR.paramName TMR.PARAM_USERMODE)+ assertEqual "TMR.paramID \"/reader/userMode\""+ TMR.PARAM_USERMODE+ (TMR.paramID "/reader/userMode")++testAntennaCheckPort :: Test+testAntennaCheckPort = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ANTENNA_CHECKPORT"+ "/reader/antenna/checkPort"+ (TMR.paramName TMR.PARAM_ANTENNA_CHECKPORT)+ assertEqual "TMR.paramID \"/reader/antenna/checkPort\""+ TMR.PARAM_ANTENNA_CHECKPORT+ (TMR.paramID "/reader/antenna/checkPort")++testAntennaPortList :: Test+testAntennaPortList = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ANTENNA_PORTLIST"+ "/reader/antenna/portList"+ (TMR.paramName TMR.PARAM_ANTENNA_PORTLIST)+ assertEqual "TMR.paramID \"/reader/antenna/portList\""+ TMR.PARAM_ANTENNA_PORTLIST+ (TMR.paramID "/reader/antenna/portList")++testAntennaConnectedPortList :: Test+testAntennaConnectedPortList = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ANTENNA_CONNECTEDPORTLIST"+ "/reader/antenna/connectedPortList"+ (TMR.paramName TMR.PARAM_ANTENNA_CONNECTEDPORTLIST)+ assertEqual "TMR.paramID \"/reader/antenna/connectedPortList\""+ TMR.PARAM_ANTENNA_CONNECTEDPORTLIST+ (TMR.paramID "/reader/antenna/connectedPortList")++testAntennaPortSwitchGpos :: Test+testAntennaPortSwitchGpos = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ANTENNA_PORTSWITCHGPOS"+ "/reader/antenna/portSwitchGpos"+ (TMR.paramName TMR.PARAM_ANTENNA_PORTSWITCHGPOS)+ assertEqual "TMR.paramID \"/reader/antenna/portSwitchGpos\""+ TMR.PARAM_ANTENNA_PORTSWITCHGPOS+ (TMR.paramID "/reader/antenna/portSwitchGpos")++testAntennaSettlingTimeList :: Test+testAntennaSettlingTimeList = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ANTENNA_SETTLINGTIMELIST"+ "/reader/antenna/settlingTimeList"+ (TMR.paramName TMR.PARAM_ANTENNA_SETTLINGTIMELIST)+ assertEqual "TMR.paramID \"/reader/antenna/settlingTimeList\""+ TMR.PARAM_ANTENNA_SETTLINGTIMELIST+ (TMR.paramID "/reader/antenna/settlingTimeList")++testAntennaReturnLoss :: Test+testAntennaReturnLoss = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ANTENNA_RETURNLOSS"+ "/reader/antenna/returnLoss"+ (TMR.paramName TMR.PARAM_ANTENNA_RETURNLOSS)+ assertEqual "TMR.paramID \"/reader/antenna/returnLoss\""+ TMR.PARAM_ANTENNA_RETURNLOSS+ (TMR.paramID "/reader/antenna/returnLoss")++testAntennaTxRxMap :: Test+testAntennaTxRxMap = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ANTENNA_TXRXMAP"+ "/reader/antenna/txRxMap"+ (TMR.paramName TMR.PARAM_ANTENNA_TXRXMAP)+ assertEqual "TMR.paramID \"/reader/antenna/txRxMap\""+ TMR.PARAM_ANTENNA_TXRXMAP+ (TMR.paramID "/reader/antenna/txRxMap")++testGpioInputList :: Test+testGpioInputList = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GPIO_INPUTLIST"+ "/reader/gpio/inputList"+ (TMR.paramName TMR.PARAM_GPIO_INPUTLIST)+ assertEqual "TMR.paramID \"/reader/gpio/inputList\""+ TMR.PARAM_GPIO_INPUTLIST+ (TMR.paramID "/reader/gpio/inputList")++testGpioOutputList :: Test+testGpioOutputList = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GPIO_OUTPUTLIST"+ "/reader/gpio/outputList"+ (TMR.paramName TMR.PARAM_GPIO_OUTPUTLIST)+ assertEqual "TMR.paramID \"/reader/gpio/outputList\""+ TMR.PARAM_GPIO_OUTPUTLIST+ (TMR.paramID "/reader/gpio/outputList")++testGen2AccessPassword :: Test+testGen2AccessPassword = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_ACCESSPASSWORD"+ "/reader/gen2/accessPassword"+ (TMR.paramName TMR.PARAM_GEN2_ACCESSPASSWORD)+ assertEqual "TMR.paramID \"/reader/gen2/accessPassword\""+ TMR.PARAM_GEN2_ACCESSPASSWORD+ (TMR.paramID "/reader/gen2/accessPassword")++testGen2Q :: Test+testGen2Q = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_Q"+ "/reader/gen2/q"+ (TMR.paramName TMR.PARAM_GEN2_Q)+ assertEqual "TMR.paramID \"/reader/gen2/q\""+ TMR.PARAM_GEN2_Q+ (TMR.paramID "/reader/gen2/q")++testGen2TagEncoding :: Test+testGen2TagEncoding = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_TAGENCODING"+ "/reader/gen2/tagEncoding"+ (TMR.paramName TMR.PARAM_GEN2_TAGENCODING)+ assertEqual "TMR.paramID \"/reader/gen2/tagEncoding\""+ TMR.PARAM_GEN2_TAGENCODING+ (TMR.paramID "/reader/gen2/tagEncoding")++testGen2Session :: Test+testGen2Session = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_SESSION"+ "/reader/gen2/session"+ (TMR.paramName TMR.PARAM_GEN2_SESSION)+ assertEqual "TMR.paramID \"/reader/gen2/session\""+ TMR.PARAM_GEN2_SESSION+ (TMR.paramID "/reader/gen2/session")++testGen2Target :: Test+testGen2Target = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_TARGET"+ "/reader/gen2/target"+ (TMR.paramName TMR.PARAM_GEN2_TARGET)+ assertEqual "TMR.paramID \"/reader/gen2/target\""+ TMR.PARAM_GEN2_TARGET+ (TMR.paramID "/reader/gen2/target")++testGen2BLF :: Test+testGen2BLF = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_BLF"+ "/reader/gen2/BLF"+ (TMR.paramName TMR.PARAM_GEN2_BLF)+ assertEqual "TMR.paramID \"/reader/gen2/BLF\""+ TMR.PARAM_GEN2_BLF+ (TMR.paramID "/reader/gen2/BLF")++testGen2Tari :: Test+testGen2Tari = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_TARI"+ "/reader/gen2/tari"+ (TMR.paramName TMR.PARAM_GEN2_TARI)+ assertEqual "TMR.paramID \"/reader/gen2/tari\""+ TMR.PARAM_GEN2_TARI+ (TMR.paramID "/reader/gen2/tari")++testGen2WriteMode :: Test+testGen2WriteMode = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_WRITEMODE"+ "/reader/gen2/writeMode"+ (TMR.paramName TMR.PARAM_GEN2_WRITEMODE)+ assertEqual "TMR.paramID \"/reader/gen2/writeMode\""+ TMR.PARAM_GEN2_WRITEMODE+ (TMR.paramID "/reader/gen2/writeMode")++testGen2Bap :: Test+testGen2Bap = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_BAP"+ "/reader/gen2/bap"+ (TMR.paramName TMR.PARAM_GEN2_BAP)+ assertEqual "TMR.paramID \"/reader/gen2/bap\""+ TMR.PARAM_GEN2_BAP+ (TMR.paramID "/reader/gen2/bap")++testGen2ProtocolExtension :: Test+testGen2ProtocolExtension = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_GEN2_PROTOCOLEXTENSION"+ "/reader/gen2/protocolExtension"+ (TMR.paramName TMR.PARAM_GEN2_PROTOCOLEXTENSION)+ assertEqual "TMR.paramID \"/reader/gen2/protocolExtension\""+ TMR.PARAM_GEN2_PROTOCOLEXTENSION+ (TMR.paramID "/reader/gen2/protocolExtension")++testIso180006bBLF :: Test+testIso180006bBLF = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ISO180006B_BLF"+ "/reader/iso180006b/BLF"+ (TMR.paramName TMR.PARAM_ISO180006B_BLF)+ assertEqual "TMR.paramID \"/reader/iso180006b/BLF\""+ TMR.PARAM_ISO180006B_BLF+ (TMR.paramID "/reader/iso180006b/BLF")++testIso180006bModulationDepth :: Test+testIso180006bModulationDepth = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ISO180006B_MODULATION_DEPTH"+ "/reader/iso180006b/modulationDepth"+ (TMR.paramName TMR.PARAM_ISO180006B_MODULATION_DEPTH)+ assertEqual "TMR.paramID \"/reader/iso180006b/modulationDepth\""+ TMR.PARAM_ISO180006B_MODULATION_DEPTH+ (TMR.paramID "/reader/iso180006b/modulationDepth")++testIso180006bDelimiter :: Test+testIso180006bDelimiter = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_ISO180006B_DELIMITER"+ "/reader/iso180006b/delimiter"+ (TMR.paramName TMR.PARAM_ISO180006B_DELIMITER)+ assertEqual "TMR.paramID \"/reader/iso180006b/delimiter\""+ TMR.PARAM_ISO180006B_DELIMITER+ (TMR.paramID "/reader/iso180006b/delimiter")++testReadAsyncOffTime :: Test+testReadAsyncOffTime = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READ_ASYNCOFFTIME"+ "/reader/read/asyncOffTime"+ (TMR.paramName TMR.PARAM_READ_ASYNCOFFTIME)+ assertEqual "TMR.paramID \"/reader/read/asyncOffTime\""+ TMR.PARAM_READ_ASYNCOFFTIME+ (TMR.paramID "/reader/read/asyncOffTime")++testReadAsyncOnTime :: Test+testReadAsyncOnTime = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READ_ASYNCONTIME"+ "/reader/read/asyncOnTime"+ (TMR.paramName TMR.PARAM_READ_ASYNCONTIME)+ assertEqual "TMR.paramID \"/reader/read/asyncOnTime\""+ TMR.PARAM_READ_ASYNCONTIME+ (TMR.paramID "/reader/read/asyncOnTime")++testReadPlan :: Test+testReadPlan = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READ_PLAN"+ "/reader/read/plan"+ (TMR.paramName TMR.PARAM_READ_PLAN)+ assertEqual "TMR.paramID \"/reader/read/plan\""+ TMR.PARAM_READ_PLAN+ (TMR.paramID "/reader/read/plan")++testRadioEnablePowerSave :: Test+testRadioEnablePowerSave = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_RADIO_ENABLEPOWERSAVE"+ "/reader/radio/enablePowerSave"+ (TMR.paramName TMR.PARAM_RADIO_ENABLEPOWERSAVE)+ assertEqual "TMR.paramID \"/reader/radio/enablePowerSave\""+ TMR.PARAM_RADIO_ENABLEPOWERSAVE+ (TMR.paramID "/reader/radio/enablePowerSave")++testRadioPowerMax :: Test+testRadioPowerMax = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_RADIO_POWERMAX"+ "/reader/radio/powerMax"+ (TMR.paramName TMR.PARAM_RADIO_POWERMAX)+ assertEqual "TMR.paramID \"/reader/radio/powerMax\""+ TMR.PARAM_RADIO_POWERMAX+ (TMR.paramID "/reader/radio/powerMax")++testRadioPowerMin :: Test+testRadioPowerMin = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_RADIO_POWERMIN"+ "/reader/radio/powerMin"+ (TMR.paramName TMR.PARAM_RADIO_POWERMIN)+ assertEqual "TMR.paramID \"/reader/radio/powerMin\""+ TMR.PARAM_RADIO_POWERMIN+ (TMR.paramID "/reader/radio/powerMin")++testRadioPortReadPowerList :: Test+testRadioPortReadPowerList = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_RADIO_PORTREADPOWERLIST"+ "/reader/radio/portReadPowerList"+ (TMR.paramName TMR.PARAM_RADIO_PORTREADPOWERLIST)+ assertEqual "TMR.paramID \"/reader/radio/portReadPowerList\""+ TMR.PARAM_RADIO_PORTREADPOWERLIST+ (TMR.paramID "/reader/radio/portReadPowerList")++testRadioPortWritePowerList :: Test+testRadioPortWritePowerList = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_RADIO_PORTWRITEPOWERLIST"+ "/reader/radio/portWritePowerList"+ (TMR.paramName TMR.PARAM_RADIO_PORTWRITEPOWERLIST)+ assertEqual "TMR.paramID \"/reader/radio/portWritePowerList\""+ TMR.PARAM_RADIO_PORTWRITEPOWERLIST+ (TMR.paramID "/reader/radio/portWritePowerList")++testRadioReadPower :: Test+testRadioReadPower = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_RADIO_READPOWER"+ "/reader/radio/readPower"+ (TMR.paramName TMR.PARAM_RADIO_READPOWER)+ assertEqual "TMR.paramID \"/reader/radio/readPower\""+ TMR.PARAM_RADIO_READPOWER+ (TMR.paramID "/reader/radio/readPower")++testRadioWritePower :: Test+testRadioWritePower = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_RADIO_WRITEPOWER"+ "/reader/radio/writePower"+ (TMR.paramName TMR.PARAM_RADIO_WRITEPOWER)+ assertEqual "TMR.paramID \"/reader/radio/writePower\""+ TMR.PARAM_RADIO_WRITEPOWER+ (TMR.paramID "/reader/radio/writePower")++testRadioTemperature :: Test+testRadioTemperature = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_RADIO_TEMPERATURE"+ "/reader/radio/temperature"+ (TMR.paramName TMR.PARAM_RADIO_TEMPERATURE)+ assertEqual "TMR.paramID \"/reader/radio/temperature\""+ TMR.PARAM_RADIO_TEMPERATURE+ (TMR.paramID "/reader/radio/temperature")++testTagReadDataRecordHighestRssi :: Test+testTagReadDataRecordHighestRssi = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGREADDATA_RECORDHIGHESTRSSI"+ "/reader/tagReadData/recordHighestRssi"+ (TMR.paramName TMR.PARAM_TAGREADDATA_RECORDHIGHESTRSSI)+ assertEqual "TMR.paramID \"/reader/tagReadData/recordHighestRssi\""+ TMR.PARAM_TAGREADDATA_RECORDHIGHESTRSSI+ (TMR.paramID "/reader/tagReadData/recordHighestRssi")++testTagReadDataReportRssiInDbm :: Test+testTagReadDataReportRssiInDbm = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGREADDATA_REPORTRSSIINDBM"+ "/reader/tagReadData/reportRssiInDbm"+ (TMR.paramName TMR.PARAM_TAGREADDATA_REPORTRSSIINDBM)+ assertEqual "TMR.paramID \"/reader/tagReadData/reportRssiInDbm\""+ TMR.PARAM_TAGREADDATA_REPORTRSSIINDBM+ (TMR.paramID "/reader/tagReadData/reportRssiInDbm")++testTagReadDataUniqueByAntenna :: Test+testTagReadDataUniqueByAntenna = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGREADDATA_UNIQUEBYANTENNA"+ "/reader/tagReadData/uniqueByAntenna"+ (TMR.paramName TMR.PARAM_TAGREADDATA_UNIQUEBYANTENNA)+ assertEqual "TMR.paramID \"/reader/tagReadData/uniqueByAntenna\""+ TMR.PARAM_TAGREADDATA_UNIQUEBYANTENNA+ (TMR.paramID "/reader/tagReadData/uniqueByAntenna")++testTagReadDataUniqueByData :: Test+testTagReadDataUniqueByData = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGREADDATA_UNIQUEBYDATA"+ "/reader/tagReadData/uniqueByData"+ (TMR.paramName TMR.PARAM_TAGREADDATA_UNIQUEBYDATA)+ assertEqual "TMR.paramID \"/reader/tagReadData/uniqueByData\""+ TMR.PARAM_TAGREADDATA_UNIQUEBYDATA+ (TMR.paramID "/reader/tagReadData/uniqueByData")++testTagopAntenna :: Test+testTagopAntenna = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGOP_ANTENNA"+ "/reader/tagop/antenna"+ (TMR.paramName TMR.PARAM_TAGOP_ANTENNA)+ assertEqual "TMR.paramID \"/reader/tagop/antenna\""+ TMR.PARAM_TAGOP_ANTENNA+ (TMR.paramID "/reader/tagop/antenna")++testTagopProtocol :: Test+testTagopProtocol = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGOP_PROTOCOL"+ "/reader/tagop/protocol"+ (TMR.paramName TMR.PARAM_TAGOP_PROTOCOL)+ assertEqual "TMR.paramID \"/reader/tagop/protocol\""+ TMR.PARAM_TAGOP_PROTOCOL+ (TMR.paramID "/reader/tagop/protocol")++testVersionHardware :: Test+testVersionHardware = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_VERSION_HARDWARE"+ "/reader/version/hardware"+ (TMR.paramName TMR.PARAM_VERSION_HARDWARE)+ assertEqual "TMR.paramID \"/reader/version/hardware\""+ TMR.PARAM_VERSION_HARDWARE+ (TMR.paramID "/reader/version/hardware")++testVersionSerial :: Test+testVersionSerial = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_VERSION_SERIAL"+ "/reader/version/serial"+ (TMR.paramName TMR.PARAM_VERSION_SERIAL)+ assertEqual "TMR.paramID \"/reader/version/serial\""+ TMR.PARAM_VERSION_SERIAL+ (TMR.paramID "/reader/version/serial")++testVersionModel :: Test+testVersionModel = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_VERSION_MODEL"+ "/reader/version/model"+ (TMR.paramName TMR.PARAM_VERSION_MODEL)+ assertEqual "TMR.paramID \"/reader/version/model\""+ TMR.PARAM_VERSION_MODEL+ (TMR.paramID "/reader/version/model")++testVersionSoftware :: Test+testVersionSoftware = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_VERSION_SOFTWARE"+ "/reader/version/software"+ (TMR.paramName TMR.PARAM_VERSION_SOFTWARE)+ assertEqual "TMR.paramID \"/reader/version/software\""+ TMR.PARAM_VERSION_SOFTWARE+ (TMR.paramID "/reader/version/software")++testVersionSupportedProtocols :: Test+testVersionSupportedProtocols = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_VERSION_SUPPORTEDPROTOCOLS"+ "/reader/version/supportedProtocols"+ (TMR.paramName TMR.PARAM_VERSION_SUPPORTEDPROTOCOLS)+ assertEqual "TMR.paramID \"/reader/version/supportedProtocols\""+ TMR.PARAM_VERSION_SUPPORTEDPROTOCOLS+ (TMR.paramID "/reader/version/supportedProtocols")++testRegionHopTable :: Test+testRegionHopTable = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_REGION_HOPTABLE"+ "/reader/region/hopTable"+ (TMR.paramName TMR.PARAM_REGION_HOPTABLE)+ assertEqual "TMR.paramID \"/reader/region/hopTable\""+ TMR.PARAM_REGION_HOPTABLE+ (TMR.paramID "/reader/region/hopTable")++testRegionHopTime :: Test+testRegionHopTime = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_REGION_HOPTIME"+ "/reader/region/hopTime"+ (TMR.paramName TMR.PARAM_REGION_HOPTIME)+ assertEqual "TMR.paramID \"/reader/region/hopTime\""+ TMR.PARAM_REGION_HOPTIME+ (TMR.paramID "/reader/region/hopTime")++testRegionId :: Test+testRegionId = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_REGION_ID"+ "/reader/region/id"+ (TMR.paramName TMR.PARAM_REGION_ID)+ assertEqual "TMR.paramID \"/reader/region/id\""+ TMR.PARAM_REGION_ID+ (TMR.paramID "/reader/region/id")++testRegionSupportedRegions :: Test+testRegionSupportedRegions = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_REGION_SUPPORTEDREGIONS"+ "/reader/region/supportedRegions"+ (TMR.paramName TMR.PARAM_REGION_SUPPORTEDREGIONS)+ assertEqual "TMR.paramID \"/reader/region/supportedRegions\""+ TMR.PARAM_REGION_SUPPORTEDREGIONS+ (TMR.paramID "/reader/region/supportedRegions")++testRegionLbtEnable :: Test+testRegionLbtEnable = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_REGION_LBT_ENABLE"+ "/reader/region/lbt/enable"+ (TMR.paramName TMR.PARAM_REGION_LBT_ENABLE)+ assertEqual "TMR.paramID \"/reader/region/lbt/enable\""+ TMR.PARAM_REGION_LBT_ENABLE+ (TMR.paramID "/reader/region/lbt/enable")++testLicenseKey :: Test+testLicenseKey = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_LICENSE_KEY"+ "/reader/licenseKey"+ (TMR.paramName TMR.PARAM_LICENSE_KEY)+ assertEqual "TMR.paramID \"/reader/licenseKey\""+ TMR.PARAM_LICENSE_KEY+ (TMR.paramID "/reader/licenseKey")++testUserConfig :: Test+testUserConfig = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_USER_CONFIG"+ "/reader/userConfig"+ (TMR.paramName TMR.PARAM_USER_CONFIG)+ assertEqual "TMR.paramID \"/reader/userConfig\""+ TMR.PARAM_USER_CONFIG+ (TMR.paramID "/reader/userConfig")++testRadioEnableSJC :: Test+testRadioEnableSJC = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_RADIO_ENABLESJC"+ "/reader/radio/enableSJC"+ (TMR.paramName TMR.PARAM_RADIO_ENABLESJC)+ assertEqual "TMR.paramID \"/reader/radio/enableSJC\""+ TMR.PARAM_RADIO_ENABLESJC+ (TMR.paramID "/reader/radio/enableSJC")++testExtendedEpc :: Test+testExtendedEpc = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_EXTENDEDEPC"+ "/reader/extendedEpc"+ (TMR.paramName TMR.PARAM_EXTENDEDEPC)+ assertEqual "TMR.paramID \"/reader/extendedEpc\""+ TMR.PARAM_EXTENDEDEPC+ (TMR.paramID "/reader/extendedEpc")++testStatistics :: Test+testStatistics = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READER_STATISTICS"+ "/reader/statistics"+ (TMR.paramName TMR.PARAM_READER_STATISTICS)+ assertEqual "TMR.paramID \"/reader/statistics\""+ TMR.PARAM_READER_STATISTICS+ (TMR.paramID "/reader/statistics")++testStats :: Test+testStats = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READER_STATS"+ "/reader/stats"+ (TMR.paramName TMR.PARAM_READER_STATS)+ assertEqual "TMR.paramID \"/reader/stats\""+ TMR.PARAM_READER_STATS+ (TMR.paramID "/reader/stats")++testUri :: Test+testUri = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_URI"+ "/reader/uri"+ (TMR.paramName TMR.PARAM_URI)+ assertEqual "TMR.paramID \"/reader/uri\""+ TMR.PARAM_URI+ (TMR.paramID "/reader/uri")++testVersionProductGroupID :: Test+testVersionProductGroupID = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_PRODUCT_GROUP_ID"+ "/reader/version/productGroupID"+ (TMR.paramName TMR.PARAM_PRODUCT_GROUP_ID)+ assertEqual "TMR.paramID \"/reader/version/productGroupID\""+ TMR.PARAM_PRODUCT_GROUP_ID+ (TMR.paramID "/reader/version/productGroupID")++testVersionProductGroup :: Test+testVersionProductGroup = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_PRODUCT_GROUP"+ "/reader/version/productGroup"+ (TMR.paramName TMR.PARAM_PRODUCT_GROUP)+ assertEqual "TMR.paramID \"/reader/version/productGroup\""+ TMR.PARAM_PRODUCT_GROUP+ (TMR.paramID "/reader/version/productGroup")++testVersionProductID :: Test+testVersionProductID = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_PRODUCT_ID"+ "/reader/version/productID"+ (TMR.paramName TMR.PARAM_PRODUCT_ID)+ assertEqual "TMR.paramID \"/reader/version/productID\""+ TMR.PARAM_PRODUCT_ID+ (TMR.paramID "/reader/version/productID")++testTagReadDataTagopSuccesses :: Test+testTagReadDataTagopSuccesses = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGREADATA_TAGOPSUCCESSCOUNT"+ "/reader/tagReadData/tagopSuccesses"+ (TMR.paramName TMR.PARAM_TAGREADATA_TAGOPSUCCESSCOUNT)+ assertEqual "TMR.paramID \"/reader/tagReadData/tagopSuccesses\""+ TMR.PARAM_TAGREADATA_TAGOPSUCCESSCOUNT+ (TMR.paramID "/reader/tagReadData/tagopSuccesses")++testTagReadDataTagopFailures :: Test+testTagReadDataTagopFailures = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGREADATA_TAGOPFAILURECOUNT"+ "/reader/tagReadData/tagopFailures"+ (TMR.paramName TMR.PARAM_TAGREADATA_TAGOPFAILURECOUNT)+ assertEqual "TMR.paramID \"/reader/tagReadData/tagopFailures\""+ TMR.PARAM_TAGREADATA_TAGOPFAILURECOUNT+ (TMR.paramID "/reader/tagReadData/tagopFailures")++testStatusAntennaEnable :: Test+testStatusAntennaEnable = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_STATUS_ENABLE_ANTENNAREPORT"+ "/reader/status/antennaEnable"+ (TMR.paramName TMR.PARAM_STATUS_ENABLE_ANTENNAREPORT)+ assertEqual "TMR.paramID \"/reader/status/antennaEnable\""+ TMR.PARAM_STATUS_ENABLE_ANTENNAREPORT+ (TMR.paramID "/reader/status/antennaEnable")++testStatusFrequencyEnable :: Test+testStatusFrequencyEnable = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_STATUS_ENABLE_FREQUENCYREPORT"+ "/reader/status/frequencyEnable"+ (TMR.paramName TMR.PARAM_STATUS_ENABLE_FREQUENCYREPORT)+ assertEqual "TMR.paramID \"/reader/status/frequencyEnable\""+ TMR.PARAM_STATUS_ENABLE_FREQUENCYREPORT+ (TMR.paramID "/reader/status/frequencyEnable")++testStatusTemperatureEnable :: Test+testStatusTemperatureEnable = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_STATUS_ENABLE_TEMPERATUREREPORT"+ "/reader/status/temperatureEnable"+ (TMR.paramName TMR.PARAM_STATUS_ENABLE_TEMPERATUREREPORT)+ assertEqual "TMR.paramID \"/reader/status/temperatureEnable\""+ TMR.PARAM_STATUS_ENABLE_TEMPERATUREREPORT+ (TMR.paramID "/reader/status/temperatureEnable")++testTagReadDataEnableReadFilter :: Test+testTagReadDataEnableReadFilter = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGREADDATA_ENABLEREADFILTER"+ "/reader/tagReadData/enableReadFilter"+ (TMR.paramName TMR.PARAM_TAGREADDATA_ENABLEREADFILTER)+ assertEqual "TMR.paramID \"/reader/tagReadData/enableReadFilter\""+ TMR.PARAM_TAGREADDATA_ENABLEREADFILTER+ (TMR.paramID "/reader/tagReadData/enableReadFilter")++testTagReadDataReadFilterTimeout :: Test+testTagReadDataReadFilterTimeout = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGREADDATA_READFILTERTIMEOUT"+ "/reader/tagReadData/readFilterTimeout"+ (TMR.paramName TMR.PARAM_TAGREADDATA_READFILTERTIMEOUT)+ assertEqual "TMR.paramID \"/reader/tagReadData/readFilterTimeout\""+ TMR.PARAM_TAGREADDATA_READFILTERTIMEOUT+ (TMR.paramID "/reader/tagReadData/readFilterTimeout")++testTagReadDataUniqueByProtocol :: Test+testTagReadDataUniqueByProtocol = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TAGREADDATA_UNIQUEBYPROTOCOL"+ "/reader/tagReadData/uniqueByProtocol"+ (TMR.paramName TMR.PARAM_TAGREADDATA_UNIQUEBYPROTOCOL)+ assertEqual "TMR.paramID \"/reader/tagReadData/uniqueByProtocol\""+ TMR.PARAM_TAGREADDATA_UNIQUEBYPROTOCOL+ (TMR.paramID "/reader/tagReadData/uniqueByProtocol")++testDescription :: Test+testDescription = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READER_DESCRIPTION"+ "/reader/description"+ (TMR.paramName TMR.PARAM_READER_DESCRIPTION)+ assertEqual "TMR.paramID \"/reader/description\""+ TMR.PARAM_READER_DESCRIPTION+ (TMR.paramID "/reader/description")++testHostname :: Test+testHostname = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READER_HOSTNAME"+ "/reader/hostname"+ (TMR.paramName TMR.PARAM_READER_HOSTNAME)+ assertEqual "TMR.paramID \"/reader/hostname\""+ TMR.PARAM_READER_HOSTNAME+ (TMR.paramID "/reader/hostname")++testCurrentTime :: Test+testCurrentTime = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_CURRENTTIME"+ "/reader/currentTime"+ (TMR.paramName TMR.PARAM_CURRENTTIME)+ assertEqual "TMR.paramID \"/reader/currentTime\""+ TMR.PARAM_CURRENTTIME+ (TMR.paramID "/reader/currentTime")++testGen2WriteReplyTimeout :: Test+testGen2WriteReplyTimeout = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READER_WRITE_REPLY_TIMEOUT"+ "/reader/gen2/writeReplyTimeout"+ (TMR.paramName TMR.PARAM_READER_WRITE_REPLY_TIMEOUT)+ assertEqual "TMR.paramID \"/reader/gen2/writeReplyTimeout\""+ TMR.PARAM_READER_WRITE_REPLY_TIMEOUT+ (TMR.paramID "/reader/gen2/writeReplyTimeout")++testGen2WriteEarlyExit :: Test+testGen2WriteEarlyExit = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READER_WRITE_EARLY_EXIT"+ "/reader/gen2/writeEarlyExit"+ (TMR.paramName TMR.PARAM_READER_WRITE_EARLY_EXIT)+ assertEqual "TMR.paramID \"/reader/gen2/writeEarlyExit\""+ TMR.PARAM_READER_WRITE_EARLY_EXIT+ (TMR.paramID "/reader/gen2/writeEarlyExit")++testStatsEnable :: Test+testStatsEnable = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_READER_STATS_ENABLE"+ "/reader/stats/enable"+ (TMR.paramName TMR.PARAM_READER_STATS_ENABLE)+ assertEqual "TMR.paramID \"/reader/stats/enable\""+ TMR.PARAM_READER_STATS_ENABLE+ (TMR.paramID "/reader/stats/enable")++testTriggerReadGpi :: Test+testTriggerReadGpi = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_TRIGGER_READ_GPI"+ "/reader/trigger/read/Gpi"+ (TMR.paramName TMR.PARAM_TRIGGER_READ_GPI)+ assertEqual "TMR.paramID \"/reader/trigger/read/Gpi\""+ TMR.PARAM_TRIGGER_READ_GPI+ (TMR.paramID "/reader/trigger/read/Gpi")++testMetadataflags :: Test+testMetadataflags = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_METADATAFLAG"+ "/reader/metadataflags"+ (TMR.paramName TMR.PARAM_METADATAFLAG)+ assertEqual "TMR.paramID \"/reader/metadataflags\""+ TMR.PARAM_METADATAFLAG+ (TMR.paramID "/reader/metadataflags")++testLicensedFeatures :: Test+testLicensedFeatures = TestCase $ do+ assertEqual "TMR.paramName TMR.PARAM_LICENSED_FEATURES"+ "/reader/licensedFeatures"+ (TMR.paramName TMR.PARAM_LICENSED_FEATURES)+ assertEqual "TMR.paramID \"/reader/licensedFeatures\""+ TMR.PARAM_LICENSED_FEATURES+ (TMR.paramID "/reader/licensedFeatures")++tests :: Test+tests = TestList+ [ TestLabel "testBaudRate" testBaudRate+ , TestLabel "testProbeBaudRates" testProbeBaudRates+ , TestLabel "testCommandTimeout" testCommandTimeout+ , TestLabel "testTransportTimeout" testTransportTimeout+ , TestLabel "testPowerMode" testPowerMode+ , TestLabel "testUserMode" testUserMode+ , TestLabel "testAntennaCheckPort" testAntennaCheckPort+ , TestLabel "testAntennaPortList" testAntennaPortList+ , TestLabel "testAntennaConnectedPortList" testAntennaConnectedPortList+ , TestLabel "testAntennaPortSwitchGpos" testAntennaPortSwitchGpos+ , TestLabel "testAntennaSettlingTimeList" testAntennaSettlingTimeList+ , TestLabel "testAntennaReturnLoss" testAntennaReturnLoss+ , TestLabel "testAntennaTxRxMap" testAntennaTxRxMap+ , TestLabel "testGpioInputList" testGpioInputList+ , TestLabel "testGpioOutputList" testGpioOutputList+ , TestLabel "testGen2AccessPassword" testGen2AccessPassword+ , TestLabel "testGen2Q" testGen2Q+ , TestLabel "testGen2TagEncoding" testGen2TagEncoding+ , TestLabel "testGen2Session" testGen2Session+ , TestLabel "testGen2Target" testGen2Target+ , TestLabel "testGen2BLF" testGen2BLF+ , TestLabel "testGen2Tari" testGen2Tari+ , TestLabel "testGen2WriteMode" testGen2WriteMode+ , TestLabel "testGen2Bap" testGen2Bap+ , TestLabel "testGen2ProtocolExtension" testGen2ProtocolExtension+ , TestLabel "testIso180006bBLF" testIso180006bBLF+ , TestLabel "testIso180006bModulationDepth" testIso180006bModulationDepth+ , TestLabel "testIso180006bDelimiter" testIso180006bDelimiter+ , TestLabel "testReadAsyncOffTime" testReadAsyncOffTime+ , TestLabel "testReadAsyncOnTime" testReadAsyncOnTime+ , TestLabel "testReadPlan" testReadPlan+ , TestLabel "testRadioEnablePowerSave" testRadioEnablePowerSave+ , TestLabel "testRadioPowerMax" testRadioPowerMax+ , TestLabel "testRadioPowerMin" testRadioPowerMin+ , TestLabel "testRadioPortReadPowerList" testRadioPortReadPowerList+ , TestLabel "testRadioPortWritePowerList" testRadioPortWritePowerList+ , TestLabel "testRadioReadPower" testRadioReadPower+ , TestLabel "testRadioWritePower" testRadioWritePower+ , TestLabel "testRadioTemperature" testRadioTemperature+ , TestLabel "testTagReadDataRecordHighestRssi" testTagReadDataRecordHighestRssi+ , TestLabel "testTagReadDataReportRssiInDbm" testTagReadDataReportRssiInDbm+ , TestLabel "testTagReadDataUniqueByAntenna" testTagReadDataUniqueByAntenna+ , TestLabel "testTagReadDataUniqueByData" testTagReadDataUniqueByData+ , TestLabel "testTagopAntenna" testTagopAntenna+ , TestLabel "testTagopProtocol" testTagopProtocol+ , TestLabel "testVersionHardware" testVersionHardware+ , TestLabel "testVersionSerial" testVersionSerial+ , TestLabel "testVersionModel" testVersionModel+ , TestLabel "testVersionSoftware" testVersionSoftware+ , TestLabel "testVersionSupportedProtocols" testVersionSupportedProtocols+ , TestLabel "testRegionHopTable" testRegionHopTable+ , TestLabel "testRegionHopTime" testRegionHopTime+ , TestLabel "testRegionId" testRegionId+ , TestLabel "testRegionSupportedRegions" testRegionSupportedRegions+ , TestLabel "testRegionLbtEnable" testRegionLbtEnable+ , TestLabel "testLicenseKey" testLicenseKey+ , TestLabel "testUserConfig" testUserConfig+ , TestLabel "testRadioEnableSJC" testRadioEnableSJC+ , TestLabel "testExtendedEpc" testExtendedEpc+ , TestLabel "testStatistics" testStatistics+ , TestLabel "testStats" testStats+ , TestLabel "testUri" testUri+ , TestLabel "testVersionProductGroupID" testVersionProductGroupID+ , TestLabel "testVersionProductGroup" testVersionProductGroup+ , TestLabel "testVersionProductID" testVersionProductID+ , TestLabel "testTagReadDataTagopSuccesses" testTagReadDataTagopSuccesses+ , TestLabel "testTagReadDataTagopFailures" testTagReadDataTagopFailures+ , TestLabel "testStatusAntennaEnable" testStatusAntennaEnable+ , TestLabel "testStatusFrequencyEnable" testStatusFrequencyEnable+ , TestLabel "testStatusTemperatureEnable" testStatusTemperatureEnable+ , TestLabel "testTagReadDataEnableReadFilter" testTagReadDataEnableReadFilter+ , TestLabel "testTagReadDataReadFilterTimeout" testTagReadDataReadFilterTimeout+ , TestLabel "testTagReadDataUniqueByProtocol" testTagReadDataUniqueByProtocol+ , TestLabel "testDescription" testDescription+ , TestLabel "testHostname" testHostname+ , TestLabel "testCurrentTime" testCurrentTime+ , TestLabel "testGen2WriteReplyTimeout" testGen2WriteReplyTimeout+ , TestLabel "testGen2WriteEarlyExit" testGen2WriteEarlyExit+ , TestLabel "testStatsEnable" testStatsEnable+ , TestLabel "testTriggerReadGpi" testTriggerReadGpi+ , TestLabel "testMetadataflags" testMetadataflags+ , TestLabel "testLicensedFeatures" testLicensedFeatures+ ]
+ tests/params.result view
@@ -0,0 +1,77 @@+Right [PARAM_BAUDRATE,PARAM_PROBEBAUDRATES,PARAM_COMMANDTIMEOUT,PARAM_TRANSPORTTIMEOUT,PARAM_POWERMODE,PARAM_USERMODE,PARAM_ANTENNA_CHECKPORT,PARAM_ANTENNA_PORTLIST,PARAM_ANTENNA_CONNECTEDPORTLIST,PARAM_ANTENNA_PORTSWITCHGPOS,PARAM_ANTENNA_SETTLINGTIMELIST,PARAM_ANTENNA_RETURNLOSS,PARAM_ANTENNA_TXRXMAP,PARAM_GPIO_INPUTLIST,PARAM_GPIO_OUTPUTLIST,PARAM_GEN2_ACCESSPASSWORD,PARAM_GEN2_Q,PARAM_GEN2_TAGENCODING,PARAM_GEN2_SESSION,PARAM_GEN2_TARGET,PARAM_GEN2_BLF,PARAM_GEN2_TARI,PARAM_GEN2_WRITEMODE,PARAM_GEN2_BAP,PARAM_GEN2_PROTOCOLEXTENSION,PARAM_ISO180006B_MODULATION_DEPTH,PARAM_ISO180006B_DELIMITER,PARAM_READ_ASYNCOFFTIME,PARAM_READ_ASYNCONTIME,PARAM_READ_PLAN,PARAM_RADIO_ENABLEPOWERSAVE,PARAM_RADIO_POWERMAX,PARAM_RADIO_POWERMIN,PARAM_RADIO_PORTREADPOWERLIST,PARAM_RADIO_PORTWRITEPOWERLIST,PARAM_RADIO_READPOWER,PARAM_RADIO_WRITEPOWER,PARAM_RADIO_TEMPERATURE,PARAM_TAGREADDATA_RECORDHIGHESTRSSI,PARAM_TAGREADDATA_REPORTRSSIINDBM,PARAM_TAGREADDATA_UNIQUEBYANTENNA,PARAM_TAGREADDATA_UNIQUEBYDATA,PARAM_TAGOP_ANTENNA,PARAM_TAGOP_PROTOCOL,PARAM_VERSION_HARDWARE,PARAM_VERSION_SERIAL,PARAM_VERSION_MODEL,PARAM_VERSION_SOFTWARE,PARAM_VERSION_SUPPORTEDPROTOCOLS,PARAM_REGION_HOPTABLE,PARAM_REGION_HOPTIME,PARAM_REGION_ID,PARAM_REGION_SUPPORTEDREGIONS,PARAM_REGION_LBT_ENABLE,PARAM_LICENSE_KEY,PARAM_USER_CONFIG,PARAM_RADIO_ENABLESJC,PARAM_EXTENDEDEPC,PARAM_READER_STATISTICS,PARAM_READER_STATS,PARAM_URI,PARAM_PRODUCT_GROUP_ID,PARAM_PRODUCT_GROUP,PARAM_PRODUCT_ID,PARAM_TAGREADATA_TAGOPSUCCESSCOUNT,PARAM_TAGREADATA_TAGOPFAILURECOUNT,PARAM_STATUS_ENABLE_ANTENNAREPORT,PARAM_STATUS_ENABLE_FREQUENCYREPORT,PARAM_STATUS_ENABLE_TEMPERATUREREPORT,PARAM_TAGREADDATA_ENABLEREADFILTER,PARAM_TAGREADDATA_READFILTERTIMEOUT,PARAM_TAGREADDATA_UNIQUEBYPROTOCOL,PARAM_READER_WRITE_REPLY_TIMEOUT,PARAM_READER_WRITE_EARLY_EXIT,PARAM_READER_STATS_ENABLE,PARAM_TRIGGER_READ_GPI,PARAM_METADATAFLAG]+Right "115200"+Right "[9600,115200,921600,19200,38400,57600,230400,460800]"+Right "1000"+Right "10000"+Right "POWER_MODE_FULL"+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_USERMODE", meUri = ""})+Right "False"+Right "[1]"+Right "[]"+Right "[]"+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_ANTENNA_SETTLINGTIMELIST", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_ANTENNA_RETURNLOSS", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_ANTENNA_TXRXMAP", meUri = ""})+Right "[1,2,3,4]"+Right "[]"+Right "0"+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_GEN2_Q", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_GEN2_TAGENCODING", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_GEN2_SESSION", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_GEN2_TARGET", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_GEN2_BLF", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_GEN2_TARI", meUri = ""})+Right "GEN2_WORD_ONLY"+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_GEN2_BAP", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_GEN2_PROTOCOLEXTENSION", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_ISO180006B_MODULATION_DEPTH", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_ISO180006B_DELIMITER", meUri = ""})+Right "0"+Right "250"+Right "SimpleReadPlan {rpWeight = 1, rpEnableAutonomousRead = False, rpAntennas = [], rpProtocol = TAG_PROTOCOL_GEN2, rpFilter = Nothing, rpTagop = Nothing, rpUseFastSearch = False, rpStopOnCount = Nothing, rpTriggerRead = Nothing}"+Right "False"+Right "2700"+Right "0"+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_RADIO_PORTREADPOWERLIST", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_RADIO_PORTWRITEPOWERLIST", meUri = ""})+Right "2300"+Right "2300"+Right "35"+Right "False"+Right "True"+Right "True"+Right "False"+Right "0"+Right "TAG_PROTOCOL_GEN2"+Right "\"30.00.00.02\""+Right "\"45160067701130324A\""+Right "\"M6e Nano\""+Right "\"01.07.01.02-20.16.12.13-BL14.12.08.00\""+Right "[TAG_PROTOCOL_GEN2]"+Right "[]"+Right "0"+Right "REGION_NONE"+Right "[REGION_NA2,REGION_NA3,REGION_IN,REGION_JP,REGION_PRC,REGION_EU3,REGION_KR2,REGION_AU,REGION_NZ,REGION_OPEN]"+Right "False"+Left (MercuryException {meStatusType = ERROR_TYPE_MISC, meStatus = ERROR_UNSUPPORTED, meMessage = "Unsupported operation", meLocation = "paramGet", meParam = "PARAM_LICENSE_KEY", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_USER_CONFIG", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_CODE, meStatus = ERROR_MSG_INVALID_PARAMETER_VALUE, meMessage = "Parameter to command is invalid", meLocation = "paramGet", meParam = "PARAM_RADIO_ENABLESJC", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_MISC, meStatus = ERROR_UNSUPPORTED, meMessage = "Unsupported operation", meLocation = "paramGet", meParam = "PARAM_EXTENDEDEPC", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_READER_STATISTICS", meUri = ""})+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_READER_STATS", meUri = ""})+Right "0"+Right "\"Embedded Reader\""+Right "17"+Right "0"+Right "0"+Right "False"+Right "False"+Right "False"+Right "True"+Right "-1"+Right "True"+Right "20000"+Right "True"+Left (MercuryException {meStatusType = ERROR_TYPE_BINDING, meStatus = ERROR_UNIMPLEMENTED_PARAM, meMessage = "The given parameter is not yet implemented in the Haskell binding.", meLocation = "paramGet", meParam = "PARAM_READER_STATS_ENABLE", meUri = ""})+Right "[]"+Right "[METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS]"
+ tests/params.transport view
@@ -0,0 +1,205 @@+Sending: VERSION 1843103.979368518+ ff 00 03 1d 0c |.....|+Received:VERSION 1843103.983059307+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1843103.983838682+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1843103.985476488+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1843103.985614147+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1843103.987230565+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1843103.987381864+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1843103.989369325+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1843103.990399529+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1843103.992509632+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1843103.992625025+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1843103.994284660+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1843103.994386061+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1843103.996347817+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1843103.996501945+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1843103.998612904+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1843103.998778861+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1843104.001433875+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: GET_PROTOCOL_PARAM 1843104.001631010+ ff 02 6b 05 10 3a 7f |..k..:.|+Received:GET_PROTOCOL_PARAM 1843104.003624443+ ff 03 6b 00 00 05 10 00 18 74 |..k......t|+Sending: GET_PROTOCOL_PARAM 1843104.003810694+ ff 02 6b 05 11 3a 7e |..k..:~|+Received:GET_PROTOCOL_PARAM 1843104.005731032+ ff 03 6b 00 00 05 11 00 19 74 |..k......t|+Sending: GET_PROTOCOL_PARAM 1843104.005829147+ ff 02 6b 03 10 3c 7f |..k..<.|+Received:GET_PROTOCOL_PARAM 1843104.007681136+ ff 02 6b 04 02 03 10 67 74 |..k....gt|+Sending: GET_POWER_MODE 1843104.008160154+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1843104.009771473+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.009907376+ ff 02 6a 01 04 2e 4a |..j...J|+Received:GET_READER_OPTIONAL_PARAMS 1843104.011909258+ ff 03 6a 00 00 01 04 00 3a 44 |..j.....:D|+Sending: GET_ANTENNA_PORT 1843104.012113365+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1843104.014034668+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.014143851+ ff 02 6a 01 03 2e 4d |..j...M|+Received:GET_READER_OPTIONAL_PARAMS 1843104.016090782+ ff 03 6a 00 00 01 03 00 3d 44 |..j.....=D|+Sending: GET_USER_GPIO_INPUTS 1843104.016234473+ ff 01 66 01 ba bc |..f...|+Received:GET_USER_GPIO_INPUTS 1843104.019013964+ ff 0d 66 00 00 01 01 00 00 02 00 00 03 00 00 04 |..f.............|+ 00 01 64 46 |..dF|+Sending: SET_USER_GPIO_OUTPUTS 1843104.019180809+ ff 01 96 01 4a bc |....J.|+Received:SET_USER_GPIO_OUTPUTS 1843104.020925470+ ff 02 96 00 00 01 00 28 e1 |.......(.|+Sending: SET_USER_GPIO_OUTPUTS 1843104.021029058+ ff 01 96 02 4a bf |....J.|+Received:SET_USER_GPIO_OUTPUTS 1843104.022778563+ ff 02 96 00 00 02 00 2b e1 |.......+.|+Sending: SET_USER_GPIO_OUTPUTS 1843104.022877259+ ff 01 96 03 4a be |....J.|+Received:SET_USER_GPIO_OUTPUTS 1843104.024651688+ ff 02 96 00 00 03 00 2a e1 |.......*.|+Sending: SET_USER_GPIO_OUTPUTS 1843104.024743719+ ff 01 96 04 4a b9 |....J.|+Received:SET_USER_GPIO_OUTPUTS 1843104.026471869+ ff 02 96 00 00 04 00 2d e1 |.......-.|+Sending: GET_USER_GPIO_INPUTS 1843104.026579568+ ff 01 66 01 ba bc |..f...|+Received:GET_USER_GPIO_INPUTS 1843104.029296517+ ff 0d 66 00 00 01 01 00 00 02 00 00 03 00 00 04 |..f.............|+ 00 01 64 46 |..dF|+Sending: SET_USER_GPIO_OUTPUTS 1843104.029482652+ ff 01 96 01 4a bc |....J.|+Received:SET_USER_GPIO_OUTPUTS 1843104.031180966+ ff 02 96 00 00 01 00 28 e1 |.......(.|+Sending: SET_USER_GPIO_OUTPUTS 1843104.031264482+ ff 01 96 02 4a bf |....J.|+Received:SET_USER_GPIO_OUTPUTS 1843104.032969922+ ff 02 96 00 00 02 00 2b e1 |.......+.|+Sending: SET_USER_GPIO_OUTPUTS 1843104.033060371+ ff 01 96 03 4a be |....J.|+Received:SET_USER_GPIO_OUTPUTS 1843104.034797771+ ff 02 96 00 00 03 00 2a e1 |.......*.|+Sending: SET_USER_GPIO_OUTPUTS 1843104.034908477+ ff 01 96 04 4a b9 |....J.|+Received:SET_USER_GPIO_OUTPUTS 1843104.036642853+ ff 02 96 00 00 04 00 2d e1 |.......-.|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.037128667+ ff 02 6a 01 01 2e 4f |..j...O|+Received:GET_READER_OPTIONAL_PARAMS 1843104.039429448+ ff 03 6a 00 00 01 01 00 3f 44 |..j.....?D|+Sending: GET_READ_TX_POWER 1843104.039533356+ ff 01 62 01 be bc |..b...|+Received:GET_READ_TX_POWER 1843104.041734922+ ff 07 62 00 00 01 08 fc 0a 8c 00 00 61 d4 |..b.........a.|+Sending: GET_READ_TX_POWER 1843104.041857989+ ff 01 62 01 be bc |..b...|+Received:GET_READ_TX_POWER 1843104.044036236+ ff 07 62 00 00 01 08 fc 0a 8c 00 00 61 d4 |..b.........a.|+Sending: GET_READ_TX_POWER 1843104.044218533+ ff 01 62 00 be bd |..b...|+Received:GET_READ_TX_POWER 1843104.046018204+ ff 03 62 00 00 00 08 fc a3 5a |..b......Z|+Sending: GET_WRITE_TX_POWER 1843104.046120446+ ff 01 64 00 b8 bd |..d...|+Received:GET_WRITE_TX_POWER 1843104.047914131+ ff 03 64 00 00 00 08 fc 84 c3 |..d.......|+Sending: GET_TEMPERATURE 1843104.048045772+ ff 00 72 1d 7d |..r.}|+Received:GET_TEMPERATURE 1843104.049703789+ ff 01 72 00 00 23 48 24 |..r..#H$|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.049820007+ ff 02 6a 01 06 2e 48 |..j...H|+Received:GET_READER_OPTIONAL_PARAMS 1843104.051713229+ ff 03 6a 00 00 01 06 00 38 44 |..j.....8D|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.051813518+ ff 02 6a 01 09 2e 47 |..j...G|+Received:GET_READER_OPTIONAL_PARAMS 1843104.053740315+ ff 03 6a 00 00 01 09 01 37 45 |..j.....7E|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.053832664+ ff 02 6a 01 00 2e 4e |..j...N|+Received:GET_READER_OPTIONAL_PARAMS 1843104.055718413+ ff 03 6a 00 00 01 00 00 3e 44 |..j.....>D|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.055836782+ ff 02 6a 01 08 2e 46 |..j...F|+Received:GET_READER_OPTIONAL_PARAMS 1843104.057753904+ ff 03 6a 00 00 01 08 01 36 45 |..j.....6E|+Sending: HW_VERSION 1843104.057897168+ ff 02 10 00 40 f0 d3 |....@..|+Received:HW_VERSION 1843104.061630608+ ff 16 10 00 00 00 40 40 12 34 35 31 36 30 30 36 |......@@.4516006|+ 37 37 30 31 31 33 30 33 32 34 41 49 5b |7701130324AI[|+Sending: GET_AVAILABLE_PROTOCOLS 1843104.061908417+ ff 00 70 1d 7f |..p..|+Received:GET_AVAILABLE_PROTOCOLS 1843104.063540235+ ff 02 70 00 00 00 05 3b 75 |..p....;u|+Sending: GET_FREQ_HOP_TABLE 1843104.063639212+ ff 00 65 1d 6a |..e.j|+Received:GET_FREQ_HOP_TABLE 1843104.065051814+ ff 00 65 00 00 b8 c3 |..e....|+Sending: GET_FREQ_HOP_TABLE 1843104.065156915+ ff 01 65 01 b9 bc |..e...|+Received:GET_FREQ_HOP_TABLE 1843104.067154924+ ff 05 65 00 00 01 00 00 00 00 4a fc |..e.......J.|+Sending: GET_REGION 1843104.067269349+ ff 00 67 1d 68 |..g.h|+Received:GET_REGION 1843104.068830337+ ff 01 67 00 00 00 b4 81 |..g.....|+Sending: GET_AVAILABLE_REGIONS 1843104.068952705+ ff 00 71 1d 7e |..q.~|+Received:GET_AVAILABLE_REGIONS 1843104.071334737+ ff 0a 71 00 00 0d 0e 04 05 06 08 09 0b 0c ff 1f |..q.............|+ dd |.|+Sending: GET_REGION 1843104.071554255+ ff 02 67 01 40 ff a3 |..g.@..|+Received:GET_REGION 1843104.073190991+ ff 00 67 01 05 99 84 |..g....|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.073326217+ ff 02 6a 01 0a 2e 44 |..j...D|+Received:GET_READER_OPTIONAL_PARAMS 1843104.075080659+ ff 01 6a 01 05 01 d7 fd |..j.....|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.075274228+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1843104.077342544+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.077450135+ ff 02 6a 01 13 2e 5d |..j...]|+Received:GET_READER_OPTIONAL_PARAMS 1843104.079492585+ ff 04 6a 00 00 01 13 00 11 79 9f |..j......y.|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.079611942+ ff 02 6a 01 0b 2e 45 |..j...E|+Received:GET_READER_OPTIONAL_PARAMS 1843104.081555871+ ff 03 6a 00 00 01 0b 00 35 44 |..j.....5D|+Sending: GET_PROTOCOL_PARAM 1843104.081659619+ ff 02 6b 05 3f 3a 50 |..k.?:P|+Received:GET_PROTOCOL_PARAM 1843104.083816779+ ff 05 6b 00 00 05 3f 00 4e 20 4d 14 |..k...?.N M.|+Sending: GET_PROTOCOL_PARAM 1843104.083938210+ ff 02 6b 05 3f 3a 50 |..k.?:P|+Received:GET_PROTOCOL_PARAM 1843104.086023365+ ff 05 6b 00 00 05 3f 00 4e 20 4d 14 |..k...?.N M.|+Sending: GET_READER_OPTIONAL_PARAMS 1843104.086194598+ ff 02 6a 01 1e 2e 50 |..j...P|+Received:GET_READER_OPTIONAL_PARAMS 1843104.088095725+ ff 03 6a 00 00 01 1e 00 20 44 |..j..... D|
+ tests/read.result view
@@ -0,0 +1,17 @@+Right 16+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\SOH\128\DLE\128\175\207", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 7064, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 10, trRssi = -44, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\SOH\DLE\DLEP\177g", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 19480, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 9, trRssi = -47, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\STX\SYN\DLE\128\176\GS", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 50693, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 10, trRssi = -36, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\STXC\DLE\128\176V", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 2511, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 9, trRssi = -50, trFrequency = 919600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\NULF\DLEP\176\231", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 29622, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 171, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 7, trRssi = -53, trFrequency = 919600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\NUL0\DLEP\176\199", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 34775, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 9, trRssi = -45, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\NUL4\DLEP\176\213", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 15522, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 8, trRssi = -47, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\STX3\DLE\128\176E", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 13851, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 5, trRssi = -50, trFrequency = 919600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\NUL\129\DLEP\177-", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 27885, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 171, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 10, trRssi = -41, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\STXD\DLE\128\176O", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 60675, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 8, trRssi = -46, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\STX\130\DLE\144\174\134", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 14404, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 168, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 4, trRssi = -58, trFrequency = 919600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\NULT\DLEP\176\247", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 8542, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 2, trRssi = -58, trFrequency = 919600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\SOH&\DLEP\177\135", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 28765, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 168, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 6, trRssi = -56, trFrequency = 919600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\NUL%\DLEP\176\189", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 32519, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 171, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 3, trRssi = -54, trFrequency = 919600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\NUL%\DLE`\178\217", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 61666, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 10, trRssi = -48, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\SO\SOH\137\DLEP\177\255", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 49247, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 171, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 3, trRssi = -53, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})
+ tests/read.transport view
@@ -0,0 +1,119 @@+Sending: VERSION 1605291.034818992+ ff 00 03 1d 0c |.....|+Received:VERSION 1605291.039468075+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1605291.039998471+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1605291.041600004+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1605291.041699340+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1605291.043273969+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1605291.043372336+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1605291.045325490+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1605291.045461142+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1605291.052225601+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1605291.052352051+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1605291.053966261+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1605291.054063294+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1605291.055938871+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1605291.056043464+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1605291.058027930+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1605291.058132382+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1605291.060352548+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1605291.060484598+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1605291.062121507+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1605291.062221101+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1605291.063918471+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1605291.064004619+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1605291.065708786+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1605291.065801253+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1605291.067461716+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1605291.067548954+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1605291.069282407+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1605291.069357329+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1605291.071382570+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1605291.071487748+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1605291.072970630+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1605291.073060872+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1605291.074807197+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1605291.074915830+ ff 05 22 00 00 13 03 e8 29 05 |..".....).|+Received:READ_TAG_ID_MULTIPLE 1605292.082519826+ ff 07 22 00 00 00 00 13 00 00 00 10 8b 49 |.."..........I|+Sending: GET_TAG_ID_BUFFER 1605292.082851068+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1605292.106795041+ ff f2 29 00 00 01 ff 00 07 0a d4 11 0e 13 e8 00 |..).............|+ 00 03 34 00 ae 05 00 00 00 00 80 30 00 e2 00 00 |..4........0....|+ 15 86 0e 01 80 10 80 af cf 1b 98 09 d1 11 0e 13 |................|+ e8 00 00 03 23 00 ae 05 00 00 00 00 80 30 00 e2 |....#........0..|+ 00 00 15 86 0e 01 10 10 50 b1 67 4c 18 0a dc 11 |........P.gL....|+ 0e 13 e8 00 00 03 28 00 ae 05 00 00 00 00 80 30 |......(........0|+ 00 e2 00 00 15 86 0e 02 16 10 80 b0 1d c6 05 09 |................|+ ce 11 0e 08 30 00 00 00 b7 00 ae 05 00 00 00 00 |....0...........|+ 80 30 00 e2 00 00 15 86 0e 02 43 10 80 b0 56 09 |.0........C...V.|+ cf 07 cb 11 0e 08 30 00 00 00 e8 00 ab 05 00 00 |......0.........|+ 00 00 80 30 00 e2 00 00 15 86 0e 00 46 10 50 b0 |...0........F.P.|+ e7 73 b6 09 d3 11 0e 13 e8 00 00 03 10 00 ae 05 |.s..............|+ 00 00 00 00 80 30 00 e2 00 00 15 86 0e 00 30 10 |.....0........0.|+ 50 b0 c7 87 d7 08 d1 11 0e 13 e8 00 00 03 5d 00 |P.............].|+ ae 05 00 00 00 00 80 30 00 e2 00 00 15 86 0e 00 |.......0........|+ 34 10 50 b0 d5 3c a2 14 c0 |4.P..<...|+Sending: GET_TAG_ID_BUFFER 1605292.109544685+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1605292.133518195+ ff f2 29 00 00 01 ff 00 07 05 ce 11 0e 08 30 00 |..)...........0.|+ 00 01 5c 00 ae 05 00 00 00 00 80 30 00 e2 00 00 |..\........0....|+ 15 86 0e 02 33 10 80 b0 45 36 1b 0a d7 11 0e 13 |....3...E6......|+ e8 00 00 03 16 00 ab 05 00 00 00 00 80 30 00 e2 |.............0..|+ 00 00 15 86 0e 00 81 10 50 b1 2d 6c ed 08 d2 11 |........P.-l....|+ 0e 13 e8 00 00 03 39 00 ae 05 00 00 00 00 80 30 |......9........0|+ 00 e2 00 00 15 86 0e 02 44 10 80 b0 4f ed 03 04 |........D...O...|+ c6 11 0e 08 30 00 00 00 4d 00 a8 05 00 00 00 00 |....0...M.......|+ 80 30 00 e2 00 00 15 86 0e 02 82 10 90 ae 86 38 |.0.............8|+ 44 02 c6 11 0e 08 30 00 00 00 54 00 ae 05 00 00 |D.....0...T.....|+ 00 00 80 30 00 e2 00 00 15 86 0e 00 54 10 50 b0 |...0........T.P.|+ f7 21 5e 06 c8 11 0e 08 30 00 00 00 5b 00 a8 05 |.!^.....0...[...|+ 00 00 00 00 80 30 00 e2 00 00 15 86 0e 01 26 10 |.....0........&.|+ 50 b1 87 70 5d 03 ca 11 0e 08 30 00 00 00 64 00 |P..p].....0...d.|+ ab 05 00 00 00 00 80 30 00 e2 00 00 15 86 0e 00 |.......0........|+ 25 10 50 b0 bd 7f 07 a0 95 |%.P......|+Sending: GET_TAG_ID_BUFFER 1605292.136180386+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1605292.144773020+ ff 48 29 00 00 01 ff 00 02 0a d0 11 0e 13 e8 00 |.H).............|+ 00 03 1b 00 ae 05 00 00 00 00 80 30 00 e2 00 00 |...........0....|+ 15 86 0e 00 25 10 60 b2 d9 f0 e2 03 cb 11 0e 13 |....%.`.........|+ e8 00 00 03 78 00 ab 05 00 00 00 00 80 30 00 e2 |....x........0..|+ 00 00 15 86 0e 01 89 10 50 b1 ff c0 5f 3f 43 |........P..._?C|
+ tests/readUser.result view
@@ -0,0 +1,3 @@+Right 2+Right (TagReadData {trTag = TagData {tdEpc = "\226\NUL\NUL\NAK\134\DC2\NULu%\DLE\EM|", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 4362, tdGen2 = Just (GEN2_TagData {g2Pc = "4\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 15, trRssi = -46, trFrequency = 924800, trTimestamp = 0, trData = "Engineer's Mini-Notebook: Forumulas, Symbols & Circuits\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right (TagReadData {trTag = TagData {tdEpc = "\226\NULQ\134\SOH\a\SOH\135\DC4\NUL\135|", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 12577, tdGen2 = Just (GEN2_TagData {g2Pc = "4\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 171, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 13, trRssi = -56, trFrequency = 924800, trTimestamp = 0, trData = "Bananagrams\NUL!\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})
+ tests/readUser.transport view
@@ -0,0 +1,95 @@+Sending: VERSION 1605849.767314237+ ff 00 03 1d 0c |.....|+Received:VERSION 1605849.771061295+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1605849.771844202+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1605849.773508249+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1605849.773657114+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1605849.775283044+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1605849.775394058+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1605849.777364867+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1605849.778223622+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1605849.780317241+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1605849.780444570+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1605849.782118781+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1605849.782238880+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1605849.784171112+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1605849.784313721+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1605849.786271469+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1605849.786379534+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1605849.788780013+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1605849.788979855+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1605849.790714839+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1605849.790866384+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1605849.792519783+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1605849.792614109+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1605849.794407465+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1605849.794567169+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1605849.796480969+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1605849.796618312+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1605849.798632728+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1605849.798778108+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1605849.801082510+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1605849.801242465+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1605849.802925103+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1605849.803069867+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1605849.805117395+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1605849.805311145+ ff 11 22 00 00 17 03 e8 01 09 28 07 d0 00 03 00 |..".......(.....|+ 00 00 00 20 49 70 |... Ip|+Received:READ_TAG_ID_MULTIPLE 1605850.819217037+ ff 4d 22 00 00 00 00 17 00 00 00 02 01 28 00 1a |.M"..........(..|+ 00 02 45 6e 67 69 6e 65 65 72 27 73 20 4d 69 6e |..Engineer's Min|+ 69 2d 4e 6f 74 65 62 6f 6f 6b 3a 20 46 6f 72 75 |i-Notebook: Foru|+ 6d 75 6c 61 73 2c 20 53 79 6d 62 6f 6c 73 20 26 |mulas, Symbols &|+ 20 43 69 72 63 75 69 74 73 00 00 00 00 00 00 00 | Circuits.......|+ 00 00 53 de |..S.|+Sending: GET_TAG_ID_BUFFER 1605850.820236496+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1605850.840283979+ ff c8 29 00 00 01 ff 00 02 0f d2 11 0e 1c 80 00 |..).............|+ 00 02 e8 00 ae 05 02 00 45 6e 67 69 6e 65 65 72 |........Engineer|+ 27 73 20 4d 69 6e 69 2d 4e 6f 74 65 62 6f 6f 6b |'s Mini-Notebook|+ 3a 20 46 6f 72 75 6d 75 6c 61 73 2c 20 53 79 6d |: Forumulas, Sym|+ 62 6f 6c 73 20 26 20 43 69 72 63 75 69 74 73 00 |bols & Circuits.|+ 00 00 00 00 00 00 00 00 00 00 80 34 00 e2 00 00 |...........4....|+ 15 86 12 00 75 25 10 19 7c 11 0a 0d c8 11 0e 1c |....u%..|.......|+ 80 00 00 02 ba 00 ab 05 02 00 42 61 6e 61 6e 61 |..........Banana|+ 67 72 61 6d 73 00 21 00 00 00 00 00 00 00 00 00 |grams.!.........|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 80 34 00 e2 |.............4..|+ 00 51 86 01 07 01 87 14 00 87 7c 31 21 76 a4 |.Q........|1!v.|
+ tests/replay.hs view
@@ -0,0 +1,496 @@+{-# LANGUAGE OverloadedStrings #-}++import Control.Exception ( throw, try )+import Control.Monad ( when, void, forM_ )+import qualified Data.ByteString as B ( pack )+import Data.List ( maximumBy, delete )+import Data.Monoid ( (<>) )+import Data.Ord ( comparing )+import qualified Data.Text as T ( empty, pack )+import Options.Applicative+ ( Alternative(many),+ Applicative((<*>)),+ Parser,+ helper,+ execParser,+ value,+ switch,+ strOption,+ str,+ short,+ metavar,+ long,+ info,+ help,+ header,+ fullDesc,+ argument,+ (<$>) )+import System.Directory ( makeAbsolute )+import System.IO+ ( Handle,+ IOMode(ReadMode, WriteMode),+ withFile,+ hPutStrLn,+ hGetLine )+import System.Info ( os )++import qualified System.Hardware.MercuryApi as TMR+import qualified System.Hardware.MercuryApi.Params as TMR+import qualified System.Hardware.MercuryApi.Testing as TMR++data TestDirection = Record | Playback++data TestState =+ TestState+ { tsDirection :: TestDirection+ , tsHandle :: Handle+ }++type TestFunc = TMR.Reader -> TestState -> IO ()++suppressUri :: Either TMR.MercuryException a -> Either TMR.MercuryException a+suppressUri (Left exc) = Left exc { TMR.meUri = T.empty }+suppressUri x = x++check :: (Read a, Show a, Eq a) => TestState -> IO a -> IO a+check ts f = do+ eth' <- try f+ let eth = suppressUri eth'+ case tsDirection ts of+ Record -> hPutStrLn (tsHandle ts) (show eth)+ Playback -> do+ ln <- hGetLine (tsHandle ts)+ let expected = read ln :: (Read a => Either TMR.MercuryException a)+ when (expected /= eth) $ do+ putStrLn "expected:"+ putStrLn ln+ putStrLn "but got:"+ print eth+ fail "test failed"+ return $ case eth of+ Left exc -> throw exc -- only thrown if caller looks at result+ Right x -> x++runTest :: String -> TestDirection -> String -> TestFunc -> IO ()+runTest uri dir name func = do+ putStrLn $ "running test: " ++ name+ let fname = "tests/" ++ name+ transportFile = fname ++ ".transport"+ resultFile = fname ++ ".result"+ case dir of+ Record -> do+ withFile transportFile WriteMode $ \hTransport -> do+ withFile resultFile WriteMode $ \hResult -> do+ TMR.withReader (T.pack uri) $ \rdr -> do+ listener <- TMR.opcodeListener hTransport+ TMR.addTransportListener rdr listener+ TMR.paramSetTransportTimeout rdr 10000+ TMR.connect rdr+ func rdr (TestState dir hResult)+ Playback -> do+ absFile <- makeAbsolute transportFile+ withFile resultFile ReadMode $ \hResult -> do+ TMR.withReader (T.pack $ "test://" ++ absFile) $ \rdr -> do+ TMR.paramSetTransportTimeout rdr 10000+ TMR.connect rdr+ func rdr (TestState dir hResult)++setRegionAndPower :: TMR.Reader -> IO ()+setRegionAndPower rdr = do+ -- pwr <- TMR.paramGetRadioPowerMax rdr+ TMR.paramSetBasics rdr TMR.REGION_NA2 2200 TMR.sparkFunAntennas+ TMR.paramSetTagReadDataRecordHighestRssi rdr True++readUser =+ TMR.TagOp_GEN2_ReadData+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opExtraBanks = []+ , TMR.opWordAddress = 0+ , TMR.opLen = 32+ }++emptyUserDataFilter :: TMR.TagFilter+emptyUserDataFilter = TMR.mkFilterGen2 TMR.GEN2_BANK_USER 0 $ B.pack [0, 0]++testParams :: TestFunc+testParams rdr ts = do+ params <- check ts $ TMR.paramList rdr+ let params' = TMR.PARAM_URI `delete` params -- because URI will be different+ forM_ params' $ \param -> do+ check ts $ TMR.paramGetString rdr param++testRead :: TestFunc+testRead rdr ts = do+ setRegionAndPower rdr++ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ forM_ tags $ \tag -> do+ check ts $ return tag { TMR.trTimestamp = 0 }++testReadUser :: TestFunc+testReadUser rdr ts = do+ setRegionAndPower rdr+ TMR.paramSetReadPlanTagop rdr (Just readUser)++ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ forM_ tags $ \tag -> do+ check ts $ return tag { TMR.trTimestamp = 0 }++testWrite :: TestFunc+testWrite rdr ts = do+ setRegionAndPower rdr+ TMR.paramSetReadPlanFilter rdr (Just emptyUserDataFilter)++ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ let trd = maximumBy (comparing TMR.trRssi) tags+ check ts $ return trd { TMR.trTimestamp = 0 }++ let epcFilt = TMR.TagFilterEPC (TMR.trTag trd)+ words = TMR.packBytesIntoWords "I am Groot"+ opWrite = TMR.TagOp_GEN2_WriteData+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opWordAddress = 0+ , TMR.opData = words+ }+ check ts $ TMR.executeTagOp rdr opWrite (Just epcFilt)++ TMR.paramSetReadPlanFilter rdr Nothing+ TMR.paramSetReadPlanTagop rdr (Just readUser)+ tags2 <- TMR.read rdr 1000+ check ts $ return $ length tags2+ forM_ tags2 $ \tag -> do+ check ts $ return tag { TMR.trTimestamp = 0 }++testWriteEpc :: TestFunc+testWriteEpc rdr ts = do+ setRegionAndPower rdr+ TMR.paramSetReadPlanFilter rdr (Just emptyUserDataFilter)++ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ let trd = maximumBy (comparing TMR.trRssi) tags+ check ts $ return trd { TMR.trTimestamp = 0 }++ let tag = TMR.trTag trd+ epcFilt = TMR.TagFilterEPC tag+ Just newEpc = TMR.hexToBytes "0123456789abcdef"+ newTag = tag { TMR.tdEpc = newEpc }+ opWrite = TMR.TagOp_GEN2_WriteTag newTag++ check ts $ TMR.executeTagOp rdr opWrite (Just epcFilt)++ TMR.paramSetReadPlanFilter rdr Nothing+ TMR.paramSetReadPlanTagop rdr (Just readUser)+ tags2 <- TMR.read rdr 1000+ check ts $ return $ length tags2+ forM_ tags2 $ \tag -> do+ check ts $ return tag { TMR.trTimestamp = 0 }++ let epcFilt2 = TMR.TagFilterEPC newTag+ opWrite2 = TMR.TagOp_GEN2_WriteTag tag++ void $ check ts $ TMR.executeTagOp rdr opWrite2 (Just epcFilt2)++testLock :: TestFunc+testLock rdr ts = do+ setRegionAndPower rdr+ TMR.paramSetReadPlanFilter rdr (Just emptyUserDataFilter)++ -- find a tag+ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ let trd = maximumBy (comparing TMR.trRssi) tags+ check ts $ return trd { TMR.trTimestamp = 0 }++ -- write access password+ let password = 12345+ epcFilt = TMR.TagFilterEPC (TMR.trTag trd)+ opWrite = TMR.TagOp_GEN2_WriteData+ { TMR.opBank = TMR.GEN2_BANK_RESERVED+ , TMR.opWordAddress = TMR.accessPasswordAddress+ , TMR.opData = TMR.passwordToWords password+ }+ check ts $ TMR.executeTagOp rdr opWrite (Just epcFilt)++ -- lock user bank+ let opLock = TMR.TagOp_GEN2_Lock+ { TMR.opMask = [TMR.GEN2_LOCK_BITS_USER]+ , TMR.opAction = [TMR.GEN2_LOCK_BITS_USER]+ , TMR.opAccessPassword = password+ }+ check ts $ TMR.executeTagOp rdr opLock (Just epcFilt)++ -- attempt to write data; should fail+ let opWrite2 = TMR.TagOp_GEN2_WriteData+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opWordAddress = 0+ , TMR.opData = TMR.packBytesIntoWords "This should fail"+ }+ check ts $ TMR.executeTagOp rdr opWrite2 (Just epcFilt)++ -- unlock user bank+ let opUnlock = TMR.TagOp_GEN2_Lock+ { TMR.opMask = [TMR.GEN2_LOCK_BITS_USER]+ , TMR.opAction = []+ , TMR.opAccessPassword = password+ }+ check ts $ TMR.executeTagOp rdr opUnlock (Just epcFilt)++ -- attempt to write data; should succeed+ let opWrite3 = TMR.TagOp_GEN2_WriteData+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opWordAddress = 0+ , TMR.opData = TMR.packBytesIntoWords "This should succeed"+ }+ void $ check ts $ TMR.executeTagOp rdr opWrite3 (Just epcFilt)++sequentialBytes = B.pack [0..7]++testBlockWrite :: TestFunc+testBlockWrite rdr ts = do+ setRegionAndPower rdr+ TMR.paramSetReadPlanFilter rdr (Just emptyUserDataFilter)++ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ let trd = maximumBy (comparing TMR.trRssi) tags+ check ts $ return trd { TMR.trTimestamp = 0 }++ let epcFilt = TMR.TagFilterEPC (TMR.trTag trd)+ words = TMR.packBytesIntoWords sequentialBytes+ opWrite = TMR.TagOp_GEN2_BlockWrite+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opWordPtr = 0+ , TMR.opData = words+ }+ check ts $ TMR.executeTagOp rdr opWrite (Just epcFilt)++ TMR.paramSetReadPlanFilter rdr Nothing+ TMR.paramSetReadPlanTagop rdr (Just readUser)+ tags2 <- TMR.read rdr 1000+ check ts $ return $ length tags2+ forM_ tags2 $ \tag -> do+ check ts $ return tag { TMR.trTimestamp = 0 }++sequentialUserDataFilter :: TMR.TagFilter+sequentialUserDataFilter = TMR.mkFilterGen2 TMR.GEN2_BANK_USER 0 sequentialBytes++testBlockErase :: TestFunc+testBlockErase rdr ts = do+ setRegionAndPower rdr+ TMR.paramSetReadPlanFilter rdr (Just sequentialUserDataFilter)++ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ let trd = maximumBy (comparing TMR.trRssi) tags+ check ts $ return trd { TMR.trTimestamp = 0 }++ let epcFilt = TMR.TagFilterEPC (TMR.trTag trd)+ opErase = TMR.TagOp_GEN2_BlockErase+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opWordPtr = 0+ , TMR.opWordCount = 4+ }+ check ts $ TMR.executeTagOp rdr opErase (Just epcFilt)++ TMR.paramSetReadPlanFilter rdr Nothing+ TMR.paramSetReadPlanTagop rdr (Just readUser)+ tags2 <- TMR.read rdr 1000+ check ts $ return $ length tags2+ forM_ tags2 $ \tag -> do+ check ts $ return tag { TMR.trTimestamp = 0 }++permalockMeFilter :: TMR.TagFilter+permalockMeFilter = TMR.mkFilterGen2 TMR.GEN2_BANK_USER 0 "permalock me"++testBlockPermalockRead :: TestFunc+testBlockPermalockRead rdr ts = do+ setRegionAndPower rdr+ TMR.paramSetReadPlanFilter rdr (Just permalockMeFilter)++ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ let trd = maximumBy (comparing TMR.trRssi) tags+ check ts $ return trd { TMR.trTimestamp = 0 }++ let epcFilt = TMR.TagFilterEPC (TMR.trTag trd)+ opPermalock = TMR.TagOp_GEN2_BlockPermaLock+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opBlockPtr = 0+ , TMR.opReadWrite = TMR.Read 1+ }+ void $ check ts $ TMR.executeTagOp rdr opPermalock (Just epcFilt)++testBlockPermalockWrite :: TestFunc+testBlockPermalockWrite rdr ts = do+ setRegionAndPower rdr+ TMR.paramSetReadPlanFilter rdr (Just permalockMeFilter)++ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ let trd = maximumBy (comparing TMR.trRssi) tags+ check ts $ return trd { TMR.trTimestamp = 0 }++ let epcFilt = TMR.TagFilterEPC (TMR.trTag trd)+ opPermalock = TMR.TagOp_GEN2_BlockPermaLock+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opBlockPtr = 0+ , TMR.opReadWrite = TMR.Write [0xaa00]+ }+ check ts $ TMR.executeTagOp rdr opPermalock (Just epcFilt)++ forM_ [0..31] $ \word -> do+ let opWrite = TMR.TagOp_GEN2_WriteData+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opWordAddress = word+ , TMR.opData = [fromIntegral word]+ }+ check ts $ TMR.executeTagOp rdr opWrite (Just epcFilt)++ TMR.paramSetReadPlanFilter rdr Nothing+ TMR.paramSetReadPlanTagop rdr (Just readUser)+ tags2 <- TMR.read rdr 1000+ check ts $ return $ length tags2+ forM_ tags2 $ \tag -> do+ check ts $ return tag { TMR.trTimestamp = 0 }++ let opPermalock2 = TMR.TagOp_GEN2_BlockPermaLock+ { TMR.opBank = TMR.GEN2_BANK_USER+ , TMR.opBlockPtr = 0+ , TMR.opReadWrite = TMR.Read 1+ }+ void $ check ts $ TMR.executeTagOp rdr opPermalock2 (Just epcFilt)++killMeFilter :: TMR.TagFilter+killMeFilter =+ TMR.mkFilterGen2 TMR.GEN2_BANK_USER 0 $ "permaloc" <> B.pack [0,4,0,5,0,6,0,7]++testKill :: TestFunc+testKill rdr ts = do+ setRegionAndPower rdr+ TMR.paramSetReadPlanFilter rdr (Just killMeFilter)++ -- find a tag+ tags <- TMR.read rdr 1000+ check ts $ return $ length tags+ let trd = maximumBy (comparing TMR.trRssi) tags+ check ts $ return trd { TMR.trTimestamp = 0 }++ -- write access password+ let password = 0xbeadead1+ epcFilt = TMR.TagFilterEPC (TMR.trTag trd)+ opWrite = TMR.TagOp_GEN2_WriteData+ { TMR.opBank = TMR.GEN2_BANK_RESERVED+ , TMR.opWordAddress = TMR.killPasswordAddress+ , TMR.opData = TMR.passwordToWords password+ }+ check ts $ TMR.executeTagOp rdr opWrite (Just epcFilt)++ -- kill+ let opKill = TMR.TagOp_GEN2_Kill password+ check ts $ TMR.executeTagOp rdr opKill (Just epcFilt)++ -- still alive?+ TMR.paramSetReadPlanFilter rdr (Just epcFilt)+ TMR.paramSetReadPlanTagop rdr (Just readUser)+ tags2 <- TMR.read rdr 1000+ void $ check ts $ return $ length tags2++mkPin :: TMR.PinNumber -> TMR.PinNumber -> TMR.GpioPin+mkPin highPin pin =+ TMR.GpioPin+ { TMR.gpId = pin+ , TMR.gpHigh = highPin == pin+ , TMR.gpOutput = True+ }++testGpo :: TestFunc+testGpo rdr ts = do+ let pins = [1..4]++ TMR.paramSetGpioOutputList rdr pins+ forM_ pins $ \pin -> do+ TMR.gpoSet rdr $ map (mkPin pin) pins++testGpi :: TestFunc+testGpi rdr ts = do+ let pins = [1..4]++ TMR.paramSetGpioInputList rdr pins+ void $ check ts $ TMR.gpiGet rdr++tests :: [(String, TestFunc)]+tests =+ [ ("params", testParams)+ , ("read", testRead)+ , ("readUser", testReadUser)+ , ("write", testWrite)+ , ("writeEpc", testWriteEpc)+ , ("lock", testLock)+ , ("blockWrite", testBlockWrite)+ , ("blockErase", testBlockErase)+ , ("blockPermalockRead", testBlockPermalockRead)+ , ("blockPermalockWrite", testBlockPermalockWrite)+ , ("kill", testKill)+ , ("gpo", testGpo)+ , ("gpi", testGpi)+ ]++allTests = map fst tests++runTests :: String -> TestDirection -> [String] -> IO ()+runTests uri dir ts = do+ forM_ ts $ \t -> do+ let mf = t `lookup` tests+ case mf of+ Nothing -> fail $ "no test named " ++ t+ Just f -> runTest uri dir t f++defUri :: String+defUri = case os of+ "darwin" -> "tmr:///dev/cu.SLAB_USBtoUART"+ "mingw32" -> "tmr:///COM4"+ _ -> "tmr:///dev/ttyUSB0"++data Opts = Opts+ { oUri :: String+ , oRecord :: Bool+ , oTests :: [String]+ }++optUri :: Parser String+optUri = strOption (long "uri" <>+ short 'u' <>+ metavar "URI" <>+ help ("Reader to connect to (default " ++ defUri ++ ")") <>+ value defUri)++optRecord :: Parser Bool+optRecord = switch (long "record" <>+ short 'R' <>+ help "record a new test from a physical reader")++opts :: Parser Opts+opts = Opts+ <$> optUri+ <*> optRecord+ <*> many (argument str (metavar "TESTS..."))++opts' = info (helper <*> opts)+ ( fullDesc <>+ header "replay - automated tests that use a simulated reader" )++main = do+ TMR.registerTransportInit+ o <- execParser opts'++ let dir = if oRecord o then Record else Playback+ let ts = case oTests o of+ [] -> allTests+ xs -> xs++ runTests (oUri o) dir ts
+ tests/unit.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE OverloadedStrings #-}++import qualified Data.ByteString as B ( ByteString )+import Data.Monoid ((<>))+import qualified Data.Text as T ( Text )+import Test.HUnit ( Assertion, Test(..), runTestTT, assertEqual )++import qualified System.Hardware.MercuryApi as TMR++helloWorld :: B.ByteString+helloWorld = "Hello, World!"++defacedBadFacade :: T.Text+defacedBadFacade = "DefacedBadFacade"++defacedBadFacadeBin :: B.ByteString+defacedBadFacadeBin = "\222\250\206\219\173\250\202\222"++-- http://www.adafruit.com/datasheets/CSN-A2%20User%20Manual.pdf+phrase :: B.ByteString+phrase = "thoroughly remove the uncommon words of anguish"++testDataHelpers :: Assertion+testDataHelpers = do+ assertEqual "TMR.packBytesIntoWords helloWorld"+ [18533,27756,28460,8279,28530,27748,8448]+ (TMR.packBytesIntoWords helloWorld)+ assertEqual "TMR.passwordToWords 0xbeadead1"+ [0xbead, 0xead1]+ (TMR.passwordToWords 0xbeadead1)++testHex :: Assertion+testHex = do+ assertEqual "TMR.bytesToHex defacedBadFacadeBin"+ "DEFACEDBADFACADE"+ (TMR.bytesToHex defacedBadFacadeBin)+ assertEqual "TMR.bytesToHexWithSpaces defacedBadFacadeBin"+ "de fa ce db ad fa ca de"+ (TMR.bytesToHexWithSpaces defacedBadFacadeBin)+ assertEqual "TMR.hexToBytes defacedBadFacade"+ (Just defacedBadFacadeBin)+ (TMR.hexToBytes defacedBadFacade)+ assertEqual "TMR.hexToBytes $ \"0x\" <> defacedBadFacade"+ (Just defacedBadFacadeBin)+ (TMR.hexToBytes $ "0x" <> defacedBadFacade)+ assertEqual "TMR.hexToBytes \"XXYYZZ\""+ Nothing+ (TMR.hexToBytes "XXYYZZ")+ assertEqual "TMR.hexToBytes \"0dd\""+ Nothing+ (TMR.hexToBytes "0dd")++testTimestamp :: Assertion+testTimestamp = do+ assertEqual "TMR.displayTimestamp 0"+ "1970-01-01T00:00:00.000Z"+ (TMR.displayTimestamp 0)+ assertEqual "TMR.displayTimestamp 123456789"+ "1970-01-02T10:17:36.789Z"+ (TMR.displayTimestamp 123456789)+ assertEqual "TMR.displayTimestamp 1513728000000"+ "2017-12-20T00:00:00.000Z"+ (TMR.displayTimestamp 1513728000000)++testData :: Assertion+testData = do+ assertEqual "TMR.displayData phrase"+ [ "74 68 6f 72 6f 75 67 68 6c 79 20 72 65 6d 6f 76 |thoroughly remov|"+ , "65 20 74 68 65 20 75 6e 63 6f 6d 6d 6f 6e 20 77 |e the uncommon w|"+ , "6f 72 64 73 20 6f 66 20 61 6e 67 75 69 73 68 |ords of anguish|"+ ]+ (TMR.displayData phrase)++tests :: Test+tests = TestList+ [ TestLabel "testDataHelpers" (TestCase testDataHelpers)+ , TestLabel "testHex" (TestCase testHex)+ , TestLabel "testTimestamp" (TestCase testTimestamp)+ , TestLabel "testData" (TestCase testData)+ ]++main = runTestTT tests
+ tests/write.result view
@@ -0,0 +1,5 @@+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NULQ\134\SOH\a\SOH\135\ap\196\193", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 47646, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 171, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 20, trRssi = -47, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right ""+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NULQ\134\SOH\a\SOH\135\ap\196\193", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 18363, tdGen2 = Just (GEN2_TagData {g2Pc = "4\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 22, trRssi = -44, trFrequency = 918400, trTimestamp = 0, trData = "I am Groot\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})
+ tests/write.transport view
@@ -0,0 +1,118 @@+Sending: VERSION 1608598.103811784+ ff 00 03 1d 0c |.....|+Received:VERSION 1608598.108389815+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1608598.108962046+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1608598.110812682+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1608598.110958814+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1608598.112779756+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1608598.112934335+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1608598.114918110+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1608598.121893539+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1608598.124219487+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1608598.124500941+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1608598.126413019+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1608598.126563793+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1608598.128513171+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1608598.128660983+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1608598.130614928+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1608598.130747717+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1608598.133116871+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1608598.133294161+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1608598.135127143+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1608598.135314487+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1608598.137182683+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1608598.137317673+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1608598.139181408+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1608598.139334656+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1608598.141248843+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1608598.141391398+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1608598.143471456+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1608598.143757271+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1608598.146075706+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1608598.146245646+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1608598.147965998+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1608598.148106117+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1608598.150175988+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1608598.150440445+ ff 10 22 03 00 13 03 e8 00 00 00 00 00 00 00 00 |..".............|+ 10 00 00 86 a3 |.....|+Received:READ_TAG_ID_MULTIPLE 1608599.160809727+ ff 07 22 00 00 03 00 13 00 00 00 01 65 8a |..".........e.|+Sending: GET_TAG_ID_BUFFER 1608599.161120138+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1608599.166592092+ ff 26 29 00 00 01 ff 00 01 14 d1 11 0e 13 e8 00 |.&).............|+ 00 03 29 00 ab 05 00 00 00 00 80 30 00 e2 00 51 |..)........0...Q|+ 86 01 07 01 87 07 70 c4 c1 ba 1e 92 d7 |......p......|+Sending: WRITE_TAG_DATA 1608599.170450637+ ff 23 24 03 e8 01 00 00 00 00 03 00 00 00 00 60 |.#$............`|+ e2 00 51 86 01 07 01 87 07 70 c4 c1 49 20 61 6d |..Q......p..I am|+ 20 47 72 6f 6f 74 a6 6a | Groot.j|+Received:WRITE_TAG_DATA 1608599.246089019+ ff 00 24 00 00 e0 26 |..$...&|+Sending: GET_READER_STATS 1608599.246448176+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1608599.248747520+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1608599.248930668+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1608599.250666122+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1608599.250844006+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1608599.252846522+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1608599.253118475+ ff 11 22 00 00 17 03 e8 01 09 28 07 d0 00 03 00 |..".......(.....|+ 00 00 00 20 49 70 |... Ip|+Received:READ_TAG_ID_MULTIPLE 1608600.265874100+ ff 4d 22 00 00 00 00 17 00 00 00 01 01 28 00 16 |.M"..........(..|+ 00 00 49 20 61 6d 20 47 72 6f 6f 74 00 00 00 00 |..I am Groot....|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 90 9a |....|+Sending: GET_TAG_ID_BUFFER 1608600.266777939+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1608600.278056115+ ff 66 29 00 00 01 ff 00 01 16 d4 11 0e 03 80 00 |.f).............|+ 00 01 a0 00 ae 05 02 00 49 20 61 6d 20 47 72 6f |........I am Gro|+ 6f 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |ot..............|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 80 34 00 e2 00 51 |...........4...Q|+ 86 01 07 01 87 07 70 c4 c1 47 bb 9a c1 |......p..G...|
+ tests/writeEpc.result view
@@ -0,0 +1,6 @@+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\226\NULQ\134\SOH\a\SOH\135\ap\196\193", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 47646, tdGen2 = Just (GEN2_TagData {g2Pc = "0\NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 174, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 31, trRssi = -47, trFrequency = 922600, trTimestamp = 0, trData = "", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right ""+Right 1+Right (TagReadData {trTag = TagData {tdEpc = "\SOH#Eg\137\171\205\239", tdProtocol = TAG_PROTOCOL_GEN2, tdCrc = 36510, tdGen2 = Just (GEN2_TagData {g2Pc = " \NUL"})}, trMetadataFlags = [METADATA_FLAG_READCOUNT,METADATA_FLAG_RSSI,METADATA_FLAG_ANTENNAID,METADATA_FLAG_FREQUENCY,METADATA_FLAG_TIMESTAMP,METADATA_FLAG_PHASE,METADATA_FLAG_PROTOCOL,METADATA_FLAG_DATA,METADATA_FLAG_GPIO_STATUS], trPhase = 171, trAntenna = 1, trGpio = [GpioPin {gpId = 1, gpHigh = False, gpOutput = False},GpioPin {gpId = 2, gpHigh = False, gpOutput = False},GpioPin {gpId = 3, gpHigh = False, gpOutput = False},GpioPin {gpId = 4, gpHigh = False, gpOutput = False}], trReadCount = 22, trRssi = -45, trFrequency = 918400, trTimestamp = 0, trData = "\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL", trEpcMemData = "", trTidMemData = "", trUserMemData = "", trReservedMemData = ""})+Right ""
+ tests/writeEpc.transport view
@@ -0,0 +1,124 @@+Sending: VERSION 1783113.335963260+ ff 00 03 1d 0c |.....|+Received:VERSION 1783113.340546799+ ff 14 03 00 00 14 12 08 00 30 00 00 02 20 16 12 |.........0... ..|+ 13 01 07 01 02 00 00 00 10 1b 05 |...........|+Sending: GET_CURRENT_PROGRAM 1783113.341025567+ ff 00 0c 1d 03 |.....|+Received:GET_CURRENT_PROGRAM 1783113.342675574+ ff 01 0c 00 00 52 63 03 |.....Rc.|+Sending: GET_POWER_MODE 1783113.342832512+ ff 00 68 1d 67 |..h.g|+Received:GET_POWER_MODE 1783113.344719334+ ff 01 68 00 00 00 a4 bf |..h.....|+Sending: GET_READER_OPTIONAL_PARAMS 1783113.344877962+ ff 02 6a 01 0e 2e 40 |..j...@|+Received:GET_READER_OPTIONAL_PARAMS 1783113.347044658+ ff 03 6a 00 00 01 0e 00 30 44 |..j.....0D|+Sending: GET_READER_OPTIONAL_PARAMS 1783113.354181389+ ff 02 6a 01 12 2e 5c |..j...\|+Received:GET_READER_OPTIONAL_PARAMS 1783113.356482817+ ff 04 6a 00 00 01 12 00 00 69 af |..j......i.|+Sending: GET_TAG_PROTOCOL 1783113.356679203+ ff 00 63 1d 6c |..c.l|+Received:GET_TAG_PROTOCOL 1783113.358546212+ ff 02 63 00 00 00 05 21 46 |..c....!F|+Sending: GET_ANTENNA_PORT 1783113.358712824+ ff 01 61 05 bd b8 |..a...|+Received:GET_ANTENNA_PORT 1783113.360832578+ ff 03 61 00 00 05 01 00 61 df |..a.....a.|+Sending: GET_READER_OPTIONAL_PARAMS 1783113.361047512+ ff 02 6a 01 0c 2e 42 |..j...B|+Received:GET_READER_OPTIONAL_PARAMS 1783113.363254874+ ff 03 6a 00 00 01 0c 01 32 45 |..j.....2E|+Sending: GET_READER_OPTIONAL_PARAMS 1783113.363464915+ ff 02 6a 01 0d 2e 43 |..j...C|+Received:GET_READER_OPTIONAL_PARAMS 1783113.365915536+ ff 06 6a 00 00 01 0d 00 00 00 00 15 43 |..j.........C|+Sending: SET_REGION 1783113.366099275+ ff 01 97 0d 4b b0 |....K.|+Received:SET_REGION 1783113.367851295+ ff 00 97 00 00 77 9e |.....w.|+Sending: SET_READ_TX_POWER 1783113.368065458+ ff 02 92 08 98 49 c1 |.....I.|+Received:SET_READ_TX_POWER 1783113.369971357+ ff 00 92 00 00 27 3b |.....';|+Sending: SET_WRITE_TX_POWER 1783113.370116064+ ff 02 94 08 98 29 07 |.....).|+Received:SET_WRITE_TX_POWER 1783113.371990494+ ff 00 94 00 00 47 fd |.....G.|+Sending: SET_ANTENNA_PORT 1783113.372144979+ ff 02 91 01 01 70 3b |.....p;|+Received:SET_ANTENNA_PORT 1783113.374086488+ ff 00 91 00 00 17 58 |......X|+Sending: SET_READER_OPTIONAL_PARAMS 1783113.374223675+ ff 03 9a 01 06 01 a9 5c |.......\|+Received:SET_READER_OPTIONAL_PARAMS 1783113.376213620+ ff 00 9a 00 00 a6 33 |......3|+Sending: GET_READER_STATS 1783113.376365163+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1783113.378504811+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1783113.378674249+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1783113.380379708+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1783113.380525173+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1783113.382539190+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1783113.382687791+ ff 10 22 03 00 13 03 e8 00 00 00 00 00 00 00 00 |..".............|+ 10 00 00 86 a3 |.....|+Received:READ_TAG_ID_MULTIPLE 1783114.389189850+ ff 07 22 00 00 03 00 13 00 00 00 01 65 8a |..".........e.|+Sending: GET_TAG_ID_BUFFER 1783114.389440192+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1783114.394987785+ ff 26 29 00 00 01 ff 00 01 1f d1 11 0e 13 e8 00 |.&).............|+ 00 03 23 00 ae 05 00 00 00 00 80 30 00 e2 00 51 |..#........0...Q|+ 86 01 07 01 87 07 70 c4 c1 ba 1e f3 0f |......p......|+Sending: WRITE_TAG_ID 1783114.395787548+ ff 1c 23 03 e8 01 00 00 00 00 60 e2 00 51 86 01 |..#.......`..Q..|+ 07 01 87 07 70 c4 c1 01 23 45 67 89 ab cd ef 5b |....p...#Eg....[|+ 20 | |+Received:WRITE_TAG_ID 1783114.473001670+ ff 00 23 00 00 90 c1 |..#....|+Sending: GET_READER_STATS 1783114.473210471+ ff 03 6c 01 9f 41 89 7b |..l..A.{|+Received:GET_READER_STATS 1783114.475568734+ ff 03 6c 00 00 01 9f 41 86 9c |..l....A..|+Sending: CLEAR_TAG_ID_BUFFER 1783114.475730903+ ff 00 2a 1d 25 |..*.%|+Received:CLEAR_TAG_ID_BUFFER 1783114.477455041+ ff 00 2a 00 00 01 e8 |..*....|+Sending: SET_ANTENNA_PORT 1783114.477668332+ ff 03 91 02 01 01 42 c5 |......B.|+Received:SET_ANTENNA_PORT 1783114.479714545+ ff 00 91 00 00 17 58 |......X|+Sending: READ_TAG_ID_MULTIPLE 1783114.479888386+ ff 11 22 00 00 17 03 e8 01 09 28 07 d0 00 03 00 |..".......(.....|+ 00 00 00 20 49 70 |... Ip|+Received:READ_TAG_ID_MULTIPLE 1783115.497038299+ ff 4d 22 00 00 00 00 17 00 00 00 01 01 28 00 16 |.M"..........(..|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 e4 bf |....|+Sending: GET_TAG_ID_BUFFER 1783115.498013194+ ff 03 29 01 ff 00 1b 03 |..).....|+Received:GET_TAG_ID_BUFFER 1783115.508879879+ ff 62 29 00 00 01 ff 00 01 16 d3 11 0e 03 80 00 |.b).............|+ 00 01 9d 00 ab 05 02 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|+ 00 00 00 00 00 00 00 00 00 00 60 20 00 01 23 45 |..........` ..#E|+ 67 89 ab cd ef 8e 9e 37 23 |g......7#|+Sending: WRITE_TAG_ID 1783115.510126246+ ff 1c 23 03 e8 01 00 00 00 00 40 01 23 45 67 89 |..#.......@.#Eg.|+ ab cd ef e2 00 51 86 01 07 01 87 07 70 c4 c1 72 |.....Q......p..r|+ c4 |.|+Received:WRITE_TAG_ID 1783115.619815239+ ff 00 23 00 00 90 c1 |..#....|