1 local cmds
= require('commands')
2 local getopt
= require('getopt')
3 local lib14a
= require('read14a')
4 local utils
= require('utils')
5 local ansicolors
= require('ansicolors')
11 This is a script that reads LTO-CM ISO14443a tags.
12 It starts from block 0 and ends at default block 254.
16 script run hf_14a_read-ltocm
19 script run hf_14a_read-ltocm -e 10
22 script run hf_14a_read-ltocm -h -s -e
26 s start block in decimal
27 e end block in decimal
31 local DEBUG
= false -- the debug flag
32 local lshift
= bit32
.lshift
33 local band
= bit32
.band
35 -- A debug printout-function
36 local function dbg(args
)
37 if not DEBUG
then return end
38 if type(args
) == 'table' then
49 -- This is only meant to be used when errors occur
50 local function oops(err
)
52 core
.clearCommandBuffer()
62 print(ansicolors
.cyan
..'Usage'..ansicolors
.reset
)
64 print(ansicolors
.cyan
..'Arguments'..ansicolors
.reset
)
66 print(ansicolors
.cyan
..'Example usage'..ansicolors
.reset
)
70 local function sendRaw(rawdata
, options
)
72 local flags
= lib14a
.ISO14A_COMMAND
.ISO14A_NO_DISCONNECT
+ lib14a
.ISO14A_COMMAND
.ISO14A_RAW
74 if options
.connect
then
75 flags
= flags
+ lib14a
.ISO14A_COMMAND
.ISO14A_CONNECT
78 if options
.no_select
then
79 flags
= flags
+ lib14a
.ISO14A_COMMAND
.ISO14A_NO_SELECT
82 if options
.append_crc
then
83 flags
= flags
+ lib14a
.ISO14A_COMMAND
.ISO14A_APPEND_CRC
86 local arg2
= #rawdata
/ 2
88 arg2
= arg2
+ tonumber(lshift(7, 16))
91 local command
= Command
:newMIX
{cmd
= cmds
.CMD_HF_ISO14443A_READER
,
92 arg1
= flags
, -- Send raw
93 -- arg2 contains the length, which is half the length
94 -- of the ASCII-string rawdata
97 return command
:sendMIX(options
.ignore_response
)
101 -- get hex data from response
102 local function getdata(usbpacket
)
103 local cmd_response
= Command
.parse(usbpacket
)
104 local len
= tonumber(cmd_response
.arg1
) * 2
105 return string.sub(tostring(cmd_response
.data
), 0, len
)
109 -- helper function to send payloads easier
110 local function send(payload
, options
)
111 local res
, err
= sendRaw(payload
, options
)
116 core
.clearCommandBuffer()
117 if options
.ignore_response
then
125 -- The main entry point
130 -- Read the parameters
131 for o
, a
in getopt
.getopt(args
, 'hs:e:') do
132 if o
== 'h' then return help() end
133 if o
== 's' then startblock
= a
end
134 if o
== 'e' then endblock
= a
end
138 -- core.console("hf 14a raw -a -k -b 7 45")
139 -- local cmd_select = string.format("hf 14a raw -c -k 9370%s", serial_number)
140 -- core.console(cmd_select)
142 -- local cmd_rd_blk = string.format("hf 14a raw -c -k 30 %02x", i)
143 -- core.console(cmd_rd_blk)
144 -- core.console("hf 14a raw -k 80")
146 -- core.console("hf 14a raw -r")
150 local res
, err
= send(payload
,{connect
= true, no_select
= true, ignore_response
= false, append_crc
= false, bits7
= true})
151 if err
then return end
155 res
, err
= send(payload
,{ignore_response
= false, append_crc
= false})
156 if err
then return end
158 local serial_number
= getdata(res
)
159 payload
= "9370"..serial_number
160 res
, err
= send(payload
,{ignore_response
= false, append_crc
= true})
161 if err
then return end
164 print(('\nFound LTO-CM serial number: [%s]\n'):format(serial_number
))
168 print('----+------------------')
169 local block_data
= {}
170 for block
= startblock
, endblock
do
172 payload
= string.format('30%02x', block
)
173 res
, err
= send(payload
, {ignore_response
= false, append_crc
= true})
174 if err
then return end
176 local d0_d15
= getdata(res
)
179 res
, err
= send(payload
, {ignore_response
= false, append_crc
= false})
180 if err
then return end
182 local d16_d31
= getdata(res
)
185 d0_d15
= string.sub(d0_d15
, 0, #d0_d15
- 4)
186 d16_d31
= string.sub(d16_d31
, 0, #d16_d31
- 4)
188 print(block
, d0_d15
..d16_d31
)
189 table.insert(block_data
, d0_d15
..d16_d31
)
191 print("----+------------------")
194 local filename
, err
= utils
.WriteDumpFile(serial_number
, block_data
)
195 if err
then return oops(err
) end
197 print(string.format('\nDumped data into %s', filename
))