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