Christina Quast | 968b974 | 2015-02-25 14:10:12 +0100 | [diff] [blame] | 1 | /* ---------------------------------------------------------------------------- |
| 2 | * ATMEL Microcontroller Software Support |
| 3 | * ---------------------------------------------------------------------------- |
| 4 | * Copyright (c) 2009, Atmel Corporation |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 5 | * Copyright (c) 2018-2019, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de> |
Christina Quast | 968b974 | 2015-02-25 14:10:12 +0100 | [diff] [blame] | 6 | * |
| 7 | * All rights reserved. |
| 8 | * |
| 9 | * Redistribution and use in source and binary forms, with or without |
| 10 | * modification, are permitted provided that the following conditions are met: |
| 11 | * |
| 12 | * - Redistributions of source code must retain the above copyright notice, |
| 13 | * this list of conditions and the disclaimer below. |
| 14 | * |
| 15 | * Atmel's name may not be used to endorse or promote products derived from |
| 16 | * this software without specific prior written permission. |
| 17 | * |
| 18 | * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR |
| 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE |
| 21 | * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 23 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, |
| 24 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 25 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| 27 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | * ---------------------------------------------------------------------------- |
| 29 | */ |
| 30 | |
| 31 | /*---------------------------------------------------------------------------- |
| 32 | * Headers |
| 33 | *----------------------------------------------------------------------------*/ |
| 34 | |
| 35 | #include "board.h" |
Harald Welte | 1605564 | 2016-03-03 11:02:45 +0100 | [diff] [blame] | 36 | #include "simtrace.h" |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 37 | #include "simtrace_usb.h" |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 38 | #include "utils.h" |
Kévin Redon | ff3d849 | 2018-08-06 17:57:20 +0200 | [diff] [blame] | 39 | #include "USBD_HAL.h" |
Christina Quast | 968b974 | 2015-02-25 14:10:12 +0100 | [diff] [blame] | 40 | |
Christina Quast | db7b1ab | 2015-03-03 12:34:36 +0100 | [diff] [blame] | 41 | #include <cciddriverdescriptors.h> |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 42 | #include <usb/common/dfu/usb_dfu.h> |
| 43 | #include <usb/device/dfu/dfu.h> |
Christina Quast | db7b1ab | 2015-03-03 12:34:36 +0100 | [diff] [blame] | 44 | |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 45 | /*------------------------------------------------------------------------------ |
| 46 | * USB String descriptors |
| 47 | *------------------------------------------------------------------------------*/ |
Harald Welte | 2363fa0 | 2017-03-05 10:16:25 +0100 | [diff] [blame] | 48 | #include "usb_strings_generated.h" |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 49 | |
| 50 | // the index of the strings (must match the order in usb_strings.txt) |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 51 | enum strDescNum { |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 52 | // static strings from usb_strings |
Harald Welte | 3b64695 | 2017-05-14 23:13:52 +0200 | [diff] [blame] | 53 | MANUF_STR = 1, |
| 54 | PRODUCT_STRING, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 55 | SNIFFER_CONF_STR, |
| 56 | CCID_CONF_STR, |
| 57 | PHONE_CONF_STR, |
| 58 | MITM_CONF_STR, |
| 59 | CARDEM_USIM1_INTF_STR, |
| 60 | CARDEM_USIM2_INTF_STR, |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 61 | CARDEM_USIM3_INTF_STR, |
| 62 | CARDEM_USIM4_INTF_STR, |
| 63 | // runtime strings |
| 64 | SERIAL_STR, |
Kévin Redon | ede87e0 | 2019-08-13 17:03:11 +0200 | [diff] [blame] | 65 | VERSION_CONF_STR, |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 66 | VERSION_STR, |
| 67 | // count |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 68 | STRING_DESC_CNT |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 69 | }; |
| 70 | |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 71 | /** array of static (from usb_strings) and runtime (serial, version) USB strings |
| 72 | */ |
Kévin Redon | ede87e0 | 2019-08-13 17:03:11 +0200 | [diff] [blame] | 73 | static const unsigned char *usb_strings_extended[ARRAY_SIZE(usb_strings) + 3]; |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 74 | |
| 75 | /* USB string for the serial (using 128-bit device ID) */ |
| 76 | static unsigned char usb_string_serial[] = { |
| 77 | USBStringDescriptor_LENGTH(32), |
| 78 | USBGenericDescriptor_STRING, |
| 79 | USBStringDescriptor_UNICODE('0'), |
| 80 | USBStringDescriptor_UNICODE('0'), |
| 81 | USBStringDescriptor_UNICODE('1'), |
| 82 | USBStringDescriptor_UNICODE('1'), |
| 83 | USBStringDescriptor_UNICODE('2'), |
| 84 | USBStringDescriptor_UNICODE('2'), |
| 85 | USBStringDescriptor_UNICODE('3'), |
| 86 | USBStringDescriptor_UNICODE('3'), |
| 87 | USBStringDescriptor_UNICODE('4'), |
| 88 | USBStringDescriptor_UNICODE('4'), |
| 89 | USBStringDescriptor_UNICODE('5'), |
| 90 | USBStringDescriptor_UNICODE('5'), |
| 91 | USBStringDescriptor_UNICODE('6'), |
| 92 | USBStringDescriptor_UNICODE('6'), |
| 93 | USBStringDescriptor_UNICODE('7'), |
| 94 | USBStringDescriptor_UNICODE('7'), |
| 95 | USBStringDescriptor_UNICODE('8'), |
| 96 | USBStringDescriptor_UNICODE('8'), |
| 97 | USBStringDescriptor_UNICODE('9'), |
| 98 | USBStringDescriptor_UNICODE('9'), |
| 99 | USBStringDescriptor_UNICODE('a'), |
| 100 | USBStringDescriptor_UNICODE('a'), |
| 101 | USBStringDescriptor_UNICODE('b'), |
| 102 | USBStringDescriptor_UNICODE('b'), |
| 103 | USBStringDescriptor_UNICODE('c'), |
| 104 | USBStringDescriptor_UNICODE('c'), |
| 105 | USBStringDescriptor_UNICODE('d'), |
| 106 | USBStringDescriptor_UNICODE('d'), |
| 107 | USBStringDescriptor_UNICODE('e'), |
| 108 | USBStringDescriptor_UNICODE('e'), |
| 109 | USBStringDescriptor_UNICODE('f'), |
| 110 | USBStringDescriptor_UNICODE('f'), |
| 111 | }; |
| 112 | |
| 113 | /* USB string for the version */ |
Kévin Redon | ede87e0 | 2019-08-13 17:03:11 +0200 | [diff] [blame] | 114 | static const unsigned char usb_string_version_conf[] = { |
| 115 | USBStringDescriptor_LENGTH(16), |
| 116 | USBGenericDescriptor_STRING, |
| 117 | USBStringDescriptor_UNICODE('f'), |
| 118 | USBStringDescriptor_UNICODE('i'), |
| 119 | USBStringDescriptor_UNICODE('r'), |
| 120 | USBStringDescriptor_UNICODE('m'), |
| 121 | USBStringDescriptor_UNICODE('w'), |
| 122 | USBStringDescriptor_UNICODE('a'), |
| 123 | USBStringDescriptor_UNICODE('r'), |
| 124 | USBStringDescriptor_UNICODE('e'), |
| 125 | USBStringDescriptor_UNICODE(' '), |
| 126 | USBStringDescriptor_UNICODE('v'), |
| 127 | USBStringDescriptor_UNICODE('e'), |
| 128 | USBStringDescriptor_UNICODE('r'), |
| 129 | USBStringDescriptor_UNICODE('s'), |
| 130 | USBStringDescriptor_UNICODE('i'), |
| 131 | USBStringDescriptor_UNICODE('o'), |
| 132 | USBStringDescriptor_UNICODE('n'), |
| 133 | }; |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 134 | static const char git_version[] = GIT_VERSION; |
| 135 | static unsigned char usb_string_version[2 + ARRAY_SIZE(git_version) * 2 - 2]; |
| 136 | |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 137 | /*------------------------------------------------------------------------------ |
| 138 | * USB Device descriptors |
| 139 | *------------------------------------------------------------------------------*/ |
| 140 | |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 141 | #ifdef HAVE_SNIFFER |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 142 | typedef struct _SIMTraceDriverConfigurationDescriptorSniffer { |
| 143 | |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 144 | /** Standard configuration descriptor. */ |
| 145 | USBConfigurationDescriptor configuration; |
| 146 | USBInterfaceDescriptor sniffer; |
| 147 | USBEndpointDescriptor sniffer_dataOut; |
| 148 | USBEndpointDescriptor sniffer_dataIn; |
| 149 | USBEndpointDescriptor sniffer_interruptIn; |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 150 | DFURT_IF_DESCRIPTOR_STRUCT; |
Christina Quast | 01bbdc3 | 2015-02-24 17:38:45 +0100 | [diff] [blame] | 151 | } __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorSniffer; |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 152 | |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 153 | static const SIMTraceDriverConfigurationDescriptorSniffer |
| 154 | configurationDescriptorSniffer = { |
| 155 | /* Standard configuration descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 156 | .configuration = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 157 | .bLength = sizeof(USBConfigurationDescriptor), |
| 158 | .bDescriptorType = USBGenericDescriptor_CONFIGURATION, |
| 159 | .wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorSniffer), |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 160 | .bNumInterfaces = 1+DFURT_NUM_IF, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 161 | .bConfigurationValue = CFG_NUM_SNIFF, |
| 162 | .iConfiguration = SNIFFER_CONF_STR, |
| 163 | .bmAttributes = USBD_BMATTRIBUTES, |
| 164 | .bMaxPower = USBConfigurationDescriptor_POWER(100), |
| 165 | }, |
| 166 | /* Communication class interface standard descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 167 | .sniffer = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 168 | .bLength = sizeof(USBInterfaceDescriptor), |
| 169 | .bDescriptorType = USBGenericDescriptor_INTERFACE, |
| 170 | .bInterfaceNumber = 0, |
| 171 | .bAlternateSetting = 0, |
| 172 | .bNumEndpoints = 3, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 173 | .bInterfaceClass = USB_CLASS_PROPRIETARY, |
| 174 | .bInterfaceSubClass = SIMTRACE_SNIFFER_USB_SUBCLASS, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 175 | .bInterfaceProtocol = 0, |
| 176 | .iInterface = SNIFFER_CONF_STR, |
| 177 | }, |
| 178 | /* Bulk-OUT endpoint standard descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 179 | .sniffer_dataOut = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 180 | .bLength = sizeof(USBEndpointDescriptor), |
| 181 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 182 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 183 | USBEndpointDescriptor_OUT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 184 | SIMTRACE_USB_EP_CARD_DATAOUT), |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 185 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 186 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 187 | .bInterval = 0, |
| 188 | }, |
| 189 | /* Bulk-IN endpoint descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 190 | .sniffer_dataIn = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 191 | .bLength = sizeof(USBEndpointDescriptor), |
| 192 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 193 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 194 | USBEndpointDescriptor_IN, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 195 | SIMTRACE_USB_EP_CARD_DATAIN), |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 196 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 197 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 198 | .bInterval = 0, |
| 199 | }, |
| 200 | // Notification endpoint descriptor |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 201 | .sniffer_interruptIn = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 202 | .bLength = sizeof(USBEndpointDescriptor), |
| 203 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 204 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 205 | USBEndpointDescriptor_IN, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 206 | SIMTRACE_USB_EP_CARD_INT), |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 207 | .bmAttributes = USBEndpointDescriptor_INTERRUPT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 208 | .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 209 | .bInterval = 0x10, |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 210 | }, |
| 211 | DFURT_IF_DESCRIPTOR(1, 0), |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 212 | }; |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 213 | #endif /* HAVE_SNIFFER */ |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 214 | |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 215 | #ifdef HAVE_CCID |
Harald Welte | ec4fe23 | 2015-11-07 18:41:25 +0100 | [diff] [blame] | 216 | static const CCIDDriverConfigurationDescriptors configurationDescriptorCCID = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 217 | // Standard USB configuration descriptor |
| 218 | { |
| 219 | .bLength = sizeof(USBConfigurationDescriptor), |
| 220 | .bDescriptorType = USBGenericDescriptor_CONFIGURATION, |
| 221 | .wTotalLength = sizeof(CCIDDriverConfigurationDescriptors), |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 222 | .bNumInterfaces = 1+DFURT_NUM_IF, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 223 | .bConfigurationValue = CFG_NUM_CCID, |
| 224 | .iConfiguration = CCID_CONF_STR, |
| 225 | .bmAttributes = BOARD_USB_BMATTRIBUTES, |
| 226 | .bMaxPower = USBConfigurationDescriptor_POWER(100), |
| 227 | }, |
| 228 | // CCID interface descriptor |
| 229 | // Table 4.3-1 Interface Descriptor |
| 230 | // Interface descriptor |
| 231 | { |
| 232 | .bLength = sizeof(USBInterfaceDescriptor), |
| 233 | .bDescriptorType = USBGenericDescriptor_INTERFACE, |
| 234 | .bInterfaceNumber = 0, |
| 235 | .bAlternateSetting = 0, |
| 236 | .bNumEndpoints = 3, |
| 237 | .bInterfaceClass = SMART_CARD_DEVICE_CLASS, |
| 238 | .bInterfaceSubClass = 0, |
| 239 | .bInterfaceProtocol = 0, |
| 240 | .iInterface = CCID_CONF_STR, |
| 241 | }, |
| 242 | { |
| 243 | .bLength = sizeof(CCIDDescriptor), |
| 244 | .bDescriptorType = CCID_DECRIPTOR_TYPE, |
| 245 | .bcdCCID = CCID1_10, // CCID version |
| 246 | .bMaxSlotIndex = 0, // 1 slot |
| 247 | .bVoltageSupport = VOLTS_3_0, |
| 248 | .dwProtocols = (1 << PROTOCOL_TO), |
| 249 | .dwDefaultClock = 3580, |
| 250 | .dwMaximumClock = 3580, |
| 251 | .bNumClockSupported = 0, |
| 252 | .dwDataRate = 9600, |
| 253 | .dwMaxDataRate = 9600, |
| 254 | .bNumDataRatesSupported = 0, |
| 255 | .dwMaxIFSD = 0xfe, |
| 256 | .dwSynchProtocols = 0, |
| 257 | .dwMechanical = 0, |
| 258 | .dwFeatures = CCID_FEATURES_AUTO_CLOCK | CCID_FEATURES_AUTO_BAUD | |
| 259 | CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | |
| 260 | CCID_FEATURES_EXC_TPDU, |
| 261 | .dwMaxCCIDMessageLength = 271, /* For extended APDU |
| 262 | level the value shall |
| 263 | be between 261 + 10 */ |
| 264 | .bClassGetResponse = 0xFF, // Echoes the class of the APDU |
| 265 | .bClassEnvelope = 0xFF, // Echoes the class of the APDU |
| 266 | .wLcdLayout = 0, // wLcdLayout: no LCD |
| 267 | .bPINSupport = 0, // bPINSupport: No PIN |
| 268 | .bMaxCCIDBusySlots = 1, |
| 269 | }, |
| 270 | // Bulk-OUT endpoint descriptor |
| 271 | { |
| 272 | .bLength = sizeof(USBEndpointDescriptor), |
| 273 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 274 | .bEndpointAddress = |
| 275 | USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, |
| 276 | CCID_EPT_DATA_OUT), |
| 277 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 278 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 279 | .bInterval = 0x00, |
| 280 | }, |
| 281 | // Bulk-IN endpoint descriptor |
| 282 | { |
| 283 | .bLength = sizeof(USBEndpointDescriptor), |
| 284 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 285 | .bEndpointAddress = |
| 286 | USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, |
| 287 | CCID_EPT_DATA_IN), |
| 288 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 289 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS), |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 290 | .bInterval = 0x00, |
| 291 | }, |
| 292 | // Notification endpoint descriptor |
| 293 | { |
| 294 | .bLength = sizeof(USBEndpointDescriptor), |
| 295 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 296 | .bEndpointAddress = |
| 297 | USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, |
| 298 | CCID_EPT_NOTIFICATION), |
| 299 | .bmAttributes = USBEndpointDescriptor_INTERRUPT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 300 | .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 301 | .bInterval = 0x10, |
| 302 | }, |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 303 | DFURT_IF_DESCRIPTOR(1, 0), |
Christina Quast | db7b1ab | 2015-03-03 12:34:36 +0100 | [diff] [blame] | 304 | }; |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 305 | #endif /* HAVE_CCID */ |
Christina Quast | db7b1ab | 2015-03-03 12:34:36 +0100 | [diff] [blame] | 306 | |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 307 | #ifdef HAVE_CARDEM |
Christina Quast | 01bbdc3 | 2015-02-24 17:38:45 +0100 | [diff] [blame] | 308 | /* SIM card emulator */ |
| 309 | typedef struct _SIMTraceDriverConfigurationDescriptorPhone { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 310 | /* Standard configuration descriptor. */ |
| 311 | USBConfigurationDescriptor configuration; |
| 312 | USBInterfaceDescriptor phone; |
| 313 | USBEndpointDescriptor phone_dataOut; |
| 314 | USBEndpointDescriptor phone_dataIn; |
| 315 | USBEndpointDescriptor phone_interruptIn; |
Harald Welte | 57b3a25 | 2016-03-02 15:20:27 +0100 | [diff] [blame] | 316 | #ifdef CARDEMU_SECOND_UART |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 317 | USBInterfaceDescriptor usim2; |
| 318 | USBEndpointDescriptor usim2_dataOut; |
| 319 | USBEndpointDescriptor usim2_dataIn; |
| 320 | USBEndpointDescriptor usim2_interruptIn; |
Harald Welte | 57b3a25 | 2016-03-02 15:20:27 +0100 | [diff] [blame] | 321 | #endif |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 322 | DFURT_IF_DESCRIPTOR_STRUCT; |
Christina Quast | 01bbdc3 | 2015-02-24 17:38:45 +0100 | [diff] [blame] | 323 | } __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorPhone; |
| 324 | |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 325 | static const SIMTraceDriverConfigurationDescriptorPhone |
| 326 | configurationDescriptorPhone = { |
| 327 | /* Standard configuration descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 328 | .configuration = { |
| 329 | .bLength = sizeof(USBConfigurationDescriptor), |
| 330 | .bDescriptorType = USBGenericDescriptor_CONFIGURATION, |
| 331 | .wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorPhone), |
Harald Welte | 57b3a25 | 2016-03-02 15:20:27 +0100 | [diff] [blame] | 332 | #ifdef CARDEMU_SECOND_UART |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 333 | .bNumInterfaces = 2+DFURT_NUM_IF, |
Harald Welte | 57b3a25 | 2016-03-02 15:20:27 +0100 | [diff] [blame] | 334 | #else |
Harald Welte | f231541 | 2017-11-28 19:16:10 +0100 | [diff] [blame] | 335 | .bNumInterfaces = 1+DFURT_NUM_IF, |
Harald Welte | 57b3a25 | 2016-03-02 15:20:27 +0100 | [diff] [blame] | 336 | #endif |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 337 | .bConfigurationValue = CFG_NUM_PHONE, |
| 338 | .iConfiguration = PHONE_CONF_STR, |
| 339 | .bmAttributes = USBD_BMATTRIBUTES, |
| 340 | .bMaxPower = USBConfigurationDescriptor_POWER(100) |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 341 | }, |
| 342 | /* Communication class interface standard descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 343 | .phone = { |
| 344 | .bLength = sizeof(USBInterfaceDescriptor), |
| 345 | .bDescriptorType = USBGenericDescriptor_INTERFACE, |
| 346 | .bInterfaceNumber = 0, |
| 347 | .bAlternateSetting = 0, |
| 348 | .bNumEndpoints = 3, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 349 | .bInterfaceClass = USB_CLASS_PROPRIETARY, |
| 350 | .bInterfaceSubClass = SIMTRACE_CARDEM_USB_SUBCLASS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 351 | .bInterfaceProtocol = 0, |
| 352 | .iInterface = CARDEM_USIM1_INTF_STR, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 353 | }, |
| 354 | /* Bulk-OUT endpoint standard descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 355 | .phone_dataOut = { |
| 356 | .bLength = sizeof(USBEndpointDescriptor), |
| 357 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 358 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 359 | USBEndpointDescriptor_OUT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 360 | SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT), |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 361 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 362 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 363 | .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 364 | }, |
| 365 | /* Bulk-IN endpoint descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 366 | .phone_dataIn = { |
| 367 | .bLength = sizeof(USBEndpointDescriptor), |
| 368 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 369 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 370 | USBEndpointDescriptor_IN, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 371 | SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN), |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 372 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 373 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 374 | .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 375 | }, |
| 376 | /* Notification endpoint descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 377 | .phone_interruptIn = { |
| 378 | .bLength = sizeof(USBEndpointDescriptor), |
| 379 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 380 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 381 | USBEndpointDescriptor_IN, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 382 | SIMTRACE_CARDEM_USB_EP_USIM1_INT), |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 383 | .bmAttributes = USBEndpointDescriptor_INTERRUPT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 384 | .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 385 | .bInterval = 0x10 |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 386 | }, |
Harald Welte | 57b3a25 | 2016-03-02 15:20:27 +0100 | [diff] [blame] | 387 | #ifdef CARDEMU_SECOND_UART |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 388 | /* Communication class interface standard descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 389 | .usim2 = { |
| 390 | .bLength = sizeof(USBInterfaceDescriptor), |
| 391 | .bDescriptorType = USBGenericDescriptor_INTERFACE, |
| 392 | .bInterfaceNumber = 1, |
| 393 | .bAlternateSetting = 0, |
| 394 | .bNumEndpoints = 3, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 395 | .bInterfaceClass = USB_CLASS_PROPRIETARY, |
| 396 | .bInterfaceSubClass = SIMTRACE_CARDEM_USB_SUBCLASS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 397 | .bInterfaceProtocol = 0, |
| 398 | .iInterface = CARDEM_USIM2_INTF_STR, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 399 | }, |
| 400 | /* Bulk-OUT endpoint standard descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 401 | .usim2_dataOut = { |
| 402 | .bLength = sizeof(USBEndpointDescriptor), |
| 403 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 404 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 405 | USBEndpointDescriptor_OUT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 406 | SIMTRACE_CARDEM_USB_EP_USIM2_DATAOUT), |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 407 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 408 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 409 | .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 410 | } |
| 411 | , |
| 412 | /* Bulk-IN endpoint descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 413 | .usim2_dataIn = { |
| 414 | .bLength = sizeof(USBEndpointDescriptor), |
| 415 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 416 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 417 | USBEndpointDescriptor_IN, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 418 | SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN), |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 419 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 420 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 421 | .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 422 | }, |
| 423 | /* Notification endpoint descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 424 | .usim2_interruptIn = { |
| 425 | .bLength = sizeof(USBEndpointDescriptor), |
| 426 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 427 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 428 | USBEndpointDescriptor_IN, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 429 | SIMTRACE_CARDEM_USB_EP_USIM2_INT), |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 430 | .bmAttributes = USBEndpointDescriptor_INTERRUPT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 431 | .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 432 | .bInterval = 0x10, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 433 | }, |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 434 | DFURT_IF_DESCRIPTOR(2, 0), |
| 435 | #else |
| 436 | DFURT_IF_DESCRIPTOR(1, 0), |
Harald Welte | 57b3a25 | 2016-03-02 15:20:27 +0100 | [diff] [blame] | 437 | #endif |
Christina Quast | 01bbdc3 | 2015-02-24 17:38:45 +0100 | [diff] [blame] | 438 | }; |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 439 | #endif /* HAVE_CARDEM */ |
Christina Quast | 01bbdc3 | 2015-02-24 17:38:45 +0100 | [diff] [blame] | 440 | |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 441 | #ifdef HAVE_MITM |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 442 | typedef struct _SIMTraceDriverConfigurationDescriptorMITM { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 443 | /* Standard configuration descriptor. */ |
| 444 | USBConfigurationDescriptor configuration; |
| 445 | USBInterfaceDescriptor simcard; |
| 446 | /// CCID descriptor |
| 447 | CCIDDescriptor ccid; |
| 448 | /// Bulk OUT endpoint descriptor |
| 449 | USBEndpointDescriptor simcard_dataOut; |
| 450 | /// Bulk IN endpoint descriptor |
| 451 | USBEndpointDescriptor simcard_dataIn; |
| 452 | /// Interrupt OUT endpoint descriptor |
| 453 | USBEndpointDescriptor simcard_interruptIn; |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 454 | |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 455 | USBInterfaceDescriptor phone; |
| 456 | USBEndpointDescriptor phone_dataOut; |
| 457 | USBEndpointDescriptor phone_dataIn; |
| 458 | USBEndpointDescriptor phone_interruptIn; |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 459 | |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 460 | DFURT_IF_DESCRIPTOR_STRUCT; |
| 461 | |
Christina Quast | 01bbdc3 | 2015-02-24 17:38:45 +0100 | [diff] [blame] | 462 | } __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorMITM; |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 463 | |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 464 | static const SIMTraceDriverConfigurationDescriptorMITM |
| 465 | configurationDescriptorMITM = { |
| 466 | /* Standard configuration descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 467 | .configuration = { |
| 468 | .bLength = sizeof(USBConfigurationDescriptor), |
| 469 | .bDescriptorType = USBGenericDescriptor_CONFIGURATION, |
| 470 | .wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorMITM), |
| 471 | .bNumInterfaces = 2+DFURT_NUM_IF, |
| 472 | .bConfigurationValue = CFG_NUM_MITM, |
| 473 | .iConfiguration = MITM_CONF_STR, |
| 474 | .bmAttributes = USBD_BMATTRIBUTES, |
| 475 | .bMaxPower = USBConfigurationDescriptor_POWER(100), |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 476 | }, |
| 477 | // CCID interface descriptor |
| 478 | // Table 4.3-1 Interface Descriptor |
| 479 | // Interface descriptor |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 480 | .simcard = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 481 | .bLength = sizeof(USBInterfaceDescriptor), |
| 482 | .bDescriptorType = USBGenericDescriptor_INTERFACE, |
| 483 | .bInterfaceNumber = 0, |
| 484 | .bAlternateSetting = 0, |
| 485 | .bNumEndpoints = 3, |
| 486 | .bInterfaceClass = SMART_CARD_DEVICE_CLASS, |
| 487 | .bInterfaceSubClass = 0, |
| 488 | .bInterfaceProtocol = 0, |
| 489 | .iInterface = CCID_CONF_STR, |
| 490 | }, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 491 | .ccid = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 492 | .bLength = sizeof(CCIDDescriptor), |
| 493 | .bDescriptorType = CCID_DECRIPTOR_TYPE, |
| 494 | .bcdCCID = CCID1_10, // CCID version |
| 495 | .bMaxSlotIndex = 0, // 1 slot |
| 496 | .bVoltageSupport = VOLTS_3_0, |
| 497 | .dwProtocols = (1 << PROTOCOL_TO), |
| 498 | .dwDefaultClock = 3580, |
| 499 | .dwMaximumClock = 3580, |
| 500 | .bNumClockSupported = 0, |
| 501 | .dwDataRate = 9600, |
| 502 | .dwMaxDataRate = 9600, |
| 503 | .bNumDataRatesSupported = 0, |
| 504 | .dwMaxIFSD = 0xfe, |
| 505 | .dwSynchProtocols = 0, |
| 506 | .dwMechanical = 0, |
| 507 | .dwFeatures = CCID_FEATURES_AUTO_CLOCK | CCID_FEATURES_AUTO_BAUD | |
| 508 | CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | |
| 509 | CCID_FEATURES_EXC_TPDU, |
| 510 | .dwMaxCCIDMessageLength = 271, /* For extended APDU |
| 511 | level the value shall |
| 512 | be between 261 + 10 */ |
| 513 | .bClassGetResponse = 0xFF, // Echoes the class of the APDU |
| 514 | .bClassEnvelope = 0xFF, // Echoes the class of the APDU |
| 515 | .wLcdLayout = 0, // wLcdLayout: no LCD |
| 516 | .bPINSupport = 0, // bPINSupport: No PIN |
| 517 | .bMaxCCIDBusySlots = 1, |
| 518 | }, |
| 519 | // Bulk-OUT endpoint descriptor |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 520 | .simcard_dataOut = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 521 | .bLength = sizeof(USBEndpointDescriptor), |
| 522 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 523 | .bEndpointAddress = |
| 524 | USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, |
| 525 | CCID_EPT_DATA_OUT), |
| 526 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 527 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 528 | .bInterval = 0x00, |
| 529 | }, |
| 530 | // Bulk-IN endpoint descriptor |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 531 | .simcard_dataIn = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 532 | .bLength = sizeof(USBEndpointDescriptor), |
| 533 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 534 | .bEndpointAddress = |
| 535 | USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, |
| 536 | CCID_EPT_DATA_IN), |
| 537 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 538 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 539 | .bInterval = 0x00, |
| 540 | }, |
| 541 | // Notification endpoint descriptor |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 542 | .simcard_interruptIn = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 543 | .bLength = sizeof(USBEndpointDescriptor), |
| 544 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 545 | .bEndpointAddress = |
| 546 | USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, |
| 547 | CCID_EPT_NOTIFICATION), |
| 548 | .bmAttributes = USBEndpointDescriptor_INTERRUPT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 549 | .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 550 | .bInterval = 0x10, |
| 551 | }, |
| 552 | |
| 553 | /* Communication class interface standard descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 554 | .phone = { |
| 555 | .bLength = sizeof(USBInterfaceDescriptor), |
| 556 | .bDescriptorType = USBGenericDescriptor_INTERFACE, |
| 557 | .bInterfaceNumber = 1, |
| 558 | .bAlternateSetting = 0, |
| 559 | .bNumEndpoints = 3, |
| 560 | .bInterfaceClass = 0xff, |
Harald Welte | f231541 | 2017-11-28 19:16:10 +0100 | [diff] [blame] | 561 | .bInterfaceSubClass = SIMTRACE_SUBCLASS_CARDEM, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 562 | .bInterfaceProtocol = 0, |
| 563 | .iInterface = PHONE_CONF_STR, |
| 564 | }, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 565 | /* Bulk-OUT endpoint standard descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 566 | .phone_dataOut = { |
| 567 | .bLength = sizeof(USBEndpointDescriptor), |
| 568 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 569 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 570 | USBEndpointDescriptor_OUT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 571 | SIMTRACE_USB_EP_PHONE_DATAOUT), |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 572 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 573 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 574 | .bInterval = 0, /* Must be 0 for full-speed bulk endpoints */ |
| 575 | }, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 576 | /* Bulk-IN endpoint descriptor */ |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 577 | .phone_dataIn = { |
| 578 | .bLength = sizeof(USBEndpointDescriptor), |
| 579 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 580 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 581 | USBEndpointDescriptor_IN, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 582 | SIMTRACE_USB_EP_PHONE_DATAIN), |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 583 | .bmAttributes = USBEndpointDescriptor_BULK, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 584 | .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 585 | .bInterval = 0, /* Must be 0 for full-speed bulk endpoints */ |
| 586 | }, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 587 | /* Notification endpoint descriptor */ |
| 588 | { |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 589 | .bLength = sizeof(USBEndpointDescriptor), |
| 590 | .bDescriptorType = USBGenericDescriptor_ENDPOINT, |
| 591 | .bEndpointAddress = USBEndpointDescriptor_ADDRESS( |
| 592 | USBEndpointDescriptor_IN, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 593 | SIMTRACE_USB_EP_PHONE_INT), |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 594 | .bmAttributes = USBEndpointDescriptor_INTERRUPT, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 595 | .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, |
Harald Welte | 495a67d | 2017-03-06 09:55:37 +0100 | [diff] [blame] | 596 | .bInterval = 0x10 |
| 597 | }, |
Harald Welte | 7ed6f3b | 2017-02-26 17:00:43 +0100 | [diff] [blame] | 598 | DFURT_IF_DESCRIPTOR(2, 0), |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 599 | }; |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 600 | #endif /* HAVE_CARDEM */ |
| 601 | |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 602 | /* USB descriptor just to show the version */ |
| 603 | typedef struct _SIMTraceDriverConfigurationDescriptorVersion { |
| 604 | /** Standard configuration descriptor. */ |
| 605 | USBConfigurationDescriptor configuration; |
Kévin Redon | ede87e0 | 2019-08-13 17:03:11 +0200 | [diff] [blame] | 606 | USBInterfaceDescriptor version; |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 607 | } __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorVersion; |
| 608 | |
| 609 | static const SIMTraceDriverConfigurationDescriptorVersion |
| 610 | configurationDescriptorVersion = { |
Kévin Redon | ede87e0 | 2019-08-13 17:03:11 +0200 | [diff] [blame] | 611 | /* Standard configuration descriptor for the interface descriptor*/ |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 612 | .configuration = { |
| 613 | .bLength = sizeof(USBConfigurationDescriptor), |
| 614 | .bDescriptorType = USBGenericDescriptor_CONFIGURATION, |
| 615 | .wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorVersion), |
Kévin Redon | ede87e0 | 2019-08-13 17:03:11 +0200 | [diff] [blame] | 616 | .bNumInterfaces = 1, |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 617 | .bConfigurationValue = CFG_NUM_VERSION, |
Kévin Redon | ede87e0 | 2019-08-13 17:03:11 +0200 | [diff] [blame] | 618 | .iConfiguration = VERSION_CONF_STR, |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 619 | .bmAttributes = USBD_BMATTRIBUTES, |
| 620 | .bMaxPower = USBConfigurationDescriptor_POWER(100), |
| 621 | }, |
Kévin Redon | ede87e0 | 2019-08-13 17:03:11 +0200 | [diff] [blame] | 622 | /* Interface standard descriptor just holding the version information */ |
| 623 | .version = { |
| 624 | .bLength = sizeof(USBInterfaceDescriptor), |
| 625 | .bDescriptorType = USBGenericDescriptor_INTERFACE, |
| 626 | .bInterfaceNumber = 0, |
| 627 | .bAlternateSetting = 0, |
| 628 | .bNumEndpoints = 0, |
| 629 | .bInterfaceClass = USB_CLASS_PROPRIETARY, |
| 630 | .bInterfaceSubClass = 0xff, |
| 631 | .bInterfaceProtocol = 0, |
| 632 | .iInterface = VERSION_STR, |
| 633 | }, |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 634 | }; |
| 635 | |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 636 | const USBConfigurationDescriptor *configurationDescriptorsArr[] = { |
| 637 | #ifdef HAVE_SNIFFER |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 638 | &configurationDescriptorSniffer.configuration, |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 639 | #endif |
| 640 | #ifdef HAVE_CCID |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 641 | &configurationDescriptorCCID.configuration, |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 642 | #endif |
| 643 | #ifdef HAVE_CARDEM |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 644 | &configurationDescriptorPhone.configuration, |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 645 | #endif |
| 646 | #ifdef HAVE_MITM |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 647 | &configurationDescriptorMITM.configuration, |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 648 | #endif |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 649 | &configurationDescriptorVersion.configuration, |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 650 | }; |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 651 | |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 652 | /** Standard USB device descriptor for the CDC serial driver */ |
| 653 | const USBDeviceDescriptor deviceDescriptor = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 654 | .bLength = sizeof(USBDeviceDescriptor), |
| 655 | .bDescriptorType = USBGenericDescriptor_DEVICE, |
| 656 | .bcdUSB = USBDeviceDescriptor_USB2_00, |
Harald Welte | eab7e45 | 2017-03-06 10:04:56 +0100 | [diff] [blame] | 657 | .bDeviceClass = 0, |
| 658 | .bDeviceSubClass = 0, |
| 659 | .bDeviceProtocol = 0, |
Kévin Redon | a1012b1 | 2018-07-01 18:11:01 +0200 | [diff] [blame] | 660 | .bMaxPacketSize0 = 64, |
Harald Welte | c6e482d | 2017-03-05 16:24:29 +0100 | [diff] [blame] | 661 | .idVendor = BOARD_USB_VENDOR_ID, |
| 662 | .idProduct = BOARD_USB_PRODUCT_ID, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 663 | .bcdDevice = 2, /* Release number */ |
| 664 | .iManufacturer = MANUF_STR, |
| 665 | .iProduct = PRODUCT_STRING, |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 666 | .iSerialNumber = SERIAL_STR, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 667 | .bNumConfigurations = ARRAY_SIZE(configurationDescriptorsArr), |
Christina Quast | 01bbdc3 | 2015-02-24 17:38:45 +0100 | [diff] [blame] | 668 | }; |
| 669 | |
Christina Quast | bd5b8bd | 2015-05-14 17:25:41 +0200 | [diff] [blame] | 670 | /* AT91SAM3S only supports full speed, but not high speed USB */ |
Harald Welte | ec4fe23 | 2015-11-07 18:41:25 +0100 | [diff] [blame] | 671 | static const USBDDriverDescriptors driverDescriptors = { |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 672 | &deviceDescriptor, |
| 673 | (const USBConfigurationDescriptor **)&(configurationDescriptorsArr), /* first full-speed configuration descriptor */ |
| 674 | 0, /* No full-speed device qualifier descriptor */ |
| 675 | 0, /* No full-speed other speed configuration */ |
| 676 | 0, /* No high-speed device descriptor */ |
| 677 | 0, /* No high-speed configuration descriptor */ |
| 678 | 0, /* No high-speed device qualifier descriptor */ |
| 679 | 0, /* No high-speed other speed configuration descriptor */ |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 680 | usb_strings_extended, |
| 681 | ARRAY_SIZE(usb_strings_extended),/* cnt string descriptors in list */ |
Christina Quast | f554950 | 2015-02-24 14:27:08 +0100 | [diff] [blame] | 682 | }; |
| 683 | |
Christina Quast | 0ae0314 | 2015-02-25 18:43:46 +0100 | [diff] [blame] | 684 | /*---------------------------------------------------------------------------- |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 685 | * Functions |
Christina Quast | 968b974 | 2015-02-25 14:10:12 +0100 | [diff] [blame] | 686 | *----------------------------------------------------------------------------*/ |
| 687 | |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 688 | void SIMtrace_USB_Initialize(void) |
Christina Quast | 968b974 | 2015-02-25 14:10:12 +0100 | [diff] [blame] | 689 | { |
Harald Welte | 4b487b8 | 2019-08-08 10:18:35 +0200 | [diff] [blame] | 690 | unsigned int i; |
Kévin Redon | f5869d4 | 2018-06-17 22:31:21 +0200 | [diff] [blame] | 691 | /* Signal USB reset by disabling the pull-up on USB D+ for at least 10 ms */ |
Kévin Redon | ff3d849 | 2018-08-06 17:57:20 +0200 | [diff] [blame] | 692 | #ifdef PIN_USB_PULLUP |
Kévin Redon | f5869d4 | 2018-06-17 22:31:21 +0200 | [diff] [blame] | 693 | const Pin usb_dp_pullup = PIN_USB_PULLUP; |
| 694 | PIO_Configure(&usb_dp_pullup, 1); |
| 695 | PIO_Set(&usb_dp_pullup); |
Kévin Redon | ff3d849 | 2018-08-06 17:57:20 +0200 | [diff] [blame] | 696 | #endif |
| 697 | USBD_HAL_Suspend(); |
| 698 | mdelay(20); |
| 699 | #ifdef PIN_USB_PULLUP |
Kévin Redon | f5869d4 | 2018-06-17 22:31:21 +0200 | [diff] [blame] | 700 | PIO_Clear(&usb_dp_pullup); |
Kévin Redon | ff3d849 | 2018-08-06 17:57:20 +0200 | [diff] [blame] | 701 | #endif |
| 702 | USBD_HAL_Activate(); |
Kévin Redon | f5869d4 | 2018-06-17 22:31:21 +0200 | [diff] [blame] | 703 | |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 704 | // Get std USB driver |
| 705 | USBDDriver *pUsbd = USBD_GetDriver(); |
Christina Quast | 968b974 | 2015-02-25 14:10:12 +0100 | [diff] [blame] | 706 | |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 707 | // put device ID into USB serial number description |
| 708 | unsigned int device_id[4]; |
| 709 | EEFC_ReadUniqueID(device_id); |
| 710 | char device_id_string[32 + 1]; |
| 711 | snprintf(device_id_string, ARRAY_SIZE(device_id_string), "%08x%08x%08x%08x", |
| 712 | device_id[0], device_id[1], device_id[2], device_id[3]); |
Harald Welte | 4b487b8 | 2019-08-08 10:18:35 +0200 | [diff] [blame] | 713 | for (i = 0; i < ARRAY_SIZE(device_id_string) - 1; i++) { |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 714 | usb_string_serial[2 + 2 * i] = device_id_string[i]; |
| 715 | } |
| 716 | |
| 717 | // put version into USB string |
| 718 | usb_string_version[0] = USBStringDescriptor_LENGTH(ARRAY_SIZE(git_version) - 1); |
| 719 | usb_string_version[1] = USBGenericDescriptor_STRING; |
Harald Welte | 4b487b8 | 2019-08-08 10:18:35 +0200 | [diff] [blame] | 720 | for (i = 0; i < ARRAY_SIZE(git_version) - 1; i++) { |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 721 | usb_string_version[2 + i * 2 + 0] = git_version[i]; |
| 722 | usb_string_version[2 + i * 2 + 1] = 0; |
| 723 | } |
| 724 | |
| 725 | // fill extended USB strings |
Harald Welte | 4b487b8 | 2019-08-08 10:18:35 +0200 | [diff] [blame] | 726 | for (i = 0; i < ARRAY_SIZE(usb_strings) && i < ARRAY_SIZE(usb_strings_extended); i++) { |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 727 | usb_strings_extended[i] = usb_strings[i]; |
| 728 | } |
| 729 | usb_strings_extended[SERIAL_STR] = usb_string_serial; |
Kévin Redon | ede87e0 | 2019-08-13 17:03:11 +0200 | [diff] [blame] | 730 | usb_strings_extended[VERSION_CONF_STR] = usb_string_version_conf; |
Kévin Redon | e026546 | 2019-08-06 15:41:31 +0200 | [diff] [blame] | 731 | usb_strings_extended[VERSION_STR] = usb_string_version; |
| 732 | |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 733 | // Initialize standard USB driver |
| 734 | USBDDriver_Initialize(pUsbd, &driverDescriptors, 0); // Multiple interface settings not supported |
| 735 | USBD_Init(); |
| 736 | USBD_Connect(); |
Christina Quast | 968b974 | 2015-02-25 14:10:12 +0100 | [diff] [blame] | 737 | |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 738 | NVIC_EnableIRQ(UDP_IRQn); |
Christina Quast | 968b974 | 2015-02-25 14:10:12 +0100 | [diff] [blame] | 739 | } |