1.4.1 firmware port
Code update for 1.4.1 fw Fix PUT_DATA[serial] command
This commit is contained in:
parent
cf6e295e47
commit
81090d3f23
59
Makefile
59
Makefile
@ -1,4 +1,6 @@
|
||||
# Copyright 2017 Cedric Mesnil <cslashm@gmail.com>, Ledger SAS
|
||||
#*******************************************************************************
|
||||
# Ledger Nano S
|
||||
# (c) 2016 Ledger
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -11,43 +13,62 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#*******************************************************************************
|
||||
|
||||
|
||||
ifeq ($(BOLOS_SDK),)
|
||||
$(error Environment variable BOLOS_SDK is not set)
|
||||
endif
|
||||
include $(BOLOS_SDK)/Makefile.defines
|
||||
|
||||
APPNAME = "OpenPGP"
|
||||
APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255" --curve secp256k1 $(COMMON_LOAD_PARAMS)
|
||||
APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255'" --curve secp256k1 $(COMMON_LOAD_PARAMS)
|
||||
|
||||
APPNAME = OpenPGP
|
||||
|
||||
SPECVERSION="3.3.1"
|
||||
|
||||
APPVERSION_M=1
|
||||
APPVERSION_N=1
|
||||
APPVERSION_P=0
|
||||
|
||||
APPVERSION_P=1
|
||||
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
|
||||
SPECVERSION="3.3.1"
|
||||
ICONNAME=images/icon_pgp.gif
|
||||
|
||||
ifeq ($(TARGET_NAME),TARGET_BLUE)
|
||||
ICONNAME=images/icon_pgp_blue.gif
|
||||
else
|
||||
ICONNAME=images/icon_pgp.gif
|
||||
endif
|
||||
|
||||
DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME) SPEC_VERSION=$(SPECVERSION)
|
||||
|
||||
################
|
||||
# Default rule #
|
||||
################
|
||||
|
||||
all: default
|
||||
|
||||
############
|
||||
# Platform #
|
||||
############
|
||||
#SCRIPT_LD := script.ld
|
||||
|
||||
ifneq ($(NO_CONSENT),)
|
||||
DEFINES += NO_CONSENT
|
||||
endif
|
||||
|
||||
DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=300
|
||||
DEFINES += HAVE_BAGL HAVE_SPRINTF
|
||||
#DEFINES += HAVE_PRINTF PRINTF=screen_printf
|
||||
DEFINES += PRINTF\(...\)=
|
||||
DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=6 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
|
||||
#DEFINES += HAVE_BLE
|
||||
DEFINES += UNUSED\(x\)=\(void\)x
|
||||
DEFINES += APPVERSION=\"$(APPVERSION)\"
|
||||
DEFINES += CUSTOM_IO_APDU_BUFFER_SIZE=\(255+5+64\)
|
||||
|
||||
DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=128
|
||||
DEFINES += HAVE_BAGL HAVE_PRINTF HAVE_SPRINTF
|
||||
DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=7 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
|
||||
DEFINES += HAVE_USB_CLASS_CCID
|
||||
|
||||
DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME) SPEC_VERSION=$(SPECVERSION)
|
||||
|
||||
##############
|
||||
# Compiler #
|
||||
# Compiler #
|
||||
##############
|
||||
#GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/
|
||||
#CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin/
|
||||
@ -55,6 +76,8 @@ CC := $(CLANGPATH)clang
|
||||
|
||||
#CFLAGS += -O0 -gdwarf-2 -gstrict-dwarf
|
||||
CFLAGS += -O3 -Os
|
||||
#CFLAGS += -fno-jump-tables -fno-lookup-tables -fsave-optimization-record
|
||||
#$(info $(CFLAGS))
|
||||
|
||||
AS := $(GCCPATH)arm-none-eabi-gcc
|
||||
|
||||
@ -66,9 +89,9 @@ LDLIBS += -lm -lgcc -lc
|
||||
# import rules to compile glyphs(/pone)
|
||||
include $(BOLOS_SDK)/Makefile.glyphs
|
||||
|
||||
### computed variables
|
||||
APP_SOURCE_PATH += src
|
||||
SDK_SOURCE_PATH += lib_stusb lib_stusb_impl
|
||||
### variables processed by the common makefile.rules of the SDK to grab source files and include dirs
|
||||
APP_SOURCE_PATH += src src/lib_stusb_impl
|
||||
SDK_SOURCE_PATH += lib_stusb
|
||||
|
||||
|
||||
load: all
|
||||
@ -81,5 +104,5 @@ delete:
|
||||
include $(BOLOS_SDK)/Makefile.rules
|
||||
|
||||
#add dependency on custom makefile filename
|
||||
dep/%.d: %.c Makefile.genericwallet
|
||||
dep/%.d: %.c Makefile
|
||||
|
||||
|
@ -370,6 +370,7 @@ the reader and the delegated PIN support.
|
||||
Edit the file ~/.gnupg/scdaemon.conf and add the following lines:
|
||||
|
||||
| ``reader-port "Ledger Token [Nano S] (0001) 01 00"``
|
||||
| ``allow-admin``
|
||||
| ``enable-pinpad-varlen``
|
||||
|
||||
|
||||
|
167
script.ld
Normal file
167
script.ld
Normal file
@ -0,0 +1,167 @@
|
||||
/*******************************************************************************
|
||||
* Ledger Blue - Secure firmware
|
||||
* (c) 2016, 2017 Ledger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
********************************************************************************/
|
||||
|
||||
/**
|
||||
* Global chip memory layout and constants
|
||||
*
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
DISCARD (rwx) : ORIGIN = 0xd0000000, LENGTH = 1M
|
||||
|
||||
FLASH (rx) : ORIGIN = 0xc0d00000, LENGTH = 400K
|
||||
SRAM (rwx) : ORIGIN = 0x20001800, LENGTH = 4K
|
||||
}
|
||||
|
||||
PAGE_SIZE = 64;
|
||||
STACK_SIZE = 768;
|
||||
END_STACK = ORIGIN(SRAM) + LENGTH(SRAM);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
ENTRY(main)
|
||||
|
||||
/****************************************************************/
|
||||
/* This section locates the code in FLASH */
|
||||
/****************************************************************/
|
||||
|
||||
/** put text in Flash memory, VMA will be equal to LMA */
|
||||
.text :
|
||||
{
|
||||
/* provide start code symbol, shall be zero */
|
||||
_text = .;
|
||||
_nvram = .;
|
||||
|
||||
PROVIDE(_setjmp = setjmp); /*thanks clang*/
|
||||
|
||||
/* ensure main is always @ 0xC0D00000 */
|
||||
*(.boot*)
|
||||
|
||||
/* place the other code and rodata defined BUT nvram variables that are displaced in a r/w area */
|
||||
*(.text*)
|
||||
*(.rodata.[^UN]*) /*.data.rel.ro* not here to detect invalid PIC usage */
|
||||
*(.rodata.N[^_]*)
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
/* all code placed */
|
||||
_etext = .;
|
||||
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
|
||||
_nvram_data = .;
|
||||
|
||||
/* NVM data (ex-filesystem) */
|
||||
*(.rodata.USBD_CfgDesc)
|
||||
*(.bss.N_* .rodata.N_* .rodata.USBD_CfgDesc)
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
_install_parameters = .;
|
||||
PROVIDE(N_install_parameters = .);
|
||||
_envram = .;
|
||||
_nvram_data_size = _envram - _nvram_data;
|
||||
|
||||
} > FLASH = 0x00
|
||||
|
||||
.data (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
|
||||
/**
|
||||
* Place RAM initialized variables
|
||||
*/
|
||||
_data = .;
|
||||
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
_edata = .;
|
||||
|
||||
} > DISCARD /*> SRAM AT>FLASH = 0x00 */
|
||||
|
||||
.bss :
|
||||
{
|
||||
/**
|
||||
* Place RAM uninitialized variables
|
||||
*/
|
||||
_bss = .;
|
||||
*(.bss*)
|
||||
_ebss = .;
|
||||
|
||||
|
||||
/**
|
||||
* Reserve stack size
|
||||
*/
|
||||
. = ALIGN(4);
|
||||
app_stack_canary = .;
|
||||
PROVIDE(app_stack_canary = .);
|
||||
. += 4;
|
||||
_stack = .;
|
||||
. = _stack + STACK_SIZE;
|
||||
PROVIDE( _stack_size = STACK_SIZE );
|
||||
PROVIDE( _estack = ABSOLUTE(END_STACK) );
|
||||
|
||||
} > SRAM = 0x00
|
||||
|
||||
/****************************************************************/
|
||||
/* DEBUG */
|
||||
/****************************************************************/
|
||||
|
||||
/* remove the debugging information from the standard libraries */
|
||||
DEBUG (NOLOAD) :
|
||||
{
|
||||
libc.a ( * )
|
||||
libm.a ( * )
|
||||
libgcc.a ( * )
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
}
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
|
||||
}
|
@ -1,591 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_if.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.1
|
||||
* @date 31-January-2014
|
||||
* @brief This file provides all the functions for USB Interface for CCID
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ccid_if.h"
|
||||
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
uint8_t Ccid_BulkState;
|
||||
uint8_t ccid_card_inserted;
|
||||
uint8_t UsbIntMessageBuffer[INTR_MAX_PACKET_SIZE]; /* data buffer*/
|
||||
__IO uint8_t PrevXferComplete_IntrIn;
|
||||
usb_ccid_param_t usb_ccid_param;
|
||||
|
||||
uint8_t* pUsbMessageBuffer;
|
||||
static uint32_t UsbMessageLength;
|
||||
Ccid_SlotStatus_t Ccid_SlotStatus;
|
||||
Protocol0_DataStructure_t Protocol0_DataStructure;
|
||||
|
||||
Ccid_bulk_data_t Ccid_bulk_data;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void CCID_Response_SendData (USBD_HandleTypeDef *pdev,
|
||||
uint8_t* pbuf,
|
||||
uint16_t len);
|
||||
/* Private function ----------------------------------------------------------*/
|
||||
/**
|
||||
* @brief CCID_Init
|
||||
* Initialize the CCID USB Layer
|
||||
* @param pdev: device instance
|
||||
* @retval None
|
||||
*/
|
||||
void CCID_Init (USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
memset(&Ccid_BulkState, 0, sizeof(Ccid_BulkState));
|
||||
memset(&UsbIntMessageBuffer, 0, sizeof(UsbIntMessageBuffer));
|
||||
memset(&PrevXferComplete_IntrIn, 0, sizeof(PrevXferComplete_IntrIn));
|
||||
memset(&usb_ccid_param, 0, sizeof(usb_ccid_param));
|
||||
memset(&pUsbMessageBuffer, 0, sizeof(pUsbMessageBuffer));
|
||||
memset(&UsbMessageLength, 0, sizeof(UsbMessageLength));
|
||||
memset(&Ccid_SlotStatus, 0, sizeof(Ccid_SlotStatus));
|
||||
memset(&Protocol0_DataStructure, 0, sizeof(Protocol0_DataStructure));
|
||||
memset(&Ccid_bulk_data, 0, sizeof(Ccid_bulk_data));
|
||||
ccid_card_inserted = 0;
|
||||
/* CCID Related Initialization */
|
||||
CCID_SetIntrTransferStatus(1); /* Transfer Complete Status */
|
||||
CCID_UpdSlotChange(1);
|
||||
SC_InitParams();
|
||||
|
||||
/* Prepare Out endpoint to receive 1st packet */
|
||||
Ccid_BulkState = CCID_STATE_IDLE;
|
||||
USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE);
|
||||
|
||||
// send the smartcard as inserted state at boot time
|
||||
io_usb_ccid_set_card_inserted(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_DeInit
|
||||
* Uninitialize the CCID Machine
|
||||
* @param pdev: device instance
|
||||
* @retval None
|
||||
*/
|
||||
void CCID_DeInit (USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
Ccid_BulkState = CCID_STATE_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_Message_In
|
||||
* Handle Bulk IN & Intr IN data stage
|
||||
* @param pdev: device instance
|
||||
* @param uint8_t epnum: endpoint index
|
||||
* @retval None
|
||||
*/
|
||||
void CCID_BulkMessage_In (USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum)
|
||||
{
|
||||
if (epnum == (CCID_BULK_IN_EP & 0x7F))
|
||||
{/* Filter the epnum by masking with 0x7f (mask of IN Direction) */
|
||||
|
||||
/*************** Handle Bulk Transfer IN data completion *****************/
|
||||
|
||||
switch (Ccid_BulkState)
|
||||
{
|
||||
case CCID_STATE_SEND_RESP: {
|
||||
unsigned int remLen = UsbMessageLength;
|
||||
|
||||
// advance with acknowledged sent chunk
|
||||
pUsbMessageBuffer += MIN(CCID_BULK_EPIN_SIZE, UsbMessageLength);
|
||||
UsbMessageLength -= MIN(CCID_BULK_EPIN_SIZE, UsbMessageLength);
|
||||
|
||||
// if remaining length is > EPIN_SIZE: send a filled bulk packet
|
||||
if (UsbMessageLength >= CCID_BULK_EPIN_SIZE) {
|
||||
CCID_Response_SendData(pdev, pUsbMessageBuffer,
|
||||
// use the header declared size packet must be well formed
|
||||
CCID_BULK_EPIN_SIZE);
|
||||
}
|
||||
|
||||
// if remaining length is 0; send an empty packet and prepare to receive a new command
|
||||
else if (UsbMessageLength == 0 && remLen == CCID_BULK_EPIN_SIZE) {
|
||||
CCID_Response_SendData(pdev, pUsbMessageBuffer,
|
||||
// use the header declared size packet must be well formed
|
||||
0);
|
||||
goto last_xfer; // won't wait ack to avoid missing a command
|
||||
}
|
||||
// else if no more data, then last packet sent, go back to idle (done on transfer ack)
|
||||
else if (UsbMessageLength == 0) { // robustness only
|
||||
last_xfer:
|
||||
Ccid_BulkState = CCID_STATE_IDLE;
|
||||
|
||||
/* Prepare EP to Receive First Cmd */
|
||||
USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE);
|
||||
}
|
||||
|
||||
// if remaining length is < EPIN_SIZE: send packet and prepare to receive a new command
|
||||
else if (UsbMessageLength < CCID_BULK_EPIN_SIZE) {
|
||||
CCID_Response_SendData(pdev, pUsbMessageBuffer,
|
||||
// use the header declared size packet must be well formed
|
||||
UsbMessageLength);
|
||||
goto last_xfer; // won't wait ack to avoid missing a command
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (epnum == (CCID_INTR_IN_EP & 0x7F))
|
||||
{
|
||||
/* Filter the epnum by masking with 0x7f (mask of IN Direction) */
|
||||
CCID_SetIntrTransferStatus(1); /* Transfer Complete Status */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_BulkMessage_Out
|
||||
* Proccess CCID OUT data
|
||||
* @param pdev: device instance
|
||||
* @param uint8_t epnum: endpoint index
|
||||
* @retval None
|
||||
*/
|
||||
void CCID_BulkMessage_Out (USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum, uint8_t* buffer, uint16_t dataLen)
|
||||
{
|
||||
|
||||
switch (Ccid_BulkState)
|
||||
{
|
||||
case CCID_STATE_IDLE:
|
||||
if (dataLen == 0x00)
|
||||
{ /* Zero Length Packet Received */
|
||||
Ccid_BulkState = CCID_STATE_IDLE;
|
||||
}
|
||||
else if (dataLen >= CCID_MESSAGE_HEADER_SIZE)
|
||||
{
|
||||
UsbMessageLength = dataLen; /* Store for future use */
|
||||
|
||||
/* Expected Data Length Packet Received */
|
||||
pUsbMessageBuffer = (uint8_t*) &Ccid_bulk_data;
|
||||
|
||||
/* Fill CCID_BulkOut Data Buffer from USB Buffer */
|
||||
memmove(pUsbMessageBuffer, buffer, dataLen);
|
||||
|
||||
/*
|
||||
Refer : 6 CCID Messages
|
||||
The response messages always contain the exact same slot number,
|
||||
and sequence number fields from the header that was contained in
|
||||
the Bulk-OUT command message.
|
||||
*/
|
||||
Ccid_bulk_data.header.bulkin.bSlot = Ccid_bulk_data.header.bulkout.bSlot;
|
||||
Ccid_bulk_data.header.bulkin.bSeq = Ccid_bulk_data.header.bulkout.bSeq;
|
||||
|
||||
if (dataLen < CCID_BULK_EPOUT_SIZE)
|
||||
{/* Short message, less than the EP Out Size, execute the command,
|
||||
if parameter like dwLength is too big, the appropriate command will
|
||||
give an error */
|
||||
CCID_CmdDecode(pdev);
|
||||
}
|
||||
else
|
||||
{ /* Long message, receive additional data with command */
|
||||
/* (u8dataLen == CCID_BULK_EPOUT_SIZE) */
|
||||
|
||||
if (Ccid_bulk_data.header.bulkout.dwLength > ABDATA_SIZE)
|
||||
{ /* Check if length of data to be sent by host is > buffer size */
|
||||
|
||||
/* Too long data received.... Error ! */
|
||||
Ccid_BulkState = CCID_STATE_UNCORRECT_LENGTH;
|
||||
}
|
||||
|
||||
else
|
||||
{ /* Expect more data on OUT EP */
|
||||
Ccid_BulkState = CCID_STATE_RECEIVE_DATA;
|
||||
pUsbMessageBuffer += dataLen; /* Point to new offset */
|
||||
|
||||
/* Prepare EP to Receive next Cmd */
|
||||
USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE);
|
||||
|
||||
} /* if (dataLen == CCID_BULK_EPOUT_SIZE) ends */
|
||||
} /* if (dataLen >= CCID_BULK_EPOUT_SIZE) ends */
|
||||
} /* if (dataLen >= CCID_MESSAGE_HEADER_SIZE) ends */
|
||||
break;
|
||||
|
||||
case CCID_STATE_RECEIVE_DATA:
|
||||
|
||||
UsbMessageLength += dataLen;
|
||||
|
||||
if (dataLen < CCID_BULK_EPOUT_SIZE)
|
||||
{/* Short message, less than the EP Out Size, execute the command,
|
||||
if parameter like dwLength is too big, the appropriate command will
|
||||
give an error */
|
||||
|
||||
/* Full command is received, process the Command */
|
||||
memmove(pUsbMessageBuffer, buffer, dataLen);
|
||||
CCID_CmdDecode(pdev);
|
||||
}
|
||||
else if (dataLen == CCID_BULK_EPOUT_SIZE)
|
||||
{
|
||||
if (UsbMessageLength < (Ccid_bulk_data.header.bulkout.dwLength + CCID_CMD_HEADER_SIZE))
|
||||
{
|
||||
memmove(pUsbMessageBuffer, buffer, dataLen);
|
||||
pUsbMessageBuffer += dataLen;
|
||||
/* Increment the pointer to receive more data */
|
||||
|
||||
/* Prepare EP to Receive next Cmd */
|
||||
USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE);
|
||||
}
|
||||
else if (UsbMessageLength == (Ccid_bulk_data.header.bulkout.dwLength + CCID_CMD_HEADER_SIZE))
|
||||
{
|
||||
/* Full command is received, process the Command */
|
||||
memmove(pUsbMessageBuffer, buffer, dataLen);
|
||||
CCID_CmdDecode(pdev);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Too long data received.... Error ! */
|
||||
Ccid_BulkState = CCID_STATE_UNCORRECT_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CCID_STATE_UNCORRECT_LENGTH:
|
||||
Ccid_BulkState = CCID_STATE_IDLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CCID_Send_Reply(USBD_HandleTypeDef *pdev) {
|
||||
/********** Decide for all commands ***************/
|
||||
if (Ccid_BulkState == CCID_STATE_SEND_RESP)
|
||||
{
|
||||
UsbMessageLength = Ccid_bulk_data.header.bulkin.dwLength+CCID_MESSAGE_HEADER_SIZE; /* Store for future use */
|
||||
|
||||
/* Expected Data Length Packet Received */
|
||||
pUsbMessageBuffer = (uint8_t*) &Ccid_bulk_data;
|
||||
|
||||
CCID_Response_SendData(pdev, pUsbMessageBuffer,
|
||||
// use the header declared size packet must be well formed
|
||||
MIN(CCID_BULK_EPIN_SIZE, UsbMessageLength));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_CmdDecode
|
||||
* Parse the commands and Proccess command
|
||||
* @param pdev: device instance
|
||||
* @retval None
|
||||
*/
|
||||
void CCID_CmdDecode(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
uint8_t errorCode;
|
||||
|
||||
switch (Ccid_bulk_data.header.bulkout.bMessageType)
|
||||
{
|
||||
case PC_TO_RDR_ICCPOWERON:
|
||||
errorCode = PC_to_RDR_IccPowerOn();
|
||||
RDR_to_PC_DataBlock(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_ICCPOWEROFF:
|
||||
errorCode = PC_to_RDR_IccPowerOff();
|
||||
RDR_to_PC_SlotStatus(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_GETSLOTSTATUS:
|
||||
errorCode = PC_to_RDR_GetSlotStatus();
|
||||
RDR_to_PC_SlotStatus(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_XFRBLOCK:
|
||||
errorCode = PC_to_RDR_XfrBlock();
|
||||
// asynchronous // RDR_to_PC_DataBlock(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_GETPARAMETERS:
|
||||
errorCode = PC_to_RDR_GetParameters();
|
||||
RDR_to_PC_Parameters(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_RESETPARAMETERS:
|
||||
errorCode = PC_to_RDR_ResetParameters();
|
||||
RDR_to_PC_Parameters(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_SETPARAMETERS:
|
||||
errorCode = PC_to_RDR_SetParameters();
|
||||
RDR_to_PC_Parameters(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_ESCAPE:
|
||||
errorCode = PC_to_RDR_Escape();
|
||||
RDR_to_PC_Escape(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_ICCCLOCK:
|
||||
errorCode = PC_to_RDR_IccClock();
|
||||
RDR_to_PC_SlotStatus(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_ABORT:
|
||||
errorCode = PC_to_RDR_Abort();
|
||||
RDR_to_PC_SlotStatus(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_T0APDU:
|
||||
errorCode = PC_TO_RDR_T0Apdu();
|
||||
RDR_to_PC_SlotStatus(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_MECHANICAL:
|
||||
errorCode = PC_TO_RDR_Mechanical();
|
||||
RDR_to_PC_SlotStatus(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY:
|
||||
errorCode = PC_TO_RDR_SetDataRateAndClockFrequency();
|
||||
RDR_to_PC_DataRateAndClockFrequency(errorCode);
|
||||
break;
|
||||
case PC_TO_RDR_SECURE:
|
||||
errorCode = PC_TO_RDR_Secure();
|
||||
// asynchronous // RDR_to_PC_DataBlock(errorCode);
|
||||
break;
|
||||
default:
|
||||
RDR_to_PC_SlotStatus(SLOTERROR_CMD_NOT_SUPPORTED);
|
||||
break;
|
||||
}
|
||||
|
||||
CCID_Send_Reply(pdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transfer_Data_Request
|
||||
* Prepare the request response to be sent to the host
|
||||
* @param uint8_t* dataPointer: Pointer to the data buffer to send
|
||||
* @param uint16_t dataLen : number of bytes to send
|
||||
* @retval None
|
||||
*/
|
||||
void Transfer_Data_Request(void)
|
||||
{
|
||||
/********** Update Global Variables ***************/
|
||||
Ccid_BulkState = CCID_STATE_SEND_RESP;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief CCID_Response_SendData
|
||||
* Send the data on bulk-in EP
|
||||
* @param pdev: device instance
|
||||
* @param uint8_t* buf: pointer to data buffer
|
||||
* @param uint16_t len: Data Length
|
||||
* @retval None
|
||||
*/
|
||||
static void CCID_Response_SendData(USBD_HandleTypeDef *pdev,
|
||||
uint8_t* buf,
|
||||
uint16_t len)
|
||||
{
|
||||
// don't ask the MCU to perform bulk split, we could quickly get into a buffer overflow
|
||||
if (len > CCID_BULK_EPIN_SIZE) {
|
||||
THROW(EXCEPTION_IO_OVERFLOW);
|
||||
}
|
||||
|
||||
G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE;
|
||||
G_io_seproxyhal_spi_buffer[1] = (3+len)>>8;
|
||||
G_io_seproxyhal_spi_buffer[2] = (3+len);
|
||||
G_io_seproxyhal_spi_buffer[3] = CCID_BULK_IN_EP;
|
||||
G_io_seproxyhal_spi_buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN;
|
||||
G_io_seproxyhal_spi_buffer[5] = len;
|
||||
io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 6);
|
||||
io_seproxyhal_spi_send(buf, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_IntMessage
|
||||
* Send the Interrupt-IN data to the host
|
||||
* @param pdev: device instance
|
||||
* @retval None
|
||||
*/
|
||||
void CCID_IntMessage(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Check if there us change in Smartcard Slot status */
|
||||
if ( CCID_IsSlotStatusChange() && CCID_IsIntrTransferComplete() )
|
||||
{
|
||||
/* Check Slot Status is changed. Card is Removed/ Fitted */
|
||||
RDR_to_PC_NotifySlotChange();
|
||||
|
||||
CCID_SetIntrTransferStatus(0); /* Reset the Status */
|
||||
CCID_UpdSlotChange(0); /* Reset the Status of Slot Change */
|
||||
|
||||
G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE;
|
||||
G_io_seproxyhal_spi_buffer[1] = (3+2)>>8;
|
||||
G_io_seproxyhal_spi_buffer[2] = (3+2);
|
||||
G_io_seproxyhal_spi_buffer[3] = CCID_INTR_IN_EP;
|
||||
G_io_seproxyhal_spi_buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN;
|
||||
G_io_seproxyhal_spi_buffer[5] = 2;
|
||||
io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 6);
|
||||
io_seproxyhal_spi_send(UsbIntMessageBuffer, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_IsIntrTransferComplete
|
||||
* Provides the status of previous Interrupt transfer status
|
||||
* @param None
|
||||
* @retval uint8_t PrevXferComplete_IntrIn: Value of the previous transfer status
|
||||
*/
|
||||
uint8_t CCID_IsIntrTransferComplete (void)
|
||||
{
|
||||
return PrevXferComplete_IntrIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_IsIntrTransferComplete
|
||||
* Set the value of the Interrupt transfer status
|
||||
* @param uint8_t xfer_Status: Value of the Interrupt transfer status to set
|
||||
* @retval None
|
||||
*/
|
||||
void CCID_SetIntrTransferStatus (uint8_t xfer_Status)
|
||||
{
|
||||
PrevXferComplete_IntrIn = xfer_Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t SC_Detect(void) {
|
||||
return ccid_card_inserted;
|
||||
}
|
||||
|
||||
void SC_Poweroff(void) {
|
||||
// nothing to do
|
||||
|
||||
}
|
||||
|
||||
void SC_InitParams (void) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
uint8_t SC_SetParams (Protocol0_DataStructure_t* pt0) {
|
||||
return SLOT_NO_ERROR;
|
||||
}
|
||||
|
||||
uint8_t SC_ExecuteEscape (uint8_t* escapePtr, uint32_t escapeLen,
|
||||
uint8_t* responseBuff,
|
||||
uint16_t* responseLen) {
|
||||
io_seproxyhal_se_reset();
|
||||
}
|
||||
uint8_t SC_SetClock (uint8_t bClockCommand) {
|
||||
return SLOT_NO_ERROR;
|
||||
}
|
||||
uint8_t SC_Request_GetClockFrequencies(uint8_t* pbuf, uint16_t* len);
|
||||
uint8_t SC_Request_GetDataRates(uint8_t* pbuf, uint16_t* len);
|
||||
uint8_t SC_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse,
|
||||
uint8_t bClassEnvelope) {
|
||||
return SLOTERROR_CMD_NOT_SUPPORTED;
|
||||
}
|
||||
uint8_t SC_Mechanical(uint8_t bFunction) {
|
||||
return SLOTERROR_CMD_NOT_SUPPORTED;
|
||||
}
|
||||
uint8_t SC_SetDataRateAndClockFrequency(uint32_t dwClockFrequency,
|
||||
uint32_t dwDataRate) {
|
||||
return SLOT_NO_ERROR;
|
||||
}
|
||||
|
||||
uint8_t SC_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter,
|
||||
uint8_t* pbuf, uint32_t* returnLen ) {
|
||||
// return SLOTERROR_CMD_NOT_SUPPORTED;
|
||||
uint16_t ret_len,off;
|
||||
switch(pbuf[0]) {
|
||||
case 0: // verify pin
|
||||
//ret_len = dwLength - 15;
|
||||
ret_len = 5;
|
||||
off = 15;
|
||||
break;
|
||||
|
||||
case 1: // modify pin
|
||||
switch(pbuf[11]) {
|
||||
case 3:
|
||||
off = 20;
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
off = 19;
|
||||
break;
|
||||
default:
|
||||
off = 18;
|
||||
break;
|
||||
}
|
||||
//ret_len = dwLength - off;
|
||||
ret_len = 5;
|
||||
break;
|
||||
|
||||
default: // unsupported
|
||||
Ccid_bulk_data.header.bulkin.dwLength = 0;
|
||||
RDR_to_PC_DataBlock(SLOTERROR_CMD_NOT_SUPPORTED);
|
||||
CCID_Send_Reply(&USBD_Device);
|
||||
return SLOTERROR_CMD_NOT_SUPPORTED;
|
||||
}
|
||||
pbuf += off;
|
||||
pbuf[0] = 0xEF;
|
||||
return SC_XferBlock(pbuf, ret_len, &ret_len);
|
||||
}
|
||||
|
||||
// prepare the apdu to be processed by the application
|
||||
uint8_t SC_XferBlock (uint8_t* ptrBlock, uint32_t blockLen, uint16_t* expectedLen) {
|
||||
// check for overflow
|
||||
if (blockLen > IO_APDU_BUFFER_SIZE) {
|
||||
return SLOTERROR_BAD_LENTGH;
|
||||
}
|
||||
|
||||
// copy received apdu
|
||||
memmove(G_io_apdu_buffer, ptrBlock, blockLen);
|
||||
G_io_apdu_length = blockLen;
|
||||
G_io_apdu_media = IO_APDU_MEDIA_USB_CCID; // for application code
|
||||
G_io_apdu_state = APDU_USB_CCID; // for next call to io_exchange
|
||||
|
||||
return SLOT_NO_ERROR;
|
||||
}
|
||||
|
||||
void io_usb_ccid_reply(unsigned char* buffer, unsigned short length) {
|
||||
// avoid memory overflow
|
||||
if (length > sizeof(Ccid_bulk_data.abData)) {
|
||||
THROW(EXCEPTION_IO_OVERFLOW);
|
||||
}
|
||||
// copy the responde apdu
|
||||
memmove(Ccid_bulk_data.abData, buffer, length);
|
||||
Ccid_bulk_data.header.bulkin.dwLength = length;
|
||||
// forge reply
|
||||
RDR_to_PC_DataBlock(SLOT_NO_ERROR);
|
||||
|
||||
// start sending rpely
|
||||
CCID_Send_Reply(&USBD_Device);
|
||||
}
|
||||
// ask for power on
|
||||
void io_usb_ccid_set_card_inserted(unsigned int inserted) {
|
||||
ccid_card_inserted = inserted;
|
||||
CCID_UpdSlotChange(1);
|
||||
CCID_IntMessage(&USBD_Device);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // HAVE_USB_CLASS_CCID
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -1,209 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_if.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.1
|
||||
* @date 31-January-2014
|
||||
* @brief This file provides all the functions prototypes for USB CCID
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CCID_IF_H
|
||||
#define __USBD_CCID_IF_H
|
||||
|
||||
#include "usbd_core.h"
|
||||
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
|
||||
|
||||
/* Exported defines ----------------------------------------------------------*/
|
||||
/* Bulk-only Command Block Wrapper */
|
||||
#define ABDATA_SIZE 261
|
||||
#define CCID_CMD_HEADER_SIZE 10
|
||||
#define CCID_RESPONSE_HEADER_SIZE 10
|
||||
|
||||
|
||||
#define CCID_INT_BUFF_SIZ 2
|
||||
|
||||
#define CARD_SLOT_FITTED 1
|
||||
#define CARD_SLOT_REMOVED 0
|
||||
|
||||
#define BULK_MAX_PACKET_SIZE 0x40
|
||||
#define CCID_IN_EP_SIZE 0x40
|
||||
#define INTR_MAX_PACKET_SIZE 8
|
||||
#define CCID_MESSAGE_HEADER_SIZE 10
|
||||
#define CCID_NUMBER_OF_SLOTS 1
|
||||
/* Number of SLOTS. For single card, this value is 1 */
|
||||
|
||||
/* Following Parameters used in PC_to_RDR_IccPowerOn */
|
||||
#define VOLTAGE_SELECTION_AUTOMATIC 0xFF
|
||||
#define VOLTAGE_SELECTION_3V 0x02
|
||||
#define VOLTAGE_SELECTION_5V 0x01
|
||||
#define VOLTAGE_SELECTION_1V8 0x03
|
||||
|
||||
#define PC_TO_RDR_ICCPOWERON 0x62
|
||||
#define PC_TO_RDR_ICCPOWEROFF 0x63
|
||||
#define PC_TO_RDR_GETSLOTSTATUS 0x65
|
||||
#define PC_TO_RDR_XFRBLOCK 0x6F
|
||||
#define PC_TO_RDR_GETPARAMETERS 0x6C
|
||||
#define PC_TO_RDR_RESETPARAMETERS 0x6D
|
||||
#define PC_TO_RDR_SETPARAMETERS 0x61
|
||||
#define PC_TO_RDR_ESCAPE 0x6B
|
||||
#define PC_TO_RDR_ICCCLOCK 0x6E
|
||||
#define PC_TO_RDR_T0APDU 0x6A
|
||||
#define PC_TO_RDR_SECURE 0x69
|
||||
#define PC_TO_RDR_MECHANICAL 0x71
|
||||
#define PC_TO_RDR_ABORT 0x72
|
||||
#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73
|
||||
|
||||
#define RDR_TO_PC_DATABLOCK 0x80
|
||||
#define RDR_TO_PC_SLOTSTATUS 0x81
|
||||
#define RDR_TO_PC_PARAMETERS 0x82
|
||||
#define RDR_TO_PC_ESCAPE 0x83
|
||||
#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84
|
||||
|
||||
#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50
|
||||
#define RDR_TO_PC_HARDWAREERROR 0x51
|
||||
|
||||
#define OFFSET_INT_BMESSAGETYPE 0
|
||||
#define OFFSET_INT_BMSLOTICCSTATE 1
|
||||
#define SLOT_ICC_PRESENT 0x01
|
||||
/* LSb : (0b = no ICC present, 1b = ICC present) */
|
||||
|
||||
#define SLOT_ICC_CHANGE 0x02 /* MSb : (0b = no change, 1b = change) */
|
||||
/*****************************************************************************/
|
||||
/*********************** CCID Bulk Transfer State machine ********************/
|
||||
/*****************************************************************************/
|
||||
#define CCID_STATE_IDLE 0 /* Idle state */
|
||||
#define CCID_STATE_DATA_OUT 1 /* Data Out state */
|
||||
#define CCID_STATE_RECEIVE_DATA 2
|
||||
#define CCID_STATE_SEND_RESP 3
|
||||
#define CCID_STATE_DATAIN 4
|
||||
#define CCID_STATE_UNCORRECT_LENGTH 5
|
||||
|
||||
#define DIR_IN 0
|
||||
#define DIR_OUT 1
|
||||
#define BOTH_DIR 2
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
#pragma pack(1)
|
||||
union {
|
||||
#pragma pack(1)
|
||||
struct {
|
||||
uint8_t bMessageType; /* Offset = 0*/
|
||||
uint32_t dwLength; /* Offset = 1, The length field (dwLength) is the length
|
||||
of the message not including the 10-byte header.*/
|
||||
uint8_t bSlot; /* Offset = 5*/
|
||||
uint8_t bSeq; /* Offset = 6*/
|
||||
uint8_t bSpecific_0; /* Offset = 7*/
|
||||
uint8_t bSpecific_1; /* Offset = 8*/
|
||||
uint8_t bSpecific_2; /* Offset = 9*/
|
||||
} bulkout;
|
||||
#pragma pack(1)
|
||||
struct {
|
||||
uint8_t bMessageType; /* Offset = 0*/
|
||||
uint32_t dwLength; /* Offset = 1*/
|
||||
uint8_t bSlot; /* Offset = 5, Same as Bulk-OUT message */
|
||||
uint8_t bSeq; /* Offset = 6, Same as Bulk-OUT message */
|
||||
uint8_t bStatus; /* Offset = 7, Slot status as defined in § 6.2.6*/
|
||||
uint8_t bError; /* Offset = 8, Slot error as defined in § 6.2.6*/
|
||||
uint8_t bSpecific; /* Offset = 9*/
|
||||
} bulkin;
|
||||
} header;
|
||||
uint8_t abData [ABDATA_SIZE]; /* Offset = 10, For reference, the absolute
|
||||
maximum block size for a TPDU T=0 block is 260 bytes
|
||||
(5 bytes command; 255 bytes data),
|
||||
or for a TPDU T=1 block is 259 bytes,
|
||||
or for a short APDU T=1 block is 261 bytes,
|
||||
or for an extended APDU T=1 block is 65544 bytes.*/
|
||||
} Ccid_bulk_data_t;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
#pragma pack()
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint8_t SlotStatus;
|
||||
__IO uint8_t SlotStatusChange;
|
||||
} Ccid_SlotStatus_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint8_t bAbortRequestFlag;
|
||||
__IO uint8_t bSeq;
|
||||
__IO uint8_t bSlot;
|
||||
} usb_ccid_param_t;
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _Protocol0_DataStructure_t
|
||||
{
|
||||
uint8_t bmFindexDindex;
|
||||
uint8_t bmTCCKST0;
|
||||
uint8_t bGuardTimeT0;
|
||||
uint8_t bWaitingIntegerT0;
|
||||
uint8_t bClockStop;
|
||||
} Protocol0_DataStructure_t;
|
||||
#pragma pack()
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ccid_core.h"
|
||||
|
||||
extern usb_ccid_param_t usb_ccid_param;
|
||||
extern Ccid_bulk_data_t Ccid_bulk_data; /* Buffer for the Out Data */
|
||||
extern Ccid_SlotStatus_t Ccid_SlotStatus;
|
||||
extern uint8_t UsbIntMessageBuffer[];
|
||||
|
||||
extern Protocol0_DataStructure_t Protocol0_DataStructure;
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void CCID_BulkMessage_In (USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum);
|
||||
|
||||
void CCID_BulkMessage_Out (USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum, uint8_t* buffer, uint16_t buflen);
|
||||
|
||||
void CCID_ReceiveCmdHeader(uint8_t* pDst, uint8_t u8length);
|
||||
void CCID_CmdDecode(USBD_HandleTypeDef *pdev);
|
||||
|
||||
void CCID_IntMessage(USBD_HandleTypeDef *pdev);
|
||||
void CCID_Init(USBD_HandleTypeDef *pdev);
|
||||
void CCID_DeInit(USBD_HandleTypeDef *pdev);
|
||||
|
||||
uint8_t CCID_IsIntrTransferComplete(void);
|
||||
void CCID_SetIntrTransferStatus (uint8_t );
|
||||
void Transfer_Data_Request(void);
|
||||
void Set_CSW (uint8_t CSW_Status, uint8_t Send_Permission);
|
||||
|
||||
void io_usb_ccid_set_card_inserted(unsigned int inserted);
|
||||
|
||||
#endif // HAVE_USB_CLASS_CCID
|
||||
|
||||
#endif /* __USBD_CCID_IF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -16,6 +16,8 @@
|
||||
#ifndef GPG_API_H
|
||||
#define GPG_API_H
|
||||
|
||||
void USBD_CCID_activate_pinpad(int enabled);
|
||||
|
||||
int gpg_oid2curve(unsigned char* oid, unsigned int len);
|
||||
|
||||
void gpg_init(void);
|
||||
|
@ -282,7 +282,7 @@ int gpg_apdu_put_data(unsigned int ref) {
|
||||
if (G_gpg_vstate.io_length != 4) {
|
||||
THROW(SW_WRONG_LENGTH);
|
||||
}
|
||||
G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset] &= ~0x07;
|
||||
G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset+3] &= ~0x07;
|
||||
nvm_write(&N_gpg_pstate->AID[10], &G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset], 4);
|
||||
break;
|
||||
|
||||
|
@ -18,7 +18,8 @@
|
||||
#include "gpg_types.h"
|
||||
#include "gpg_api.h"
|
||||
#include "gpg_vars.h"
|
||||
#include "usbd_ccid_impl.h"
|
||||
#include "usbd_impl.h"
|
||||
|
||||
#define SHORT(x) ((x)>>8)&0xFF, (x)&0xFF
|
||||
/* ----------------------*/
|
||||
/* -- A Kind of Magic -- */
|
||||
@ -322,3 +323,15 @@ int gpg_install(unsigned char app_state) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define USBD_OFFSET_CfgDesc_bPINSupport (sizeof(USBD_CfgDesc)-16)
|
||||
void USBD_CCID_activate_pinpad(int enabled) {
|
||||
unsigned short length;
|
||||
uint8_t *cfgDesc;
|
||||
unsigned char e;
|
||||
e = enabled?3:0;
|
||||
length = 0;
|
||||
cfgDesc = USBD_GetCfgDesc_impl(&length);
|
||||
nvm_write(cfgDesc+(length-16), &e,1);
|
||||
}
|
@ -165,7 +165,7 @@ __attribute__((section(".boot"))) int main(void) {
|
||||
//start communication with MCU
|
||||
io_seproxyhal_init();
|
||||
|
||||
USB_CCID_power(1);
|
||||
USB_power(1);
|
||||
io_usb_ccid_set_card_inserted(1);
|
||||
|
||||
|
||||
|
@ -97,7 +97,8 @@ static int gpg_sign(gpg_key_t *sigkey) {
|
||||
CX_RND_TRNG,
|
||||
CX_NONE,
|
||||
G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length,
|
||||
G_gpg_vstate.work.io_buffer);
|
||||
G_gpg_vstate.work.io_buffer,
|
||||
NULL);
|
||||
//reencode r,s in MPI format
|
||||
gpg_io_discard(0);
|
||||
|
||||
@ -116,11 +117,12 @@ static int gpg_sign(gpg_key_t *sigkey) {
|
||||
rs += 2;
|
||||
}
|
||||
} else{
|
||||
sz = cx_eddsa_sign(key, NULL,
|
||||
sz = cx_eddsa_sign(key,
|
||||
CX_NONE,
|
||||
CX_SHA512,
|
||||
G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length,
|
||||
G_gpg_vstate.work.io_buffer+128);
|
||||
CX_SHA512, G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length,
|
||||
NULL, 0,
|
||||
G_gpg_vstate.work.io_buffer+128,
|
||||
NULL);
|
||||
gpg_io_discard(0);
|
||||
gpg_io_insert(G_gpg_vstate.work.io_buffer+128, sz);
|
||||
}
|
||||
|
32
src/lib_stusb_impl/usbd_ccid_impl.h
Normal file
32
src/lib_stusb_impl/usbd_ccid_impl.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef USBD_CCID_IMPL_H
|
||||
#define USBD_CCID_IMPL_H
|
||||
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
|
||||
// ================================================
|
||||
// CCID
|
||||
|
||||
#define TPDU_EXCHANGE 0x01
|
||||
#define SHORT_APDU_EXCHANGE 0x02
|
||||
#define EXTENDED_APDU_EXCHANGE 0x04
|
||||
#define CHARACTER_EXCHANGE 0x00
|
||||
|
||||
#define EXCHANGE_LEVEL_FEATURE SHORT_APDU_EXCHANGE
|
||||
|
||||
#define CCID_INTF 2
|
||||
#define CCID_BULK_IN_EP 0x83
|
||||
#define CCID_BULK_EPIN_SIZE 64
|
||||
#define CCID_BULK_OUT_EP 0x03
|
||||
#define CCID_BULK_EPOUT_SIZE 64
|
||||
|
||||
#ifdef HAVE_CCID_INTERRUPT
|
||||
#define CCID_INTR_IN_EP 0x84
|
||||
#define CCID_INTR_EPIN_SIZE 16
|
||||
#endif // HAVE_CCID_INTERRUPT
|
||||
|
||||
#define IO_CCID_DATA_BUFFER_SIZE IO_APDU_BUFFER_SIZE
|
||||
#define G_io_ccid_data_buffer G_io_apdu_buffer
|
||||
|
||||
#endif // HAVE_USB_CLASS_CCID
|
||||
|
||||
#endif // USBD_CCID_IMPL_H
|
29
src/lib_stusb_impl/usbd_hid_impl.h
Normal file
29
src/lib_stusb_impl/usbd_hid_impl.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef USBD_HID_IMPL_H
|
||||
#define USBD_HID_IMPL_H
|
||||
|
||||
// ================================================
|
||||
// HIDGEN
|
||||
|
||||
#define HID_INTF 0
|
||||
|
||||
#define HID_EPIN_ADDR 0x82
|
||||
#define HID_EPIN_SIZE 0x40
|
||||
|
||||
#define HID_EPOUT_ADDR 0x02
|
||||
#define HID_EPOUT_SIZE 0x40
|
||||
|
||||
#ifdef HAVE_IO_U2F
|
||||
// ================================================
|
||||
// HID U2F
|
||||
|
||||
#define U2F_INTF 1
|
||||
|
||||
#define U2F_EPIN_ADDR 0x81
|
||||
#define U2F_EPIN_SIZE 0x40
|
||||
|
||||
#define U2F_EPOUT_ADDR 0x01
|
||||
#define U2F_EPOUT_SIZE 0x40
|
||||
#endif // HAVE_IO_U2F
|
||||
|
||||
#endif // USBD_HID_IMPL_H
|
||||
|
913
src/lib_stusb_impl/usbd_impl.c
Normal file
913
src/lib_stusb_impl/usbd_impl.c
Normal file
@ -0,0 +1,913 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_hid.c
|
||||
* @author MCD Application Team
|
||||
* @version V2.2.0
|
||||
* @date 13-June-2014
|
||||
* @brief This file provides the HID core functions.
|
||||
*
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* HID Class Description
|
||||
* ===================================================================
|
||||
* This module manages the HID class V1.11 following the "Device Class Definition
|
||||
* for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - The Boot Interface Subclass
|
||||
* - Usage Page : Generic Desktop
|
||||
* - Usage : Vendor
|
||||
* - Collection : Application
|
||||
*
|
||||
* @note In HS mode and when the DMA is used, all variables and data structures
|
||||
* dealing with the DMA during the transaction process should be 32-bit aligned.
|
||||
*
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#include "os.h"
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbd_hid.h"
|
||||
#include "usbd_hid_impl.h"
|
||||
|
||||
#include "usbd_ctlreq.h"
|
||||
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_conf.h"
|
||||
|
||||
#include "usbd_def.h"
|
||||
#include "os_io_seproxyhal.h"
|
||||
|
||||
#ifdef HAVE_IO_U2F
|
||||
#include "u2f_transport.h"
|
||||
#include "u2f_impl.h"
|
||||
#endif // HAVE_IO_U2F
|
||||
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
#include "usbd_ccid_core.h"
|
||||
#endif // HAVE_USB_CLASS_CCID
|
||||
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_HID
|
||||
* @brief usbd core module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_HID_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_HID_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_HID_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @defgroup USBD_HID_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_HID_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define HID_EPIN_ADDR 0x82
|
||||
#define HID_EPIN_SIZE 0x40
|
||||
|
||||
#define HID_EPOUT_ADDR 0x02
|
||||
#define HID_EPOUT_SIZE 0x40
|
||||
|
||||
#define USBD_LANGID_STRING 0x409
|
||||
|
||||
#ifdef HAVE_VID_PID_PROBER
|
||||
#define USBD_VID 0x2581
|
||||
#define USBD_PID 0xf1d1
|
||||
#else
|
||||
#define USBD_VID 0x2C97
|
||||
#if defined(TARGET_BLUE) // blue
|
||||
#define USBD_PID 0x0000
|
||||
static const uint8_t const USBD_PRODUCT_FS_STRING[] = {
|
||||
4*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'B', 0,
|
||||
'l', 0,
|
||||
'u', 0,
|
||||
'e', 0,
|
||||
};
|
||||
|
||||
#elif defined(TARGET_NANOS) // nano s
|
||||
#define USBD_PID 0x0001
|
||||
static const uint8_t const USBD_PRODUCT_FS_STRING[] = {
|
||||
6*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'N', 0,
|
||||
'a', 0,
|
||||
'n', 0,
|
||||
'o', 0,
|
||||
' ', 0,
|
||||
'S', 0,
|
||||
};
|
||||
#elif defined(TARGET_ARAMIS) // aramis
|
||||
#define USBD_PID 0x0002
|
||||
static const uint8_t const USBD_PRODUCT_FS_STRING[] = {
|
||||
6*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'A', 0,
|
||||
'r', 0,
|
||||
'a', 0,
|
||||
'm', 0,
|
||||
'i', 0,
|
||||
's', 0,
|
||||
};
|
||||
#else
|
||||
#error unknown TARGET_ID
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t const USBD_LangIDDesc[]=
|
||||
{
|
||||
USB_LEN_LANGID_STR_DESC,
|
||||
USB_DESC_TYPE_STRING,
|
||||
LOBYTE(USBD_LANGID_STRING),
|
||||
HIBYTE(USBD_LANGID_STRING),
|
||||
};
|
||||
|
||||
static const uint8_t const USB_SERIAL_STRING[] =
|
||||
{
|
||||
4*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'0', 0,
|
||||
'0', 0,
|
||||
'0', 0,
|
||||
'1', 0,
|
||||
};
|
||||
|
||||
static const uint8_t const USBD_MANUFACTURER_STRING[] = {
|
||||
6*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'L', 0,
|
||||
'e', 0,
|
||||
'd', 0,
|
||||
'g', 0,
|
||||
'e', 0,
|
||||
'r', 0,
|
||||
};
|
||||
|
||||
#define USBD_INTERFACE_FS_STRING USBD_PRODUCT_FS_STRING
|
||||
#define USBD_CONFIGURATION_FS_STRING USBD_PRODUCT_FS_STRING
|
||||
|
||||
static const uint8_t const HID_ReportDesc[] = {
|
||||
0x06, 0xA0, 0xFF, // Usage page (vendor defined)
|
||||
0x09, 0x01, // Usage ID (vendor defined)
|
||||
0xA1, 0x01, // Collection (application)
|
||||
|
||||
// The Input report
|
||||
0x09, 0x03, // Usage ID - vendor defined
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x75, 0x08, // Report Size (8 bits)
|
||||
0x95, HID_EPIN_SIZE, // Report Count (64 fields)
|
||||
0x81, 0x08, // Input (Data, Variable, Absolute)
|
||||
|
||||
// The Output report
|
||||
0x09, 0x04, // Usage ID - vendor defined
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x75, 0x08, // Report Size (8 bits)
|
||||
0x95, HID_EPOUT_SIZE, // Report Count (64 fields)
|
||||
0x91, 0x08, // Output (Data, Variable, Absolute)
|
||||
0xC0
|
||||
};
|
||||
|
||||
#ifdef HAVE_IO_U2F
|
||||
static const uint8_t const HID_ReportDesc_fido[] = {
|
||||
0x06, 0xD0, 0xF1, // Usage page (vendor defined)
|
||||
0x09, 0x01, // Usage ID (vendor defined)
|
||||
0xA1, 0x01, // Collection (application)
|
||||
|
||||
// The Input report
|
||||
0x09, 0x03, // Usage ID - vendor defined
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x75, 0x08, // Report Size (8 bits)
|
||||
0x95, U2F_EPIN_SIZE, // Report Count (64 fields)
|
||||
0x81, 0x08, // Input (Data, Variable, Absolute)
|
||||
|
||||
// The Output report
|
||||
0x09, 0x04, // Usage ID - vendor defined
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x75, 0x08, // Report Size (8 bits)
|
||||
0x95, U2F_EPOUT_SIZE, // Report Count (64 fields)
|
||||
0x91, 0x08, // Output (Data, Variable, Absolute)
|
||||
0xC0
|
||||
};
|
||||
#endif // HAVE_IO_U2F
|
||||
|
||||
#define ARRAY_U2LE(l) (l)&0xFF, (l)>>8
|
||||
|
||||
/* USB HID device Configuration Descriptor */
|
||||
static __ALIGN_BEGIN const uint8_t const N_USBD_CfgDesc[] __ALIGN_END =
|
||||
{
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
ARRAY_U2LE(0x9 /* wTotalLength: Bytes returned */
|
||||
+0x9+0x9+0x7+0x7
|
||||
#ifdef HAVE_IO_U2F
|
||||
+0x9+0x9+0x7+0x7
|
||||
#endif // HAVE_IO_U2F
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
+0x9+0x36+0x7+0x7
|
||||
#endif // HAVE_USB_CLASS_CCID
|
||||
),
|
||||
1
|
||||
#ifdef HAVE_IO_U2F
|
||||
+1
|
||||
#endif // HAVE_IO_U2F
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
+1
|
||||
#endif // HAVE_USB_CLASS_CCID
|
||||
, /*bNumInterfaces */
|
||||
0x01, /*bConfigurationValue: Configuration value*/
|
||||
USBD_IDX_PRODUCT_STR, /*iConfiguration: Index of string descriptor describing the configuration*/
|
||||
0xC0, /*bmAttributes: bus powered */
|
||||
0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
|
||||
|
||||
/* HIDGEN ################################################################################################ */
|
||||
|
||||
/************** Descriptor of KBD HID interface ****************/
|
||||
0x09, /*bLength: Interface Descriptor size*/
|
||||
USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
|
||||
HID_INTF, /*bInterfaceNumber: Number of Interface*/
|
||||
0x00, /*bAlternateSetting: Alternate setting*/
|
||||
0x02, /*bNumEndpoints*/
|
||||
0x03, /*bInterfaceClass: HID*/
|
||||
0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
|
||||
0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
|
||||
USBD_IDX_PRODUCT_STR, /*iInterface: Index of string descriptor*/
|
||||
|
||||
/******************** Descriptor of HID *************************/
|
||||
0x09, /*bLength: HID Descriptor size*/
|
||||
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
||||
0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/
|
||||
0x01,
|
||||
0x00, /*bCountryCode: Hardware target country*/
|
||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||
0x22, /*bDescriptorType*/
|
||||
sizeof(HID_ReportDesc),/*wItemLength: Total length of Report descriptor*/
|
||||
0x00,
|
||||
|
||||
/******************** Descriptor of Custom HID endpoints ********************/
|
||||
0x07, /*bLength: Endpoint Descriptor size*/
|
||||
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
|
||||
HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
|
||||
0x03, /*bmAttributes: Interrupt endpoint*/
|
||||
HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */
|
||||
0x00,
|
||||
0x01, /*bInterval: Polling Interval (20 ms)*/
|
||||
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */
|
||||
0x00,
|
||||
0x01, /* bInterval: Polling Interval (20 ms) */
|
||||
|
||||
#ifdef HAVE_IO_U2F
|
||||
/* HID FIDO ################################################################################################ */
|
||||
|
||||
/************** Descriptor of KBD HID interface ****************/
|
||||
0x09, /*bLength: Interface Descriptor size*/
|
||||
USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
|
||||
U2F_INTF, /*bInterfaceNumber: Number of Interface*/
|
||||
0x00, /*bAlternateSetting: Alternate setting*/
|
||||
0x02, /*bNumEndpoints*/
|
||||
0x03, /*bInterfaceClass: HID*/
|
||||
0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
|
||||
0x01, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
|
||||
USBD_IDX_PRODUCT_STR, /*iInterface: Index of string descriptor*/
|
||||
|
||||
/******************** Descriptor of HID *************************/
|
||||
0x09, /*bLength: HID Descriptor size*/
|
||||
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
||||
0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/
|
||||
0x01,
|
||||
0x21, /*bCountryCode: Hardware target country*/ // 0x21: US, 0x08: FR, 0x0D: ISO Intl
|
||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||
0x22, /*bDescriptorType*/
|
||||
sizeof(HID_ReportDesc_fido),/*wItemLength: Total length of Report descriptor*/
|
||||
0x00,
|
||||
/******************** Descriptor of Custom HID endpoints ********************/
|
||||
0x07, /*bLength: Endpoint Descriptor size*/
|
||||
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
|
||||
U2F_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
|
||||
0x03, /*bmAttributes: Interrupt endpoint*/
|
||||
U2F_EPIN_SIZE, /*wMaxPacketSize: */
|
||||
0x00,
|
||||
0x01, /*bInterval: Polling Interval */
|
||||
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
U2F_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
U2F_EPOUT_SIZE, /* wMaxPacketSize: */
|
||||
0x00,
|
||||
0x01,/* bInterval: Polling Interval */
|
||||
#endif // HAVE_IO_U2F
|
||||
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
/* CCID ################################################################################################ */
|
||||
|
||||
/******************** CCID **** interface ********************/
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
0x04, /* bDescriptorType: */
|
||||
CCID_INTF, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints: endpoints used */
|
||||
0x0B, /* bInterfaceClass: user's interface for CCID */
|
||||
0x00, /* bInterfaceSubClass : */
|
||||
0x00, /* nInterfaceProtocol : None */
|
||||
0x05, /* iInterface: */
|
||||
|
||||
/******************* CCID class descriptor ********************/
|
||||
0x36, /* bLength: CCID Descriptor size */
|
||||
0x21, /* bDescriptorType: Functional Descriptor type. */
|
||||
0x10, /* bcdCCID(LSB): CCID Class Spec release number (1.00) */
|
||||
0x01, /* bcdCCID(MSB) */
|
||||
|
||||
0x00, /* bMaxSlotIndex :highest available slot on this device */
|
||||
0x03, /* bVoltageSupport: bit Wise OR for 01h-5.0V 02h-3.0V
|
||||
04h 1.8V*/
|
||||
|
||||
0x01,0x00,0x00,0x00, /* dwProtocols: 0001h = Protocol T=0 */
|
||||
0x10,0x0E,0x00,0x00, /* dwDefaultClock: 3.6Mhz = 3600kHz = 0x0E10,
|
||||
for 4 Mhz the value is (0x00000FA0) :
|
||||
This is used in ETU and waiting time calculations*/
|
||||
0x10,0x0E,0x00,0x00, /* dwMaximumClock: Maximum supported ICC clock frequency
|
||||
in KHz. So, 3.6Mhz = 3600kHz = 0x0E10,
|
||||
4 Mhz (0x00000FA0) : */
|
||||
0x00, /* bNumClockSupported : no setting from PC
|
||||
If the value is 00h, the
|
||||
supported clock frequencies are assumed to be the
|
||||
default clock frequency defined by dwDefaultClock
|
||||
and the maximum clock frequency defined by
|
||||
dwMaximumClock */
|
||||
|
||||
0xCD,0x25,0x00,0x00, /* dwDataRate: Default ICC I/O data rate in bps
|
||||
9677 bps = 0x25CD
|
||||
for example 10752 bps (0x00002A00) */
|
||||
|
||||
0xCD,0x25,0x00,0x00, /* dwMaxDataRate: Maximum supported ICC I/O data
|
||||
rate in bps */
|
||||
0x00, /* bNumDataRatesSupported :
|
||||
The number of data rates that are supported by the CCID
|
||||
If the value is 00h, all data rates between the default
|
||||
data rate dwDataRate and the maximum data rate
|
||||
dwMaxDataRate are supported.
|
||||
Dont support GET_CLOCK_FREQUENCIES
|
||||
*/
|
||||
//46
|
||||
0x00,0x00,0x00,0x00, /* dwMaxIFSD: 0 (T=0 only) */
|
||||
0x00,0x00,0x00,0x00, /* dwSynchProtocols */
|
||||
0x00,0x00,0x00,0x00, /* dwMechanical: no special characteristics */
|
||||
|
||||
0xBA, 0x06, 0x02, 0x00,
|
||||
//0x38,0x00,EXCHANGE_LEVEL_FEATURE,0x00,
|
||||
/* dwFeatures: clk, baud rate, voltage : automatic */
|
||||
/* 00000008h Automatic ICC voltage selection
|
||||
00000010h Automatic ICC clock frequency change
|
||||
00000020h Automatic baud rate change according to
|
||||
active parameters provided by the Host or self
|
||||
determined 00000100h CCID can set
|
||||
ICC in clock stop mode
|
||||
|
||||
Only one of the following values may be present to
|
||||
select a level of exchange:
|
||||
00010000h TPDU level exchanges with CCID
|
||||
00020000h Short APDU level exchange with CCID
|
||||
00040000h Short and Extended APDU level exchange
|
||||
If none of those values : character level of exchange*/
|
||||
0x0F,0x01,0x00,0x00, /* dwMaxCCIDMessageLength: Maximum block size + header*/
|
||||
/* 261 + 10 */
|
||||
|
||||
0x00, /* bClassGetResponse*/
|
||||
0x00, /* bClassEnvelope */
|
||||
0x00,0x00, /* wLcdLayout : 0000h no LCD. */
|
||||
0x00, /* bPINSupport : no PIN verif and modif */
|
||||
0x01, /* bMaxCCIDBusySlots */
|
||||
|
||||
/******************** CCID Endpoints ********************/
|
||||
0x07, /*Endpoint descriptor length = 7*/
|
||||
0x05, /*Endpoint descriptor type */
|
||||
CCID_BULK_IN_EP, /*Endpoint address (IN, address 1) */
|
||||
0x02, /*Bulk endpoint type */
|
||||
LOBYTE(CCID_BULK_EPIN_SIZE),
|
||||
HIBYTE(CCID_BULK_EPIN_SIZE),
|
||||
0x00, /*Polling interval in milliseconds */
|
||||
|
||||
0x07, /*Endpoint descriptor length = 7 */
|
||||
0x05, /*Endpoint descriptor type */
|
||||
CCID_BULK_OUT_EP, /*Endpoint address (OUT, address 1) */
|
||||
0x02, /*Bulk endpoint type */
|
||||
LOBYTE(CCID_BULK_EPOUT_SIZE),
|
||||
HIBYTE(CCID_BULK_EPOUT_SIZE),
|
||||
0x00, /*Polling interval in milliseconds*/
|
||||
#endif // HAVE_USB_CLASS_CCID
|
||||
} ;
|
||||
|
||||
#ifdef HAVE_IO_U2F
|
||||
/* USB HID device Configuration Descriptor */
|
||||
__ALIGN_BEGIN const uint8_t const USBD_HID_Desc_fido[] __ALIGN_END =
|
||||
{
|
||||
/******************** Descriptor of HID *************************/
|
||||
0x09, /*bLength: HID Descriptor size*/
|
||||
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
||||
0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/
|
||||
0x01,
|
||||
0x21, /*bCountryCode: Hardware target country*/ // 0x21: US, 0x08: FR, 0x0D: ISO Intl
|
||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||
0x22, /*bDescriptorType*/
|
||||
sizeof(HID_ReportDesc_fido),/*wItemLength: Total length of Report descriptor*/
|
||||
0x00,
|
||||
};
|
||||
#endif // HAVE_IO_U2F
|
||||
|
||||
/* USB HID device Configuration Descriptor */
|
||||
__ALIGN_BEGIN const uint8_t const USBD_HID_Desc[] __ALIGN_END =
|
||||
{
|
||||
/* 18 */
|
||||
0x09, /*bLength: HID Descriptor size*/
|
||||
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
||||
0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/
|
||||
0x01,
|
||||
0x00, /*bCountryCode: Hardware target country*/
|
||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||
0x22, /*bDescriptorType*/
|
||||
sizeof(HID_ReportDesc),/*wItemLength: Total length of Report descriptor*/
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static __ALIGN_BEGIN const uint8_t const USBD_DeviceQualifierDesc[] __ALIGN_END =
|
||||
{
|
||||
USB_LEN_DEV_QUALIFIER_DESC,
|
||||
USB_DESC_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t const USBD_DeviceDesc[]= {
|
||||
0x12, /* bLength */
|
||||
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
|
||||
0x00, /* bcdUSB */
|
||||
0x02,
|
||||
0x00, /* bDeviceClass */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
USB_MAX_EP0_SIZE, /* bMaxPacketSize */
|
||||
LOBYTE(USBD_VID), /* idVendor */
|
||||
HIBYTE(USBD_VID), /* idVendor */
|
||||
LOBYTE(USBD_PID), /* idVendor */
|
||||
HIBYTE(USBD_PID), /* idVendor */
|
||||
0x00, /* bcdDevice rel. 2.00 */
|
||||
0x02,
|
||||
USBD_IDX_MFC_STR, /* Index of manufacturer string */
|
||||
USBD_IDX_PRODUCT_STR, /* Index of product string */
|
||||
USBD_IDX_SERIAL_STR, /* Index of serial number string */
|
||||
1 /* bNumConfigurations */
|
||||
}; /* USB_DeviceDescriptor */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns the device descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_DeviceDesc);
|
||||
return (uint8_t*)USBD_DeviceDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the LangID string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_LangIDDesc);
|
||||
return (uint8_t*)USBD_LangIDDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the product string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_PRODUCT_FS_STRING);
|
||||
return (uint8_t*)USBD_PRODUCT_FS_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the manufacturer string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_MANUFACTURER_STRING);
|
||||
return (uint8_t*)USBD_MANUFACTURER_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the serial number string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USB_SERIAL_STRING);
|
||||
return (uint8_t*)USB_SERIAL_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the configuration string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_CONFIGURATION_FS_STRING);
|
||||
return (uint8_t*)USBD_CONFIGURATION_FS_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the interface string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_INTERFACE_FS_STRING);
|
||||
return (uint8_t*)USBD_INTERFACE_FS_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_GetDeviceQualifierDesc_impl (uint16_t *length)
|
||||
{
|
||||
*length = sizeof (USBD_DeviceQualifierDesc);
|
||||
return (uint8_t*)USBD_DeviceQualifierDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_GetCfgDesc
|
||||
* return configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_GetCfgDesc_impl (uint16_t *length)
|
||||
{
|
||||
*length = sizeof (N_USBD_CfgDesc);
|
||||
return (uint8_t*)N_USBD_CfgDesc;
|
||||
}
|
||||
|
||||
uint8_t* USBD_HID_GetHidDescriptor_impl(uint16_t* len) {
|
||||
switch (USBD_Device.request.wIndex&0xFF) {
|
||||
#ifdef HAVE_IO_U2F
|
||||
case U2F_INTF:
|
||||
*len = sizeof(USBD_HID_Desc_fido);
|
||||
return (uint8_t*)USBD_HID_Desc_fido;
|
||||
#endif // HAVE_IO_U2F
|
||||
case HID_INTF:
|
||||
*len = sizeof(USBD_HID_Desc);
|
||||
return (uint8_t*)USBD_HID_Desc;
|
||||
}
|
||||
*len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* USBD_HID_GetReportDescriptor_impl(uint16_t* len) {
|
||||
switch (USBD_Device.request.wIndex&0xFF) {
|
||||
#ifdef HAVE_IO_U2F
|
||||
case U2F_INTF:
|
||||
|
||||
// very dirty work due to lack of callback when USB_HID_Init is called
|
||||
USBD_LL_OpenEP(&USBD_Device,
|
||||
U2F_EPIN_ADDR,
|
||||
USBD_EP_TYPE_INTR,
|
||||
U2F_EPIN_SIZE);
|
||||
|
||||
USBD_LL_OpenEP(&USBD_Device,
|
||||
U2F_EPOUT_ADDR,
|
||||
USBD_EP_TYPE_INTR,
|
||||
U2F_EPOUT_SIZE);
|
||||
|
||||
/* Prepare Out endpoint to receive 1st packet */
|
||||
USBD_LL_PrepareReceive(&USBD_Device, U2F_EPOUT_ADDR, U2F_EPOUT_SIZE);
|
||||
|
||||
|
||||
*len = sizeof(HID_ReportDesc_fido);
|
||||
return (uint8_t*)HID_ReportDesc_fido;
|
||||
#endif // HAVE_IO_U2F
|
||||
case HID_INTF:
|
||||
*len = sizeof(HID_ReportDesc);
|
||||
return (uint8_t*)HID_ReportDesc;
|
||||
}
|
||||
*len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_DataOut
|
||||
* handle data OUT Stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*
|
||||
* This function is the default behavior for our implementation when data are sent over the out hid endpoint
|
||||
*/
|
||||
extern volatile unsigned short G_io_apdu_length;
|
||||
|
||||
#ifdef HAVE_IO_U2F
|
||||
uint8_t USBD_U2F_DataIn_impl (USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
// only the data hid endpoint will receive data
|
||||
switch (epnum) {
|
||||
// FIDO endpoint
|
||||
case (U2F_EPIN_ADDR&0x7F):
|
||||
// advance the u2f sending machine state
|
||||
u2f_transport_sent(&G_io_u2f, U2F_MEDIA_USB);
|
||||
break;
|
||||
}
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
uint8_t USBD_U2F_DataOut_impl (USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum, uint8_t* buffer)
|
||||
{
|
||||
switch (epnum) {
|
||||
// FIDO endpoint
|
||||
case (U2F_EPOUT_ADDR&0x7F):
|
||||
USBD_LL_PrepareReceive(pdev, U2F_EPOUT_ADDR , U2F_EPOUT_SIZE);
|
||||
u2f_transport_received(&G_io_u2f, buffer, io_seproxyhal_get_ep_rx_size(U2F_EPOUT_ADDR), U2F_MEDIA_USB);
|
||||
break;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
#endif // HAVE_IO_U2F
|
||||
|
||||
uint8_t USBD_HID_DataOut_impl (USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum, uint8_t* buffer)
|
||||
{
|
||||
// only the data hid endpoint will receive data
|
||||
switch (epnum) {
|
||||
|
||||
// HID gen endpoint
|
||||
case (HID_EPOUT_ADDR&0x7F):
|
||||
// prepare receiving the next chunk (masked time)
|
||||
USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR , HID_EPOUT_SIZE);
|
||||
|
||||
// avoid troubles when an apdu has not been replied yet
|
||||
if (G_io_apdu_media == IO_APDU_MEDIA_NONE) {
|
||||
// add to the hid transport
|
||||
switch(io_usb_hid_receive(io_usb_send_apdu_data, buffer, io_seproxyhal_get_ep_rx_size(HID_EPOUT_ADDR))) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case IO_USB_APDU_RECEIVED:
|
||||
G_io_apdu_media = IO_APDU_MEDIA_USB_HID; // for application code
|
||||
G_io_apdu_state = APDU_USB_HID; // for next call to io_exchange
|
||||
G_io_apdu_length = G_io_usb_hid_total_length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/** @defgroup USBD_HID_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
// note: how core lib usb calls the hid class
|
||||
const USBD_DescriptorsTypeDef const HID_Desc = {
|
||||
USBD_DeviceDescriptor,
|
||||
USBD_LangIDStrDescriptor,
|
||||
USBD_ManufacturerStrDescriptor,
|
||||
USBD_ProductStrDescriptor,
|
||||
USBD_SerialStrDescriptor,
|
||||
USBD_ConfigStrDescriptor,
|
||||
USBD_InterfaceStrDescriptor,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#ifdef HAVE_IO_U2F
|
||||
static const USBD_ClassTypeDef const USBD_U2F =
|
||||
{
|
||||
USBD_HID_Init,
|
||||
USBD_HID_DeInit,
|
||||
USBD_HID_Setup,
|
||||
NULL, /*EP0_TxSent*/
|
||||
NULL, /*EP0_RxReady*/ /* STATUS STAGE IN */
|
||||
USBD_U2F_DataIn_impl, /*DataIn*/
|
||||
USBD_U2F_DataOut_impl, /*DataOut*/
|
||||
NULL, /*SOF */
|
||||
NULL,
|
||||
NULL,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetDeviceQualifierDesc_impl,
|
||||
};
|
||||
#endif // HAVE_IO_U2F
|
||||
|
||||
static const USBD_ClassTypeDef const USBD_HID =
|
||||
{
|
||||
USBD_HID_Init,
|
||||
USBD_HID_DeInit,
|
||||
USBD_HID_Setup,
|
||||
NULL, /*EP0_TxSent*/
|
||||
NULL, /*EP0_RxReady*/ /* STATUS STAGE IN */
|
||||
NULL, /*DataIn*/
|
||||
USBD_HID_DataOut_impl, /*DataOut*/
|
||||
NULL, /*SOF */
|
||||
NULL,
|
||||
NULL,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetDeviceQualifierDesc_impl,
|
||||
};
|
||||
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
static const USBD_ClassTypeDef USBD_CCID =
|
||||
{
|
||||
USBD_CCID_Init,
|
||||
USBD_CCID_DeInit,
|
||||
USBD_CCID_Setup,
|
||||
NULL, /*EP0_TxSent*/
|
||||
NULL, /*EP0_RxReady*/
|
||||
USBD_CCID_DataIn,
|
||||
USBD_CCID_DataOut,
|
||||
NULL, /*SOF */
|
||||
NULL, /*ISOIn*/
|
||||
NULL, /*ISOOut*/
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetDeviceQualifierDesc_impl,
|
||||
};
|
||||
|
||||
uint8_t SC_AnswerToReset (uint8_t voltage, uint8_t* atr_buffer) {
|
||||
UNUSED(voltage);
|
||||
// return the atr length
|
||||
atr_buffer[0] = 0x3B;
|
||||
atr_buffer[1] = 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
void SC_Poweroff(void) {
|
||||
// nothing to do ?
|
||||
}
|
||||
|
||||
uint8_t SC_ExecuteEscape (uint8_t* escapePtr, uint32_t escapeLen,
|
||||
uint8_t* responseBuff,
|
||||
uint16_t* responseLen) {
|
||||
UNUSED(escapePtr);
|
||||
UNUSED(escapeLen);
|
||||
UNUSED(responseBuff);
|
||||
UNUSED(responseLen);
|
||||
// nothing to do ?
|
||||
return 0;
|
||||
}
|
||||
#endif // HAVE_USB_CLASS_CCID
|
||||
|
||||
void USB_power(unsigned char enabled) {
|
||||
os_memset(&USBD_Device, 0, sizeof(USBD_Device));
|
||||
|
||||
if (enabled) {
|
||||
os_memset(&USBD_Device, 0, sizeof(USBD_Device));
|
||||
/* Init Device Library */
|
||||
USBD_Init(&USBD_Device, (USBD_DescriptorsTypeDef*)&HID_Desc, 0);
|
||||
|
||||
/* Register the HID class */
|
||||
USBD_RegisterClassForInterface(HID_INTF, &USBD_Device, (USBD_ClassTypeDef*)&USBD_HID);
|
||||
#ifdef HAVE_IO_U2F
|
||||
USBD_RegisterClassForInterface(U2F_INTF, &USBD_Device, (USBD_ClassTypeDef*)&USBD_U2F);
|
||||
// initialize the U2F tunnel transport
|
||||
u2f_transport_init(&G_io_u2f, G_io_apdu_buffer, IO_APDU_BUFFER_SIZE);
|
||||
#endif // HAVE_IO_U2F
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
USBD_RegisterClassForInterface(CCID_INTF, &USBD_Device, (USBD_ClassTypeDef*)&USBD_CCID);
|
||||
#endif // HAVE_USB_CLASS_CCID
|
||||
|
||||
|
||||
/* Start Device Process */
|
||||
USBD_Start(&USBD_Device);
|
||||
}
|
||||
else {
|
||||
USBD_DeInit(&USBD_Device);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
7
src/lib_stusb_impl/usbd_impl.h
Normal file
7
src/lib_stusb_impl/usbd_impl.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef USBD_IMPL_H
|
||||
#define USBD_IMPL_H
|
||||
|
||||
|
||||
uint8_t *USBD_GetCfgDesc_impl (uint16_t *length);
|
||||
|
||||
#endif //USBD_IMPL_H
|
@ -1,463 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_core.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.1
|
||||
* @date 31-January-2014
|
||||
* @brief This file provides all the CCID core functions.
|
||||
*
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* CCID Class Description
|
||||
* ===================================================================
|
||||
* This module manages the Specification for Integrated Circuit(s)
|
||||
* Cards Interface Revision 1.1
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - Bulk Transfers
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ccid_core.h"
|
||||
|
||||
#ifdef HAVE_USB_CLASS_CCID
|
||||
|
||||
#define USBD_LANGID_STRING 0x409
|
||||
|
||||
#define USBD_VID 0x2C97
|
||||
#if TARGET_ID == 0x31000002 // blue
|
||||
#define USBD_PID 0x0000
|
||||
static const uint8_t const USBD_PRODUCT_FS_STRING[] = {
|
||||
4*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'B', 0,
|
||||
'l', 0,
|
||||
'u', 0,
|
||||
'e', 0,
|
||||
};
|
||||
|
||||
#elif TARGET_ID == 0x31100002 // nano s
|
||||
#define USBD_PID 0x0001
|
||||
static const uint8_t const USBD_PRODUCT_FS_STRING[] = {
|
||||
6*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'N', 0,
|
||||
'a', 0,
|
||||
'n', 0,
|
||||
'o', 0,
|
||||
' ', 0,
|
||||
'S', 0,
|
||||
};
|
||||
#elif TARGET_ID == 0x31200002 // aramis
|
||||
#define USBD_PID 0x0002
|
||||
static const uint8_t const USBD_PRODUCT_FS_STRING[] = {
|
||||
6*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'A', 0,
|
||||
'r', 0,
|
||||
'a', 0,
|
||||
'm', 0,
|
||||
'i', 0,
|
||||
's', 0,
|
||||
};
|
||||
#else
|
||||
#error unknown TARGET_ID
|
||||
#endif
|
||||
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static __ALIGN_BEGIN const uint8_t const USBD_DeviceQualifierDesc[] __ALIGN_END =
|
||||
{
|
||||
USB_LEN_DEV_QUALIFIER_DESC,
|
||||
USB_DESC_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t const USBD_LangIDDesc[]=
|
||||
{
|
||||
USB_LEN_LANGID_STR_DESC,
|
||||
USB_DESC_TYPE_STRING,
|
||||
LOBYTE(USBD_LANGID_STRING),
|
||||
HIBYTE(USBD_LANGID_STRING),
|
||||
};
|
||||
|
||||
static const uint8_t const USB_SERIAL_STRING[] =
|
||||
{
|
||||
4*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'0', 0,
|
||||
'0', 0,
|
||||
'0', 0,
|
||||
'1', 0,
|
||||
};
|
||||
|
||||
static const uint8_t const USBD_MANUFACTURER_STRING[] = {
|
||||
6*2+2,
|
||||
USB_DESC_TYPE_STRING,
|
||||
'L', 0,
|
||||
'e', 0,
|
||||
'd', 0,
|
||||
'g', 0,
|
||||
'e', 0,
|
||||
'r', 0,
|
||||
};
|
||||
|
||||
#define USBD_INTERFACE_FS_STRING USBD_PRODUCT_FS_STRING
|
||||
#define USBD_CONFIGURATION_FS_STRING USBD_PRODUCT_FS_STRING
|
||||
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t const USBD_DeviceDesc[]= {
|
||||
0x12, /* bLength */
|
||||
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
|
||||
0x00, /* bcdUSB */
|
||||
0x02,
|
||||
0x00, /* bDeviceClass */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
USB_MAX_EP0_SIZE, /* bMaxPacketSize */
|
||||
LOBYTE(USBD_VID), /* idVendor */
|
||||
HIBYTE(USBD_VID), /* idVendor */
|
||||
LOBYTE(USBD_PID), /* idVendor */
|
||||
HIBYTE(USBD_PID), /* idVendor */
|
||||
0x00, /* bcdDevice rel. 2.00 */
|
||||
0x02,
|
||||
USBD_IDX_MFC_STR, /* Index of manufacturer string */
|
||||
USBD_IDX_PRODUCT_STR, /* Index of product string */
|
||||
USBD_IDX_SERIAL_STR, /* Index of serial number string */
|
||||
USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */
|
||||
}; /* USB_DeviceDescriptor */
|
||||
|
||||
|
||||
/* USB Mass storage device Configuration Descriptor */
|
||||
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
|
||||
#define USBD_OFFSET_CfgDesc_bPINSupport 70
|
||||
const uint8_t N_USBD_CfgDesc[] =
|
||||
{
|
||||
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
0x9+0x9+0x36+0x7+0x7+0x7,
|
||||
|
||||
0x00,
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: */
|
||||
0x04, /* iConfiguration: */
|
||||
0x80, /*bmAttributes: bus powered */
|
||||
0x32, /* MaxPower 100 mA */
|
||||
|
||||
/******************** CCID **** interface ********************/
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
0x04, /* bDescriptorType: */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x03, /* bNumEndpoints: 3 endpoints used */
|
||||
0x0B, /* bInterfaceClass: user's interface for CCID */
|
||||
0x00, /* bInterfaceSubClass : */
|
||||
0x00, /* nInterfaceProtocol : None */
|
||||
0x05, /* iInterface: */
|
||||
|
||||
/******************* CCID class descriptor ********************/
|
||||
0x36, /* bLength: CCID Descriptor size */
|
||||
0x21, /* bDescriptorType: Functional Descriptor type. */
|
||||
0x10, /* bcdCCID(LSB): CCID Class Spec release number (1.00) */
|
||||
0x01, /* bcdCCID(MSB) */
|
||||
|
||||
0x00, /* bMaxSlotIndex :highest available slot on this device */
|
||||
0x03, /* bVoltageSupport: bit Wise OR for 01h-5.0V 02h-3.0V
|
||||
04h 1.8V*/
|
||||
|
||||
0x01,0x00,0x00,0x00, /* dwProtocols: 0001h = Protocol T=0 */
|
||||
0x10,0x0E,0x00,0x00, /* dwDefaultClock: 3.6Mhz = 3600kHz = 0x0E10,
|
||||
for 4 Mhz the value is (0x00000FA0) :
|
||||
This is used in ETU and waiting time calculations*/
|
||||
0x10,0x0E,0x00,0x00, /* dwMaximumClock: Maximum supported ICC clock frequency
|
||||
in KHz. So, 3.6Mhz = 3600kHz = 0x0E10,
|
||||
4 Mhz (0x00000FA0) : */
|
||||
0x00, /* bNumClockSupported : no setting from PC
|
||||
If the value is 00h, the
|
||||
supported clock frequencies are assumed to be the
|
||||
default clock frequency defined by dwDefaultClock
|
||||
and the maximum clock frequency defined by
|
||||
dwMaximumClock */
|
||||
|
||||
0xCD,0x25,0x00,0x00, /* dwDataRate: Default ICC I/O data rate in bps
|
||||
9677 bps = 0x25CD
|
||||
for example 10752 bps (0x00002A00) */
|
||||
|
||||
0xCD,0x25,0x00,0x00, /* dwMaxDataRate: Maximum supported ICC I/O data
|
||||
rate in bps */
|
||||
0x00, /* bNumDataRatesSupported :
|
||||
The number of data rates that are supported by the CCID
|
||||
If the value is 00h, all data rates between the default
|
||||
data rate dwDataRate and the maximum data rate
|
||||
dwMaxDataRate are supported.
|
||||
Dont support GET_CLOCK_FREQUENCIES
|
||||
*/
|
||||
//46
|
||||
0x00,0x00,0x00,0x00, /* dwMaxIFSD: 0 (T=0 only) */
|
||||
0x00,0x00,0x00,0x00, /* dwSynchProtocols */
|
||||
0x00,0x00,0x00,0x00, /* dwMechanical: no special characteristics */
|
||||
|
||||
0x38,0x00,EXCHANGE_LEVEL_FEATURE,0x00,
|
||||
/* dwFeatures: clk, baud rate, voltage : automatic */
|
||||
/* 00000008h Automatic ICC voltage selection
|
||||
00000010h Automatic ICC clock frequency change
|
||||
00000020h Automatic baud rate change according to
|
||||
active parameters provided by the Host or self
|
||||
determined 00000100h CCID can set
|
||||
ICC in clock stop mode
|
||||
|
||||
Only one of the following values may be present to
|
||||
select a level of exchange:
|
||||
00010000h TPDU level exchanges with CCID
|
||||
00020000h Short APDU level exchange with CCID
|
||||
00040000h Short and Extended APDU level exchange
|
||||
If none of those values : character level of exchange*/
|
||||
#if 1
|
||||
0x0F,0x01,0x00,0x00, /* dwMaxCCIDMessageLength: Maximum block size + header*/
|
||||
/* 261 + 10 */
|
||||
#else
|
||||
0xF8,0x00,0x00,0x00, /* dwMaxCCIDMessageLength: Maximum block size + header*/
|
||||
/* EEh + 10 */
|
||||
#endif
|
||||
0x00, /* bClassGetResponse*/
|
||||
0x00, /* bClassEnvelope */
|
||||
0x00,0x00, /* wLcdLayout : 0000h no LCD. */
|
||||
0x03, /* bPINSupport : no PIN verif and modif */ //<= offset: 70
|
||||
0x01, /* bMaxCCIDBusySlots */
|
||||
|
||||
//72
|
||||
/******************** CCID Endpoints ********************/
|
||||
0x07, /*Endpoint descriptor length = 7*/
|
||||
0x05, /*Endpoint descriptor type */
|
||||
CCID_BULK_IN_EP, /*Endpoint address (IN, address 1) */
|
||||
0x02, /*Bulk endpoint type */
|
||||
LOBYTE(CCID_BULK_EPIN_SIZE),
|
||||
HIBYTE(CCID_BULK_EPIN_SIZE),
|
||||
0x00, /*Polling interval in milliseconds */
|
||||
|
||||
0x07, /*Endpoint descriptor length = 7 */
|
||||
0x05, /*Endpoint descriptor type */
|
||||
CCID_BULK_OUT_EP, /*Endpoint address (OUT, address 1) */
|
||||
0x02, /*Bulk endpoint type */
|
||||
LOBYTE(CCID_BULK_EPOUT_SIZE),
|
||||
HIBYTE(CCID_BULK_EPOUT_SIZE),
|
||||
0x00, /*Polling interval in milliseconds*/
|
||||
|
||||
|
||||
0x07, /*bLength: Endpoint Descriptor size*/
|
||||
0x05, /*bDescriptorType:*/
|
||||
CCID_INTR_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
LOBYTE(CCID_INTR_EPIN_SIZE),
|
||||
HIBYTE(CCID_INTR_EPIN_SIZE),
|
||||
0x18 /*Polling interval in milliseconds */
|
||||
};
|
||||
|
||||
|
||||
|
||||
static uint8_t *USBD_GetCfgDesc_impl (uint16_t *length)
|
||||
{
|
||||
*length = sizeof (N_USBD_CfgDesc);
|
||||
return (uint8_t*)(N_USBD_CfgDesc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the device descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_DeviceDesc);
|
||||
return (uint8_t*)USBD_DeviceDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the LangID string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_LangIDDesc);
|
||||
return (uint8_t*)USBD_LangIDDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the product string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_PRODUCT_FS_STRING);
|
||||
return (uint8_t*)USBD_PRODUCT_FS_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the manufacturer string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_MANUFACTURER_STRING);
|
||||
return (uint8_t*)USBD_MANUFACTURER_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the serial number string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USB_SERIAL_STRING);
|
||||
return (uint8_t*)USB_SERIAL_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the configuration string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_CONFIGURATION_FS_STRING);
|
||||
return (uint8_t*)USBD_CONFIGURATION_FS_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the interface string descriptor.
|
||||
* @param speed: Current device speed
|
||||
* @param length: Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_INTERFACE_FS_STRING);
|
||||
return (uint8_t*)USBD_INTERFACE_FS_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_GetDeviceQualifierDesc_impl (uint16_t *length)
|
||||
{
|
||||
*length = sizeof (USBD_DeviceQualifierDesc);
|
||||
return (uint8_t*)USBD_DeviceQualifierDesc;
|
||||
}
|
||||
|
||||
|
||||
uint8_t SC_AnswerToReset (uint8_t voltage, uint8_t* atr_buffer) {
|
||||
// return the atr length
|
||||
atr_buffer[0] = 0x3B;
|
||||
atr_buffer[1] = 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
// note: how core lib usb calls the hid class
|
||||
static const USBD_DescriptorsTypeDef const CCID_Desc = {
|
||||
USBD_DeviceDescriptor,
|
||||
USBD_LangIDStrDescriptor,
|
||||
USBD_ManufacturerStrDescriptor,
|
||||
USBD_ProductStrDescriptor,
|
||||
USBD_SerialStrDescriptor,
|
||||
USBD_ConfigStrDescriptor,
|
||||
USBD_InterfaceStrDescriptor,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const USBD_ClassTypeDef USBD_CCID =
|
||||
{
|
||||
USBD_CCID_Init,
|
||||
USBD_CCID_DeInit,
|
||||
USBD_CCID_Setup,
|
||||
NULL, /*EP0_TxSent*/
|
||||
NULL, /*EP0_RxReady*/
|
||||
USBD_CCID_DataIn,
|
||||
USBD_CCID_DataOut,
|
||||
NULL, /*SOF */
|
||||
NULL, /*ISOIn*/
|
||||
NULL, /*ISOOut*/
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetCfgDesc_impl,
|
||||
USBD_GetDeviceQualifierDesc_impl,
|
||||
};
|
||||
|
||||
|
||||
void USBD_CCID_activate_pinpad(int enabled) {
|
||||
unsigned char e;
|
||||
e = enabled?3:0;
|
||||
nvm_write(((char*)PIC(N_USBD_CfgDesc))+USBD_OFFSET_CfgDesc_bPINSupport, &e,1);
|
||||
}
|
||||
|
||||
void USB_CCID_power(unsigned char enabled) {
|
||||
os_memset(&USBD_Device, 0, sizeof(USBD_Device));
|
||||
|
||||
if (enabled) {
|
||||
os_memset(&USBD_Device, 0, sizeof(USBD_Device));
|
||||
/* Init Device Library */
|
||||
USBD_Init(&USBD_Device, (USBD_DescriptorsTypeDef*)&CCID_Desc, 0);
|
||||
|
||||
/* Register the HID class */
|
||||
USBD_RegisterClass(&USBD_Device, (USBD_ClassTypeDef*)&USBD_CCID);
|
||||
|
||||
/* Start Device Process */
|
||||
USBD_Start(&USBD_Device);
|
||||
}
|
||||
else {
|
||||
USBD_DeInit(&USBD_Device);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_USB_CLASS_CCID
|
@ -1,24 +0,0 @@
|
||||
#ifndef USBD_CCID_IMPL_H
|
||||
#define USBD_CCID_IMPL_H
|
||||
|
||||
#define TPDU_EXCHANGE 0x01
|
||||
#define SHORT_APDU_EXCHANGE 0x02
|
||||
#define EXTENDED_APDU_EXCHANGE 0x04
|
||||
#define CHARACTER_EXCHANGE 0x00
|
||||
|
||||
#define EXCHANGE_LEVEL_FEATURE SHORT_APDU_EXCHANGE
|
||||
|
||||
|
||||
#define CCID_BULK_IN_EP 0x82
|
||||
#define CCID_BULK_EPIN_SIZE 64
|
||||
#define CCID_BULK_OUT_EP 0x02
|
||||
#define CCID_BULK_EPOUT_SIZE 64
|
||||
#define CCID_INTR_IN_EP 0x81
|
||||
#define CCID_INTR_EPIN_SIZE 16
|
||||
|
||||
#define CCID_EP0_BUFF_SIZ 64
|
||||
|
||||
void USB_CCID_power(unsigned char enabled);
|
||||
void USBD_CCID_activate_pinpad(int enabled);
|
||||
|
||||
#endif // USBD_CCID_IMPL_H
|
Loading…
Reference in New Issue
Block a user