2 This is a library to read 14443b tags. It can be used something like this
4 local reader = require('read14b')
5 result, err = reader.select1443b()
13 -- Loads the commands-library
14 local cmds = require('commands')
15 local utils = require('utils')
17 local ISO14B_COMMAND = {
19 ISO14B_DISCONNECT = 2,
22 ISO14B_REQUEST_TRIGGER = 0x10,
23 ISO14B_APPEND_CRC = 0x20,
24 ISO14B_SELECT_STD = 0x40,
25 ISO14B_SELECT_SR = 0x80,
28 local function parse1443b(data)
31 Based on this struct :
39 } __attribute__((__packed__)) iso14b_card_select_t;
43 local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data)
44 uid = uid:sub(1,2*uidlen)
45 return { uid = uid, uidlen = uidlen, atqb = atqb, chipid = chipid, cid = cid }
48 --- Sends a USBpacket to the device
49 -- @param command - the usb packet to send
50 -- @param ignoreresponse - if set to true, we don't read the device answer packet
51 -- which is usually recipe for fail. If not sent, the host will wait 2s for a
52 -- response of type CMD_ACK
53 -- @return packet,nil if successfull
54 -- nil, errormessage if unsuccessfull
55 local function sendToDevice(cmd, ignoreresponse)
56 --core.clearCommandBuffer()
57 local bytes = cmd:getBytes()
58 local count,c,arg0,arg1,arg2 = bin.unpack('LLLL',bytes)
59 local err = core.SendCommand(cmd:getBytes())
64 if ignoreresponse then return nil,nil end
66 local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
69 --- Picks out and displays the data read from a tag
70 -- Specifically, takes a usb packet, converts to a Command
71 -- (as in commands.lua), takes the data-array and
72 -- reads the number of bytes specified in arg1 (arg0 in c-struct)
73 -- and displays the data
74 -- @param usbpacket the data received from the device
75 local function showData(usbpacket)
76 local response = Command.parse(usbpacket)
77 local len = response.arg2 * 2
78 local data = string.sub(response.data, 0, len);
83 -- This function does a connect and retrieves some info
84 -- @return if successfull: an table containing card info
85 -- @return if unsuccessfull : nil, error
86 local function read14443b(disconnect)
88 local command, result, info, err, data
90 local flags = ISO14B_COMMAND.ISO14B_CONNECT +
91 ISO14B_COMMAND.ISO14B_SELECT_STD
95 flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT
98 command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
99 local result,err = sendToDevice(command, false)
101 local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
103 data = string.sub(result, count)
104 info, err = parse1443b(data)
106 err = "iso14443b card select failed"
109 err = "No response from card"
118 --PING / PONG - Custom Anticollison for Navigo.
120 -- local ping = ('BA00')
121 -- result, err = sendRaw(ping, 1, 1)
123 -- resp = Command.parse( result )
125 -- return nil, "iso14443b card - PING/PONG failed"
129 -- err = "No response from card"
136 -- Waits for a mifare card to be placed within the vicinity of the reader.
137 -- @return if successfull: an table containing card info
138 -- @return if unsuccessfull : nil, error
139 local function waitFor14443b()
140 print("Waiting for card... press any key to quit")
141 while not core.ukbhit() do
142 res, err = read14443b(false)
143 if res then return res end
144 -- err means that there was no response from card
146 return nil, "Aborted by user"
150 parse1443b = parse1443b,
151 read1443b = read14443b,
152 waitFor14443b = waitFor14443b,
153 sendToDevice = sendToDevice,
155 ISO14B_COMMAND = ISO14B_COMMAND,