mirror of https://gerrit.osmocom.org/simtrace2
732 lines
26 KiB
C
732 lines
26 KiB
C
/* ----------------------------------------------------------------------------
|
|
* ATMEL Microcontroller Software Support
|
|
* ----------------------------------------------------------------------------
|
|
* Copyright (c) 2009, Atmel Corporation
|
|
* Copyright (c) 2018-2019, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
|
*
|
|
* 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 <cciddriverdescriptors.h>
|
|
#include <usb/common/dfu/usb_dfu.h>
|
|
#include <usb/device/dfu/dfu.h>
|
|
|
|
/*------------------------------------------------------------------------------
|
|
* 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 = 0x10,
|
|
},
|
|
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 = 0x10
|
|
},
|
|
#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 = 0x10,
|
|
},
|
|
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 = 0x10,
|
|
},
|
|
|
|
/* 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 = 0x10
|
|
},
|
|
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_Suspend();
|
|
mdelay(20);
|
|
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);
|
|
}
|