4df3eb3f |
1 | local cmds = require('commands') |
b61f426c |
2 | local getopt = require('getopt') |
3 | local lib14a = require('read14a') |
4 | |
450d2e3a |
5 | example = "script run 14araw -x 6000F57b" |
b61f426c |
6 | author = "Martin Holst Swende" |
7 | |
8 | |
9 | desc = |
4df3eb3f |
10 | [[ |
b61f426c |
11 | This is a script to allow raw 1444a commands to be sent and received. |
12 | |
13 | Arguments: |
14 | -o do not connect - use this only if you previously used -p to stay connected |
15 | -r do not read response |
16 | -c calculate and append CRC |
17 | -p stay connected - dont inactivate the field |
18 | -x <payload> Data to send (NO SPACES!) |
19 | -d Debug flag |
20 | |
21 | Examples : |
4df3eb3f |
22 | |
b61f426c |
23 | # 1. Connect and don't disconnect |
450d2e3a |
24 | script run 14araw -p |
b61f426c |
25 | # 2. Send mf auth, read response (nonce) |
450d2e3a |
26 | script run 14araw -o -x 6000F57b -p |
b61f426c |
27 | # 3. disconnect |
450d2e3a |
28 | script run 14araw -o |
4df3eb3f |
29 | |
b61f426c |
30 | # All three steps in one go: |
450d2e3a |
31 | script run 14araw -x 6000F57b |
4df3eb3f |
32 | ]] |
33 | |
b61f426c |
34 | --[[ |
4df3eb3f |
35 | |
b61f426c |
36 | This script communicates with |
37 | /armsrc/iso14443a.c, specifically ReaderIso14443a() at around line 1779 and onwards. |
38 | |
39 | Check there for details about data format and how commands are interpreted on the |
40 | device-side. |
41 | ]] |
42 | |
43 | -- Some globals |
4df3eb3f |
44 | local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds |
b61f426c |
45 | local DEBUG = false -- the debug flag |
4df3eb3f |
46 | |
b61f426c |
47 | ------------------------------- |
48 | -- Some utilities |
49 | ------------------------------- |
50 | |
51 | --- |
52 | -- A debug printout-function |
53 | function dbg(args) |
54 | if DEBUG then |
450d2e3a |
55 | print("###", args) |
4df3eb3f |
56 | end |
b61f426c |
57 | end |
58 | --- |
59 | -- This is only meant to be used when errors occur |
60 | function oops(err) |
61 | print("ERROR: ",err) |
4df3eb3f |
62 | end |
63 | |
24d48e60 |
64 | |
b61f426c |
65 | --- |
66 | -- Usage help |
67 | function help() |
68 | print(desc) |
69 | print("Example usage") |
70 | print(example) |
71 | end |
72 | |
73 | --- |
74 | -- The main entry point |
75 | function main(args) |
76 | |
77 | if args == nil or #args == 0 then |
78 | return help() |
79 | end |
80 | |
81 | local ignore_response = false |
82 | local appendcrc = false |
83 | local stayconnected = false |
84 | local payload = nil |
85 | local doconnect = true |
86 | |
87 | -- Read the parameters |
88 | for o, a in getopt.getopt(args, 'corcpx:') do |
89 | if o == "o" then doconnect = false end |
90 | if o == "r" then ignore_response = true end |
91 | if o == "c" then appendcrc = true end |
92 | if o == "p" then stayconnected = true end |
93 | if o == "x" then payload = a end |
94 | if o == "d" then DEBUG = true end |
95 | end |
96 | |
97 | -- First of all, connect |
98 | if doconnect then |
99 | dbg("doconnect") |
100 | -- We reuse the connect functionality from a |
101 | -- common library |
102 | info, err = lib14a.read1443a(true) |
103 | |
104 | if err then return oops(err) end |
105 | print(("Connected to card, uid = %s"):format(info.uid)) |
106 | end |
107 | |
108 | -- The actual raw payload, if any |
109 | if payload then |
110 | res,err = sendRaw(payload,{ignore_response = ignore_response}) |
111 | if err then return oops(err) end |
112 | |
113 | if not ignoreresponse then |
114 | -- Display the returned data |
115 | showdata(res) |
116 | end |
117 | end |
118 | -- And, perhaps disconnect? |
119 | if not stayconnected then |
120 | disconnect() |
121 | end |
122 | end |
123 | |
124 | --- Picks out and displays the data read from a tag |
125 | -- Specifically, takes a usb packet, converts to a Command |
126 | -- (as in commands.lua), takes the data-array and |
127 | -- reads the number of bytes specified in arg1 (arg0 in c-struct) |
128 | -- and displays the data |
129 | -- @param usbpacket the data received from the device |
130 | function showdata(usbpacket) |
131 | local cmd_response = Command.parse(usbpacket) |
132 | local len = tonumber(cmd_response.arg1) *2 |
133 | --print("data length:",len) |
134 | local data = string.sub(tostring(cmd_response.data), 0, len); |
135 | print("<< ",data) |
136 | --print("----------------") |
137 | end |
138 | |
139 | |
140 | |
141 | function sendRaw(rawdata, options) |
142 | print(">> ", rawdata) |
143 | |
144 | local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW |
145 | |
146 | local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, |
147 | arg1 = flags, -- Send raw |
148 | -- arg2 contains the length, which is half the length |
149 | -- of the ASCII-string rawdata |
24d48e60 |
150 | arg2 = string.len(rawdata)/2, |
4df3eb3f |
151 | data = rawdata} |
b61f426c |
152 | return lib14a.sendToDevice(command, options.ignore_response) |
153 | end |
154 | |
155 | -- Sends an instruction to do nothing, only disconnect |
156 | function disconnect() |
157 | |
158 | local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, |
3e69b211 |
159 | arg1 = 0, -- Nothing |
160 | } |
b61f426c |
161 | -- We can ignore the response here, no ACK is returned for this command |
162 | -- Check /armsrc/iso14443a.c, ReaderIso14443a() for details |
163 | return lib14a.sendToDevice(command,true) |
164 | end |
165 | |
166 | |
167 | ------------------------- |
168 | -- Testing |
169 | ------------------------- |
170 | function selftest() |
450d2e3a |
171 | DEBUG = true |
172 | dbg("Performing test") |
173 | main() |
b61f426c |
174 | main("-p") |
175 | main(" -o -x 6000F57b -p") |
176 | main("-o") |
177 | main("-x 6000F57b") |
450d2e3a |
178 | dbg("Tests done") |
b61f426c |
179 | end |
180 | -- Flip the switch here to perform a sanity check. |
181 | -- It read a nonce in two different ways, as specified in the usage-section |
450d2e3a |
182 | if "--test"==args then |
b61f426c |
183 | selftest() |
184 | else |
185 | -- Call the main |
186 | main(args) |
4df3eb3f |
187 | end |