2 * Dissector for the Integrated Circuit Card Interface Device Class
5 * http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.pdf
7 * Copyright 2011, Tyson Key <tyson.key@gmail.com>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include <epan/decode_as.h>
19 #include <epan/packet.h>
20 #include <epan/prefs.h>
22 #include <epan/unit_strings.h>
24 #include <wsutil/array.h>
25 #include "packet-usb.h"
27 static int proto_ccid
;
29 static dissector_table_t subdissector_table
;
31 static int hf_ccid_bMessageType
;
32 static int hf_ccid_dwLength
;
33 static int hf_ccid_bSlot
;
34 static int hf_ccid_bSeq
;
35 static int hf_ccid_bStatus
;
36 static int hf_ccid_bStatus_bmIccStatus
;
37 static int hf_ccid_bStatus_bmCommandStatus
;
38 static int hf_ccid_bError
;
39 static int hf_ccid_bRFU
;
40 static int hf_ccid_abRFU
;
41 static int hf_ccid_bChainParameter
;
42 static int hf_ccid_bPowerSelect
;
43 static int hf_ccid_bClockStatus
;
44 static int hf_ccid_bProtocolNum
;
45 static int hf_ccid_bBWI
;
46 static int hf_ccid_wLevelParameter
;
47 static int hf_ccid_bcdCCID
;
48 static int hf_ccid_bMaxSlotIndex
;
49 static int hf_ccid_bVoltageSupport
;
50 static int hf_ccid_bVoltageSupport18
;
51 static int hf_ccid_bVoltageSupport30
;
52 static int hf_ccid_bVoltageSupport50
;
53 static int hf_ccid_dwProtocols
;
54 static int hf_ccid_dwProtocols_t0
;
55 static int hf_ccid_dwProtocols_t1
;
56 static int hf_ccid_dwDefaultClock
;
57 static int hf_ccid_dwMaximumClock
;
58 static int hf_ccid_bNumClockSupported
;
59 static int hf_ccid_dwDataRate
;
60 static int hf_ccid_dwMaxDataRate
;
61 static int hf_ccid_bNumDataRatesSupported
;
62 static int hf_ccid_dwMaxIFSD
;
63 static int hf_ccid_dwSynchProtocols
;
64 static int hf_ccid_dwMechanical
;
65 static int hf_ccid_dwFeatures
;
66 static int hf_ccid_dwFeatures_autoParam
;
67 static int hf_ccid_dwFeatures_autoIccActivation
;
68 static int hf_ccid_dwFeatures_autoIccVoltSelect
;
69 static int hf_ccid_dwFeatures_autoIccClk
;
70 static int hf_ccid_dwFeatures_autoBaudRate
;
71 static int hf_ccid_dwFeatures_autoParamNegotiation
;
72 static int hf_ccid_dwFeatures_autoPPS
;
73 static int hf_ccid_dwFeatures_stopIccClk
;
74 static int hf_ccid_dwFeatures_nadValNot0accept
;
75 static int hf_ccid_dwFeatures_autoIfsd
;
76 static int hf_ccid_dwFeatures_levelExchangeTDPU
;
77 static int hf_ccid_dwFeatures_levelExchangeShortAPDU
;
78 static int hf_ccid_dwFeatures_levelExchangeShortExtendedAPDU
;
79 static int hf_ccid_dwFeatures_UsbWakeUp
;
80 static int hf_ccid_dwMaxCCIDMessageLength
;
81 static int hf_ccid_bClassGetResponse
;
82 static int hf_ccid_bClassEnvelope
;
83 static int hf_ccid_wLcdLayout
;
84 static int hf_ccid_wLcdLayout_lines
;
85 static int hf_ccid_wLcdLayout_chars
;
86 static int hf_ccid_bPINSupport
;
87 static int hf_ccid_bPINSupport_modify
;
88 static int hf_ccid_bPINSupport_vrfy
;
89 static int hf_ccid_bMaxCCIDBusySlots
;
90 static int hf_ccid_Reserved
;
91 static int hf_ccid_bmSlotICCState
;
92 static int hf_ccid_bmSlotICCState_slot0Current
;
93 static int hf_ccid_bmSlotICCState_slot0Changed
;
94 static int hf_ccid_bmSlotICCState_slot1Current
;
95 static int hf_ccid_bmSlotICCState_slot1Changed
;
96 static int hf_ccid_bmSlotICCState_slot2Current
;
97 static int hf_ccid_bmSlotICCState_slot2Changed
;
98 static int hf_ccid_bmSlotICCState_slot3Current
;
99 static int hf_ccid_bmSlotICCState_slot3Changed
;
100 static int hf_ccid_bmSlotICCState_slot4Current
;
101 static int hf_ccid_bmSlotICCState_slot4Changed
;
102 static int hf_ccid_bmSlotICCState_slot5Current
;
103 static int hf_ccid_bmSlotICCState_slot5Changed
;
104 static int hf_ccid_bmSlotICCState_slot6Current
;
105 static int hf_ccid_bmSlotICCState_slot6Changed
;
106 static int hf_ccid_bmSlotICCState_slot7Current
;
107 static int hf_ccid_bmSlotICCState_slot7Changed
;
108 static int hf_ccid_bHardwareErrorCode
;
109 static int hf_ccid_bmFindexDindex
;
110 static int hf_ccid_bmTCCKST0
;
111 static int hf_ccid_bmTCCKST1
;
112 static int hf_ccid_bGuardTimeT0
;
113 static int hf_ccid_bGuardTimeT1
;
114 static int hf_ccid_bWaitingIntegerT0
;
115 static int hf_ccid_bmWaitingIntegersT1
;
116 static int hf_ccid_bClockStop
;
117 static int hf_ccid_bIFSC
;
118 static int hf_ccid_bNadValue
;
120 static dissector_handle_t usb_ccid_handle
;
121 static dissector_handle_t usb_ccid_descr_handle
;
124 static int * const bVoltageLevel_fields
[] = {
125 &hf_ccid_bVoltageSupport18
,
126 &hf_ccid_bVoltageSupport30
,
127 &hf_ccid_bVoltageSupport50
,
131 static int * const dwProtocols_fields
[] = {
132 &hf_ccid_dwProtocols_t0
,
133 &hf_ccid_dwProtocols_t1
,
137 static int * const bFeatures_fields
[] = {
138 /* XXX - add the missing components */
139 &hf_ccid_dwFeatures_autoParam
,
140 &hf_ccid_dwFeatures_autoIccActivation
,
141 &hf_ccid_dwFeatures_autoIccVoltSelect
,
142 &hf_ccid_dwFeatures_autoIccClk
,
143 &hf_ccid_dwFeatures_autoBaudRate
,
144 &hf_ccid_dwFeatures_autoParamNegotiation
,
145 &hf_ccid_dwFeatures_autoPPS
,
146 &hf_ccid_dwFeatures_stopIccClk
,
147 &hf_ccid_dwFeatures_nadValNot0accept
,
148 &hf_ccid_dwFeatures_autoIfsd
,
149 &hf_ccid_dwFeatures_levelExchangeTDPU
,
150 &hf_ccid_dwFeatures_levelExchangeShortAPDU
,
151 &hf_ccid_dwFeatures_levelExchangeShortExtendedAPDU
,
152 &hf_ccid_dwFeatures_UsbWakeUp
,
156 static int * const bPINSupport_fields
[] = {
157 &hf_ccid_bPINSupport_modify
,
158 &hf_ccid_bPINSupport_vrfy
,
162 static int * const bmSlotICCStateb0_fields
[] = {
163 &hf_ccid_bmSlotICCState_slot0Current
,
164 &hf_ccid_bmSlotICCState_slot0Changed
,
165 &hf_ccid_bmSlotICCState_slot1Current
,
166 &hf_ccid_bmSlotICCState_slot1Changed
,
167 &hf_ccid_bmSlotICCState_slot2Current
,
168 &hf_ccid_bmSlotICCState_slot2Changed
,
169 &hf_ccid_bmSlotICCState_slot3Current
,
170 &hf_ccid_bmSlotICCState_slot3Changed
,
174 static int * const bmSlotICCStateb1_fields
[] = {
175 &hf_ccid_bmSlotICCState_slot4Current
,
176 &hf_ccid_bmSlotICCState_slot4Changed
,
177 &hf_ccid_bmSlotICCState_slot5Current
,
178 &hf_ccid_bmSlotICCState_slot5Changed
,
179 &hf_ccid_bmSlotICCState_slot6Current
,
180 &hf_ccid_bmSlotICCState_slot6Changed
,
181 &hf_ccid_bmSlotICCState_slot7Current
,
182 &hf_ccid_bmSlotICCState_slot7Changed
,
186 static int * const bStatus_fields
[] = {
187 &hf_ccid_bStatus_bmIccStatus
,
188 &hf_ccid_bStatus_bmCommandStatus
,
192 /* smart card descriptor, as defined in section 5.1
193 of the USB CCID specification */
194 #define USB_DESC_TYPE_SMARTCARD 0x21
196 /* Standardised Bulk Out message types */
197 #define PC_RDR_SET_PARAMS 0x61
198 #define PC_RDR_ICC_ON 0x62
199 #define PC_RDR_ICC_OFF 0x63
200 #define PC_RDR_GET_SLOT_STATUS 0x65
201 #define PC_RDR_SECURE 0x69
202 #define PC_RDR_T0APDU 0x6A
203 #define PC_RDR_ESCAPE 0x6B
204 #define PC_RDR_GET_PARAMS 0x6C
205 #define PC_RDR_RESET_PARAMS 0x6D
206 #define PC_RDR_ICC_CLOCK 0x6E
207 #define PC_RDR_XFR_BLOCK 0x6F
208 #define PC_RDR_MECH 0x71
209 #define PC_RDR_ABORT 0x72
210 #define PC_RDR_DATA_CLOCK 0x73
212 /* Standardised Bulk In message types */
213 #define RDR_PC_DATA_BLOCK 0x80
214 #define RDR_PC_SLOT_STATUS 0x81
215 #define RDR_PC_PARAMS 0x82
216 #define RDR_PC_ESCAPE 0x83
217 #define RDR_PC_DATA_CLOCK 0x84
219 /* Standardised Interrupt IN message types */
220 #define RDR_PC_NOTIF_SLOT_CHNG 0x50
221 #define RDR_PC_HWERROR 0x51
223 void proto_register_ccid(void);
224 void proto_reg_handoff_ccid(void);
226 static const value_string ccid_descriptor_type_vals
[] = {
227 {USB_DESC_TYPE_SMARTCARD
, "smart card"},
230 static value_string_ext ccid_descriptor_type_vals_ext
=
231 VALUE_STRING_EXT_INIT(ccid_descriptor_type_vals
);
233 static const value_string ccid_opcode_vals
[] = {
234 /* Standardised Bulk Out message types */
235 {PC_RDR_SET_PARAMS
, "PC_to_RDR_SetParameters"},
236 {PC_RDR_ICC_ON
, "PC_to_RDR_IccPowerOn"},
237 {PC_RDR_ICC_OFF
, "PC_to_RDR_IccPowerOff"},
238 {PC_RDR_GET_SLOT_STATUS
, "PC_to_RDR_GetSlotStatus"},
239 {PC_RDR_SECURE
, "PC_to_RDR_Secure"},
240 {PC_RDR_T0APDU
, "PC_to_RDR_T0APDU"},
241 {PC_RDR_ESCAPE
, "PC_to_RDR_Escape"},
242 {PC_RDR_GET_PARAMS
, "PC_to_RDR_GetParameters"},
243 {PC_RDR_RESET_PARAMS
, "PC_to_RDR_ResetParameters"},
244 {PC_RDR_ICC_CLOCK
, "PC_to_RDR_IccClock"},
245 {PC_RDR_XFR_BLOCK
, "PC_to_RDR_XfrBlock"},
246 {PC_RDR_MECH
, "PC_to_RDR_Mechanical"},
247 {PC_RDR_ABORT
, "PC_to_RDR_Abort"},
248 {PC_RDR_DATA_CLOCK
, "PC_to_RDR_SetDataRateAndClockFrequency"},
250 /* Standardised Bulk In message types */
251 {RDR_PC_DATA_BLOCK
, "RDR_to_PC_DataBlock"},
252 {RDR_PC_SLOT_STATUS
, "RDR_to_PC_SlotStatus"},
253 {RDR_PC_PARAMS
, "RDR_to_PC_Parameters"},
254 {RDR_PC_ESCAPE
, "RDR_to_PC_Escape"},
255 {RDR_PC_DATA_CLOCK
, "RDR_to_PC_DataRateAndClockFrequency"},
257 /* Standardised Interrupt IN message types */
258 {RDR_PC_NOTIF_SLOT_CHNG
, "RDR_to_PC_NotifySlotChange"},
259 {RDR_PC_HWERROR
, "RDR_to_PC_HardwareError"},
261 /* End of message types */
265 static const value_string ccid_messagetypes_vals
[] = {
266 /* Standardised Bulk Out message types */
267 {PC_RDR_SET_PARAMS
, "PC to Reader: Set Parameters"},
268 {PC_RDR_ICC_ON
, "PC to Reader: ICC Power On"},
269 {PC_RDR_ICC_OFF
, "PC to Reader: ICC Power Off"},
270 {PC_RDR_GET_SLOT_STATUS
, "PC to Reader: Get Slot Status"},
271 {PC_RDR_SECURE
, "PC to Reader: Secure"},
272 {PC_RDR_T0APDU
, "PC to Reader: T=0 APDU"},
273 {PC_RDR_ESCAPE
, "PC to Reader: Escape"},
274 {PC_RDR_GET_PARAMS
, "PC to Reader: Get Parameters"},
275 {PC_RDR_RESET_PARAMS
, "PC to Reader: Reset Parameters"},
276 {PC_RDR_ICC_CLOCK
, "PC to Reader: ICC Clock"},
277 {PC_RDR_XFR_BLOCK
, "PC to Reader: Transfer Block"},
278 {PC_RDR_MECH
, "PC to Reader: Mechanical"},
279 {PC_RDR_ABORT
, "PC to Reader: Abort"},
280 {PC_RDR_DATA_CLOCK
, "PC to Reader: Set Data Rate and Clock Frequency"},
282 /* Standardised Bulk In message types */
283 {RDR_PC_DATA_BLOCK
, "Reader to PC: Data Block"},
284 {RDR_PC_SLOT_STATUS
, "Reader to PC: Slot Status"},
285 {RDR_PC_PARAMS
, "Reader to PC: Parameters"},
286 {RDR_PC_ESCAPE
, "Reader to PC: Escape"},
287 {RDR_PC_DATA_CLOCK
, "Reader to PC: Data Rate and Clock Frequency"},
289 /* Standardised Interrupt IN message types */
290 {RDR_PC_NOTIF_SLOT_CHNG
, "Reader to PC: Notify Slot Change"},
291 {RDR_PC_HWERROR
, "Reader to PC: Hardware Error"},
293 /* End of message types */
297 static const value_string ccid_voltage_levels_vals
[] = {
298 /* Standardised voltage levels */
299 {0x00, "Automatic Voltage Selection"},
304 /* End of voltage levels */
308 static const value_string ccid_clock_states_vals
[] = {
309 /* Standardised clock states */
310 {0x00, "Clock running"},
311 {0x01, "Clock stopped in state L"},
312 {0x02, "Clock stopped in state H"},
313 {0x03, "Clock stopped in an unknown state"},
315 /* End of clock states */
319 static const value_string ccid_proto_structs_vals
[] = {
320 /* Standardised clock states */
321 {0x00, "Structure for protocol T=0"},
322 {0x01, "Structure for protocol T=1"},
324 /* Marked as RFU, but added for completeness: */
325 {0x80, "Structure for 2-wire protocol"},
326 {0x81, "Structure for 3-wire protocol"},
327 {0x82, "Structure for I2C protocol"},
329 /* End of protocol structures */
333 static const value_string ccid_status_icc_status_vals
[] = {
334 /* Standardised icc status */
335 { 0x00, "An ICC is present and active" },
336 { 0x01, "An ICC is present and inactive" },
337 { 0x02, "No ICC is present" },
340 /* End of icc status */
344 static const value_string ccid_status_cmd_status_vals
[] = {
345 /* Standardised status values */
346 { 0x00, "Processed without error " },
348 { 0x02, "Time Extension is requested " },
351 /* End of status values */
355 /* Subtree handles: set by register_subtree_array */
357 static int ett_ccid_desc
;
358 static int ett_ccid_protocol_data_structure
;
359 static int ett_ccid_voltage_level
;
360 static int ett_ccid_protocols
;
361 static int ett_ccid_features
;
362 static int ett_ccid_lcd_layout
;
363 static int ett_ccid_pin_support
;
364 static int ett_ccid_slot_change
;
365 static int ett_ccid_status
;
368 dissect_usb_ccid_descriptor(tvbuff_t
*tvb
, packet_info
*pinfo _U_
,
369 proto_tree
*tree
, void *data _U_
)
372 uint8_t descriptor_type
;
373 uint8_t descriptor_len
;
374 proto_item
*freq_item
;
375 proto_tree
*desc_tree
;
376 uint8_t num_clock_supp
;
377 proto_item
*lcd_layout_item
;
378 proto_tree
*lcd_layout_tree
;
380 descriptor_len
= tvb_get_uint8(tvb
, offset
);
381 descriptor_type
= tvb_get_uint8(tvb
, offset
+1);
382 if (descriptor_type
!=USB_DESC_TYPE_SMARTCARD
)
385 desc_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, descriptor_len
,
386 ett_ccid_desc
, NULL
, "SMART CARD DEVICE CLASS DESCRIPTOR");
388 dissect_usb_descriptor_header(desc_tree
, tvb
, offset
,
389 &ccid_descriptor_type_vals_ext
);
392 proto_tree_add_item(desc_tree
, hf_ccid_bcdCCID
, tvb
,
393 offset
, 2, ENC_LITTLE_ENDIAN
);
396 proto_tree_add_item(desc_tree
, hf_ccid_bMaxSlotIndex
, tvb
,
397 offset
, 1, ENC_LITTLE_ENDIAN
);
399 proto_tree_add_bitmask(desc_tree
, tvb
, offset
,
400 hf_ccid_bVoltageSupport
, ett_ccid_voltage_level
, bVoltageLevel_fields
,
404 proto_tree_add_bitmask(desc_tree
, tvb
, offset
,
405 hf_ccid_dwProtocols
, ett_ccid_protocols
, dwProtocols_fields
,
409 proto_tree_add_item(desc_tree
, hf_ccid_dwDefaultClock
, tvb
,
410 offset
, 4, ENC_LITTLE_ENDIAN
);
412 proto_tree_add_item(desc_tree
, hf_ccid_dwMaximumClock
, tvb
,
413 offset
, 4, ENC_LITTLE_ENDIAN
);
415 num_clock_supp
= tvb_get_uint8(tvb
, offset
);
416 freq_item
= proto_tree_add_item(desc_tree
, hf_ccid_bNumClockSupported
, tvb
,
417 offset
, 1, ENC_LITTLE_ENDIAN
);
418 if (num_clock_supp
==0)
419 proto_item_append_text(freq_item
, " (only default and maximum)");
422 proto_tree_add_item(desc_tree
, hf_ccid_dwDataRate
,
423 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
425 proto_tree_add_item(desc_tree
, hf_ccid_dwMaxDataRate
,
426 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
428 proto_tree_add_item(desc_tree
, hf_ccid_bNumDataRatesSupported
,
429 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
432 proto_tree_add_item(desc_tree
, hf_ccid_dwMaxIFSD
,
433 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
436 proto_tree_add_item(desc_tree
, hf_ccid_dwSynchProtocols
,
437 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
440 proto_tree_add_item(desc_tree
, hf_ccid_dwMechanical
,
441 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
444 proto_tree_add_bitmask(desc_tree
, tvb
, offset
,
445 hf_ccid_dwFeatures
, ett_ccid_features
, bFeatures_fields
,
449 proto_tree_add_item(desc_tree
, hf_ccid_dwMaxCCIDMessageLength
,
450 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
453 proto_tree_add_item(desc_tree
, hf_ccid_bClassGetResponse
,
454 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
456 proto_tree_add_item(desc_tree
, hf_ccid_bClassEnvelope
,
457 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
460 lcd_layout_item
= proto_tree_add_item(desc_tree
, hf_ccid_wLcdLayout
,
461 tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
462 lcd_layout_tree
= proto_item_add_subtree(
463 lcd_layout_item
, ett_ccid_lcd_layout
);
464 proto_tree_add_item(lcd_layout_tree
, hf_ccid_wLcdLayout_lines
,
465 tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
466 proto_tree_add_item(lcd_layout_tree
, hf_ccid_wLcdLayout_chars
,
467 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
470 proto_tree_add_bitmask(desc_tree
, tvb
, offset
,
471 hf_ccid_bPINSupport
, ett_ccid_pin_support
, bPINSupport_fields
,
475 proto_tree_add_item(desc_tree
, hf_ccid_bMaxCCIDBusySlots
,
476 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
484 dissect_ccid(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
487 proto_tree
*ccid_tree
;
489 uint32_t payload_len
;
493 uint8_t bProtocolNum
;
494 proto_tree
*protocol_tree
;
496 /* Reject the packet if data is NULL */
499 urb
= (urb_info_t
*)data
;
501 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "USBCCID");
502 col_set_str(pinfo
->cinfo
, COL_INFO
, "CCID Packet");
504 /* Start with a top-level item to add everything else to */
505 item
= proto_tree_add_item(tree
, proto_ccid
, tvb
, 0, 10, ENC_NA
);
506 ccid_tree
= proto_item_add_subtree(item
, ett_ccid
);
508 proto_tree_add_item(ccid_tree
, hf_ccid_bMessageType
, tvb
, 0, 1, ENC_LITTLE_ENDIAN
);
509 cmd
= tvb_get_uint8(tvb
, 0);
511 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s", val_to_str_const(cmd
, ccid_messagetypes_vals
, "Unknown"));
515 case PC_RDR_SET_PARAMS
:
516 proto_tree_add_item(ccid_tree
, hf_ccid_dwLength
, tvb
, 1, 4, ENC_LITTLE_ENDIAN
);
517 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
);
518 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 6, 1, ENC_LITTLE_ENDIAN
);
519 proto_tree_add_item(ccid_tree
, hf_ccid_bProtocolNum
, tvb
, 7, 1, ENC_LITTLE_ENDIAN
);
521 /* Placeholder for abRFU */
522 proto_tree_add_item(ccid_tree
, hf_ccid_Reserved
, tvb
, 8, 2, ENC_LITTLE_ENDIAN
);
524 payload_len
= tvb_get_letohl(tvb
, 1);
526 /* abProtocolDataStructure */
527 bProtocolNum
= tvb_get_uint8(tvb
, 7);
528 switch (bProtocolNum
)
531 protocol_tree
= proto_tree_add_subtree(tree
, tvb
, 10, payload_len
, ett_ccid_protocol_data_structure
, NULL
, "Protocol Data Structure for Protocol T=0");
532 proto_tree_add_item(protocol_tree
, hf_ccid_bmFindexDindex
, tvb
, 10, 1, ENC_LITTLE_ENDIAN
);
533 proto_tree_add_item(protocol_tree
, hf_ccid_bmTCCKST0
, tvb
, 11, 1, ENC_LITTLE_ENDIAN
);
534 proto_tree_add_item(protocol_tree
, hf_ccid_bGuardTimeT0
, tvb
, 12, 1, ENC_LITTLE_ENDIAN
);
535 proto_tree_add_item(protocol_tree
, hf_ccid_bWaitingIntegerT0
, tvb
, 13, 1, ENC_LITTLE_ENDIAN
);
536 proto_tree_add_item(protocol_tree
, hf_ccid_bClockStop
, tvb
, 14, 1, ENC_LITTLE_ENDIAN
);
540 protocol_tree
= proto_tree_add_subtree(tree
, tvb
, 10, payload_len
, ett_ccid_protocol_data_structure
, NULL
, "Protocol Data Structure for Protocol T=1");
541 proto_tree_add_item(protocol_tree
, hf_ccid_bmFindexDindex
, tvb
, 10, 1, ENC_LITTLE_ENDIAN
);
542 proto_tree_add_item(protocol_tree
, hf_ccid_bmTCCKST1
, tvb
, 11, 1, ENC_LITTLE_ENDIAN
);
543 proto_tree_add_item(protocol_tree
, hf_ccid_bGuardTimeT1
, tvb
, 12, 1, ENC_LITTLE_ENDIAN
);
544 proto_tree_add_item(protocol_tree
, hf_ccid_bmWaitingIntegersT1
, tvb
, 13, 1, ENC_LITTLE_ENDIAN
);
545 proto_tree_add_item(protocol_tree
, hf_ccid_bClockStop
, tvb
, 14, 1, ENC_LITTLE_ENDIAN
);
546 proto_tree_add_item(protocol_tree
, hf_ccid_bIFSC
, tvb
, 15, 1, ENC_LITTLE_ENDIAN
);
547 proto_tree_add_item(protocol_tree
, hf_ccid_bNadValue
, tvb
, 16, 1, ENC_LITTLE_ENDIAN
);
551 next_tvb
= tvb_new_subset_remaining(tvb
, 10);
552 call_data_dissector(next_tvb
, pinfo
, tree
);
557 proto_tree_add_item(ccid_tree
, hf_ccid_dwLength
, tvb
, 1, 4, ENC_LITTLE_ENDIAN
);
558 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
);
559 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 6, 1, ENC_LITTLE_ENDIAN
);
560 proto_tree_add_item(ccid_tree
, hf_ccid_bPowerSelect
, tvb
, 7, 1, ENC_LITTLE_ENDIAN
);
562 /* Placeholder for abRFU */
563 proto_tree_add_item(ccid_tree
, hf_ccid_Reserved
, tvb
, 8, 2, ENC_LITTLE_ENDIAN
);
567 proto_tree_add_item(ccid_tree
, hf_ccid_dwLength
, tvb
, 1, 4, ENC_LITTLE_ENDIAN
);
568 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
);
569 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 6, 1, ENC_LITTLE_ENDIAN
);
571 /* Placeholder for abRFU */
572 proto_tree_add_item(ccid_tree
, hf_ccid_Reserved
, tvb
, 7, 3, ENC_LITTLE_ENDIAN
);
575 case PC_RDR_GET_SLOT_STATUS
:
576 proto_tree_add_item(ccid_tree
, hf_ccid_dwLength
, tvb
, 1, 4, ENC_LITTLE_ENDIAN
);
577 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
);
578 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 6, 1, ENC_LITTLE_ENDIAN
);
580 /* Placeholder for abRFU */
581 proto_tree_add_item(ccid_tree
, hf_ccid_Reserved
, tvb
, 7, 3, ENC_LITTLE_ENDIAN
);
584 case PC_RDR_GET_PARAMS
:
585 proto_tree_add_item(ccid_tree
, hf_ccid_dwLength
, tvb
, 1, 4, ENC_LITTLE_ENDIAN
);
586 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
);
587 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 6, 1, ENC_LITTLE_ENDIAN
);
589 /* Placeholder for abRFU */
590 proto_tree_add_item(ccid_tree
, hf_ccid_Reserved
, tvb
, 7, 3, ENC_LITTLE_ENDIAN
);
593 case PC_RDR_XFR_BLOCK
:
595 proto_tree_add_item_ret_uint(ccid_tree
, hf_ccid_dwLength
,
596 tvb
, 1, 4, ENC_LITTLE_ENDIAN
, &payload_len
);
597 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
);
598 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 6, 1, ENC_LITTLE_ENDIAN
);
600 if (cmd
== PC_RDR_ESCAPE
) {
601 proto_tree_add_item(ccid_tree
, hf_ccid_abRFU
, tvb
, 7, 3, ENC_NA
);
603 proto_tree_add_item(ccid_tree
, hf_ccid_bBWI
, tvb
, 7, 1, ENC_LITTLE_ENDIAN
);
604 proto_tree_add_item(ccid_tree
, hf_ccid_wLevelParameter
, tvb
, 8, 2, ENC_LITTLE_ENDIAN
);
607 if (payload_len
== 0)
610 next_tvb
= tvb_new_subset_length(tvb
, 10, payload_len
);
611 /* sent/received is from the perspective of the card reader */
612 pinfo
->p2p_dir
= P2P_DIR_SENT
;
614 if (!dissector_try_payload_with_data(subdissector_table
, next_tvb
, pinfo
, tree
, true, urb
)) {
615 call_data_dissector(next_tvb
, pinfo
, tree
);
619 case RDR_PC_DATA_BLOCK
:
621 proto_tree_add_item_ret_uint(ccid_tree
, hf_ccid_dwLength
,
622 tvb
, 1, 4, ENC_LITTLE_ENDIAN
, &payload_len
);
623 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
);
624 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 6, 1, ENC_LITTLE_ENDIAN
);
625 proto_tree_add_bitmask(ccid_tree
, tvb
, 7, hf_ccid_bStatus
, ett_ccid_status
, bStatus_fields
, ENC_LITTLE_ENDIAN
);
626 proto_tree_add_item(ccid_tree
, hf_ccid_bError
, tvb
, 8, 1, ENC_LITTLE_ENDIAN
);
627 if (cmd
== RDR_PC_ESCAPE
)
628 proto_tree_add_item(ccid_tree
, hf_ccid_bRFU
, tvb
, 9, 1, ENC_LITTLE_ENDIAN
);
630 proto_tree_add_item(ccid_tree
, hf_ccid_bChainParameter
, tvb
, 9, 1, ENC_LITTLE_ENDIAN
);
632 if (payload_len
== 0)
635 next_tvb
= tvb_new_subset_length(tvb
, 10, payload_len
);
636 pinfo
->p2p_dir
= P2P_DIR_RECV
;
638 if (!dissector_try_payload_with_data(subdissector_table
, next_tvb
, pinfo
, tree
, true, urb
)) {
639 call_data_dissector(next_tvb
, pinfo
, tree
);
643 case RDR_PC_SLOT_STATUS
:
644 proto_tree_add_item(ccid_tree
, hf_ccid_dwLength
, tvb
, 1, 4, ENC_LITTLE_ENDIAN
);
645 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
);
646 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 6, 1, ENC_LITTLE_ENDIAN
);
647 proto_tree_add_bitmask(ccid_tree
, tvb
, 7, hf_ccid_bStatus
, ett_ccid_status
, bStatus_fields
, ENC_LITTLE_ENDIAN
);
648 proto_tree_add_item(ccid_tree
, hf_ccid_bError
, tvb
, 8, 1, ENC_LITTLE_ENDIAN
);
649 proto_tree_add_item(ccid_tree
, hf_ccid_bClockStatus
, tvb
, 9, 1, ENC_LITTLE_ENDIAN
);
653 proto_tree_add_item_ret_uint(ccid_tree
, hf_ccid_dwLength
, tvb
, 1, 4, ENC_LITTLE_ENDIAN
, &payload_len
);
654 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
);
655 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 6, 1, ENC_LITTLE_ENDIAN
);
656 proto_tree_add_bitmask(ccid_tree
, tvb
, 7, hf_ccid_bStatus
, ett_ccid_status
, bStatus_fields
, ENC_LITTLE_ENDIAN
);
657 proto_tree_add_item(ccid_tree
, hf_ccid_bError
, tvb
, 8, 1, ENC_LITTLE_ENDIAN
);
658 proto_tree_add_item(ccid_tree
, hf_ccid_bProtocolNum
, tvb
, 9, 1, ENC_LITTLE_ENDIAN
);
660 /* abProtocolDataStructure */
661 bProtocolNum
= tvb_get_uint8(tvb
, 9);
662 switch (bProtocolNum
)
665 if (payload_len
> 0) {
666 protocol_tree
= proto_tree_add_subtree(tree
, tvb
, 10, payload_len
, ett_ccid_protocol_data_structure
, NULL
, "Protocol Data Structure for Protocol T=0");
667 proto_tree_add_item(protocol_tree
, hf_ccid_bmFindexDindex
, tvb
, 10, 1, ENC_LITTLE_ENDIAN
);
668 proto_tree_add_item(protocol_tree
, hf_ccid_bmTCCKST0
, tvb
, 11, 1, ENC_LITTLE_ENDIAN
);
669 proto_tree_add_item(protocol_tree
, hf_ccid_bGuardTimeT0
, tvb
, 12, 1, ENC_LITTLE_ENDIAN
);
670 proto_tree_add_item(protocol_tree
, hf_ccid_bWaitingIntegerT0
, tvb
, 13, 1, ENC_LITTLE_ENDIAN
);
671 proto_tree_add_item(protocol_tree
, hf_ccid_bClockStop
, tvb
, 14, 1, ENC_LITTLE_ENDIAN
);
676 protocol_tree
= proto_tree_add_subtree(tree
, tvb
, 10, payload_len
, ett_ccid_protocol_data_structure
, NULL
, "Protocol Data Structure for Protocol T=1");
677 proto_tree_add_item(protocol_tree
, hf_ccid_bmFindexDindex
, tvb
, 10, 1, ENC_LITTLE_ENDIAN
);
678 proto_tree_add_item(protocol_tree
, hf_ccid_bmTCCKST1
, tvb
, 11, 1, ENC_LITTLE_ENDIAN
);
679 proto_tree_add_item(protocol_tree
, hf_ccid_bGuardTimeT1
, tvb
, 12, 1, ENC_LITTLE_ENDIAN
);
680 proto_tree_add_item(protocol_tree
, hf_ccid_bmWaitingIntegersT1
, tvb
, 13, 1, ENC_LITTLE_ENDIAN
);
681 proto_tree_add_item(protocol_tree
, hf_ccid_bClockStop
, tvb
, 14, 1, ENC_LITTLE_ENDIAN
);
682 proto_tree_add_item(protocol_tree
, hf_ccid_bIFSC
, tvb
, 15, 1, ENC_LITTLE_ENDIAN
);
683 proto_tree_add_item(protocol_tree
, hf_ccid_bNadValue
, tvb
, 16, 1, ENC_LITTLE_ENDIAN
);
687 next_tvb
= tvb_new_subset_remaining(tvb
, 10);
688 call_data_dissector(next_tvb
, pinfo
, tree
);
693 case RDR_PC_NOTIF_SLOT_CHNG
:
694 proto_tree_add_bitmask(ccid_tree
, tvb
, 1,
695 hf_ccid_bmSlotICCState
, ett_ccid_slot_change
, bmSlotICCStateb0_fields
,
697 len_remaining
= tvb_reported_length_remaining (tvb
, 2);
698 if (len_remaining
<= 0)
700 proto_tree_add_bitmask(ccid_tree
, tvb
, 2,
701 hf_ccid_bmSlotICCState
, ett_ccid_slot_change
, bmSlotICCStateb1_fields
,
706 proto_tree_add_item(ccid_tree
, hf_ccid_bSlot
, tvb
, 1, 1, ENC_LITTLE_ENDIAN
);
707 proto_tree_add_item(ccid_tree
, hf_ccid_bSeq
, tvb
, 2, 1, ENC_LITTLE_ENDIAN
);
708 proto_tree_add_item(ccid_tree
, hf_ccid_bHardwareErrorCode
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
715 /* TODO: Try use "offset" instead of hardcoded constants */
716 return tvb_captured_length(tvb
);
720 proto_register_ccid(void)
722 static hf_register_info hf
[] = {
724 {&hf_ccid_bMessageType
,
725 { "Message Type", "usbccid.bMessageType", FT_UINT8
, BASE_HEX
,
726 VALS(ccid_opcode_vals
), 0x0, NULL
, HFILL
}},
728 { "Packet Length", "usbccid.dwLength", FT_UINT32
, BASE_DEC
,
729 NULL
, 0x0, NULL
, HFILL
}},
731 { "Slot", "usbccid.bSlot", FT_UINT8
, BASE_DEC
,
732 NULL
, 0x0, NULL
, HFILL
}},
734 { "Sequence", "usbccid.bSeq", FT_UINT8
, BASE_DEC
,
735 NULL
, 0x0, NULL
, HFILL
}},
737 { "Status", "usbccid.bStatus", FT_UINT8
, BASE_DEC
,
738 NULL
, 0x0, NULL
, HFILL
}},
739 {&hf_ccid_bStatus_bmIccStatus
,
740 { "Status", "usbccid.bStatus.bmIccStatus", FT_UINT8
, BASE_DEC
,
741 VALS(ccid_status_icc_status_vals
), 0x03, NULL
, HFILL
}},
742 {&hf_ccid_bStatus_bmCommandStatus
,
743 { "Status", "usbccid.bStatus.bmCommandStatus", FT_UINT8
, BASE_DEC
,
744 VALS(ccid_status_cmd_status_vals
), 0xC0, NULL
, HFILL
}},
746 { "Error", "usbccid.bError", FT_UINT8
, BASE_DEC
,
747 NULL
, 0x0, NULL
, HFILL
}},
749 { "RFU", "usbccid.bRFU", FT_UINT8
, BASE_HEX
,
750 NULL
, 0x0, NULL
, HFILL
}},
752 { "RFU", "usbccid.abRFU", FT_BYTES
, BASE_NONE
,
753 NULL
, 0x0, NULL
, HFILL
}},
754 {&hf_ccid_bChainParameter
,
755 { "Chain Parameter", "usbccid.bChainParameter", FT_UINT8
, BASE_DEC
,
756 NULL
, 0x0, NULL
, HFILL
}},
757 {&hf_ccid_bPowerSelect
,
758 { "Voltage Level", "usbccid.bPowerSelect", FT_UINT8
, BASE_HEX
,
759 VALS(ccid_voltage_levels_vals
), 0x0, NULL
, HFILL
}},
760 {&hf_ccid_bClockStatus
,
761 { "Clock Status", "usbccid.bClockStatus", FT_UINT8
, BASE_HEX
,
762 VALS(ccid_clock_states_vals
), 0x0, NULL
, HFILL
}},
763 {&hf_ccid_bProtocolNum
,
764 { "Data Structure Type", "usbccid.bProtocolNum", FT_UINT8
, BASE_HEX
,
765 VALS(ccid_proto_structs_vals
), 0x0, NULL
, HFILL
}},
767 { "Block Wait Time Integer", "usbccid.bBWI", FT_UINT8
, BASE_HEX
,
768 NULL
, 0x0, NULL
, HFILL
}},
769 {&hf_ccid_wLevelParameter
,
770 { "Level Parameter", "usbccid.wLevelParameter", FT_UINT16
, BASE_HEX
,
771 NULL
, 0x0, NULL
, HFILL
}},
773 { "bcdCCID", "usbccid.bcdCCID", FT_UINT16
, BASE_HEX
,
774 NULL
, 0x0, NULL
, HFILL
}},
775 {&hf_ccid_bMaxSlotIndex
,
776 { "max slot index", "usbccid.bMaxSlotIndex", FT_UINT8
, BASE_HEX
,
777 NULL
, 0x0, NULL
, HFILL
}},
778 {&hf_ccid_bVoltageSupport
,
779 { "voltage support", "usbccid.bVoltageSupport", FT_UINT8
, BASE_HEX
,
780 NULL
, 0x0, NULL
, HFILL
}},
781 {&hf_ccid_bVoltageSupport18
,
782 { "1.8V", "usbccid.bVoltageSupport.18", FT_BOOLEAN
, 8,
783 TFS(&tfs_supported_not_supported
), 0x04, NULL
, HFILL
}},
784 {&hf_ccid_bVoltageSupport30
,
785 { "3.0V", "usbccid.bVoltageSupport.30", FT_BOOLEAN
, 8,
786 TFS(&tfs_supported_not_supported
), 0x02, NULL
, HFILL
}},
787 {&hf_ccid_bVoltageSupport50
,
788 { "5.0V", "usbccid.bVoltageSupport.50", FT_BOOLEAN
, 8,
789 TFS(&tfs_supported_not_supported
), 0x01, NULL
, HFILL
}},
790 {&hf_ccid_dwProtocols
,
791 { "dwProtocols", "usbccid.dwProtocols", FT_UINT32
, BASE_HEX
,
792 NULL
, 0x0, NULL
, HFILL
}},
793 {&hf_ccid_dwProtocols_t0
,
794 { "T=0", "usbccid.dwProtocols.t0", FT_BOOLEAN
, 32,
795 TFS(&tfs_supported_not_supported
), 0x00000001, NULL
, HFILL
}},
796 {&hf_ccid_dwProtocols_t1
,
797 { "T=1", "usbccid.dwProtocols.t1", FT_BOOLEAN
, 32,
798 TFS(&tfs_supported_not_supported
), 0x00000002, NULL
, HFILL
}},
799 {&hf_ccid_dwDefaultClock
,
800 { "default clock frequency", "usbccid.dwDefaultClock",
801 FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_khz
), 0x0, NULL
, HFILL
}},
802 {&hf_ccid_dwMaximumClock
,
803 { "maximum clock frequency", "usbccid.dwMaximumClock",
804 FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_khz
), 0x0, NULL
, HFILL
}},
805 {&hf_ccid_bNumClockSupported
,
806 { "number of supported clock frequencies", "usbccid.bNumClockSupported",
807 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
808 {&hf_ccid_dwDataRate
,
809 { "default ICC I/O data rate in bps", "usbccid.dwDataRate",
810 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
811 {&hf_ccid_dwMaxDataRate
,
812 { "maximum ICC I/O data rate in bps", "usbccid.dwMaxDataRate",
813 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
814 {&hf_ccid_bNumDataRatesSupported
,
815 { "number of supported data rates", "usbccid.bNumDataRatesSupported",
816 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
817 { &hf_ccid_dwMaxIFSD
,
818 { "maximum IFSD supported", "usbccid.dwMaxIFSD",
819 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
820 {&hf_ccid_dwSynchProtocols
,
821 { "supported protocol types", "usbccid.dwSynchProtocols",
822 FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
823 {&hf_ccid_dwMechanical
,
824 { "mechanical characteristics", "usbccid.dwMechanical",
825 FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
826 {&hf_ccid_dwFeatures
,
827 { "intelligent features", "usbccid.dwFeatures",
828 FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
829 {&hf_ccid_dwFeatures_autoIccActivation
,
830 { "Automatic activation of ICC on inserting",
831 "usbccid.dwFeatures.autoIccActivation", FT_BOOLEAN
, 32,
832 TFS(&tfs_supported_not_supported
), 0x00000004, NULL
, HFILL
}},
833 {&hf_ccid_dwFeatures_autoIccVoltSelect
,
834 { "Automatic ICC voltage selection",
835 "usbccid.dwFeatures.autoIccVoltSelect", FT_BOOLEAN
, 32,
836 TFS(&tfs_supported_not_supported
), 0x00000008, NULL
, HFILL
}},
837 {&hf_ccid_dwFeatures_autoParam
,
838 { "Automatic parameter configuration based on ATR",
839 "usbccid.dwFeatures.autoParam", FT_BOOLEAN
, 32,
840 TFS(&tfs_supported_not_supported
), 0x00000002, NULL
, HFILL
}},
841 {&hf_ccid_dwFeatures_autoIccClk
,
842 { "Automatic ICC clock frequency change",
843 "usbccid.dwFeatures.autoIccClk", FT_BOOLEAN
, 32,
844 TFS(&tfs_supported_not_supported
), 0x00000010, NULL
, HFILL
}},
845 {&hf_ccid_dwFeatures_autoBaudRate
,
846 { "Automatic baud rate change",
847 "usbccid.dwFeatures.autoBaudRate", FT_BOOLEAN
, 32,
848 TFS(&tfs_supported_not_supported
), 0x00000020, NULL
, HFILL
}},
849 {&hf_ccid_dwFeatures_autoParamNegotiation
,
850 { "Automatic parameters negotiation",
851 "usbccid.dwFeatures.autoParamNegotiation", FT_BOOLEAN
, 32,
852 TFS(&tfs_supported_not_supported
), 0x00000040, NULL
, HFILL
}},
853 {&hf_ccid_dwFeatures_autoPPS
,
855 "usbccid.dwFeatures.autoPPS", FT_BOOLEAN
, 32,
856 TFS(&tfs_supported_not_supported
), 0x00000080, NULL
, HFILL
}},
857 {&hf_ccid_dwFeatures_stopIccClk
,
858 { "CCID can set ICC in clock stop mode",
859 "usbccid.dwFeatures.stopIccClk", FT_BOOLEAN
, 32,
860 TFS(&tfs_supported_not_supported
), 0x00000100, NULL
, HFILL
}},
861 {&hf_ccid_dwFeatures_nadValNot0accept
,
862 { "NAD value other than 00 accepted",
863 "usbccid.dwFeatures.nadValNot0accept", FT_BOOLEAN
, 32,
864 TFS(&tfs_supported_not_supported
), 0x00000200, NULL
, HFILL
}},
865 {&hf_ccid_dwFeatures_autoIfsd
,
866 { "Automatic IFSD exchange as first exchange",
867 "usbccid.dwFeatures.autoIfsd", FT_BOOLEAN
, 32,
868 TFS(&tfs_supported_not_supported
), 0x00000400, NULL
, HFILL
}},
869 {&hf_ccid_dwFeatures_levelExchangeTDPU
,
870 { "TPDU level exchanges",
871 "usbccid.dwFeatures.levelExchangeTDPU", FT_BOOLEAN
, 32,
872 TFS(&tfs_supported_not_supported
), 0x00010000, NULL
, HFILL
}},
873 {&hf_ccid_dwFeatures_levelExchangeShortAPDU
,
874 { "Short APDU level exchange",
875 "usbccid.dwFeatures.levelExchangeShortAPDU", FT_BOOLEAN
, 32,
876 TFS(&tfs_supported_not_supported
), 0x00020000, NULL
, HFILL
}},
877 {&hf_ccid_dwFeatures_levelExchangeShortExtendedAPDU
,
878 { "Short and Extended APDU level exchange",
879 "usbccid.dwFeatures.levelExchangeShortExtendedAPDU", FT_BOOLEAN
, 32,
880 TFS(&tfs_supported_not_supported
), 0x00040000, NULL
, HFILL
}},
881 {&hf_ccid_dwFeatures_UsbWakeUp
,
882 { "USB Wake up signaling supported on card insertion and removal",
883 "usbccid.dwFeatures.UsbWakeUp", FT_BOOLEAN
, 32,
884 TFS(&tfs_supported_not_supported
), 0x00100000, NULL
, HFILL
}},
885 {&hf_ccid_dwMaxCCIDMessageLength
,
886 { "maximum CCID message length", "usbccid.dwMaxCCIDMessageLength",
887 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
888 {&hf_ccid_bClassGetResponse
,
889 { "default class for Get Response", "usbccid.hf_ccid_bClassGetResponse",
890 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
891 {&hf_ccid_bClassEnvelope
,
892 { "default class for Envelope", "usbccid.hf_ccid_bClassEnvelope",
893 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
894 {&hf_ccid_wLcdLayout
,
895 { "LCD layout", "usbccid.hf_ccid_wLcdLayout",
896 FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
897 {&hf_ccid_wLcdLayout_lines
,
898 { "Lines", "usbccid.hf_ccid_wLcdLayout.lines",
899 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
900 {&hf_ccid_wLcdLayout_chars
,
901 { "Characters per line", "usbccid.hf_ccid_wLcdLayout.chars",
902 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
903 {&hf_ccid_bPINSupport
,
904 { "PIN support", "usbccid.hf_ccid_bPINSupport",
905 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
906 {&hf_ccid_bPINSupport_modify
,
907 { "PIN modification", "usbccid.hf_ccid_bPINSupport.modify",
908 FT_BOOLEAN
, 8, TFS(&tfs_supported_not_supported
), 0x02, NULL
, HFILL
}},
909 {&hf_ccid_bPINSupport_vrfy
,
910 { "PIN verification", "usbccid.hf_ccid_bPINSupport.verify",
911 FT_BOOLEAN
, 8, TFS(&tfs_supported_not_supported
), 0x01, NULL
, HFILL
}},
912 {&hf_ccid_bMaxCCIDBusySlots
,
913 { "maximum number of busy slots", "usbccid.hf_ccid_bMaxCCIDBusySlots",
914 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
916 { "Reserved for Future Use", "usbccid.hf_ccid_Reserved",
917 FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
918 { &hf_ccid_bmSlotICCState
,
919 { "Slot ICC State", "usbccid.hf_ccid_bmSlotICCState",
920 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
921 { &hf_ccid_bmSlotICCState_slot0Current
,
922 { "Slot 0 Current Status", "usbccid.hf_ccid_bmSlotICCState.slot0Current",
923 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x01, NULL
, HFILL
} },
924 { &hf_ccid_bmSlotICCState_slot0Changed
,
925 { "Slot 0 Status changed", "usbccid.hf_ccid_bmSlotICCState.slot0Changed",
926 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02, NULL
, HFILL
} },
927 { &hf_ccid_bmSlotICCState_slot1Current
,
928 { "Slot 1 Current Status", "usbccid.hf_ccid_bmSlotICCState.slot1Current",
929 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x04, NULL
, HFILL
} },
930 { &hf_ccid_bmSlotICCState_slot1Changed
,
931 { "Slot 1 Status changed", "usbccid.hf_ccid_bmSlotICCState.slot1Changed",
932 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08, NULL
, HFILL
} },
933 { &hf_ccid_bmSlotICCState_slot2Current
,
934 { "Slot 2 Current Status", "usbccid.hf_ccid_bmSlotICCState.slot2Current",
935 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x10, NULL
, HFILL
} },
936 { &hf_ccid_bmSlotICCState_slot2Changed
,
937 { "Slot 2 Status changed", "usbccid.hf_ccid_bmSlotICCState.slot2Changed",
938 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20, NULL
, HFILL
} },
939 { &hf_ccid_bmSlotICCState_slot3Current
,
940 { "Slot 3 Current Status", "usbccid.hf_ccid_bmSlotICCState.slot3Current",
941 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x40, NULL
, HFILL
} },
942 { &hf_ccid_bmSlotICCState_slot3Changed
,
943 { "Slot 3 Status changed", "usbccid.hf_ccid_bmSlotICCState.slot3Changed",
944 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80, NULL
, HFILL
} },
945 { &hf_ccid_bmSlotICCState_slot4Current
,
946 { "Slot 4 Current Status", "usbccid.hf_ccid_bmSlotICCState.slot4Current",
947 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x01, NULL
, HFILL
} },
948 { &hf_ccid_bmSlotICCState_slot4Changed
,
949 { "Slot 4 Status changed", "usbccid.hf_ccid_bmSlotICCState.slot4Changed",
950 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02, NULL
, HFILL
} },
951 { &hf_ccid_bmSlotICCState_slot5Current
,
952 { "Slot 5 Current Status", "usbccid.hf_ccid_bmSlotICCState.slot5Current",
953 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x04, NULL
, HFILL
} },
954 { &hf_ccid_bmSlotICCState_slot5Changed
,
955 { "Slot 5 Status changed", "usbccid.hf_ccid_bmSlotICCState.slot5Changed",
956 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08, NULL
, HFILL
} },
957 { &hf_ccid_bmSlotICCState_slot6Current
,
958 { "Slot 6 Current Status", "usbccid.hf_ccid_bmSlotICCState.slot6Current",
959 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x10, NULL
, HFILL
} },
960 { &hf_ccid_bmSlotICCState_slot6Changed
,
961 { "Slot 6 Status changed", "usbccid.hf_ccid_bmSlotICCState.slot6Changed",
962 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20, NULL
, HFILL
} },
963 { &hf_ccid_bmSlotICCState_slot7Current
,
964 { "Slot 7 Current Status", "usbccid.hf_ccid_bmSlotICCState.slot7Current",
965 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x40, NULL
, HFILL
} },
966 { &hf_ccid_bmSlotICCState_slot7Changed
,
967 { "Slot 7 Status changed", "usbccid.hf_ccid_bmSlotICCState.slot7Changed",
968 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80, NULL
, HFILL
} },
969 { &hf_ccid_bHardwareErrorCode
,
970 { "Hardware Error Code", "usbccid.hf_ccid_bHardwareErrorCode",
971 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
972 {&hf_ccid_bmFindexDindex
,
973 { "Fi/Di selecting clock rate", "usbccid.bmFindexDindex", FT_UINT8
, BASE_HEX
,
974 NULL
, 0x0, NULL
, HFILL
}},
976 { "Convention used", "usbccid.bmTCCKST0", FT_UINT8
, BASE_HEX
,
977 NULL
, 0x0, NULL
, HFILL
}},
979 { "Checksum type - Convention used", "usbccid.bmTCCKST1", FT_UINT8
, BASE_HEX
,
980 NULL
, 0x0, NULL
, HFILL
}},
981 {&hf_ccid_bGuardTimeT0
,
982 { "Extra Guardtime between two characters", "usbccid.bGuardTimeT0", FT_UINT8
, BASE_HEX
,
983 NULL
, 0x0, NULL
, HFILL
}},
984 {&hf_ccid_bGuardTimeT1
,
985 { "Extra Guardtime", "usbccid.bGuardTimeT1", FT_UINT8
, BASE_HEX
,
986 NULL
, 0x0, NULL
, HFILL
}},
987 {&hf_ccid_bmWaitingIntegersT1
,
988 { "BWI - CWI", "usbccid.bmWaitingIntegersT1", FT_UINT8
, BASE_HEX
,
989 NULL
, 0x0, NULL
, HFILL
}},
990 {&hf_ccid_bClockStop
,
991 { "ICC Clock Stop Support", "usbccid.bClockStop", FT_UINT8
, BASE_HEX
,
992 NULL
, 0x0, NULL
, HFILL
}},
994 { "Size of negotiated IFSC", "usbccid.bIFSC", FT_UINT8
, BASE_HEX
,
995 NULL
, 0x0, NULL
, HFILL
}},
997 { "NAD", "usbccid.bNadValue", FT_UINT8
, BASE_HEX
,
998 NULL
, 0x0, NULL
, HFILL
}},
999 {&hf_ccid_bWaitingIntegerT0
,
1000 { "WI for T= 0 used to define WWT", "usbccid.bWaitingIntegerT0", FT_UINT8
, BASE_HEX
,
1001 NULL
, 0x0, NULL
, HFILL
}},
1004 static int *ett
[] = {
1007 &ett_ccid_protocol_data_structure
,
1008 &ett_ccid_voltage_level
,
1009 &ett_ccid_protocols
,
1011 &ett_ccid_lcd_layout
,
1012 &ett_ccid_pin_support
,
1013 &ett_ccid_slot_change
,
1019 proto_ccid
= proto_register_protocol("USB CCID", "USBCCID", "usbccid");
1020 proto_register_field_array(proto_ccid
, hf
, array_length(hf
));
1021 proto_register_subtree_array(ett
, array_length(ett
));
1023 pref_mod
= prefs_register_protocol_obsolete(proto_ccid
);
1024 prefs_register_obsolete_preference(pref_mod
, "prtype");
1026 usb_ccid_handle
= register_dissector("usbccid", dissect_ccid
, proto_ccid
);
1027 usb_ccid_descr_handle
= register_dissector("usbccid.descriptor", dissect_usb_ccid_descriptor
, proto_ccid
);
1029 subdissector_table
= register_decode_as_next_proto(proto_ccid
, "usbccid.subdissector", "USB CCID payload", NULL
);
1032 /* Handler registration */
1034 proto_reg_handoff_ccid(void)
1036 dissector_add_uint("usb.descriptor", IF_CLASS_SMART_CARD
, usb_ccid_descr_handle
);
1038 dissector_add_uint("usb.bulk", IF_CLASS_SMART_CARD
, usb_ccid_handle
);
1040 dissector_add_for_decode_as("usb.device", usb_ccid_handle
);
1041 dissector_add_for_decode_as("usb.product", usb_ccid_handle
);
1042 dissector_add_for_decode_as("usb.protocol", usb_ccid_handle
);
1046 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1051 * indent-tabs-mode: nil
1054 * ex: set shiftwidth=4 tabstop=8 expandtab:
1055 * :indentSize=4:tabSize=8:noTabs=true: