]>
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 | |
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 |