/* ---------------------------------------------------------------------------- * ATMEL Microcontroller Software Support * ---------------------------------------------------------------------------- * Copyright (c) 2009, Atmel Corporation * Copyright (c) 2018-2019, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * * Atmel's name may not be used to endorse or promote products derived from * this software without specific prior written permission. * * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ---------------------------------------------------------------------------- */ /*---------------------------------------------------------------------------- * Headers *----------------------------------------------------------------------------*/ #include "board.h" #include "simtrace.h" #include "simtrace_usb.h" #include "utils.h" #include "USBD_HAL.h" #include #include #include /*------------------------------------------------------------------------------ * USB String descriptors *------------------------------------------------------------------------------*/ #include "usb_strings_generated.h" // the index of the strings (must match the order in usb_strings.txt) enum strDescNum { // static strings from usb_strings MANUF_STR = 1, PRODUCT_STRING, SNIFFER_CONF_STR, CCID_CONF_STR, PHONE_CONF_STR, MITM_CONF_STR, CARDEM_USIM1_INTF_STR, CARDEM_USIM2_INTF_STR, CARDEM_USIM3_INTF_STR, CARDEM_USIM4_INTF_STR, // runtime strings SERIAL_STR, VERSION_CONF_STR, VERSION_STR, // count STRING_DESC_CNT }; /** array of static (from usb_strings) and runtime (serial, version) USB strings */ static const unsigned char *usb_strings_extended[ARRAY_SIZE(usb_strings) + 3]; /* USB string for the serial (using 128-bit device ID) */ static unsigned char usb_string_serial[] = { USBStringDescriptor_LENGTH(32), USBGenericDescriptor_STRING, USBStringDescriptor_UNICODE('0'), USBStringDescriptor_UNICODE('0'), USBStringDescriptor_UNICODE('1'), USBStringDescriptor_UNICODE('1'), USBStringDescriptor_UNICODE('2'), USBStringDescriptor_UNICODE('2'), USBStringDescriptor_UNICODE('3'), USBStringDescriptor_UNICODE('3'), USBStringDescriptor_UNICODE('4'), USBStringDescriptor_UNICODE('4'), USBStringDescriptor_UNICODE('5'), USBStringDescriptor_UNICODE('5'), USBStringDescriptor_UNICODE('6'), USBStringDescriptor_UNICODE('6'), USBStringDescriptor_UNICODE('7'), USBStringDescriptor_UNICODE('7'), USBStringDescriptor_UNICODE('8'), USBStringDescriptor_UNICODE('8'), USBStringDescriptor_UNICODE('9'), USBStringDescriptor_UNICODE('9'), USBStringDescriptor_UNICODE('a'), USBStringDescriptor_UNICODE('a'), USBStringDescriptor_UNICODE('b'), USBStringDescriptor_UNICODE('b'), USBStringDescriptor_UNICODE('c'), USBStringDescriptor_UNICODE('c'), USBStringDescriptor_UNICODE('d'), USBStringDescriptor_UNICODE('d'), USBStringDescriptor_UNICODE('e'), USBStringDescriptor_UNICODE('e'), USBStringDescriptor_UNICODE('f'), USBStringDescriptor_UNICODE('f'), }; /* USB string for the version */ static const unsigned char usb_string_version_conf[] = { USBStringDescriptor_LENGTH(16), USBGenericDescriptor_STRING, USBStringDescriptor_UNICODE('f'), USBStringDescriptor_UNICODE('i'), USBStringDescriptor_UNICODE('r'), USBStringDescriptor_UNICODE('m'), USBStringDescriptor_UNICODE('w'), USBStringDescriptor_UNICODE('a'), USBStringDescriptor_UNICODE('r'), USBStringDescriptor_UNICODE('e'), USBStringDescriptor_UNICODE(' '), USBStringDescriptor_UNICODE('v'), USBStringDescriptor_UNICODE('e'), USBStringDescriptor_UNICODE('r'), USBStringDescriptor_UNICODE('s'), USBStringDescriptor_UNICODE('i'), USBStringDescriptor_UNICODE('o'), USBStringDescriptor_UNICODE('n'), }; static const char git_version[] = GIT_VERSION; static unsigned char usb_string_version[2 + ARRAY_SIZE(git_version) * 2 - 2]; /*------------------------------------------------------------------------------ * USB Device descriptors *------------------------------------------------------------------------------*/ #ifdef HAVE_SNIFFER typedef struct _SIMTraceDriverConfigurationDescriptorSniffer { /** Standard configuration descriptor. */ USBConfigurationDescriptor configuration; USBInterfaceDescriptor sniffer; USBEndpointDescriptor sniffer_dataOut; USBEndpointDescriptor sniffer_dataIn; USBEndpointDescriptor sniffer_interruptIn; DFURT_IF_DESCRIPTOR_STRUCT; } __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorSniffer; static const SIMTraceDriverConfigurationDescriptorSniffer configurationDescriptorSniffer = { /* Standard configuration descriptor */ .configuration = { .bLength = sizeof(USBConfigurationDescriptor), .bDescriptorType = USBGenericDescriptor_CONFIGURATION, .wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorSniffer), .bNumInterfaces = 1+DFURT_NUM_IF, .bConfigurationValue = CFG_NUM_SNIFF, .iConfiguration = SNIFFER_CONF_STR, .bmAttributes = USBD_BMATTRIBUTES, .bMaxPower = USBConfigurationDescriptor_POWER(100), }, /* Communication class interface standard descriptor */ .sniffer = { .bLength = sizeof(USBInterfaceDescriptor), .bDescriptorType = USBGenericDescriptor_INTERFACE, .bInterfaceNumber = 0, .bAlternateSetting = 0, .bNumEndpoints = 3, .bInterfaceClass = USB_CLASS_PROPRIETARY, .bInterfaceSubClass = SIMTRACE_SNIFFER_USB_SUBCLASS, .bInterfaceProtocol = 0, .iInterface = SNIFFER_CONF_STR, }, /* Bulk-OUT endpoint standard descriptor */ .sniffer_dataOut = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_OUT, SIMTRACE_USB_EP_CARD_DATAOUT), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0, }, /* Bulk-IN endpoint descriptor */ .sniffer_dataIn = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, SIMTRACE_USB_EP_CARD_DATAIN), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0, }, // Notification endpoint descriptor .sniffer_interruptIn = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, SIMTRACE_USB_EP_CARD_INT), .bmAttributes = USBEndpointDescriptor_INTERRUPT, .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, .bInterval = 1, }, DFURT_IF_DESCRIPTOR(1, 0), }; #endif /* HAVE_SNIFFER */ #ifdef HAVE_CCID static const CCIDDriverConfigurationDescriptors configurationDescriptorCCID = { // Standard USB configuration descriptor { .bLength = sizeof(USBConfigurationDescriptor), .bDescriptorType = USBGenericDescriptor_CONFIGURATION, .wTotalLength = sizeof(CCIDDriverConfigurationDescriptors), .bNumInterfaces = 1+DFURT_NUM_IF, .bConfigurationValue = CFG_NUM_CCID, .iConfiguration = CCID_CONF_STR, .bmAttributes = BOARD_USB_BMATTRIBUTES, .bMaxPower = USBConfigurationDescriptor_POWER(100), }, // CCID interface descriptor // Table 4.3-1 Interface Descriptor // Interface descriptor { .bLength = sizeof(USBInterfaceDescriptor), .bDescriptorType = USBGenericDescriptor_INTERFACE, .bInterfaceNumber = 0, .bAlternateSetting = 0, .bNumEndpoints = 3, .bInterfaceClass = SMART_CARD_DEVICE_CLASS, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, .iInterface = CCID_CONF_STR, }, { .bLength = sizeof(CCIDDescriptor), .bDescriptorType = CCID_DECRIPTOR_TYPE, .bcdCCID = CCID1_10, // CCID version .bMaxSlotIndex = 0, // 1 slot .bVoltageSupport = VOLTS_3_0, .dwProtocols = (1 << PROTOCOL_TO), .dwDefaultClock = 3580, .dwMaximumClock = 3580, .bNumClockSupported = 0, .dwDataRate = 9600, .dwMaxDataRate = 9600, .bNumDataRatesSupported = 0, .dwMaxIFSD = 0xfe, .dwSynchProtocols = 0, .dwMechanical = 0, .dwFeatures = CCID_FEATURES_AUTO_CLOCK | CCID_FEATURES_AUTO_BAUD | CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU, .dwMaxCCIDMessageLength = 271, /* For extended APDU level the value shall be between 261 + 10 */ .bClassGetResponse = 0xFF, // Echoes the class of the APDU .bClassEnvelope = 0xFF, // Echoes the class of the APDU .wLcdLayout = 0, // wLcdLayout: no LCD .bPINSupport = 0, // bPINSupport: No PIN .bMaxCCIDBusySlots = 1, }, // Bulk-OUT endpoint descriptor { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0x00, }, // Bulk-IN endpoint descriptor { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_DATA_IN), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS), .bInterval = 0x00, }, // Notification endpoint descriptor { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION), .bmAttributes = USBEndpointDescriptor_INTERRUPT, .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, .bInterval = 0x10, }, DFURT_IF_DESCRIPTOR(1, 0), }; #endif /* HAVE_CCID */ #ifdef HAVE_CARDEM /* SIM card emulator */ typedef struct _SIMTraceDriverConfigurationDescriptorPhone { /* Standard configuration descriptor. */ USBConfigurationDescriptor configuration; USBInterfaceDescriptor phone; USBEndpointDescriptor phone_dataOut; USBEndpointDescriptor phone_dataIn; USBEndpointDescriptor phone_interruptIn; #ifdef CARDEMU_SECOND_UART USBInterfaceDescriptor usim2; USBEndpointDescriptor usim2_dataOut; USBEndpointDescriptor usim2_dataIn; USBEndpointDescriptor usim2_interruptIn; #endif DFURT_IF_DESCRIPTOR_STRUCT; } __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorPhone; static const SIMTraceDriverConfigurationDescriptorPhone configurationDescriptorPhone = { /* Standard configuration descriptor */ .configuration = { .bLength = sizeof(USBConfigurationDescriptor), .bDescriptorType = USBGenericDescriptor_CONFIGURATION, .wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorPhone), #ifdef CARDEMU_SECOND_UART .bNumInterfaces = 2+DFURT_NUM_IF, #else .bNumInterfaces = 1+DFURT_NUM_IF, #endif .bConfigurationValue = CFG_NUM_PHONE, .iConfiguration = PHONE_CONF_STR, .bmAttributes = USBD_BMATTRIBUTES, .bMaxPower = USBConfigurationDescriptor_POWER(100) }, /* Communication class interface standard descriptor */ .phone = { .bLength = sizeof(USBInterfaceDescriptor), .bDescriptorType = USBGenericDescriptor_INTERFACE, .bInterfaceNumber = 0, .bAlternateSetting = 0, .bNumEndpoints = 3, .bInterfaceClass = USB_CLASS_PROPRIETARY, .bInterfaceSubClass = SIMTRACE_CARDEM_USB_SUBCLASS, .bInterfaceProtocol = 0, .iInterface = CARDEM_USIM1_INTF_STR, }, /* Bulk-OUT endpoint standard descriptor */ .phone_dataOut = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_OUT, SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ }, /* Bulk-IN endpoint descriptor */ .phone_dataIn = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ }, /* Notification endpoint descriptor */ .phone_interruptIn = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, SIMTRACE_CARDEM_USB_EP_USIM1_INT), .bmAttributes = USBEndpointDescriptor_INTERRUPT, .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, .bInterval = 1 }, #ifdef CARDEMU_SECOND_UART /* Communication class interface standard descriptor */ .usim2 = { .bLength = sizeof(USBInterfaceDescriptor), .bDescriptorType = USBGenericDescriptor_INTERFACE, .bInterfaceNumber = 1, .bAlternateSetting = 0, .bNumEndpoints = 3, .bInterfaceClass = USB_CLASS_PROPRIETARY, .bInterfaceSubClass = SIMTRACE_CARDEM_USB_SUBCLASS, .bInterfaceProtocol = 0, .iInterface = CARDEM_USIM2_INTF_STR, }, /* Bulk-OUT endpoint standard descriptor */ .usim2_dataOut = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_OUT, SIMTRACE_CARDEM_USB_EP_USIM2_DATAOUT), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ } , /* Bulk-IN endpoint descriptor */ .usim2_dataIn = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ }, /* Notification endpoint descriptor */ .usim2_interruptIn = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, SIMTRACE_CARDEM_USB_EP_USIM2_INT), .bmAttributes = USBEndpointDescriptor_INTERRUPT, .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, .bInterval = 1, }, DFURT_IF_DESCRIPTOR(2, 0), #else DFURT_IF_DESCRIPTOR(1, 0), #endif }; #endif /* HAVE_CARDEM */ #ifdef HAVE_MITM typedef struct _SIMTraceDriverConfigurationDescriptorMITM { /* Standard configuration descriptor. */ USBConfigurationDescriptor configuration; USBInterfaceDescriptor simcard; /// CCID descriptor CCIDDescriptor ccid; /// Bulk OUT endpoint descriptor USBEndpointDescriptor simcard_dataOut; /// Bulk IN endpoint descriptor USBEndpointDescriptor simcard_dataIn; /// Interrupt OUT endpoint descriptor USBEndpointDescriptor simcard_interruptIn; USBInterfaceDescriptor phone; USBEndpointDescriptor phone_dataOut; USBEndpointDescriptor phone_dataIn; USBEndpointDescriptor phone_interruptIn; DFURT_IF_DESCRIPTOR_STRUCT; } __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorMITM; static const SIMTraceDriverConfigurationDescriptorMITM configurationDescriptorMITM = { /* Standard configuration descriptor */ .configuration = { .bLength = sizeof(USBConfigurationDescriptor), .bDescriptorType = USBGenericDescriptor_CONFIGURATION, .wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorMITM), .bNumInterfaces = 2+DFURT_NUM_IF, .bConfigurationValue = CFG_NUM_MITM, .iConfiguration = MITM_CONF_STR, .bmAttributes = USBD_BMATTRIBUTES, .bMaxPower = USBConfigurationDescriptor_POWER(100), }, // CCID interface descriptor // Table 4.3-1 Interface Descriptor // Interface descriptor .simcard = { .bLength = sizeof(USBInterfaceDescriptor), .bDescriptorType = USBGenericDescriptor_INTERFACE, .bInterfaceNumber = 0, .bAlternateSetting = 0, .bNumEndpoints = 3, .bInterfaceClass = SMART_CARD_DEVICE_CLASS, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, .iInterface = CCID_CONF_STR, }, .ccid = { .bLength = sizeof(CCIDDescriptor), .bDescriptorType = CCID_DECRIPTOR_TYPE, .bcdCCID = CCID1_10, // CCID version .bMaxSlotIndex = 0, // 1 slot .bVoltageSupport = VOLTS_3_0, .dwProtocols = (1 << PROTOCOL_TO), .dwDefaultClock = 3580, .dwMaximumClock = 3580, .bNumClockSupported = 0, .dwDataRate = 9600, .dwMaxDataRate = 9600, .bNumDataRatesSupported = 0, .dwMaxIFSD = 0xfe, .dwSynchProtocols = 0, .dwMechanical = 0, .dwFeatures = CCID_FEATURES_AUTO_CLOCK | CCID_FEATURES_AUTO_BAUD | CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU, .dwMaxCCIDMessageLength = 271, /* For extended APDU level the value shall be between 261 + 10 */ .bClassGetResponse = 0xFF, // Echoes the class of the APDU .bClassEnvelope = 0xFF, // Echoes the class of the APDU .wLcdLayout = 0, // wLcdLayout: no LCD .bPINSupport = 0, // bPINSupport: No PIN .bMaxCCIDBusySlots = 1, }, // Bulk-OUT endpoint descriptor .simcard_dataOut = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0x00, }, // Bulk-IN endpoint descriptor .simcard_dataIn = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_DATA_IN), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0x00, }, // Notification endpoint descriptor .simcard_interruptIn = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION), .bmAttributes = USBEndpointDescriptor_INTERRUPT, .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, .bInterval = 1, }, /* Communication class interface standard descriptor */ .phone = { .bLength = sizeof(USBInterfaceDescriptor), .bDescriptorType = USBGenericDescriptor_INTERFACE, .bInterfaceNumber = 1, .bAlternateSetting = 0, .bNumEndpoints = 3, .bInterfaceClass = 0xff, .bInterfaceSubClass = SIMTRACE_SUBCLASS_CARDEM, .bInterfaceProtocol = 0, .iInterface = PHONE_CONF_STR, }, /* Bulk-OUT endpoint standard descriptor */ .phone_dataOut = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_OUT, SIMTRACE_USB_EP_PHONE_DATAOUT), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0, /* Must be 0 for full-speed bulk endpoints */ }, /* Bulk-IN endpoint descriptor */ .phone_dataIn = { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, SIMTRACE_USB_EP_PHONE_DATAIN), .bmAttributes = USBEndpointDescriptor_BULK, .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS, .bInterval = 0, /* Must be 0 for full-speed bulk endpoints */ }, /* Notification endpoint descriptor */ { .bLength = sizeof(USBEndpointDescriptor), .bDescriptorType = USBGenericDescriptor_ENDPOINT, .bEndpointAddress = USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, SIMTRACE_USB_EP_PHONE_INT), .bmAttributes = USBEndpointDescriptor_INTERRUPT, .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS, .bInterval = 1 }, DFURT_IF_DESCRIPTOR(2, 0), }; #endif /* HAVE_CARDEM */ /* USB descriptor just to show the version */ typedef struct _SIMTraceDriverConfigurationDescriptorVersion { /** Standard configuration descriptor. */ USBConfigurationDescriptor configuration; USBInterfaceDescriptor version; } __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorVersion; static const SIMTraceDriverConfigurationDescriptorVersion configurationDescriptorVersion = { /* Standard configuration descriptor for the interface descriptor*/ .configuration = { .bLength = sizeof(USBConfigurationDescriptor), .bDescriptorType = USBGenericDescriptor_CONFIGURATION, .wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorVersion), .bNumInterfaces = 1, .bConfigurationValue = CFG_NUM_VERSION, .iConfiguration = VERSION_CONF_STR, .bmAttributes = USBD_BMATTRIBUTES, .bMaxPower = USBConfigurationDescriptor_POWER(100), }, /* Interface standard descriptor just holding the version information */ .version = { .bLength = sizeof(USBInterfaceDescriptor), .bDescriptorType = USBGenericDescriptor_INTERFACE, .bInterfaceNumber = 0, .bAlternateSetting = 0, .bNumEndpoints = 0, .bInterfaceClass = USB_CLASS_PROPRIETARY, .bInterfaceSubClass = 0xff, .bInterfaceProtocol = 0, .iInterface = VERSION_STR, }, }; const USBConfigurationDescriptor *configurationDescriptorsArr[] = { #ifdef HAVE_SNIFFER &configurationDescriptorSniffer.configuration, #endif #ifdef HAVE_CCID &configurationDescriptorCCID.configuration, #endif #ifdef HAVE_CARDEM &configurationDescriptorPhone.configuration, #endif #ifdef HAVE_MITM &configurationDescriptorMITM.configuration, #endif &configurationDescriptorVersion.configuration, }; /** Standard USB device descriptor for the CDC serial driver */ const USBDeviceDescriptor deviceDescriptor = { .bLength = sizeof(USBDeviceDescriptor), .bDescriptorType = USBGenericDescriptor_DEVICE, .bcdUSB = USBDeviceDescriptor_USB2_00, .bDeviceClass = 0, .bDeviceSubClass = 0, .bDeviceProtocol = 0, .bMaxPacketSize0 = 64, .idVendor = BOARD_USB_VENDOR_ID, .idProduct = BOARD_USB_PRODUCT_ID, .bcdDevice = 2, /* Release number */ .iManufacturer = MANUF_STR, .iProduct = PRODUCT_STRING, .iSerialNumber = SERIAL_STR, .bNumConfigurations = ARRAY_SIZE(configurationDescriptorsArr), }; /* AT91SAM3S only supports full speed, but not high speed USB */ static const USBDDriverDescriptors driverDescriptors = { &deviceDescriptor, (const USBConfigurationDescriptor **)&(configurationDescriptorsArr), /* first full-speed configuration descriptor */ 0, /* No full-speed device qualifier descriptor */ 0, /* No full-speed other speed configuration */ 0, /* No high-speed device descriptor */ 0, /* No high-speed configuration descriptor */ 0, /* No high-speed device qualifier descriptor */ 0, /* No high-speed other speed configuration descriptor */ usb_strings_extended, ARRAY_SIZE(usb_strings_extended),/* cnt string descriptors in list */ }; /*---------------------------------------------------------------------------- * Functions *----------------------------------------------------------------------------*/ void SIMtrace_USB_Initialize(void) { unsigned int i; /* Signal USB reset by disabling the pull-up on USB D+ for at least 10 ms */ USBD_HAL_Disconnect(); USBD_HAL_Suspend(); mdelay(500); USBD_HAL_Activate(); // Get std USB driver USBDDriver *pUsbd = USBD_GetDriver(); // put device ID into USB serial number description unsigned int device_id[4]; EEFC_ReadUniqueID(device_id); char device_id_string[32 + 1]; snprintf(device_id_string, ARRAY_SIZE(device_id_string), "%08x%08x%08x%08x", device_id[0], device_id[1], device_id[2], device_id[3]); for (i = 0; i < ARRAY_SIZE(device_id_string) - 1; i++) { usb_string_serial[2 + 2 * i] = device_id_string[i]; } // put version into USB string usb_string_version[0] = USBStringDescriptor_LENGTH(ARRAY_SIZE(git_version) - 1); usb_string_version[1] = USBGenericDescriptor_STRING; for (i = 0; i < ARRAY_SIZE(git_version) - 1; i++) { usb_string_version[2 + i * 2 + 0] = git_version[i]; usb_string_version[2 + i * 2 + 1] = 0; } // fill extended USB strings for (i = 0; i < ARRAY_SIZE(usb_strings) && i < ARRAY_SIZE(usb_strings_extended); i++) { usb_strings_extended[i] = usb_strings[i]; } usb_strings_extended[SERIAL_STR] = usb_string_serial; usb_strings_extended[VERSION_CONF_STR] = usb_string_version_conf; usb_strings_extended[VERSION_STR] = usb_string_version; // Initialize standard USB driver USBDDriver_Initialize(pUsbd, &driverDescriptors, 0); // Multiple interface settings not supported USBD_Init(); USBD_Connect(); NVIC_EnableIRQ(UDP_IRQn); }