2 This is a library to read 15693 tags. It can be used something like this
4 local reader = require('read15')
5 local info, err = reader.read()
13 -- Loads the commands-library
14 local cmds
= require('commands')
15 local utils
= require('utils')
17 -- Shouldn't take longer than 2 seconds
20 local ISO15_COMMAND
= {
21 ISO15_REQ_SUBCARRIER_SINGLE
= 0,
22 ISO15_REQ_DATARATE_HIGH
= 2,
23 ISO15_REQ_NONINVENTORY
= 0,
26 local function errorString15693(number)
28 errors
[0x01] = "The command is not supported"
29 errors
[0x02] = "The command is not recognised"
30 errors
[0x03] = "The option is not supported."
31 errors
[0x0f] = "Unknown error."
32 errors
[0x10] = "The specified block is not available (doesn’t exist)."
33 errors
[0x11] = "The specified block is already -locked and thus cannot be locked again"
34 errors
[0x12] = "The specified block is locked and its content cannot be changed."
35 errors
[0x13] = "The specified block was not successfully programmed."
36 errors
[0x14] = "The specified block was not successfully locked."
38 return errors
[number] or "Reserved for Future Use or Custom command error."
41 local function parse15693(data
)
42 local bytes
= utils
.ConvertAsciiToBytes(data
)
43 local tmp
= utils
.ConvertAsciiToHex(data
)
45 -- define ISO15_CRC_CHECK 0F47
46 local crcStr
= utils
.Crc15(tmp
, #tmp
)
48 if string.sub(crcStr
, #crcStr
- 3) ~= '470F' then
50 return nil, 'CRC failed'
53 if bytes
[1] % 2 == 1 then
54 -- Above is a poor-mans bit check:
55 -- recv[0] & ISO15_RES_ERROR //(0x01)
56 local err
= 'Tag returned error %i: %s'
57 err
= string.format(err
, bytes
[1], errorString15693(bytes
[1]))
60 local uid
= utils
.ConvertBytesToHex( bytes
, true )
61 uid
= uid
:sub(5, #uid
-4)
65 -- This function does a connect and retrieves som info
66 -- @param dont_disconnect - if true, does not disable the field
67 -- @return if successful: an table containing card info
68 -- @return if unsuccessful : nil, error
69 local function read15693(slow
, dont_readresponse
)
72 We start by trying this command:
73 MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
77 Tag Info: Texas Instrument; Tag-it HF-I Standard; 8x32bit
80 From which we obtain less information than the above one.
84 -- #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
85 -- #define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
86 -- #define ISO15_REQ_NONINVENTORY 0x00
93 local command
, result
, info
, err
, data
95 data
= utils
.Crc15("260100")
97 command
= Command
:newMIX
{
98 cmd
= cmds
.CMD_HF_ISO15693_COMMAND
,
108 if dont_readresponse
then
112 local result
, err
= command
:sendMIX()
114 local count
, cmd
, len
, arg2
, arg3
= bin
.unpack('LLLL', result
)
116 return nil, 'iso15693 card select failed'
118 data
= string.sub(result
, count
, count
+len
-1)
119 info
, err
= parse15693(data
)
121 err
= 'No response from card'
132 -- Waits for a ISO15693 card to be placed within the vicinity of the reader.
133 -- @return if successful: an table containing card info
134 -- @return if unsuccessful : nil, error
135 local function waitFor15693()
136 print('Waiting for card... press <Enter> to quit')
137 while not core
.kbd_enter_pressed() do
138 res
, err
= read15693()
139 if res
then return res
end
140 -- err means that there was no response from card
142 return nil, 'Aborted by user'
145 -- Sends an instruction to do nothing, only disconnect
146 local function disconnect15693()
147 local c
= Command
:newMIX
{cmd
= cmds
.CMD_HF_ISO15693_COMMAND
}
148 -- We can ignore the response here, no ACK is returned for this command
149 -- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
150 return c
:sendMIX(true)
155 waitFor15693
= waitFor15693
,
156 parse15693
= parse15693
,
157 disconnect
= disconnect15693
,