/src/wireshark/epan/dissectors/packet-acr122.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-acr122.c |
2 | | * Routines for ACR122 USB NFC dongle |
3 | | * |
4 | | * Copyright 2013, Michal Labedzki for Tieto Corporation |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | */ |
12 | | |
13 | | #include "config.h" |
14 | | |
15 | | #include <epan/packet.h> |
16 | | #include <epan/prefs.h> |
17 | | #include <epan/expert.h> |
18 | | #include <epan/tfs.h> |
19 | | |
20 | | #include "packet-usb.h" |
21 | | |
22 | | static int proto_acr122; |
23 | | |
24 | | static int hf_class; |
25 | | static int hf_ins; |
26 | | static int hf_p1; |
27 | | static int hf_p2; |
28 | | static int hf_length; |
29 | | static int hf_status_word; |
30 | | static int hf_status_word_sw1; |
31 | | static int hf_status_word_sw2; |
32 | | static int hf_status_word_led_reserved; |
33 | | static int hf_status_word_led_green; |
34 | | static int hf_status_word_led_red; |
35 | | static int hf_command; |
36 | | static int hf_response; |
37 | | static int hf_response_for; |
38 | | static int hf_picc_operating_auto_picc_polling; |
39 | | static int hf_picc_operating_auto_ats_generation; |
40 | | static int hf_picc_operating_polling_interval; |
41 | | static int hf_picc_operating_felica_424k; |
42 | | static int hf_picc_operating_felica_212k; |
43 | | static int hf_picc_operating_topaz; |
44 | | static int hf_picc_operating_iso_14443_type_b; |
45 | | static int hf_picc_operating_iso_14443_type_a; |
46 | | static int hf_firmware_version; |
47 | | static int hf_led_green_blinking_state; |
48 | | static int hf_led_red_blinking_state; |
49 | | static int hf_led_green_mask; |
50 | | static int hf_led_red_mask; |
51 | | static int hf_led_initial_green_blinking_state; |
52 | | static int hf_led_initial_red_blinking_state; |
53 | | static int hf_led_final_green_state; |
54 | | static int hf_led_final_red_state; |
55 | | static int hf_led_t1_duration; |
56 | | static int hf_led_t2_duration; |
57 | | static int hf_led_number_of_repetition; |
58 | | static int hf_led_link_to_buzzer; |
59 | | static int hf_timeout; |
60 | | static int hf_poll_buzzer_status; |
61 | | static int hf_key; |
62 | | static int hf_key_structure; |
63 | | static int hf_key_number; |
64 | | static int hf_key_type; |
65 | | static int hf_block_number; |
66 | | static int hf_source_block_number; |
67 | | static int hf_target_block_number; |
68 | | static int hf_vb_op; |
69 | | static int hf_static_byte; |
70 | | static int hf_version; |
71 | | static int hf_value; |
72 | | static int hf_uid; |
73 | | static int hf_ats; |
74 | | static int hf_data; |
75 | | |
76 | | static int ett_acr122; |
77 | | static int ett_p1_item; |
78 | | static int ett_p2_item; |
79 | | static int ett_status_word; |
80 | | static int ett_status_word_sw2; |
81 | | |
82 | | static expert_field ei_unknown_command_or_invalid_parameters; |
83 | | |
84 | | static dissector_handle_t acr122_handle; |
85 | | static dissector_handle_t pn532_handle; |
86 | | |
87 | | static wmem_tree_t *command_info; |
88 | | |
89 | | typedef struct command_data_t { |
90 | | uint32_t bus_id; |
91 | | uint32_t device_address; |
92 | | uint32_t endpoint; |
93 | | |
94 | | uint8_t command; |
95 | | uint32_t command_frame_number; |
96 | | uint32_t response_frame_number; |
97 | | } command_data_t; |
98 | | |
99 | | /* Not part of protocol, generated values */ |
100 | 0 | #define CMD_UNKNOWN 0x00 |
101 | 0 | #define CMD_GET_DATA_UID 0x01 |
102 | 0 | #define CMD_GET_DATA_ATS 0x02 |
103 | 0 | #define CMD_LOAD_AUTHENTICATION_KEYS 0x03 |
104 | 0 | #define CMD_AUTHENTICATION_OBSOLETE 0x04 |
105 | 0 | #define CMD_AUTHENTICATION 0x05 |
106 | 0 | #define CMD_READ_BINARY_BLOCKS 0x06 |
107 | 0 | #define CMD_UPDATE_BINARY_BLOCKS 0x07 |
108 | 0 | #define CMD_VALUE_BLOCK_OPERATION 0x08 |
109 | 0 | #define CMD_READ_VALUE_BLOCK 0x09 |
110 | 0 | #define CMD_RESTORE_VALUE_BLOCK 0x0A |
111 | 0 | #define CMD_DIRECT_TRANSMIT 0x0B |
112 | 0 | #define CMD_BI_COLOR_AND_BUZZER_LED_CONTROL 0x0C |
113 | 0 | #define CMD_GET_FIRMWARE_VERSION 0x0D |
114 | 0 | #define CMD_GET_PICC_OPERATING_PARAMETER 0x0E |
115 | 0 | #define CMD_SET_PICC_OPERATING_PARAMETER 0x0F |
116 | 0 | #define CMD_SET_TIMEOUT_PARAMETER 0x10 |
117 | 0 | #define CMD_SET_BUZZER_OUTPUT_FOR_CARD_DETECTION 0x11 |
118 | | |
119 | | static const value_string command_vals[] = { |
120 | | { CMD_GET_DATA_UID, "Get Data - UID" }, |
121 | | { CMD_GET_DATA_ATS, "Get Data - ATS" }, |
122 | | { CMD_LOAD_AUTHENTICATION_KEYS, "Load Authentication Keys" }, |
123 | | { CMD_AUTHENTICATION_OBSOLETE, "Authentication (Obsolete)" }, |
124 | | { CMD_AUTHENTICATION, "Authentication" }, |
125 | | { CMD_READ_BINARY_BLOCKS, "Read Binary Blocks" }, |
126 | | { CMD_UPDATE_BINARY_BLOCKS, "Update Binary Blocks" }, |
127 | | { CMD_VALUE_BLOCK_OPERATION, "Value Block Operation" }, |
128 | | { CMD_READ_VALUE_BLOCK, "Read Value Block" }, |
129 | | { CMD_RESTORE_VALUE_BLOCK, "Restore Value Block" }, |
130 | | { CMD_DIRECT_TRANSMIT, "Direct Transmit" }, |
131 | | { CMD_BI_COLOR_AND_BUZZER_LED_CONTROL, "Bi-Color and Buzzer LED Control" }, |
132 | | { CMD_GET_FIRMWARE_VERSION, "Get Firmware Version" }, |
133 | | { CMD_GET_PICC_OPERATING_PARAMETER, "Get PICC Operating Parameter" }, |
134 | | { CMD_SET_PICC_OPERATING_PARAMETER, "Set PICC Operating Parameter" }, |
135 | | { CMD_SET_TIMEOUT_PARAMETER, "Set Timeout Parameter" }, |
136 | | { CMD_SET_BUZZER_OUTPUT_FOR_CARD_DETECTION, "Set Buzzer Output for Card Detection" }, |
137 | | { 0, NULL } |
138 | | }; |
139 | | static value_string_ext command_vals_ext = VALUE_STRING_EXT_INIT(command_vals); |
140 | | |
141 | | static const range_string status_word_rvals[] = { |
142 | | { 0x6300, 0x6300, "Operation Fail" }, |
143 | | { 0x6a81, 0x6a81, "Function not Supported" }, |
144 | | { 0x9000, 0x90FF, "Success" }, |
145 | | { 0, 0, NULL } |
146 | | }; |
147 | | |
148 | | static const value_string link_to_buzzer_vals[] = { |
149 | | { 0x00, "The buzzer will not turn on" }, |
150 | | { 0x01, "The buzzer will turn on during the T1 Duration" }, |
151 | | { 0x02, "The buzzer will turn on during the T2 Duration" }, |
152 | | { 0x03, "The buzzer will turn on during the T1 and T2 Duration" }, |
153 | | { 0, NULL } |
154 | | }; |
155 | | |
156 | | static const value_string key_structure_vals[] = { |
157 | | { 0x00, "Key is loaded into the reader volatile memory" }, |
158 | | { 0, NULL } |
159 | | }; |
160 | | |
161 | | static const value_string poll_buzzer_status_vals[] = { |
162 | | { 0x00, "Buzzer disabled on card detected" }, |
163 | | { 0xFF, "Buzzer enabled on card detected" }, |
164 | | { 0, NULL } |
165 | | }; |
166 | | |
167 | | static const value_string key_type_vals[] = { |
168 | | { 0x60, "Type A" }, |
169 | | { 0x61, "Type B" }, |
170 | | { 0, NULL } |
171 | | }; |
172 | | |
173 | | static const value_string vb_op_vals[] = { |
174 | | { 0x00, "Store the \"Value\" into the block. The block will then be converted to a value block." }, |
175 | | { 0x01, "Increment the value of the value block by the \"Value\". This command is only valid for value block." }, |
176 | | { 0x02, "Decrement the value of the value block by the \"Value\". This command is only valid for value block." }, |
177 | | { 0, NULL } |
178 | | }; |
179 | | |
180 | | void proto_register_acr122(void); |
181 | | void proto_reg_handoff_acr122(void); |
182 | | |
183 | | static void |
184 | 0 | duration_base(char *buf, uint32_t value) { |
185 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "%u.%03u s", value * 100 / 1000, value * 100 % 1000); |
186 | 0 | } |
187 | | |
188 | | static void |
189 | 0 | timeout_base(char *buf, uint32_t value) { |
190 | 0 | if (value == 0x00) |
191 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "No timeout check"); |
192 | 0 | else if (value == 0xFF) |
193 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "Wait until the contactless chip responds"); |
194 | 0 | else if (value < 12) |
195 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "%u [s]", value * 5); |
196 | 0 | else |
197 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "%u:%02u [mm:ss]", value * 5 / 60, value * 5 % 60); |
198 | 0 | } |
199 | | |
200 | | |
201 | | static int |
202 | | dissect_acr122(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
203 | 0 | { |
204 | 0 | proto_item *main_item; |
205 | 0 | proto_tree *main_tree; |
206 | 0 | proto_item *p1_item; |
207 | 0 | proto_tree *p1_tree; |
208 | 0 | proto_item *p2_item; |
209 | 0 | proto_tree *p2_tree; |
210 | 0 | proto_item *sub_item; |
211 | 0 | proto_item *sub_tree; |
212 | 0 | proto_item *sw2_item; |
213 | 0 | proto_item *sw2_tree; |
214 | 0 | int offset = 0; |
215 | 0 | uint32_t value; |
216 | 0 | tvbuff_t *next_tvb; |
217 | 0 | uint8_t acr_class; |
218 | 0 | uint8_t ins; |
219 | 0 | uint8_t p1; |
220 | 0 | uint8_t p2; |
221 | 0 | uint8_t length; |
222 | 0 | uint8_t command = CMD_UNKNOWN; |
223 | 0 | command_data_t *command_data; |
224 | 0 | urb_info_t *urb; |
225 | 0 | wmem_tree_key_t key[5]; |
226 | 0 | uint32_t bus_id; |
227 | 0 | uint32_t device_address; |
228 | 0 | uint32_t endpoint; |
229 | 0 | uint32_t k_bus_id; |
230 | 0 | uint32_t k_device_address; |
231 | 0 | uint32_t k_endpoint; |
232 | 0 | uint32_t k_frame_number; |
233 | |
|
234 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACR 122"); |
235 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
236 | |
|
237 | 0 | main_item = proto_tree_add_item(tree, proto_acr122, tvb, offset, -1, ENC_NA); |
238 | 0 | main_tree = proto_item_add_subtree(main_item, ett_acr122); |
239 | |
|
240 | 0 | if (!data) return offset; |
241 | 0 | urb = (urb_info_t *) data; |
242 | |
|
243 | 0 | bus_id = urb->bus_id; |
244 | 0 | device_address = urb->device_address; |
245 | 0 | endpoint = urb->endpoint; |
246 | |
|
247 | 0 | k_bus_id = bus_id; |
248 | 0 | k_device_address = device_address; |
249 | 0 | k_endpoint = endpoint; |
250 | 0 | k_frame_number = pinfo->num; |
251 | |
|
252 | 0 | key[0].length = 1; |
253 | 0 | key[0].key = &k_bus_id; |
254 | 0 | key[1].length = 1; |
255 | 0 | key[1].key = &k_device_address; |
256 | 0 | key[2].length = 1; |
257 | 0 | key[2].key = &k_endpoint; |
258 | 0 | key[3].length = 1; |
259 | 0 | key[3].key = &k_frame_number; |
260 | 0 | key[4].length = 0; |
261 | 0 | key[4].key = NULL; |
262 | | |
263 | |
|
264 | 0 | if (pinfo->p2p_dir == P2P_DIR_SENT) { /* Request */ |
265 | 0 | acr_class = tvb_get_uint8(tvb, offset); |
266 | 0 | ins = tvb_get_uint8(tvb, offset + 1); |
267 | 0 | p1 = tvb_get_uint8(tvb, offset + 2); |
268 | 0 | p2 = tvb_get_uint8(tvb, offset + 3); |
269 | 0 | length = tvb_get_uint8(tvb, offset + 4); |
270 | | |
271 | | /* Recognize command by simple heuristic */ |
272 | 0 | if (acr_class == 0xFF) { |
273 | 0 | if (ins == 0xCA && p1 == 0x00 && p2 == 0x00 && length == 0) |
274 | 0 | command = CMD_GET_DATA_UID; |
275 | 0 | if (ins == 0xCA && p1 == 0x01 && p2 == 0x00 && length == 0) |
276 | 0 | command = CMD_GET_DATA_ATS; |
277 | 0 | else if (ins == 0x82 && length == 6) |
278 | 0 | command = CMD_LOAD_AUTHENTICATION_KEYS; |
279 | 0 | else if (ins == 0x88 && p1 == 0x00) |
280 | 0 | command = CMD_AUTHENTICATION_OBSOLETE; |
281 | 0 | else if (ins == 0x86 && p1 == 0x00 && p2 == 0x00 && length == 5) |
282 | 0 | command = CMD_AUTHENTICATION; |
283 | 0 | else if (ins == 0xB0 && p1 == 0x00) |
284 | 0 | command = CMD_READ_BINARY_BLOCKS; |
285 | 0 | else if (ins == 0xD6 && p1 == 0x00) |
286 | 0 | command = CMD_UPDATE_BINARY_BLOCKS; |
287 | 0 | else if (ins == 0xD7 && p1 == 0x00 && length == 5) |
288 | 0 | command = CMD_VALUE_BLOCK_OPERATION; |
289 | 0 | else if (ins == 0xB1 && p1 == 0x00 && length == 4) |
290 | 0 | command = CMD_READ_VALUE_BLOCK; |
291 | 0 | else if (ins == 0xD7 && p1 == 0x00 && length == 2) |
292 | 0 | command = CMD_RESTORE_VALUE_BLOCK; |
293 | 0 | else if (ins == 0x00 && p1 == 0x00 && p2 == 0x00) |
294 | 0 | command = CMD_DIRECT_TRANSMIT; |
295 | 0 | else if (ins == 0x00 && p1 == 0x40 && length == 4) |
296 | 0 | command = CMD_BI_COLOR_AND_BUZZER_LED_CONTROL; |
297 | 0 | else if (ins == 0x00 && p1 == 0x48 && p2 == 0x00) |
298 | 0 | command = CMD_GET_FIRMWARE_VERSION; |
299 | 0 | else if (ins == 0x00 && p1 == 0x50 && p2 == 0x00) |
300 | 0 | command = CMD_GET_PICC_OPERATING_PARAMETER; |
301 | 0 | else if (ins == 0x00 && p1 == 0x51 && length == 0) |
302 | 0 | command = CMD_SET_PICC_OPERATING_PARAMETER; |
303 | 0 | else if (ins == 0x00 && p1 == 0x41 && length == 0) |
304 | 0 | command = CMD_SET_TIMEOUT_PARAMETER; |
305 | 0 | else if (ins == 0x00 && p1 == 0x52 && length == 0) |
306 | 0 | command = CMD_SET_BUZZER_OUTPUT_FOR_CARD_DETECTION; |
307 | 0 | } |
308 | |
|
309 | 0 | sub_item = proto_tree_add_uint(main_tree, hf_command, tvb, offset, 4 + length, command); |
310 | 0 | proto_item_set_generated(sub_item); |
311 | 0 | if (command == CMD_UNKNOWN) |
312 | 0 | expert_add_info(pinfo, sub_item, &ei_unknown_command_or_invalid_parameters); |
313 | |
|
314 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Command: %s", val_to_str_ext_const(command, &command_vals_ext, "Unknown")); |
315 | |
|
316 | 0 | proto_tree_add_item(main_tree, hf_class, tvb, offset, 1, ENC_BIG_ENDIAN); |
317 | 0 | offset += 1; |
318 | |
|
319 | 0 | proto_tree_add_item(main_tree, hf_ins, tvb, offset, 1, ENC_BIG_ENDIAN); |
320 | 0 | offset += 1; |
321 | |
|
322 | 0 | p1_item = proto_tree_add_item(main_tree, hf_p1, tvb, offset, 1, ENC_BIG_ENDIAN); |
323 | 0 | offset += 1; |
324 | |
|
325 | 0 | p2_item = proto_tree_add_item(main_tree, hf_p2, tvb, offset, 1, ENC_BIG_ENDIAN); |
326 | 0 | offset += 1; |
327 | |
|
328 | 0 | proto_tree_add_item(main_tree, hf_length, tvb, offset, 1, ENC_BIG_ENDIAN); |
329 | 0 | offset += 1; |
330 | |
|
331 | 0 | switch (command) { |
332 | 0 | case CMD_DIRECT_TRANSMIT: |
333 | 0 | if (length > 0) { |
334 | 0 | next_tvb = tvb_new_subset_length(tvb, offset, length); |
335 | 0 | call_dissector_with_data(pn532_handle, next_tvb, pinfo, tree, urb); |
336 | 0 | offset += length; |
337 | 0 | } |
338 | 0 | break; |
339 | 0 | case CMD_BI_COLOR_AND_BUZZER_LED_CONTROL: |
340 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
341 | 0 | proto_tree_add_item(p2_tree, hf_led_green_blinking_state, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
342 | 0 | proto_tree_add_item(p2_tree, hf_led_red_blinking_state, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
343 | 0 | proto_tree_add_item(p2_tree, hf_led_green_mask, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
344 | 0 | proto_tree_add_item(p2_tree, hf_led_red_mask, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
345 | 0 | proto_tree_add_item(p2_tree, hf_led_initial_green_blinking_state, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
346 | 0 | proto_tree_add_item(p2_tree, hf_led_initial_red_blinking_state, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
347 | 0 | proto_tree_add_item(p2_tree, hf_led_final_green_state, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
348 | 0 | proto_tree_add_item(p2_tree, hf_led_final_red_state, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
349 | |
|
350 | 0 | proto_tree_add_item(main_tree, hf_led_t1_duration, tvb, offset, 1, ENC_BIG_ENDIAN); |
351 | 0 | offset += 1; |
352 | |
|
353 | 0 | proto_tree_add_item(main_tree, hf_led_t2_duration, tvb, offset, 1, ENC_BIG_ENDIAN); |
354 | 0 | offset += 1; |
355 | |
|
356 | 0 | proto_tree_add_item(main_tree, hf_led_number_of_repetition, tvb, offset, 1, ENC_BIG_ENDIAN); |
357 | 0 | offset += 1; |
358 | |
|
359 | 0 | proto_tree_add_item(main_tree, hf_led_link_to_buzzer, tvb, offset, 1, ENC_BIG_ENDIAN); |
360 | 0 | offset += 1; |
361 | 0 | break; |
362 | 0 | case CMD_GET_DATA_UID: |
363 | 0 | case CMD_GET_DATA_ATS: |
364 | | /* Nothing to decode */ |
365 | 0 | break; |
366 | 0 | case CMD_LOAD_AUTHENTICATION_KEYS: |
367 | 0 | p1_tree = proto_item_add_subtree(p1_item, ett_p1_item); |
368 | 0 | proto_tree_add_item(p1_tree, hf_key_structure, tvb, offset - 3, 1, ENC_BIG_ENDIAN); |
369 | |
|
370 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
371 | 0 | proto_tree_add_item(p2_tree, hf_key_number, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
372 | |
|
373 | 0 | proto_tree_add_item(main_tree, hf_key, tvb, offset, 6, ENC_NA); |
374 | 0 | offset += 6; |
375 | 0 | break; |
376 | 0 | case CMD_AUTHENTICATION_OBSOLETE: |
377 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
378 | 0 | proto_tree_add_item(p2_tree, hf_block_number, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
379 | |
|
380 | 0 | proto_tree_add_item(main_tree, hf_key_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
381 | 0 | offset += 1; |
382 | |
|
383 | 0 | proto_tree_add_item(main_tree, hf_key_number, tvb, offset, 1, ENC_BIG_ENDIAN); |
384 | 0 | offset += 1; |
385 | 0 | break; |
386 | 0 | case CMD_AUTHENTICATION: |
387 | 0 | proto_tree_add_item(main_tree, hf_version, tvb, offset, 2, ENC_BIG_ENDIAN); |
388 | 0 | offset += 2; |
389 | |
|
390 | 0 | proto_tree_add_item(main_tree, hf_block_number, tvb, offset, 1, ENC_BIG_ENDIAN); |
391 | 0 | offset += 1; |
392 | |
|
393 | 0 | proto_tree_add_item(main_tree, hf_key_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
394 | 0 | offset += 1; |
395 | |
|
396 | 0 | proto_tree_add_item(main_tree, hf_key_number, tvb, offset, 1, ENC_BIG_ENDIAN); |
397 | 0 | offset += 1; |
398 | 0 | break; |
399 | 0 | case CMD_READ_BINARY_BLOCKS: |
400 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
401 | 0 | proto_tree_add_item(p2_tree, hf_block_number, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
402 | 0 | break; |
403 | 0 | case CMD_UPDATE_BINARY_BLOCKS: |
404 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
405 | 0 | proto_tree_add_item(p2_tree, hf_block_number, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
406 | |
|
407 | 0 | proto_tree_add_item(main_tree, hf_data, tvb, offset, length, ENC_NA); |
408 | 0 | offset += length; |
409 | 0 | break; |
410 | 0 | case CMD_VALUE_BLOCK_OPERATION: |
411 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
412 | 0 | proto_tree_add_item(p2_tree, hf_block_number, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
413 | |
|
414 | 0 | proto_tree_add_item(main_tree, hf_vb_op, tvb, offset, 1, ENC_BIG_ENDIAN); |
415 | 0 | offset += 1; |
416 | |
|
417 | 0 | proto_tree_add_item(main_tree, hf_value, tvb, offset, 4, ENC_BIG_ENDIAN); |
418 | 0 | offset += 4; |
419 | 0 | break; |
420 | 0 | case CMD_READ_VALUE_BLOCK: |
421 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
422 | 0 | proto_tree_add_item(p2_tree, hf_block_number, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
423 | |
|
424 | 0 | break; |
425 | 0 | case CMD_RESTORE_VALUE_BLOCK: |
426 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
427 | 0 | proto_tree_add_item(p2_tree, hf_source_block_number, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
428 | |
|
429 | 0 | proto_tree_add_item(main_tree, hf_static_byte, tvb, offset, 1, ENC_BIG_ENDIAN); |
430 | 0 | offset += 1; |
431 | |
|
432 | 0 | proto_tree_add_item(main_tree, hf_target_block_number, tvb, offset, 1, ENC_BIG_ENDIAN); |
433 | 0 | offset += 1; |
434 | 0 | break; |
435 | 0 | case CMD_SET_PICC_OPERATING_PARAMETER: |
436 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
437 | 0 | proto_tree_add_item(p2_tree, hf_picc_operating_auto_picc_polling, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
438 | 0 | proto_tree_add_item(p2_tree, hf_picc_operating_auto_ats_generation, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
439 | 0 | proto_tree_add_item(p2_tree, hf_picc_operating_polling_interval, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
440 | 0 | proto_tree_add_item(p2_tree, hf_picc_operating_felica_424k, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
441 | 0 | proto_tree_add_item(p2_tree, hf_picc_operating_felica_212k, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
442 | 0 | proto_tree_add_item(p2_tree, hf_picc_operating_topaz, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
443 | 0 | proto_tree_add_item(p2_tree, hf_picc_operating_iso_14443_type_b, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
444 | 0 | proto_tree_add_item(p2_tree, hf_picc_operating_iso_14443_type_a, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
445 | 0 | break; |
446 | 0 | case CMD_SET_TIMEOUT_PARAMETER: |
447 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
448 | 0 | proto_tree_add_item(p2_tree, hf_timeout, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
449 | 0 | break; |
450 | 0 | case CMD_SET_BUZZER_OUTPUT_FOR_CARD_DETECTION: |
451 | 0 | p2_tree = proto_item_add_subtree(p2_item, ett_p2_item); |
452 | 0 | proto_tree_add_item(p2_tree, hf_poll_buzzer_status, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
453 | 0 | break; |
454 | 0 | case CMD_GET_PICC_OPERATING_PARAMETER: |
455 | | /* No parameters */ |
456 | 0 | break; |
457 | 0 | } |
458 | | |
459 | 0 | if (!pinfo->fd->visited) { |
460 | 0 | command_data = wmem_new(wmem_file_scope(), command_data_t); |
461 | 0 | command_data->bus_id = bus_id; |
462 | 0 | command_data->device_address = device_address; |
463 | 0 | command_data->endpoint = endpoint; |
464 | |
|
465 | 0 | command_data->command = command; |
466 | 0 | command_data->command_frame_number = pinfo->num; |
467 | 0 | command_data->response_frame_number = 0; |
468 | |
|
469 | 0 | wmem_tree_insert32_array(command_info, key, command_data); |
470 | 0 | } |
471 | |
|
472 | 0 | } else { /* Response */ |
473 | 0 | uint32_t command_frame_number = 0; |
474 | 0 | bool use_status_word = false; |
475 | 0 | wmem_tree_t *wmem_tree; |
476 | |
|
477 | 0 | key[3].length = 0; |
478 | 0 | key[3].key = NULL; |
479 | |
|
480 | 0 | wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(command_info, key); |
481 | 0 | if (wmem_tree) { |
482 | 0 | command_data = (command_data_t *) wmem_tree_lookup32_le(wmem_tree, pinfo->num); |
483 | |
|
484 | 0 | if (command_data && (command_data->response_frame_number == 0 || |
485 | 0 | command_data->response_frame_number == pinfo->num)) { |
486 | |
|
487 | 0 | command = command_data->command; |
488 | 0 | command_frame_number = command_data->command_frame_number; |
489 | 0 | if (!pinfo->fd->visited && command_data->response_frame_number == 0) { |
490 | 0 | command_data->response_frame_number = pinfo->num; |
491 | 0 | } |
492 | 0 | } |
493 | 0 | } |
494 | |
|
495 | 0 | sub_item = proto_tree_add_uint(main_tree, hf_response, tvb, offset, tvb_captured_length_remaining(tvb, offset), command); |
496 | 0 | proto_item_set_generated(sub_item); |
497 | |
|
498 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Response: %s", val_to_str_ext_const(command, &command_vals_ext, "Unknown")); |
499 | |
|
500 | 0 | if (command != CMD_UNKNOWN) { |
501 | 0 | sub_item = proto_tree_add_uint(main_tree, hf_response_for, tvb, offset, tvb_captured_length_remaining(tvb, offset), command_frame_number); |
502 | 0 | proto_item_set_generated(sub_item); |
503 | 0 | } |
504 | |
|
505 | 0 | switch (command) { |
506 | 0 | case CMD_GET_FIRMWARE_VERSION: |
507 | 0 | proto_tree_add_item(main_tree, hf_firmware_version, tvb, offset, -1, ENC_NA | ENC_ASCII); |
508 | 0 | offset += tvb_captured_length_remaining(tvb, offset); |
509 | 0 | break; |
510 | | |
511 | 0 | case CMD_DIRECT_TRANSMIT: |
512 | 0 | use_status_word = true; |
513 | |
|
514 | 0 | if (tvb_captured_length_remaining(tvb, offset) > 2) { |
515 | 0 | next_tvb = tvb_new_subset_length(tvb, offset, tvb_captured_length_remaining(tvb, offset) - 2); |
516 | 0 | call_dissector_with_data(pn532_handle, next_tvb, pinfo, tree, urb); |
517 | 0 | offset += tvb_captured_length_remaining(tvb, offset) - 2; |
518 | 0 | } |
519 | 0 | break; |
520 | | |
521 | | |
522 | 0 | case CMD_READ_BINARY_BLOCKS: |
523 | 0 | use_status_word = true; |
524 | 0 | proto_tree_add_item(main_tree, hf_data, tvb, offset, tvb_captured_length_remaining(tvb, offset) - 2, ENC_NA); |
525 | 0 | offset += tvb_captured_length_remaining(tvb, offset) - 2; |
526 | 0 | break; |
527 | | |
528 | 0 | case CMD_READ_VALUE_BLOCK: |
529 | 0 | use_status_word = true; |
530 | 0 | proto_tree_add_item(main_tree, hf_value, tvb, offset, 4, ENC_BIG_ENDIAN); |
531 | 0 | break; |
532 | | |
533 | 0 | case CMD_GET_DATA_UID: |
534 | 0 | use_status_word = true; |
535 | 0 | proto_tree_add_item(main_tree, hf_uid, tvb, offset, tvb_captured_length_remaining(tvb, offset) - 2, ENC_NA); |
536 | 0 | offset += tvb_captured_length_remaining(tvb, offset) - 2; |
537 | 0 | break; |
538 | | |
539 | 0 | case CMD_GET_DATA_ATS: |
540 | 0 | use_status_word = true; |
541 | 0 | proto_tree_add_item(main_tree, hf_ats, tvb, offset, tvb_captured_length_remaining(tvb, offset) - 2, ENC_NA); |
542 | 0 | offset += tvb_captured_length_remaining(tvb, offset) - 2; |
543 | 0 | break; |
544 | | |
545 | 0 | case CMD_BI_COLOR_AND_BUZZER_LED_CONTROL: |
546 | 0 | case CMD_LOAD_AUTHENTICATION_KEYS: |
547 | 0 | case CMD_AUTHENTICATION: |
548 | 0 | case CMD_AUTHENTICATION_OBSOLETE: |
549 | 0 | case CMD_UPDATE_BINARY_BLOCKS: |
550 | 0 | case CMD_VALUE_BLOCK_OPERATION: |
551 | 0 | case CMD_RESTORE_VALUE_BLOCK: |
552 | 0 | case CMD_SET_TIMEOUT_PARAMETER: |
553 | 0 | case CMD_SET_BUZZER_OUTPUT_FOR_CARD_DETECTION: |
554 | 0 | case CMD_SET_PICC_OPERATING_PARAMETER: |
555 | 0 | case CMD_GET_PICC_OPERATING_PARAMETER: |
556 | 0 | default: |
557 | 0 | use_status_word = true; |
558 | 0 | break; |
559 | 0 | } |
560 | | |
561 | 0 | if (use_status_word) { |
562 | 0 | value = tvb_get_ntohs(tvb, offset); |
563 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " - %s%s", |
564 | 0 | (((value & 0xFF00) != 0x9000) && (value & 0xFF00) != 0x6100) ? |
565 | 0 | "Error: " : "", |
566 | 0 | rval_to_str_const(value, status_word_rvals, "Unknown error")); |
567 | |
|
568 | 0 | if ((value & 0xFF00) == 0x6100) |
569 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " - Length %u", value & 0x00FF); |
570 | |
|
571 | 0 | sub_item = proto_tree_add_item(main_tree, hf_status_word, tvb, offset, 2, ENC_BIG_ENDIAN); |
572 | 0 | sub_tree = proto_item_add_subtree(sub_item, ett_status_word); |
573 | 0 | proto_tree_add_item(sub_tree, hf_status_word_sw1, tvb, offset, 1, ENC_BIG_ENDIAN); |
574 | 0 | offset += 1; |
575 | 0 | sw2_item = proto_tree_add_item(sub_tree, hf_status_word_sw2, tvb, offset, 1, ENC_BIG_ENDIAN); |
576 | |
|
577 | 0 | if (command == CMD_BI_COLOR_AND_BUZZER_LED_CONTROL) { |
578 | 0 | sw2_tree = proto_item_add_subtree(sw2_item, ett_status_word_sw2); |
579 | |
|
580 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " - Red LED: %s, Green LED: %s", (value & 0x02) ? "On" : "Off", (value & 0x01) ? "On" : "Off"); |
581 | |
|
582 | 0 | proto_tree_add_item(sw2_tree, hf_status_word_led_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); |
583 | 0 | proto_tree_add_item(sw2_tree, hf_status_word_led_green, tvb, offset, 1, ENC_BIG_ENDIAN); |
584 | 0 | proto_tree_add_item(sw2_tree, hf_status_word_led_red, tvb, offset, 1, ENC_BIG_ENDIAN); |
585 | 0 | } else if (command == CMD_SET_PICC_OPERATING_PARAMETER || command == CMD_GET_PICC_OPERATING_PARAMETER) { |
586 | 0 | sw2_tree = proto_item_add_subtree(sw2_item, ett_status_word_sw2); |
587 | 0 | proto_tree_add_item(sw2_tree, hf_picc_operating_auto_picc_polling, tvb, offset, 1, ENC_BIG_ENDIAN); |
588 | 0 | proto_tree_add_item(sw2_tree, hf_picc_operating_auto_ats_generation, tvb, offset, 1, ENC_BIG_ENDIAN); |
589 | 0 | proto_tree_add_item(sw2_tree, hf_picc_operating_polling_interval, tvb, offset, 1, ENC_BIG_ENDIAN); |
590 | 0 | proto_tree_add_item(sw2_tree, hf_picc_operating_felica_424k, tvb, offset, 1, ENC_BIG_ENDIAN); |
591 | 0 | proto_tree_add_item(sw2_tree, hf_picc_operating_felica_212k, tvb, offset, 1, ENC_BIG_ENDIAN); |
592 | 0 | proto_tree_add_item(sw2_tree, hf_picc_operating_topaz, tvb, offset, 1, ENC_BIG_ENDIAN); |
593 | 0 | proto_tree_add_item(sw2_tree, hf_picc_operating_iso_14443_type_b, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
594 | 0 | proto_tree_add_item(sw2_tree, hf_picc_operating_iso_14443_type_a, tvb, offset - 2, 1, ENC_BIG_ENDIAN); |
595 | 0 | } |
596 | 0 | offset += 1; |
597 | 0 | } |
598 | 0 | } |
599 | | |
600 | 0 | return offset; |
601 | 0 | } |
602 | | |
603 | | void |
604 | | proto_register_acr122(void) |
605 | 14 | { |
606 | 14 | module_t *module; |
607 | 14 | expert_module_t *expert_module; |
608 | | |
609 | 14 | static hf_register_info hf[] = { |
610 | 14 | { &hf_class, |
611 | 14 | { "Class", "acr122.class", |
612 | 14 | FT_UINT8, BASE_HEX, NULL, 0x00, |
613 | 14 | NULL, HFILL } |
614 | 14 | }, |
615 | 14 | { &hf_ins, |
616 | 14 | { "Ins", "acr122.ins", |
617 | 14 | FT_UINT8, BASE_HEX, NULL, 0x00, |
618 | 14 | NULL, HFILL } |
619 | 14 | }, |
620 | 14 | { &hf_p1, |
621 | 14 | { "P1", "acr122.p1", |
622 | 14 | FT_UINT8, BASE_HEX, NULL, 0x00, |
623 | 14 | NULL, HFILL } |
624 | 14 | }, |
625 | 14 | { &hf_p2, |
626 | 14 | { "P2", "acr122.p2", |
627 | 14 | FT_UINT8, BASE_HEX, NULL, 0x00, |
628 | 14 | NULL, HFILL } |
629 | 14 | }, |
630 | 14 | { &hf_length, |
631 | 14 | { "Length", "acr122.length", |
632 | 14 | FT_UINT8, BASE_HEX, NULL, 0x00, |
633 | 14 | NULL, HFILL } |
634 | 14 | }, |
635 | 14 | { &hf_status_word, |
636 | 14 | { "Status Word", "acr122.status_word", |
637 | 14 | FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(status_word_rvals), 0x00, |
638 | 14 | NULL, HFILL } |
639 | 14 | }, |
640 | 14 | { &hf_status_word_sw1, |
641 | 14 | { "SW1", "acr122.status_word.sw1", |
642 | 14 | FT_UINT8, BASE_HEX, NULL, 0x00, |
643 | 14 | NULL, HFILL } |
644 | 14 | }, |
645 | 14 | { &hf_status_word_sw2, |
646 | 14 | { "SW2", "acr122.status_word.sw2", |
647 | 14 | FT_UINT8, BASE_HEX, NULL, 0x00, |
648 | 14 | NULL, HFILL } |
649 | 14 | }, |
650 | 14 | { &hf_command, |
651 | 14 | { "Command", "acr122.command", |
652 | 14 | FT_UINT8, BASE_HEX | BASE_EXT_STRING, &command_vals_ext, 0x00, |
653 | 14 | NULL, HFILL } |
654 | 14 | }, |
655 | 14 | { &hf_response, |
656 | 14 | { "Response", "acr122.response", |
657 | 14 | FT_UINT8, BASE_HEX | BASE_EXT_STRING, &command_vals_ext, 0x00, |
658 | 14 | NULL, HFILL } |
659 | 14 | }, |
660 | 14 | { &hf_response_for, |
661 | 14 | { "Response for", "acr122.response_for", |
662 | 14 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, |
663 | 14 | NULL, HFILL } |
664 | 14 | }, |
665 | 14 | { &hf_picc_operating_auto_picc_polling, |
666 | 14 | { "Auto PICC Polling", "acr122.picc_operating.auto_picc_polling", |
667 | 14 | FT_BOOLEAN, 8, NULL, 0x80, |
668 | 14 | NULL, HFILL } |
669 | 14 | }, |
670 | 14 | { &hf_picc_operating_auto_ats_generation, |
671 | 14 | { "ATS Generation", "acr122.picc_operating.ats_generation", |
672 | 14 | FT_BOOLEAN, 8, NULL, 0x40, |
673 | 14 | NULL, HFILL } |
674 | 14 | }, |
675 | 14 | { &hf_picc_operating_polling_interval, |
676 | 14 | { "Polling Interval", "acr122.picc_operating.polling_interval", |
677 | 14 | FT_BOOLEAN, 8, NULL, 0x20, |
678 | 14 | NULL, HFILL } |
679 | 14 | }, |
680 | 14 | { &hf_picc_operating_felica_424k, |
681 | 14 | { "FeliCa 424k", "acr122.picc_operating.felica_424k", |
682 | 14 | FT_BOOLEAN, 8, NULL, 0x10, |
683 | 14 | NULL, HFILL } |
684 | 14 | }, |
685 | 14 | { &hf_picc_operating_felica_212k, |
686 | 14 | { "FeliCa 212k", "acr122.picc_operating.felica_212k", |
687 | 14 | FT_BOOLEAN, 8, NULL, 0x08, |
688 | 14 | NULL, HFILL } |
689 | 14 | }, |
690 | 14 | { &hf_picc_operating_topaz, |
691 | 14 | { "Topaz", "acr122.picc_operating.topaz", |
692 | 14 | FT_BOOLEAN, 8, NULL, 0x04, |
693 | 14 | NULL, HFILL } |
694 | 14 | }, |
695 | 14 | { &hf_picc_operating_iso_14443_type_b, |
696 | 14 | { "ISO 14443 Type B", "acr122.picc_operating.iso_14443_type_b", |
697 | 14 | FT_BOOLEAN, 8, NULL, 0x02, |
698 | 14 | NULL, HFILL } |
699 | 14 | }, |
700 | 14 | { &hf_picc_operating_iso_14443_type_a, |
701 | 14 | { "ISO 14443 Type A", "acr122.picc_operating.iso_14443_type_a", |
702 | 14 | FT_BOOLEAN, 8, NULL, 0x01, |
703 | 14 | NULL, HFILL } |
704 | 14 | }, |
705 | 14 | { &hf_firmware_version, |
706 | 14 | { "Firmware Version", "acr122.firmware_version", |
707 | 14 | FT_STRING, BASE_NONE, NULL, 0x00, |
708 | 14 | NULL, HFILL } |
709 | 14 | }, |
710 | 14 | { &hf_led_green_blinking_state, |
711 | 14 | { "Green LED Blinking", "acr122.led.green.blinking", |
712 | 14 | FT_BOOLEAN, 8, NULL, 0x80, |
713 | 14 | NULL, HFILL } |
714 | 14 | }, |
715 | 14 | { &hf_led_red_blinking_state, |
716 | 14 | { "Red LED Blinking", "acr122.led.red.blinking", |
717 | 14 | FT_BOOLEAN, 8, NULL, 0x40, |
718 | 14 | NULL, HFILL } |
719 | 14 | }, |
720 | 14 | { &hf_led_green_mask, |
721 | 14 | { "Green LED Mask", "acr122.led.green.mask", |
722 | 14 | FT_BOOLEAN, 8, NULL, 0x20, |
723 | 14 | NULL, HFILL } |
724 | 14 | }, |
725 | 14 | { &hf_led_red_mask, |
726 | 14 | { "Red LED Mask", "acr122.led.red.mask", |
727 | 14 | FT_BOOLEAN, 8, NULL, 0x10, |
728 | 14 | NULL, HFILL } |
729 | 14 | }, |
730 | 14 | { &hf_led_initial_green_blinking_state, |
731 | 14 | { "Initial Green LED Blinking", "acr122.led.green.initial", |
732 | 14 | FT_BOOLEAN, 8, NULL, 0x08, |
733 | 14 | NULL, HFILL } |
734 | 14 | }, |
735 | 14 | { &hf_led_initial_red_blinking_state, |
736 | 14 | { "Initial Red LED Blinking", "acr122.led.red.initial", |
737 | 14 | FT_BOOLEAN, 8, NULL, 0x04, |
738 | 14 | NULL, HFILL } |
739 | 14 | }, |
740 | 14 | { &hf_led_final_green_state, |
741 | 14 | { "Final Green LED", "acr122.led.green.final", |
742 | 14 | FT_BOOLEAN, 8, NULL, 0x02, |
743 | 14 | NULL, HFILL } |
744 | 14 | }, |
745 | 14 | { &hf_led_final_red_state, |
746 | 14 | { "Final Red LED", "acr122.led.red.final", |
747 | 14 | FT_BOOLEAN, 8, NULL, 0x01, |
748 | 14 | NULL, HFILL } |
749 | 14 | }, |
750 | 14 | { &hf_led_t1_duration, |
751 | 14 | { "T1 Duration", "acr122.led.t1_duration", |
752 | 14 | FT_UINT8, BASE_CUSTOM, CF_FUNC(duration_base), 0x00, |
753 | 14 | "Initial Blinking State", HFILL } |
754 | 14 | }, |
755 | 14 | { &hf_led_t2_duration, |
756 | 14 | { "T2 Duration", "acr122.led.t2_duration", |
757 | 14 | FT_UINT8, BASE_CUSTOM, CF_FUNC(duration_base), 0x00, |
758 | 14 | "Toggle Blinking State", HFILL } |
759 | 14 | }, |
760 | 14 | { &hf_led_number_of_repetition, |
761 | 14 | { "Number of Repetition", "acr122.led.number_of_repetition", |
762 | 14 | FT_UINT8, BASE_DEC, NULL, 0x00, |
763 | 14 | NULL, HFILL } |
764 | 14 | }, |
765 | 14 | { &hf_led_link_to_buzzer, |
766 | 14 | { "Link to Buzzer", "acr122.led.link_to_buzzer", |
767 | 14 | FT_UINT8, BASE_HEX, VALS(link_to_buzzer_vals), 0x00, |
768 | 14 | NULL, HFILL } |
769 | 14 | }, |
770 | 14 | { &hf_poll_buzzer_status, |
771 | 14 | { "Poll Buzzer Status", "acr122.poll_buzzer_status", |
772 | 14 | FT_UINT8, BASE_HEX, VALS(poll_buzzer_status_vals), 0x00, |
773 | 14 | NULL, HFILL } |
774 | 14 | }, |
775 | 14 | { &hf_timeout, |
776 | 14 | { "Timeout", "acr122.timeout", |
777 | 14 | FT_UINT8, BASE_CUSTOM, CF_FUNC(timeout_base), 0x00, |
778 | 14 | NULL, HFILL } |
779 | 14 | }, |
780 | 14 | { &hf_status_word_led_reserved, |
781 | 14 | { "Reserved", "acr122.status_word.sw2.reserved", |
782 | 14 | FT_UINT8, BASE_HEX, NULL, 0xFC, |
783 | 14 | NULL, HFILL } |
784 | 14 | }, |
785 | 14 | { &hf_status_word_led_green, |
786 | 14 | { "Current Green LED", "acr122.status_word.sw2.led.green", |
787 | 14 | FT_BOOLEAN, 8, NULL, 0x02, |
788 | 14 | NULL, HFILL } |
789 | 14 | }, |
790 | 14 | { &hf_status_word_led_red, |
791 | 14 | { "Current Red LED", "acr122.status_word.sw2.led.red", |
792 | 14 | FT_BOOLEAN, 8, NULL, 0x01, |
793 | 14 | NULL, HFILL } |
794 | 14 | }, |
795 | 14 | { &hf_key, |
796 | 14 | { "Key", "acr122.key", |
797 | 14 | FT_BYTES, BASE_NONE, NULL, 0x00, |
798 | 14 | NULL, HFILL } |
799 | 14 | }, |
800 | 14 | { &hf_key_structure, |
801 | 14 | { "Key Structure", "acr122.key_structure", |
802 | 14 | FT_UINT8, BASE_HEX, VALS(key_structure_vals), 0x00, |
803 | 14 | NULL, HFILL } |
804 | 14 | }, |
805 | 14 | { &hf_key_number, |
806 | 14 | { "Key Number", "acr122.key_number", |
807 | 14 | FT_UINT8, BASE_DEC, NULL, 0x00, |
808 | 14 | NULL, HFILL } |
809 | 14 | }, |
810 | 14 | { &hf_key_type, |
811 | 14 | { "Key Type", "acr122.key_type", |
812 | 14 | FT_UINT8, BASE_HEX, VALS(key_type_vals), 0x00, |
813 | 14 | NULL, HFILL } |
814 | 14 | }, |
815 | 14 | { &hf_block_number, |
816 | 14 | { "Block Number", "acr122.block_number", |
817 | 14 | FT_UINT8, BASE_DEC_HEX, NULL, 0x00, |
818 | 14 | NULL, HFILL } |
819 | 14 | }, |
820 | 14 | { &hf_source_block_number, |
821 | 14 | { "Source Block Number", "acr122.source_block_number", |
822 | 14 | FT_UINT8, BASE_DEC_HEX, NULL, 0x00, |
823 | 14 | NULL, HFILL } |
824 | 14 | }, |
825 | 14 | { &hf_target_block_number, |
826 | 14 | { "Target Block Number", "acr122.target_block_number", |
827 | 14 | FT_UINT8, BASE_DEC_HEX, NULL, 0x00, |
828 | 14 | NULL, HFILL } |
829 | 14 | }, |
830 | 14 | { &hf_static_byte, |
831 | 14 | { "Static Byte", "acr122.static_byte", |
832 | 14 | FT_UINT8, BASE_HEX, NULL, 0x00, |
833 | 14 | NULL, HFILL } |
834 | 14 | }, |
835 | 14 | { &hf_vb_op, |
836 | 14 | { "VB Op", "acr122.vb_op", |
837 | 14 | FT_UINT8, BASE_HEX, VALS(vb_op_vals), 0x00, |
838 | 14 | NULL, HFILL } |
839 | 14 | }, |
840 | 14 | { &hf_version, |
841 | 14 | { "Version", "acr122.version", |
842 | 14 | FT_UINT16, BASE_HEX, NULL, 0x00, |
843 | 14 | NULL, HFILL } |
844 | 14 | }, |
845 | 14 | { &hf_value, |
846 | 14 | { "Value", "acr122.value", |
847 | 14 | FT_INT32, BASE_DEC, NULL, 0x00, |
848 | 14 | NULL, HFILL } |
849 | 14 | }, |
850 | 14 | { &hf_uid, |
851 | 14 | { "UID", "acr122.uid", |
852 | 14 | FT_BYTES, BASE_NONE, NULL, 0x00, |
853 | 14 | NULL, HFILL } |
854 | 14 | }, |
855 | 14 | { &hf_ats, |
856 | 14 | { "ATS", "acr122.ats", |
857 | 14 | FT_BYTES, BASE_NONE, NULL, 0x00, |
858 | 14 | NULL, HFILL } |
859 | 14 | }, |
860 | 14 | { &hf_data, |
861 | 14 | { "Data", "acr122.data", |
862 | 14 | FT_BYTES, BASE_NONE, NULL, 0x00, |
863 | 14 | NULL, HFILL } |
864 | 14 | }, |
865 | 14 | }; |
866 | | |
867 | 14 | static int *ett[] = { |
868 | 14 | &ett_acr122, |
869 | 14 | &ett_p1_item, |
870 | 14 | &ett_p2_item, |
871 | 14 | &ett_status_word, |
872 | 14 | &ett_status_word_sw2 |
873 | 14 | }; |
874 | | |
875 | 14 | static ei_register_info ei[] = { |
876 | 14 | { &ei_unknown_command_or_invalid_parameters, { "acr122.expert.unknown_command", PI_PROTOCOL, PI_NOTE, "Unknown command or invalid parameters", EXPFILL }}, |
877 | 14 | }; |
878 | | |
879 | 14 | command_info = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
880 | | |
881 | 14 | proto_acr122 = proto_register_protocol("Advanced Card Systems ACR122", "ACR 122", "acr122"); |
882 | 14 | acr122_handle = register_dissector("acr122", dissect_acr122, proto_acr122); |
883 | | |
884 | 14 | proto_register_field_array(proto_acr122, hf, array_length(hf)); |
885 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
886 | 14 | expert_module = expert_register_protocol(proto_acr122); |
887 | 14 | expert_register_field_array(expert_module, ei, array_length(ei)); |
888 | | |
889 | 14 | module = prefs_register_protocol(proto_acr122, NULL); |
890 | 14 | prefs_register_static_text_preference(module, "version", |
891 | 14 | "ACR122U USB NFC Reader - Application Programming Interface V2.02", |
892 | 14 | "Version of protocol supported by this dissector."); |
893 | 14 | } |
894 | | |
895 | | void |
896 | | proto_reg_handoff_acr122(void) |
897 | 14 | { |
898 | 14 | pn532_handle = find_dissector_add_dependency("pn532", proto_acr122); |
899 | 14 | dissector_add_for_decode_as("usbccid.subdissector", acr122_handle); |
900 | 14 | } |
901 | | |
902 | | /* |
903 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
904 | | * |
905 | | * Local variables: |
906 | | * c-basic-offset: 4 |
907 | | * tab-width: 8 |
908 | | * indent-tabs-mode: nil |
909 | | * End: |
910 | | * |
911 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
912 | | * :indentSize=4:tabSize=8:noTabs=true: |
913 | | */ |