Merge branch 'master' into ccid
This commit is contained in:
@@ -21,6 +21,9 @@ firmware-hacker-debug-1:
|
||||
firmware-hacker-debug-2:
|
||||
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=2 EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0'
|
||||
|
||||
firmware-secure-non-solokeys:
|
||||
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DFLASH_ROP=2'
|
||||
|
||||
firmware-secure:
|
||||
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DUSE_SOLOKEYS_CERT -DFLASH_ROP=2'
|
||||
|
||||
@@ -59,7 +62,6 @@ boot-no-sig:
|
||||
|
||||
build-release-locked: cbor clean2 boot-sig-checking clean all-locked
|
||||
$(VENV) $(merge_hex) solo.hex bootloader.hex all.hex
|
||||
rm -f solo.hex bootloader.hex # don't program solo.hex ...
|
||||
|
||||
build-release: cbor clean2 boot-sig-checking clean all
|
||||
$(VENV) $(merge_hex) solo.hex bootloader.hex all.hex
|
||||
|
@@ -7,7 +7,7 @@ SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c
|
||||
SRC += $(DRIVER_LIBS) $(USB_LIB)
|
||||
|
||||
# FIDO2 lib
|
||||
SRC += ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c
|
||||
SRC += ../../fido2/apdu.c ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c
|
||||
SRC += ../../fido2/stubs.c ../../fido2/log.c ../../fido2/ctaphid.c ../../fido2/ctap.c
|
||||
SRC += ../../fido2/ctap_parse.c ../../fido2/main.c
|
||||
SRC += ../../fido2/extensions/extensions.c ../../fido2/extensions/solo.c
|
||||
|
@@ -6,7 +6,7 @@ AR=$(PREFIX)arm-none-eabi-ar
|
||||
DRIVER_LIBS := lib/stm32l4xx_hal_pcd.c lib/stm32l4xx_hal_pcd_ex.c lib/stm32l4xx_ll_gpio.c \
|
||||
lib/stm32l4xx_ll_rcc.c lib/stm32l4xx_ll_rng.c lib/stm32l4xx_ll_tim.c \
|
||||
lib/stm32l4xx_ll_usb.c lib/stm32l4xx_ll_utils.c lib/stm32l4xx_ll_pwr.c \
|
||||
lib/stm32l4xx_ll_usart.c lib/stm32l4xx_ll_spi.c
|
||||
lib/stm32l4xx_ll_usart.c lib/stm32l4xx_ll_spi.c lib/stm32l4xx_ll_exti.c
|
||||
|
||||
USB_LIB := lib/usbd/usbd_cdc.c lib/usbd/usbd_cdc_if.c lib/usbd/usbd_composite.c \
|
||||
lib/usbd/usbd_conf.c lib/usbd/usbd_core.c lib/usbd/usbd_ioreq.c \
|
||||
|
290
targets/stm32l432/lib/stm32l4xx_ll_exti.c
Normal file
290
targets/stm32l432/lib/stm32l4xx_ll_exti.c
Normal file
@@ -0,0 +1,290 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_exti.c
|
||||
* @author MCD Application Team
|
||||
* @brief EXTI LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_exti.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (EXTI)
|
||||
|
||||
/** @defgroup EXTI_LL EXTI
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup EXTI_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_LL_EXTI_LINE_0_31(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_0_31) == 0x00000000U)
|
||||
#define IS_LL_EXTI_LINE_32_63(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_32_63) == 0x00000000U)
|
||||
|
||||
#define IS_LL_EXTI_MODE(__VALUE__) (((__VALUE__) == LL_EXTI_MODE_IT) \
|
||||
|| ((__VALUE__) == LL_EXTI_MODE_EVENT) \
|
||||
|| ((__VALUE__) == LL_EXTI_MODE_IT_EVENT))
|
||||
|
||||
|
||||
#define IS_LL_EXTI_TRIGGER(__VALUE__) (((__VALUE__) == LL_EXTI_TRIGGER_NONE) \
|
||||
|| ((__VALUE__) == LL_EXTI_TRIGGER_RISING) \
|
||||
|| ((__VALUE__) == LL_EXTI_TRIGGER_FALLING) \
|
||||
|| ((__VALUE__) == LL_EXTI_TRIGGER_RISING_FALLING))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup EXTI_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the EXTI registers to their default reset values.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - 0x00: EXTI registers are de-initialized
|
||||
*/
|
||||
uint32_t LL_EXTI_DeInit(void)
|
||||
{
|
||||
/* Interrupt mask register set to default reset values */
|
||||
LL_EXTI_WriteReg(IMR1, 0xFF820000U);
|
||||
/* Event mask register set to default reset values */
|
||||
LL_EXTI_WriteReg(EMR1, 0x00000000U);
|
||||
/* Rising Trigger selection register set to default reset values */
|
||||
LL_EXTI_WriteReg(RTSR1, 0x00000000U);
|
||||
/* Falling Trigger selection register set to default reset values */
|
||||
LL_EXTI_WriteReg(FTSR1, 0x00000000U);
|
||||
/* Software interrupt event register set to default reset values */
|
||||
LL_EXTI_WriteReg(SWIER1, 0x00000000U);
|
||||
/* Pending register clear */
|
||||
LL_EXTI_WriteReg(PR1, 0x007DFFFFU);
|
||||
|
||||
/* Interrupt mask register 2 set to default reset values */
|
||||
#if defined(LL_EXTI_LINE_40)
|
||||
LL_EXTI_WriteReg(IMR2, 0x00000187U);
|
||||
#else
|
||||
LL_EXTI_WriteReg(IMR2, 0x00000087U);
|
||||
#endif
|
||||
/* Event mask register 2 set to default reset values */
|
||||
LL_EXTI_WriteReg(EMR2, 0x00000000U);
|
||||
/* Rising Trigger selection register 2 set to default reset values */
|
||||
LL_EXTI_WriteReg(RTSR2, 0x00000000U);
|
||||
/* Falling Trigger selection register 2 set to default reset values */
|
||||
LL_EXTI_WriteReg(FTSR2, 0x00000000U);
|
||||
/* Software interrupt event register 2 set to default reset values */
|
||||
LL_EXTI_WriteReg(SWIER2, 0x00000000U);
|
||||
/* Pending register 2 clear */
|
||||
LL_EXTI_WriteReg(PR2, 0x00000078U);
|
||||
|
||||
return 0x00u;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the EXTI registers according to the specified parameters in EXTI_InitStruct.
|
||||
* @param EXTI_InitStruct pointer to a @ref LL_EXTI_InitTypeDef structure.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - 0x00: EXTI registers are initialized
|
||||
* - any other calue : wrong configuration
|
||||
*/
|
||||
uint32_t LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct)
|
||||
{
|
||||
uint32_t status = 0x00u;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LL_EXTI_LINE_0_31(EXTI_InitStruct->Line_0_31));
|
||||
assert_param(IS_LL_EXTI_LINE_32_63(EXTI_InitStruct->Line_32_63));
|
||||
assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->LineCommand));
|
||||
assert_param(IS_LL_EXTI_MODE(EXTI_InitStruct->Mode));
|
||||
|
||||
/* ENABLE LineCommand */
|
||||
if (EXTI_InitStruct->LineCommand != DISABLE)
|
||||
{
|
||||
assert_param(IS_LL_EXTI_TRIGGER(EXTI_InitStruct->Trigger));
|
||||
|
||||
/* Configure EXTI Lines in range from 0 to 31 */
|
||||
if (EXTI_InitStruct->Line_0_31 != LL_EXTI_LINE_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Mode)
|
||||
{
|
||||
case LL_EXTI_MODE_IT:
|
||||
/* First Disable Event on provided Lines */
|
||||
LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* Then Enable IT on provided Lines */
|
||||
LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
case LL_EXTI_MODE_EVENT:
|
||||
/* First Disable IT on provided Lines */
|
||||
LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* Then Enable Event on provided Lines */
|
||||
LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
case LL_EXTI_MODE_IT_EVENT:
|
||||
/* Directly Enable IT & Event on provided Lines */
|
||||
LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
|
||||
LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
default:
|
||||
status = 0x01u;
|
||||
break;
|
||||
}
|
||||
if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Trigger)
|
||||
{
|
||||
case LL_EXTI_TRIGGER_RISING:
|
||||
/* First Disable Falling Trigger on provided Lines */
|
||||
LL_EXTI_DisableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* Then Enable Rising Trigger on provided Lines */
|
||||
LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_FALLING:
|
||||
/* First Disable Rising Trigger on provided Lines */
|
||||
LL_EXTI_DisableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* Then Enable Falling Trigger on provided Lines */
|
||||
LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_RISING_FALLING:
|
||||
LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
default:
|
||||
status |= 0x02u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Configure EXTI Lines in range from 32 to 63 */
|
||||
if (EXTI_InitStruct->Line_32_63 != LL_EXTI_LINE_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Mode)
|
||||
{
|
||||
case LL_EXTI_MODE_IT:
|
||||
/* First Disable Event on provided Lines */
|
||||
LL_EXTI_DisableEvent_32_63(EXTI_InitStruct->Line_32_63);
|
||||
/* Then Enable IT on provided Lines */
|
||||
LL_EXTI_EnableIT_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
case LL_EXTI_MODE_EVENT:
|
||||
/* First Disable IT on provided Lines */
|
||||
LL_EXTI_DisableIT_32_63(EXTI_InitStruct->Line_32_63);
|
||||
/* Then Enable Event on provided Lines */
|
||||
LL_EXTI_EnableEvent_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
case LL_EXTI_MODE_IT_EVENT:
|
||||
/* Directly Enable IT & Event on provided Lines */
|
||||
LL_EXTI_EnableIT_32_63(EXTI_InitStruct->Line_32_63);
|
||||
LL_EXTI_EnableEvent_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
default:
|
||||
status |= 0x04u;
|
||||
break;
|
||||
}
|
||||
if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Trigger)
|
||||
{
|
||||
case LL_EXTI_TRIGGER_RISING:
|
||||
/* First Disable Falling Trigger on provided Lines */
|
||||
LL_EXTI_DisableFallingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
/* Then Enable IT on provided Lines */
|
||||
LL_EXTI_EnableRisingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_FALLING:
|
||||
/* First Disable Rising Trigger on provided Lines */
|
||||
LL_EXTI_DisableRisingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
/* Then Enable Falling Trigger on provided Lines */
|
||||
LL_EXTI_EnableFallingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_RISING_FALLING:
|
||||
LL_EXTI_EnableRisingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
LL_EXTI_EnableFallingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
default:
|
||||
status = ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* DISABLE LineCommand */
|
||||
else
|
||||
{
|
||||
/* De-configure EXTI Lines in range from 0 to 31 */
|
||||
LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
|
||||
LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* De-configure EXTI Lines in range from 32 to 63 */
|
||||
LL_EXTI_DisableIT_32_63(EXTI_InitStruct->Line_32_63);
|
||||
LL_EXTI_DisableEvent_32_63(EXTI_InitStruct->Line_32_63);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_EXTI_InitTypeDef field to default value.
|
||||
* @param EXTI_InitStruct Pointer to a @ref LL_EXTI_InitTypeDef structure.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct)
|
||||
{
|
||||
EXTI_InitStruct->Line_0_31 = LL_EXTI_LINE_NONE;
|
||||
EXTI_InitStruct->Line_32_63 = LL_EXTI_LINE_NONE;
|
||||
EXTI_InitStruct->LineCommand = DISABLE;
|
||||
EXTI_InitStruct->Mode = LL_EXTI_MODE_IT;
|
||||
EXTI_InitStruct->Trigger = LL_EXTI_TRIGGER_FALLING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (EXTI) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
1361
targets/stm32l432/lib/stm32l4xx_ll_exti.h
Normal file
1361
targets/stm32l432/lib/stm32l4xx_ll_exti.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -27,229 +27,256 @@ static uint8_t *USBD_Composite_GetOtherSpeedCfgDesc (uint16_t *length);
|
||||
|
||||
static uint8_t *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length);
|
||||
|
||||
#define NUM_INTERFACES 3
|
||||
#define NUM_CLASSES 3
|
||||
|
||||
#if NUM_INTERFACES>2
|
||||
|
||||
#if NUM_CLASSES>2
|
||||
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (90 + 8+9 + 4 + 84)
|
||||
#define NUM_INTERFACES 4
|
||||
#elif NUM_CLASSES>1
|
||||
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (90 + 84)
|
||||
#elif NUM_INTERFACES>1
|
||||
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (90)
|
||||
#define NUM_INTERFACES 2
|
||||
#else
|
||||
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (41)
|
||||
#define NUM_INTERFACES 1
|
||||
#endif
|
||||
|
||||
#define HID_INTF_NUM 0
|
||||
#define CDC_INTF_NUM 1
|
||||
#define CCID_INTF_NUM 2
|
||||
#define HID_INTF_NUM 0
|
||||
#define CCID_INTF_NUM 1
|
||||
#define CDC_MASTER_INTF_NUM 2
|
||||
#define CDC_SLAVE_INTF_NUM 3
|
||||
__ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_SIZE] __ALIGN_END =
|
||||
{
|
||||
/*Configuration Descriptor*/
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
COMPOSITE_CDC_HID_DESCRIPTOR_SIZE, /* wTotalLength:no of returned bytes */
|
||||
0x00,
|
||||
NUM_INTERFACES, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
0x80, /* bmAttributes: self powered */
|
||||
0x32, /* MaxPower 100 mA */
|
||||
{
|
||||
/*Configuration Descriptor*/
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
COMPOSITE_CDC_HID_DESCRIPTOR_SIZE, /* wTotalLength:no of returned bytes */
|
||||
0x00,
|
||||
NUM_INTERFACES, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
0x80, /* bmAttributes: self powered */
|
||||
0x32, /* MaxPower 100 mA */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* */
|
||||
/* HID */
|
||||
/* */
|
||||
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
0x09, /*bLength: Interface Descriptor size*/
|
||||
USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
|
||||
HID_INTF_NUM, /*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*/
|
||||
2, /*iInterface: Index of string descriptor*/
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
0x09, /*bLength: HID Descriptor size*/
|
||||
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
||||
0x11, /*bcdHID: HID Class Spec release number*/
|
||||
0x01,
|
||||
0x00, /*bCountryCode: Hardware target country*/
|
||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||
0x22, /*bDescriptorType*/
|
||||
HID_FIDO_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
|
||||
0,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
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: 4 Byte max */
|
||||
0x00,
|
||||
HID_BINTERVAL, /*bInterval: Polling Interval */
|
||||
|
||||
0x07, /*bLength: Endpoint Descriptor size*/
|
||||
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
|
||||
HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
|
||||
0x03, /*bmAttributes: Interrupt endpoint*/
|
||||
HID_EPOUT_SIZE, /*wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_BINTERVAL, /*bInterval: Polling Interval */
|
||||
/* */
|
||||
/* HID */
|
||||
/* */
|
||||
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
0x09, /*bLength: Interface Descriptor size*/
|
||||
USB_DESC_TYPE_INTERFACE, /*bDescriptorType: Interface descriptor type*/
|
||||
HID_INTF_NUM, /*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*/
|
||||
2, /*iInterface: Index of string descriptor*/
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
0x09, /*bLength: HID Descriptor size*/
|
||||
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
||||
0x11, /*bcdHID: HID Class Spec release number*/
|
||||
0x01,
|
||||
0x00, /*bCountryCode: Hardware target country*/
|
||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||
0x22, /*bDescriptorType*/
|
||||
HID_FIDO_REPORT_DESC_SIZE, /*wItemLength: Total length of Report descriptor*/
|
||||
0,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
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: 4 Byte max */
|
||||
0x00,
|
||||
HID_BINTERVAL, /*bInterval: Polling Interval */
|
||||
|
||||
0x07, /*bLength: Endpoint Descriptor size*/
|
||||
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
|
||||
HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
|
||||
0x03, /*bmAttributes: Interrupt endpoint*/
|
||||
HID_EPOUT_SIZE, /*wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_BINTERVAL, /*bInterval: Polling Interval */
|
||||
|
||||
#if NUM_INTERFACES>1
|
||||
|
||||
/* */
|
||||
/* CDC */
|
||||
/* */
|
||||
/* CCID Interface Descriptor */
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||
CCID_INTF_NUM, /* bInterfaceNumber: CCID Interface */
|
||||
0, /* Alternate setting for this interface */
|
||||
3, /* bNumEndpoints: Bulk-IN, Bulk-OUT, Intr-IN */
|
||||
0x0B, /* CCID class */
|
||||
0x00, /* CCID subclass */
|
||||
0x00, /* CCID protocol */
|
||||
0, /* string index for interface */
|
||||
|
||||
/* ICC Descriptor */
|
||||
54, /* bLength: */
|
||||
0x21, /* bDescriptorType: USBDESCR_ICC */
|
||||
0x10, 0x01, /* bcdCCID: revision 1.1 (of CCID) */
|
||||
0, /* bMaxSlotIndex: */
|
||||
1, /* bVoltageSupport: 5V-only */
|
||||
0x02, 0, 0, 0, /* dwProtocols: T=1 */
|
||||
0xa0, 0x0f, 0, 0, /* dwDefaultClock: 4000 */
|
||||
0xa0, 0x0f, 0, 0, /* dwMaximumClock: 4000 */
|
||||
0, /* bNumClockSupported: 0x00 */
|
||||
0x80, 0x25, 0, 0, /* dwDataRate: 9600 */
|
||||
0x80, 0x25, 0, 0, /* dwMaxDataRate: 9600 */
|
||||
0, /* bNumDataRateSupported: 0x00 */
|
||||
0xfe, 0, 0, 0, /* dwMaxIFSD: 254 */
|
||||
0, 0, 0, 0, /* dwSynchProtocols: 0 */
|
||||
0, 0, 0, 0, /* dwMechanical: 0 */
|
||||
0x7a, 0x04, 0x02, 0x00, /* dwFeatures:
|
||||
* Short and extended APDU level: 0x40000 ----
|
||||
* Short APDU level : 0x20000 *
|
||||
* (ICCD?) : 0x00800 ----
|
||||
* Automatic IFSD : 0x00400 *
|
||||
* NAD value other than 0x00 : 0x00200
|
||||
* Can set ICC in clock stop : 0x00100
|
||||
* Automatic PPS CUR : 0x00080
|
||||
* Automatic PPS PROP : 0x00040 *
|
||||
* Auto baud rate change : 0x00020 *
|
||||
* Auto clock change : 0x00010 *
|
||||
* Auto voltage selection : 0x00008 *
|
||||
* Auto activaction of ICC : 0x00004
|
||||
* Automatic conf. based on ATR : 0x00002 *
|
||||
*/
|
||||
0x0f, 0x01, 0, 0, /* dwMaxCCIDMessageLength: 271 */
|
||||
0xff, /* bClassGetResponse: 0xff */
|
||||
0x00, /* bClassEnvelope: 0 */
|
||||
0, 0, /* wLCDLayout: 0 */
|
||||
0, /* bPinSupport: No PIN pad */
|
||||
|
||||
/*Interface Descriptor */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||
/* Interface descriptor type */
|
||||
/*!*/ CDC_INTF_NUM, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x03, /* bNumEndpoints: 3 endpoints used */
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x00, /* bInterfaceProtocol: Common AT commands */
|
||||
0x00, /* iInterface: */
|
||||
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||
0x10, /* bcdCDC: spec release number */
|
||||
0x01,
|
||||
|
||||
/*Call Management Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||
0x00, /* bmCapabilities: D0+D1 */
|
||||
/*!*/ CDC_INTF_NUM, /* bDataInterface: 0 */
|
||||
|
||||
/*ACM Functional Descriptor*/
|
||||
0x04, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||
0x02, /* bmCapabilities */
|
||||
|
||||
/*Union Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x06, /* bDescriptorSubtype: Union func desc */
|
||||
/*!*/ CDC_INTF_NUM, /* bMasterInterface: Communication class interface */
|
||||
/*!*/ CDC_INTF_NUM, /* bSlaveInterface0: Data Class Interface */
|
||||
|
||||
/*Endpoint 2 Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_CMD_EP, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_CMD_PACKET_SIZE),
|
||||
0x10, /* bInterval: */
|
||||
|
||||
/*Endpoint OUT Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_OUT_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
|
||||
/*Endpoint IN Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
1, /* bMaxCCIDBusySlots: 1 */
|
||||
/*Endpoint IN1 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CCID_IN_EP, /* bEndpointAddress: (IN1) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
HID_FIDO_REPORT_DESC_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval */
|
||||
/*Endpoint OUT1 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CCID_OUT_EP, /* bEndpointAddress: (OUT1) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
HID_FIDO_REPORT_DESC_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval */
|
||||
/*Endpoint IN2 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CCID_CMD_EP, /* bEndpointAddress: (IN2) */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
0x04, 0x00, /* wMaxPacketSize: 4 */
|
||||
0xFF, /* bInterval (255ms) */
|
||||
|
||||
#endif
|
||||
#if NUM_INTERFACES>2
|
||||
|
||||
/* CCID Interface Descriptor */
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||
CCID_INTF_NUM, /* bInterfaceNumber: CCID Interface */
|
||||
0, /* Alternate setting for this interface */
|
||||
3, /* bNumEndpoints: Bulk-IN, Bulk-OUT, Intr-IN */
|
||||
0x0B, /* CCID class */
|
||||
0x00, /* CCID subclass */
|
||||
0x00, /* CCID protocol */
|
||||
0, /* string index for interface */
|
||||
#if NUM_INTERFACES > 2
|
||||
|
||||
/* ICC Descriptor */
|
||||
54, /* bLength: */
|
||||
0x21, /* bDescriptorType: USBDESCR_ICC */
|
||||
0x10, 0x01, /* bcdCCID: revision 1.1 (of CCID) */
|
||||
0, /* bMaxSlotIndex: */
|
||||
1, /* bVoltageSupport: 5V-only */
|
||||
0x02, 0, 0, 0, /* dwProtocols: T=1 */
|
||||
0xa0, 0x0f, 0, 0, /* dwDefaultClock: 4000 */
|
||||
0xa0, 0x0f, 0, 0, /* dwMaximumClock: 4000 */
|
||||
0, /* bNumClockSupported: 0x00 */
|
||||
0x80, 0x25, 0, 0, /* dwDataRate: 9600 */
|
||||
0x80, 0x25, 0, 0, /* dwMaxDataRate: 9600 */
|
||||
0, /* bNumDataRateSupported: 0x00 */
|
||||
0xfe, 0, 0, 0, /* dwMaxIFSD: 254 */
|
||||
0, 0, 0, 0, /* dwSynchProtocols: 0 */
|
||||
0, 0, 0, 0, /* dwMechanical: 0 */
|
||||
0x7a, 0x04, 0x02, 0x00, /* dwFeatures:
|
||||
* Short and extended APDU level: 0x40000 ----
|
||||
* Short APDU level : 0x20000 *
|
||||
* (ICCD?) : 0x00800 ----
|
||||
* Automatic IFSD : 0x00400 *
|
||||
* NAD value other than 0x00 : 0x00200
|
||||
* Can set ICC in clock stop : 0x00100
|
||||
* Automatic PPS CUR : 0x00080
|
||||
* Automatic PPS PROP : 0x00040 *
|
||||
* Auto baud rate change : 0x00020 *
|
||||
* Auto clock change : 0x00010 *
|
||||
* Auto voltage selection : 0x00008 *
|
||||
* Auto activaction of ICC : 0x00004
|
||||
* Automatic conf. based on ATR : 0x00002 *
|
||||
*/
|
||||
0x0f, 0x01, 0, 0, /* dwMaxCCIDMessageLength: 271 */
|
||||
0xff, /* bClassGetResponse: 0xff */
|
||||
0x00, /* bClassEnvelope: 0 */
|
||||
0, 0, /* wLCDLayout: 0 */
|
||||
0, /* bPinSupport: No PIN pad */
|
||||
/* */
|
||||
/* CDC */
|
||||
/* */
|
||||
// This "IAD" is needed for Windows since it ignores the standard Union Functional Descriptor
|
||||
0x08, // bLength
|
||||
0x0B, // IAD type
|
||||
CDC_MASTER_INTF_NUM, // First interface
|
||||
CDC_SLAVE_INTF_NUM, // Next interface
|
||||
0x02, // bInterfaceClass of the first interface
|
||||
0x02, // bInterfaceSubClass of the first interface
|
||||
0x00, // bInterfaceProtocol of the first interface
|
||||
0x00, // Interface string index
|
||||
|
||||
1, /* bMaxCCIDBusySlots: 1 */
|
||||
/*Endpoint IN1 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CCID_IN_EP, /* bEndpointAddress: (IN1) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
HID_FIDO_REPORT_DESC_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval */
|
||||
/*Endpoint OUT1 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CCID_OUT_EP, /* bEndpointAddress: (OUT1) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
HID_FIDO_REPORT_DESC_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval */
|
||||
/*Endpoint IN2 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CCID_CMD_EP, /* bEndpointAddress: (IN2) */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
0x04, 0x00, /* wMaxPacketSize: 4 */
|
||||
0xFF, /* bInterval (255ms) */
|
||||
/*Interface Descriptor */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||
/* Interface descriptor type */
|
||||
/*!*/ CDC_MASTER_INTF_NUM, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: 1 endpoint used */
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x00, /* bInterfaceProtocol: Common AT commands */
|
||||
0x00, /* iInterface: */
|
||||
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||
0x10, /* bcdCDC: spec release number */
|
||||
0x01,
|
||||
|
||||
/*Call Management Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||
0x00, /* bmCapabilities: D0+D1 */
|
||||
/*!*/ CDC_SLAVE_INTF_NUM, /* bDataInterface: 0 */
|
||||
|
||||
/*ACM Functional Descriptor*/
|
||||
0x04, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||
0x02, /* bmCapabilities */
|
||||
|
||||
/*Union Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x06, /* bDescriptorSubtype: Union func desc */
|
||||
/*!*/ CDC_MASTER_INTF_NUM, /* bMasterInterface: Communication class interface */
|
||||
/*!*/ CDC_SLAVE_INTF_NUM, /* bSlaveInterface0: Data Class Interface */
|
||||
|
||||
/* Control Endpoint Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_CMD_EP, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_CMD_PACKET_SIZE),
|
||||
0x10, /* bInterval: */
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, /* bLength */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
|
||||
CDC_SLAVE_INTF_NUM, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0A, /* bInterfaceClass: Communication class data */
|
||||
0x00, /* bInterfaceSubClass */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
0x00,
|
||||
|
||||
/*Endpoint OUT Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_OUT_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
|
||||
/*Endpoint IN Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
|
||||
4, /* Descriptor size */
|
||||
3, /* Descriptor type */
|
||||
0x09,
|
||||
0x04,
|
||||
#endif
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
USBD_ClassTypeDef USBD_Composite =
|
||||
{
|
||||
USBD_Composite_Init,
|
||||
@@ -274,21 +301,31 @@ int in_endpoint_to_class[MAX_ENDPOINTS];
|
||||
|
||||
int out_endpoint_to_class[MAX_ENDPOINTS];
|
||||
|
||||
void USBD_Composite_Set_Classes(USBD_ClassTypeDef *class0, USBD_ClassTypeDef *class1, USBD_ClassTypeDef *class2)
|
||||
void USBD_Composite_Set_Classes(USBD_ClassTypeDef *hid_class, USBD_ClassTypeDef *ccid_class, USBD_ClassTypeDef *cdc_class)) {
|
||||
USBD_Classes[0] = hid_class;
|
||||
USBD_Classes[1] = ccid_class;
|
||||
USBD_Classes[2] = cdc_class;
|
||||
}
|
||||
|
||||
static USBD_ClassTypeDef * getClass(uint8_t index)
|
||||
{
|
||||
//Y
|
||||
USBD_Classes[0] = class0;
|
||||
USBD_Classes[1] = class1;
|
||||
USBD_Classes[2] = class2;
|
||||
//Y
|
||||
switch(index)
|
||||
{
|
||||
case HID_INTF_NUM:
|
||||
return USBD_Classes[0];
|
||||
case CCID_INTF_NUM:
|
||||
return USBD_Classes[2];
|
||||
case CDC_MASTER_INTF_NUM:
|
||||
case CDC_SLAVE_INTF_NUM:
|
||||
return USBD_Classes[3];
|
||||
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
|
||||
int i;
|
||||
|
||||
//N
|
||||
|
||||
for(i = 0; i < NUM_INTERFACES; i++) {
|
||||
for(i = 0; i < NUM_CLASSES; i++) {
|
||||
if (USBD_Classes[i]->Init(pdev, cfgidx) != USBD_OK) {
|
||||
return USBD_FAIL;
|
||||
}
|
||||
@@ -299,7 +336,7 @@ static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
|
||||
|
||||
static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
|
||||
int i;
|
||||
for(i = 0; i < NUM_INTERFACES; i++) {
|
||||
for(i = 0; i < NUM_CLASSES; i++) {
|
||||
if (USBD_Classes[i]->DeInit(pdev, cfgidx) != USBD_OK) {
|
||||
return USBD_FAIL;
|
||||
}
|
||||
@@ -310,11 +347,13 @@ static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
|
||||
static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) {
|
||||
int i;
|
||||
//N
|
||||
USBD_ClassTypeDef * device_class;
|
||||
device_class = getClass(req->wIndex);
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||
case USB_REQ_TYPE_CLASS :
|
||||
if (req->wIndex < NUM_INTERFACES)
|
||||
return USBD_Classes[req->wIndex]->Setup(pdev, req);
|
||||
if (device_class != NULL)
|
||||
return device_class->Setup(pdev, req);
|
||||
else
|
||||
return USBD_FAIL;
|
||||
|
||||
@@ -323,7 +362,7 @@ static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqType
|
||||
switch (req->bRequest) {
|
||||
|
||||
case USB_REQ_GET_DESCRIPTOR :
|
||||
for(i = 0; i < NUM_INTERFACES; i++) {
|
||||
for(i = 0; i < NUM_CLASSES; i++) {
|
||||
if (USBD_Classes[i]->Setup(pdev, req) != USBD_OK) {
|
||||
return USBD_FAIL;
|
||||
}
|
||||
@@ -333,8 +372,8 @@ static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqType
|
||||
|
||||
case USB_REQ_GET_INTERFACE :
|
||||
case USB_REQ_SET_INTERFACE :
|
||||
if (req->wIndex < NUM_INTERFACES)
|
||||
return USBD_Classes[req->wIndex]->Setup(pdev, req);
|
||||
if (device_class != NULL)
|
||||
return device_class->Setup(pdev, req);
|
||||
else
|
||||
return USBD_FAIL;
|
||||
}
|
||||
@@ -361,7 +400,7 @@ static uint8_t USBD_Composite_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
|
||||
static uint8_t USBD_Composite_EP0_RxReady (USBD_HandleTypeDef *pdev) {
|
||||
int i;
|
||||
for(i = 0; i < NUM_INTERFACES; i++) {
|
||||
for(i = 0; i < NUM_CLASSES; i++) {
|
||||
if (USBD_Classes[i]->EP0_RxReady != NULL) {
|
||||
if (USBD_Classes[i]->EP0_RxReady(pdev) != USBD_OK) {
|
||||
return USBD_FAIL;
|
||||
|
@@ -342,6 +342,7 @@ static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf = NULL;
|
||||
uint16_t status_info = 0U;
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
req->wLength = req->wLength & 0x7f;
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||
{
|
||||
@@ -386,6 +387,7 @@ static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev,
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
req->wLength = req->wLength & 0x7f;
|
||||
if(req->wValue >> 8 == HID_REPORT_DESC)
|
||||
{
|
||||
len = MIN(HID_FIDO_REPORT_DESC_SIZE , req->wLength);
|
||||
|
@@ -31,7 +31,7 @@
|
||||
// #define DISABLE_CTAPHID_WINK
|
||||
// #define DISABLE_CTAPHID_CBOR
|
||||
|
||||
#define ENABLE_SERIAL_PRINTING
|
||||
// #define ENABLE_SERIAL_PRINTING
|
||||
|
||||
#if defined(SOLO_HACKER)
|
||||
#define SOLO_PRODUCT_NAME "Solo Hacker " SOLO_VERSION
|
||||
|
@@ -157,6 +157,11 @@ void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
|
||||
key = master_secret;
|
||||
klen = sizeof(master_secret)/2;
|
||||
}
|
||||
else if (key == CRYPTO_TRANSPORT_KEY2)
|
||||
{
|
||||
key = transport_secret;
|
||||
klen = 32;
|
||||
}
|
||||
|
||||
|
||||
if(klen > 64)
|
||||
@@ -277,6 +282,11 @@ void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8
|
||||
memmove(x,pubkey,32);
|
||||
memmove(y,pubkey+32,32);
|
||||
}
|
||||
void crypto_ecc256_compute_public_key(uint8_t * privkey, uint8_t * pubkey)
|
||||
{
|
||||
uECC_compute_public_key(privkey, pubkey, _es256_curve);
|
||||
}
|
||||
|
||||
|
||||
void crypto_load_external_key(uint8_t * key, int len)
|
||||
{
|
||||
|
@@ -38,11 +38,14 @@ void wait_for_usb_tether();
|
||||
|
||||
|
||||
uint32_t __90_ms = 0;
|
||||
uint32_t __last_button_press_time = 0;
|
||||
uint32_t __last_button_bounce_time = 0;
|
||||
uint32_t __device_status = 0;
|
||||
uint32_t __last_update = 0;
|
||||
extern PCD_HandleTypeDef hpcd;
|
||||
static int _NFC_status = 0;
|
||||
static bool isLowFreq = 0;
|
||||
static bool _RequestComeFromNFC = false;
|
||||
|
||||
// #define IS_BUTTON_PRESSED() (0 == (LL_GPIO_ReadInputPort(SOLO_BUTTON_PORT) & SOLO_BUTTON_PIN))
|
||||
static int is_physical_button_pressed()
|
||||
@@ -57,6 +60,10 @@ static int is_touch_button_pressed()
|
||||
|
||||
int (*IS_BUTTON_PRESSED)() = is_physical_button_pressed;
|
||||
|
||||
void request_from_nfc(bool request_active) {
|
||||
_RequestComeFromNFC = request_active;
|
||||
}
|
||||
|
||||
// Timer6 overflow handler. happens every ~90ms.
|
||||
void TIM6_DAC_IRQHandler()
|
||||
{
|
||||
@@ -70,6 +77,21 @@ void TIM6_DAC_IRQHandler()
|
||||
ctaphid_update_status(__device_status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (is_touch_button_pressed == IS_BUTTON_PRESSED)
|
||||
{
|
||||
if (IS_BUTTON_PRESSED())
|
||||
{
|
||||
// Only allow 1 press per 25 ms.
|
||||
if ((millis() - __last_button_bounce_time) > 25)
|
||||
{
|
||||
__last_button_press_time = millis();
|
||||
}
|
||||
__last_button_bounce_time = millis();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IS_BOOTLOADER
|
||||
// NFC sending WTX if needs
|
||||
if (device_is_nfc() == NFC_IS_ACTIVE)
|
||||
@@ -79,6 +101,21 @@ void TIM6_DAC_IRQHandler()
|
||||
#endif
|
||||
}
|
||||
|
||||
// Interrupt on rising edge of button (button released)
|
||||
void EXTI0_IRQHandler(void)
|
||||
{
|
||||
EXTI->PR1 = EXTI->PR1;
|
||||
if (is_physical_button_pressed == IS_BUTTON_PRESSED)
|
||||
{
|
||||
// Only allow 1 press per 25 ms.
|
||||
if ((millis() - __last_button_bounce_time) > 25)
|
||||
{
|
||||
__last_button_press_time = millis();
|
||||
}
|
||||
__last_button_bounce_time = millis();
|
||||
}
|
||||
}
|
||||
|
||||
// Global USB interrupt handler
|
||||
void USB_IRQHandler(void)
|
||||
{
|
||||
@@ -488,13 +525,49 @@ static int handle_packets()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wait_for_button_activate(uint32_t wait)
|
||||
{
|
||||
int ret;
|
||||
uint32_t start = millis();
|
||||
do
|
||||
{
|
||||
if ((start + wait) < millis())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
delay(1);
|
||||
ret = handle_packets();
|
||||
if (ret)
|
||||
return ret;
|
||||
} while (!IS_BUTTON_PRESSED());
|
||||
return 0;
|
||||
}
|
||||
static int wait_for_button_release(uint32_t wait)
|
||||
{
|
||||
int ret;
|
||||
uint32_t start = millis();
|
||||
do
|
||||
{
|
||||
if ((start + wait) < millis())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
delay(1);
|
||||
ret = handle_packets();
|
||||
if (ret)
|
||||
return ret;
|
||||
} while (IS_BUTTON_PRESSED());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ctap_user_presence_test(uint32_t up_delay)
|
||||
{
|
||||
int ret;
|
||||
if (device_is_nfc() == NFC_IS_ACTIVE)
|
||||
if (device_is_nfc() == NFC_IS_ACTIVE || _RequestComeFromNFC)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if SKIP_BUTTON_CHECK_WITH_DELAY
|
||||
int i=500;
|
||||
while(i--)
|
||||
@@ -507,53 +580,41 @@ int ctap_user_presence_test(uint32_t up_delay)
|
||||
#elif SKIP_BUTTON_CHECK_FAST
|
||||
delay(2);
|
||||
ret = handle_packets();
|
||||
if (ret) return ret;
|
||||
if (ret)
|
||||
return ret;
|
||||
goto done;
|
||||
#endif
|
||||
uint32_t t1 = millis();
|
||||
|
||||
// If button was pressed within last [2] seconds, succeed.
|
||||
if (__last_button_press_time && (millis() - __last_button_press_time < 2000))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Set LED status and wait.
|
||||
led_rgb(0xff3520);
|
||||
|
||||
if (IS_BUTTON_PRESSED == is_touch_button_pressed)
|
||||
{
|
||||
// Wait for user to release touch button if it's already pressed
|
||||
while (IS_BUTTON_PRESSED())
|
||||
{
|
||||
if (t1 + up_delay < millis())
|
||||
{
|
||||
printf1(TAG_GEN,"Button not pressed\n");
|
||||
goto fail;
|
||||
}
|
||||
ret = handle_packets();
|
||||
if (ret) return ret;
|
||||
}
|
||||
}
|
||||
|
||||
t1 = millis();
|
||||
|
||||
do
|
||||
{
|
||||
if (t1 + up_delay < millis())
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
delay(1);
|
||||
ret = handle_packets();
|
||||
// Block and wait for some time.
|
||||
ret = wait_for_button_activate(up_delay);
|
||||
if (ret) return ret;
|
||||
ret = wait_for_button_release(up_delay);
|
||||
if (ret) return ret;
|
||||
}
|
||||
while (! IS_BUTTON_PRESSED());
|
||||
|
||||
led_rgb(0x001040);
|
||||
|
||||
delay(50);
|
||||
// If button was pressed within last [2] seconds, succeed.
|
||||
if (__last_button_press_time && (millis() - __last_button_press_time < 2000))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
#if SKIP_BUTTON_CHECK_WITH_DELAY || SKIP_BUTTON_CHECK_FAST
|
||||
done:
|
||||
#endif
|
||||
return 1;
|
||||
ret = wait_for_button_release(up_delay);
|
||||
__last_button_press_time = 0;
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ctap_generate_rng(uint8_t * dst, size_t num)
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "stm32l4xx_ll_rng.h"
|
||||
#include "stm32l4xx_ll_spi.h"
|
||||
#include "stm32l4xx_ll_usb.h"
|
||||
#include "stm32l4xx_ll_exti.h"
|
||||
#include "stm32l4xx_hal_pcd.h"
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
@@ -851,19 +852,17 @@ void init_gpio(void)
|
||||
LL_GPIO_SetPinMode(SOLO_BUTTON_PORT,SOLO_BUTTON_PIN,LL_GPIO_MODE_INPUT);
|
||||
LL_GPIO_SetPinPull(SOLO_BUTTON_PORT,SOLO_BUTTON_PIN,LL_GPIO_PULL_UP);
|
||||
|
||||
#ifdef SOLO_AMS_IRQ_PORT
|
||||
// SAVE POWER
|
||||
// LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
|
||||
// /**/
|
||||
// LL_GPIO_InitTypeDef GPIO_InitStruct;
|
||||
// GPIO_InitStruct.Pin = SOLO_AMS_IRQ_PIN;
|
||||
// GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
|
||||
// GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
|
||||
// LL_GPIO_Init(SOLO_AMS_IRQ_PORT, &GPIO_InitStruct);
|
||||
//
|
||||
//
|
||||
// LL_GPIO_SetPinMode(SOLO_AMS_IRQ_PORT,SOLO_AMS_IRQ_PIN,LL_GPIO_MODE_INPUT);
|
||||
// LL_GPIO_SetPinPull(SOLO_AMS_IRQ_PORT,SOLO_AMS_IRQ_PIN,LL_GPIO_PULL_UP);
|
||||
#ifndef IS_BOOTLOADER
|
||||
LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTA, LL_SYSCFG_EXTI_LINE0);
|
||||
LL_EXTI_InitTypeDef EXTI_InitStruct;
|
||||
EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_0; // GPIOA_0
|
||||
EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
|
||||
EXTI_InitStruct.LineCommand = ENABLE;
|
||||
EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
|
||||
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
|
||||
LL_EXTI_Init(&EXTI_InitStruct);
|
||||
|
||||
NVIC_EnableIRQ(EXTI0_IRQn);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@@ -14,6 +14,20 @@
|
||||
|
||||
#define IS_IRQ_ACTIVE() (1 == (LL_GPIO_ReadInputPort(SOLO_AMS_IRQ_PORT) & SOLO_AMS_IRQ_PIN))
|
||||
|
||||
// chain buffer for 61XX responses
|
||||
static uint8_t resp_chain_buffer[2048] = {0};
|
||||
static size_t resp_chain_buffer_len = 0;
|
||||
|
||||
uint8_t p14443_block_offset(uint8_t pcb) {
|
||||
uint8_t offset = 1;
|
||||
// NAD following
|
||||
if (pcb & 0x04) offset++;
|
||||
// CID following
|
||||
if (pcb & 0x08) offset++;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
// Capability container
|
||||
const CAPABILITY_CONTAINER NFC_CC = {
|
||||
.cclen_hi = 0x00, .cclen_lo = 0x0f,
|
||||
@@ -82,19 +96,27 @@ int nfc_init()
|
||||
return NFC_IS_NA;
|
||||
}
|
||||
|
||||
static uint8_t gl_int0 = 0;
|
||||
void process_int0(uint8_t int0)
|
||||
{
|
||||
|
||||
gl_int0 = int0;
|
||||
}
|
||||
|
||||
bool ams_wait_for_tx(uint32_t timeout_ms)
|
||||
{
|
||||
if (gl_int0 & AMS_INT_TXE) {
|
||||
uint8_t int0 = ams_read_reg(AMS_REG_INT0);
|
||||
process_int0(int0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t tstart = millis();
|
||||
while (tstart + timeout_ms > millis())
|
||||
{
|
||||
uint8_t int0 = ams_read_reg(AMS_REG_INT0);
|
||||
if (int0) process_int0(int0);
|
||||
if (int0 & AMS_INT_TXE)
|
||||
process_int0(int0);
|
||||
if (int0 & AMS_INT_TXE || int0 & AMS_INT_RXE)
|
||||
return true;
|
||||
|
||||
delay(1);
|
||||
@@ -111,7 +133,13 @@ bool ams_receive_with_timeout(uint32_t timeout_ms, uint8_t * data, int maxlen, i
|
||||
uint32_t tstart = millis();
|
||||
while (tstart + timeout_ms > millis())
|
||||
{
|
||||
uint8_t int0 = ams_read_reg(AMS_REG_INT0);
|
||||
uint8_t int0 = 0;
|
||||
if (gl_int0 & AMS_INT_RXE) {
|
||||
int0 = gl_int0;
|
||||
} else {
|
||||
int0 = ams_read_reg(AMS_REG_INT0);
|
||||
process_int0(int0);
|
||||
}
|
||||
uint8_t buffer_status2 = ams_read_reg(AMS_REG_BUF2);
|
||||
|
||||
if (buffer_status2 && (int0 & AMS_INT_RXE))
|
||||
@@ -161,14 +189,25 @@ bool nfc_write_response_ex(uint8_t req0, uint8_t * data, uint8_t len, uint16_t r
|
||||
if (len > 32 - 3)
|
||||
return false;
|
||||
|
||||
res[0] = NFC_CMD_IBLOCK | (req0 & 3);
|
||||
res[0] = NFC_CMD_IBLOCK | (req0 & 0x0f);
|
||||
res[1] = 0;
|
||||
res[2] = 0;
|
||||
|
||||
uint8_t block_offset = p14443_block_offset(req0);
|
||||
|
||||
if (len && data)
|
||||
memcpy(&res[1], data, len);
|
||||
memcpy(&res[block_offset], data, len);
|
||||
|
||||
res[len + 1] = resp >> 8;
|
||||
res[len + 2] = resp & 0xff;
|
||||
nfc_write_frame(res, 3 + len);
|
||||
res[len + block_offset + 0] = resp >> 8;
|
||||
res[len + block_offset + 1] = resp & 0xff;
|
||||
|
||||
nfc_write_frame(res, block_offset + len + 2);
|
||||
|
||||
if (!ams_wait_for_tx(1))
|
||||
{
|
||||
printf1(TAG_NFC, "TX resp timeout. len: %d \r\n", len);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -178,25 +217,28 @@ bool nfc_write_response(uint8_t req0, uint16_t resp)
|
||||
return nfc_write_response_ex(req0, NULL, 0, resp);
|
||||
}
|
||||
|
||||
void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
|
||||
void nfc_write_response_chaining_plain(uint8_t req0, uint8_t * data, int len)
|
||||
{
|
||||
uint8_t res[32 + 2];
|
||||
int sendlen = 0;
|
||||
uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 3);
|
||||
uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 0x0f);
|
||||
uint8_t block_offset = p14443_block_offset(req0);
|
||||
|
||||
if (len <= 31)
|
||||
{
|
||||
uint8_t res[32] = {0};
|
||||
res[0] = iBlock;
|
||||
res[0] = iBlock;
|
||||
if (len && data)
|
||||
memcpy(&res[1], data, len);
|
||||
nfc_write_frame(res, len + 1);
|
||||
memcpy(&res[block_offset], data, len);
|
||||
nfc_write_frame(res, len + block_offset);
|
||||
} else {
|
||||
int sendlen = 0;
|
||||
do {
|
||||
// transmit I block
|
||||
int vlen = MIN(31, len - sendlen);
|
||||
res[0] = iBlock;
|
||||
memcpy(&res[1], &data[sendlen], vlen);
|
||||
int vlen = MIN(32 - block_offset, len - sendlen);
|
||||
res[0] = iBlock;
|
||||
res[1] = 0;
|
||||
res[2] = 0;
|
||||
memcpy(&res[block_offset], &data[sendlen], vlen);
|
||||
|
||||
// if not a last block
|
||||
if (vlen + sendlen < len)
|
||||
@@ -205,15 +247,15 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
|
||||
}
|
||||
|
||||
// send data
|
||||
nfc_write_frame(res, vlen + 1);
|
||||
nfc_write_frame(res, vlen + block_offset);
|
||||
sendlen += vlen;
|
||||
|
||||
// wait for transmit (32 bytes aprox 2,5ms)
|
||||
// if (!ams_wait_for_tx(10))
|
||||
// {
|
||||
// printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen);
|
||||
// break;
|
||||
// }
|
||||
if (!ams_wait_for_tx(5))
|
||||
{
|
||||
printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen);
|
||||
break;
|
||||
}
|
||||
|
||||
// if needs to receive R block (not a last block)
|
||||
if (res[0] & 0x10)
|
||||
@@ -226,9 +268,10 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
|
||||
break;
|
||||
}
|
||||
|
||||
if (reclen != 1)
|
||||
uint8_t rblock_offset = p14443_block_offset(recbuf[0]);
|
||||
if (reclen != rblock_offset)
|
||||
{
|
||||
printf1(TAG_NFC, "R block length error. len: %d. %d/%d \r\n", reclen,sendlen,len);
|
||||
printf1(TAG_NFC, "R block length error. len: %d. %d/%d \r\n", reclen, sendlen, len);
|
||||
dump_hex1(TAG_NFC, recbuf, reclen);
|
||||
break;
|
||||
}
|
||||
@@ -245,6 +288,37 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
|
||||
}
|
||||
}
|
||||
|
||||
void append_get_response(uint8_t *data, size_t rest_len)
|
||||
{
|
||||
data[0] = 0x61;
|
||||
data[1] = 0x00;
|
||||
if (rest_len <= 0xff)
|
||||
data[1] = rest_len & 0xff;
|
||||
}
|
||||
|
||||
void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len, bool extapdu)
|
||||
{
|
||||
resp_chain_buffer_len = 0;
|
||||
|
||||
// if we dont need to break data to parts that need to exchange via GET RESPONSE command (ISO 7816-4 7.1.3)
|
||||
if (len <= 255 || extapdu)
|
||||
{
|
||||
nfc_write_response_chaining_plain(req0, data, len);
|
||||
} else {
|
||||
size_t pcklen = MIN(253, len);
|
||||
resp_chain_buffer_len = len - pcklen;
|
||||
printf1(TAG_NFC, "61XX chaining %d/%d.\r\n", pcklen, resp_chain_buffer_len);
|
||||
|
||||
memmove(resp_chain_buffer, data, pcklen);
|
||||
append_get_response(&resp_chain_buffer[pcklen], resp_chain_buffer_len);
|
||||
|
||||
nfc_write_response_chaining_plain(req0, resp_chain_buffer, pcklen + 2); // 2 for 61XX
|
||||
|
||||
// put the rest data into chain buffer
|
||||
memmove(resp_chain_buffer, &data[pcklen], resp_chain_buffer_len);
|
||||
}
|
||||
}
|
||||
|
||||
// WTX on/off:
|
||||
// sends/receives WTX frame to reader every `WTX_time` time in ms
|
||||
// works via timer interrupts
|
||||
@@ -297,7 +371,7 @@ bool WTX_off()
|
||||
void WTX_timer_exec()
|
||||
{
|
||||
// condition: (timer on) or (not expired[300ms])
|
||||
if ((WTX_timer <= 0) || WTX_timer + 300 > millis())
|
||||
if ((WTX_timer == 0) || WTX_timer + 300 > millis())
|
||||
return;
|
||||
|
||||
WTX_process(10);
|
||||
@@ -308,12 +382,12 @@ void WTX_timer_exec()
|
||||
// read timeout must be 10 ms to call from interrupt
|
||||
bool WTX_process(int read_timeout)
|
||||
{
|
||||
uint8_t wtx[] = {0xf2, 0x01};
|
||||
if (WTX_fail)
|
||||
return false;
|
||||
|
||||
if (!WTX_sent)
|
||||
{
|
||||
uint8_t wtx[] = {0xf2, 0x01};
|
||||
nfc_write_frame(wtx, sizeof(wtx));
|
||||
WTX_sent = true;
|
||||
return true;
|
||||
@@ -371,39 +445,72 @@ int answer_rats(uint8_t parameter)
|
||||
|
||||
|
||||
nfc_write_frame(res, sizeof(res));
|
||||
ams_wait_for_tx(10);
|
||||
if (!ams_wait_for_tx(10))
|
||||
{
|
||||
printf1(TAG_NFC, "RATS TX timeout.\r\n");
|
||||
ams_write_command(AMS_CMD_DEFAULT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rblock_acknowledge()
|
||||
void rblock_acknowledge(uint8_t req0, bool ack)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
uint8_t buf[32] = {0};
|
||||
|
||||
uint8_t block_offset = p14443_block_offset(req0);
|
||||
NFC_STATE.block_num = !NFC_STATE.block_num;
|
||||
buf[0] = NFC_CMD_RBLOCK | NFC_STATE.block_num;
|
||||
nfc_write_frame(buf,1);
|
||||
|
||||
buf[0] = NFC_CMD_RBLOCK | (req0 & 0x0f);
|
||||
if (ack)
|
||||
buf[0] |= NFC_CMD_RBLOCK_ACK;
|
||||
|
||||
nfc_write_frame(buf, block_offset);
|
||||
}
|
||||
|
||||
// international AID = RID:PIX
|
||||
// RID length == 5 bytes
|
||||
// usually aid length must be between 5 and 16 bytes
|
||||
int applet_cmp(uint8_t * aid, int len, uint8_t * const_aid, int const_len)
|
||||
{
|
||||
if (len > const_len)
|
||||
return 10;
|
||||
|
||||
// if international AID
|
||||
if ((const_aid[0] & 0xf0) == 0xa0)
|
||||
{
|
||||
if (len < 5)
|
||||
return 11;
|
||||
return memcmp(aid, const_aid, MIN(len, const_len));
|
||||
} else {
|
||||
if (len != const_len)
|
||||
return 11;
|
||||
|
||||
return memcmp(aid, const_aid, const_len);
|
||||
}
|
||||
}
|
||||
|
||||
// Selects application. Returns 1 if success, 0 otherwise
|
||||
int select_applet(uint8_t * aid, int len)
|
||||
{
|
||||
if (memcmp(aid,AID_FIDO,sizeof(AID_FIDO)) == 0)
|
||||
if (applet_cmp(aid, len, (uint8_t *)AID_FIDO, sizeof(AID_FIDO) - 1) == 0)
|
||||
{
|
||||
NFC_STATE.selected_applet = APP_FIDO;
|
||||
return APP_FIDO;
|
||||
}
|
||||
else if (memcmp(aid,AID_NDEF_TYPE_4,sizeof(AID_NDEF_TYPE_4)) == 0)
|
||||
else if (applet_cmp(aid, len, (uint8_t *)AID_NDEF_TYPE_4, sizeof(AID_NDEF_TYPE_4) - 1) == 0)
|
||||
{
|
||||
NFC_STATE.selected_applet = APP_NDEF_TYPE_4;
|
||||
return APP_NDEF_TYPE_4;
|
||||
}
|
||||
else if (memcmp(aid,AID_CAPABILITY_CONTAINER,sizeof(AID_CAPABILITY_CONTAINER)) == 0)
|
||||
else if (applet_cmp(aid, len, (uint8_t *)AID_CAPABILITY_CONTAINER, sizeof(AID_CAPABILITY_CONTAINER) - 1) == 0)
|
||||
{
|
||||
NFC_STATE.selected_applet = APP_CAPABILITY_CONTAINER;
|
||||
return APP_CAPABILITY_CONTAINER;
|
||||
}
|
||||
else if (memcmp(aid,AID_NDEF_TAG,sizeof(AID_NDEF_TAG)) == 0)
|
||||
else if (applet_cmp(aid, len, (uint8_t *)AID_NDEF_TAG, sizeof(AID_NDEF_TAG) - 1) == 0)
|
||||
{
|
||||
NFC_STATE.selected_applet = APP_NDEF_TAG;
|
||||
return APP_NDEF_TAG;
|
||||
@@ -413,25 +520,80 @@ int select_applet(uint8_t * aid, int len)
|
||||
|
||||
void nfc_process_iblock(uint8_t * buf, int len)
|
||||
{
|
||||
APDU_HEADER * apdu = (APDU_HEADER *)(buf + 1);
|
||||
uint8_t * payload = buf + 1 + 5;
|
||||
uint8_t plen = apdu->lc;
|
||||
int selected;
|
||||
CTAP_RESPONSE ctap_resp;
|
||||
int status;
|
||||
uint16_t reslen;
|
||||
|
||||
printf1(TAG_NFC,"Iblock: ");
|
||||
dump_hex1(TAG_NFC, buf, len);
|
||||
uint8_t block_offset = p14443_block_offset(buf[0]);
|
||||
|
||||
APDU_STRUCT apdu;
|
||||
if (apdu_decode(buf + block_offset, len - block_offset, &apdu)) {
|
||||
printf1(TAG_NFC,"apdu decode error\r\n");
|
||||
nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED);
|
||||
return;
|
||||
}
|
||||
printf1(TAG_NFC,"apdu ok. %scase=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%d le=%d\r\n",
|
||||
apdu.extended_apdu ? "[e]":"", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.le);
|
||||
|
||||
// check CLA
|
||||
if (apdu.cla != 0x00 && apdu.cla != 0x80) {
|
||||
printf1(TAG_NFC, "Unknown CLA %02x\r\n", apdu.cla);
|
||||
nfc_write_response(buf[0], SW_CLA_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO this needs to be organized better
|
||||
switch(apdu->ins)
|
||||
switch(apdu.ins)
|
||||
{
|
||||
case APDU_INS_SELECT:
|
||||
if (plen > len - 6)
|
||||
// ISO 7816. 7.1 GET RESPONSE command
|
||||
case APDU_GET_RESPONSE:
|
||||
if (apdu.p1 != 0x00 || apdu.p2 != 0x00)
|
||||
{
|
||||
printf1(TAG_ERR, "Truncating APDU length %d\r\n", apdu->lc);
|
||||
plen = len-6;
|
||||
nfc_write_response(buf[0], SW_INCORRECT_P1P2);
|
||||
printf1(TAG_NFC, "P1 or P2 error\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// too many bytes needs. 0x00 and 0x100 - any length
|
||||
if (apdu.le != 0 && apdu.le != 0x100 && apdu.le > resp_chain_buffer_len)
|
||||
{
|
||||
uint16_t wlresp = SW_WRONG_LENGTH; // here can be 6700, 6C00, 6FXX. but the most standard way - 67XX or 6700
|
||||
if (resp_chain_buffer_len <= 0xff)
|
||||
wlresp += resp_chain_buffer_len & 0xff;
|
||||
nfc_write_response(buf[0], wlresp);
|
||||
printf1(TAG_NFC, "buffer length less than requesteds\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// create temporary packet
|
||||
uint8_t pck[255] = {0};
|
||||
size_t pcklen = 253;
|
||||
if (apdu.le)
|
||||
pcklen = apdu.le;
|
||||
if (pcklen > resp_chain_buffer_len)
|
||||
pcklen = resp_chain_buffer_len;
|
||||
|
||||
printf1(TAG_NFC, "GET RESPONSE. pck len: %d buffer len: %d\r\n", pcklen, resp_chain_buffer_len);
|
||||
|
||||
// create packet and add 61XX there if we have another portion(s) of data
|
||||
memmove(pck, resp_chain_buffer, pcklen);
|
||||
size_t dlen = 0;
|
||||
if (resp_chain_buffer_len - pcklen)
|
||||
{
|
||||
append_get_response(&pck[pcklen], resp_chain_buffer_len - pcklen);
|
||||
dlen = 2;
|
||||
}
|
||||
|
||||
// send
|
||||
nfc_write_response_chaining_plain(buf[0], pck, pcklen + dlen); // dlen for 61XX
|
||||
|
||||
// shift the buffer
|
||||
resp_chain_buffer_len -= pcklen;
|
||||
memmove(resp_chain_buffer, &resp_chain_buffer[pcklen], resp_chain_buffer_len);
|
||||
break;
|
||||
|
||||
case APDU_INS_SELECT:
|
||||
// if (apdu->p1 == 0 && apdu->p2 == 0x0c)
|
||||
// {
|
||||
// printf1(TAG_NFC,"Select NDEF\r\n");
|
||||
@@ -446,14 +608,9 @@ void nfc_process_iblock(uint8_t * buf, int len)
|
||||
// }
|
||||
// else
|
||||
{
|
||||
selected = select_applet(payload, plen);
|
||||
selected = select_applet(apdu.data, apdu.lc);
|
||||
if (selected == APP_FIDO)
|
||||
{
|
||||
// block = buf[0] & 1;
|
||||
// block = NFC_STATE.block_num;
|
||||
// block = !block;
|
||||
// NFC_STATE.block_num = block;
|
||||
// NFC_STATE.block_num = block;
|
||||
nfc_write_response_ex(buf[0], (uint8_t *)"U2F_V2", 6, SW_SUCCESS);
|
||||
printf1(TAG_NFC, "FIDO applet selected.\r\n");
|
||||
}
|
||||
@@ -465,7 +622,7 @@ void nfc_process_iblock(uint8_t * buf, int len)
|
||||
else
|
||||
{
|
||||
nfc_write_response(buf[0], SW_FILE_NOT_FOUND);
|
||||
printf1(TAG_NFC, "NOT selected\r\n"); dump_hex1(TAG_NFC,payload, plen);
|
||||
printf1(TAG_NFC, "NOT selected "); dump_hex1(TAG_NFC, apdu.data, apdu.lc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -478,7 +635,8 @@ void nfc_process_iblock(uint8_t * buf, int len)
|
||||
|
||||
printf1(TAG_NFC, "U2F GetVersion command.\r\n");
|
||||
|
||||
nfc_write_response_ex(buf[0], (uint8_t *)"U2F_V2", 6, SW_SUCCESS);
|
||||
u2f_request_nfc(&buf[block_offset], apdu.data, apdu.lc, &ctap_resp);
|
||||
nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length, apdu.extended_apdu);
|
||||
break;
|
||||
|
||||
case APDU_FIDO_U2F_REGISTER:
|
||||
@@ -489,9 +647,9 @@ void nfc_process_iblock(uint8_t * buf, int len)
|
||||
|
||||
printf1(TAG_NFC, "U2F Register command.\r\n");
|
||||
|
||||
if (plen != 64)
|
||||
if (apdu.lc != 64)
|
||||
{
|
||||
printf1(TAG_NFC, "U2F Register request length error. len=%d.\r\n", plen);
|
||||
printf1(TAG_NFC, "U2F Register request length error. len=%d.\r\n", apdu.lc);
|
||||
nfc_write_response(buf[0], SW_WRONG_LENGTH);
|
||||
return;
|
||||
}
|
||||
@@ -502,19 +660,15 @@ void nfc_process_iblock(uint8_t * buf, int len)
|
||||
// WTX_on(WTX_TIME_DEFAULT);
|
||||
// SystemClock_Config_LF32();
|
||||
// delay(300);
|
||||
if (device_is_nfc()) device_set_clock_rate(DEVICE_LOW_POWER_FAST);;
|
||||
u2f_request_nfc(&buf[1], len, &ctap_resp);
|
||||
if (device_is_nfc()) device_set_clock_rate(DEVICE_LOW_POWER_IDLE);;
|
||||
if (device_is_nfc() == NFC_IS_ACTIVE) device_set_clock_rate(DEVICE_LOW_POWER_FAST);
|
||||
u2f_request_nfc(&buf[block_offset], apdu.data, apdu.lc, &ctap_resp);
|
||||
if (device_is_nfc() == NFC_IS_ACTIVE) device_set_clock_rate(DEVICE_LOW_POWER_IDLE);
|
||||
// if (!WTX_off())
|
||||
// return;
|
||||
|
||||
printf1(TAG_NFC, "U2F resp len: %d\r\n", ctap_resp.length);
|
||||
printf1(TAG_NFC,"U2F Register P2 took %d\r\n", timestamp());
|
||||
nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length);
|
||||
|
||||
// printf1(TAG_NFC, "U2F resp len: %d\r\n", ctap_resp.length);
|
||||
|
||||
|
||||
|
||||
nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length, apdu.extended_apdu);
|
||||
|
||||
printf1(TAG_NFC,"U2F Register answered %d (took %d)\r\n", millis(), timestamp());
|
||||
break;
|
||||
@@ -527,41 +681,43 @@ void nfc_process_iblock(uint8_t * buf, int len)
|
||||
|
||||
printf1(TAG_NFC, "U2F Authenticate command.\r\n");
|
||||
|
||||
if (plen != 64 + 1 + buf[6 + 64])
|
||||
if (apdu.lc != 64 + 1 + apdu.data[64])
|
||||
{
|
||||
delay(5);
|
||||
printf1(TAG_NFC, "U2F Authenticate request length error. len=%d keyhlen=%d.\r\n", plen, buf[6 + 64]);
|
||||
printf1(TAG_NFC, "U2F Authenticate request length error. len=%d keyhlen=%d.\r\n", apdu.lc, apdu.data[64]);
|
||||
nfc_write_response(buf[0], SW_WRONG_LENGTH);
|
||||
return;
|
||||
}
|
||||
|
||||
timestamp();
|
||||
// WTX_on(WTX_TIME_DEFAULT);
|
||||
u2f_request_nfc(&buf[1], len, &ctap_resp);
|
||||
u2f_request_nfc(&buf[block_offset], apdu.data, apdu.lc, &ctap_resp);
|
||||
// if (!WTX_off())
|
||||
// return;
|
||||
|
||||
printf1(TAG_NFC, "U2F resp len: %d\r\n", ctap_resp.length);
|
||||
printf1(TAG_NFC,"U2F Authenticate processing %d (took %d)\r\n", millis(), timestamp());
|
||||
nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length);
|
||||
nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length, apdu.extended_apdu);
|
||||
printf1(TAG_NFC,"U2F Authenticate answered %d (took %d)\r\n", millis(), timestamp);
|
||||
break;
|
||||
|
||||
case APDU_FIDO_NFCCTAP_MSG:
|
||||
if (NFC_STATE.selected_applet != APP_FIDO) {
|
||||
nfc_write_response(buf[0], SW_INS_INVALID);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
printf1(TAG_NFC, "FIDO2 CTAP message. %d\r\n", timestamp());
|
||||
|
||||
WTX_on(WTX_TIME_DEFAULT);
|
||||
// WTX_on(WTX_TIME_DEFAULT);
|
||||
request_from_nfc(true);
|
||||
ctap_response_init(&ctap_resp);
|
||||
status = ctap_request(payload, plen, &ctap_resp);
|
||||
if (!WTX_off())
|
||||
return;
|
||||
status = ctap_request(apdu.data, apdu.lc, &ctap_resp);
|
||||
request_from_nfc(false);
|
||||
// if (!WTX_off())
|
||||
// return;
|
||||
|
||||
printf1(TAG_NFC, "CTAP resp: 0x%02<EFBFBD> len: %d\r\n", status, ctap_resp.length);
|
||||
printf1(TAG_NFC, "CTAP resp: 0x%02x len: %d\r\n", status, ctap_resp.length);
|
||||
|
||||
if (status == CTAP1_ERR_SUCCESS)
|
||||
{
|
||||
@@ -575,49 +731,45 @@ void nfc_process_iblock(uint8_t * buf, int len)
|
||||
ctap_resp.data[ctap_resp.length - 1] = SW_SUCCESS & 0xff;
|
||||
|
||||
printf1(TAG_NFC,"CTAP processing %d (took %d)\r\n", millis(), timestamp());
|
||||
nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length);
|
||||
nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length, apdu.extended_apdu);
|
||||
printf1(TAG_NFC,"CTAP answered %d (took %d)\r\n", millis(), timestamp());
|
||||
break;
|
||||
|
||||
case APDU_INS_READ_BINARY:
|
||||
|
||||
|
||||
// response length
|
||||
reslen = apdu.le & 0xffff;
|
||||
switch(NFC_STATE.selected_applet)
|
||||
{
|
||||
case APP_CAPABILITY_CONTAINER:
|
||||
printf1(TAG_NFC,"APP_CAPABILITY_CONTAINER\r\n");
|
||||
if (plen > 15)
|
||||
{
|
||||
printf1(TAG_ERR, "Truncating requested CC length %d\r\n", apdu->lc);
|
||||
plen = 15;
|
||||
}
|
||||
nfc_write_response_ex(buf[0], (uint8_t *)&NFC_CC, plen, SW_SUCCESS);
|
||||
if (reslen == 0 || reslen > sizeof(NFC_CC))
|
||||
reslen = sizeof(NFC_CC);
|
||||
nfc_write_response_ex(buf[0], (uint8_t *)&NFC_CC, reslen, SW_SUCCESS);
|
||||
ams_wait_for_tx(10);
|
||||
break;
|
||||
case APP_NDEF_TAG:
|
||||
printf1(TAG_NFC,"APP_NDEF_TAG\r\n");
|
||||
if (plen > (sizeof(NDEF_SAMPLE) - 1))
|
||||
{
|
||||
printf1(TAG_ERR, "Truncating requested CC length %d\r\n", apdu->lc);
|
||||
plen = sizeof(NDEF_SAMPLE) - 1;
|
||||
}
|
||||
nfc_write_response_ex(buf[0], NDEF_SAMPLE, plen, SW_SUCCESS);
|
||||
if (reslen == 0 || reslen > sizeof(NDEF_SAMPLE) - 1)
|
||||
reslen = sizeof(NDEF_SAMPLE) - 1;
|
||||
nfc_write_response_ex(buf[0], NDEF_SAMPLE, reslen, SW_SUCCESS);
|
||||
ams_wait_for_tx(10);
|
||||
break;
|
||||
default:
|
||||
nfc_write_response(buf[0], SW_FILE_NOT_FOUND);
|
||||
printf1(TAG_ERR, "No binary applet selected!\r\n");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
printf1(TAG_NFC, "Unknown INS %02x\r\n", apdu->ins);
|
||||
printf1(TAG_NFC, "Unknown INS %02x\r\n", apdu.ins);
|
||||
nfc_write_response(buf[0], SW_INS_INVALID);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
printf1(TAG_NFC,"prev.Iblock: ");
|
||||
dump_hex1(TAG_NFC, buf, len);
|
||||
}
|
||||
|
||||
static uint8_t ibuf[1024];
|
||||
@@ -631,16 +783,24 @@ void clear_ibuf()
|
||||
|
||||
void nfc_process_block(uint8_t * buf, unsigned int len)
|
||||
{
|
||||
|
||||
printf1(TAG_NFC, "-----\r\n");
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
if (IS_PPSS_CMD(buf[0]))
|
||||
{
|
||||
printf1(TAG_NFC, "NFC_CMD_PPSS\r\n");
|
||||
printf1(TAG_NFC, "NFC_CMD_PPSS [%d] 0x%02x\r\n", len, (len > 2) ? buf[2] : 0);
|
||||
|
||||
if (buf[1] == 0x11 && (buf[2] & 0x0f) == 0x00) {
|
||||
nfc_write_frame(buf, 1); // ack with correct start byte
|
||||
} else {
|
||||
printf1(TAG_NFC, "NFC_CMD_PPSS ERROR!!!\r\n");
|
||||
nfc_write_frame((uint8_t*)"\x00", 1); // this should not happend. but iso14443-4 dont have NACK here, so just 0x00
|
||||
}
|
||||
}
|
||||
else if (IS_IBLOCK(buf[0]))
|
||||
{
|
||||
uint8_t block_offset = p14443_block_offset(buf[0]);
|
||||
if (buf[0] & 0x10)
|
||||
{
|
||||
printf1(TAG_NFC_APDU, "NFC_CMD_IBLOCK chaining blen=%d len=%d\r\n", ibuflen, len);
|
||||
@@ -654,27 +814,27 @@ void nfc_process_block(uint8_t * buf, unsigned int len)
|
||||
printf1(TAG_NFC_APDU,"i> ");
|
||||
dump_hex1(TAG_NFC_APDU, buf, len);
|
||||
|
||||
if (len)
|
||||
if (len > block_offset)
|
||||
{
|
||||
memcpy(&ibuf[ibuflen], &buf[1], len - 1);
|
||||
ibuflen += len - 1;
|
||||
memcpy(&ibuf[ibuflen], &buf[block_offset], len - block_offset);
|
||||
ibuflen += len - block_offset;
|
||||
}
|
||||
|
||||
// send R block
|
||||
uint8_t rb = NFC_CMD_RBLOCK | NFC_CMD_RBLOCK_ACK | (buf[0] & 3);
|
||||
nfc_write_frame(&rb, 1);
|
||||
rblock_acknowledge(buf[0], true);
|
||||
} else {
|
||||
if (ibuflen)
|
||||
{
|
||||
if (len)
|
||||
if (len > block_offset)
|
||||
{
|
||||
memcpy(&ibuf[ibuflen], &buf[1], len - 1);
|
||||
ibuflen += len - 1;
|
||||
memcpy(&ibuf[ibuflen], &buf[block_offset], len - block_offset);
|
||||
ibuflen += len - block_offset;
|
||||
}
|
||||
|
||||
memmove(&ibuf[1], ibuf, ibuflen);
|
||||
ibuf[0] = buf[0];
|
||||
ibuflen++;
|
||||
// add last chaining to top of the block
|
||||
memmove(&ibuf[block_offset], ibuf, ibuflen);
|
||||
memmove(ibuf, buf, block_offset);
|
||||
ibuflen += block_offset;
|
||||
|
||||
printf1(TAG_NFC_APDU, "NFC_CMD_IBLOCK chaining last block. blen=%d len=%d\r\n", ibuflen, len);
|
||||
|
||||
@@ -683,7 +843,6 @@ void nfc_process_block(uint8_t * buf, unsigned int len)
|
||||
|
||||
nfc_process_iblock(ibuf, ibuflen);
|
||||
} else {
|
||||
// printf1(TAG_NFC, "NFC_CMD_IBLOCK\r\n");
|
||||
nfc_process_iblock(buf, len);
|
||||
}
|
||||
clear_ibuf();
|
||||
@@ -691,7 +850,7 @@ void nfc_process_block(uint8_t * buf, unsigned int len)
|
||||
}
|
||||
else if (IS_RBLOCK(buf[0]))
|
||||
{
|
||||
rblock_acknowledge();
|
||||
rblock_acknowledge(buf[0], false);
|
||||
printf1(TAG_NFC, "NFC_CMD_RBLOCK\r\n");
|
||||
}
|
||||
else if (IS_SBLOCK(buf[0]))
|
||||
@@ -710,6 +869,7 @@ void nfc_process_block(uint8_t * buf, unsigned int len)
|
||||
else
|
||||
{
|
||||
printf1(TAG_NFC, "NFC_CMD_SBLOCK, Unknown. len[%d]\r\n", len);
|
||||
nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED);
|
||||
}
|
||||
dump_hex1(TAG_NFC, buf, len);
|
||||
}
|
||||
@@ -728,6 +888,8 @@ int nfc_loop()
|
||||
|
||||
|
||||
read_reg_block(&ams);
|
||||
uint8_t old_int0 = gl_int0;
|
||||
process_int0(ams.regs.int0);
|
||||
uint8_t state = AMS_STATE_MASK & ams.regs.rfid_status;
|
||||
|
||||
if (state != AMS_STATE_SELECTED && state != AMS_STATE_SELECTEDX)
|
||||
@@ -741,7 +903,7 @@ int nfc_loop()
|
||||
// if (state != AMS_STATE_SENSE)
|
||||
// printf1(TAG_NFC," %s x%02x\r\n", ams_get_state_string(ams.regs.rfid_status), state);
|
||||
}
|
||||
if (ams.regs.int0 & AMS_INT_INIT)
|
||||
if (ams.regs.int0 & AMS_INT_INIT || old_int0 & AMS_INT_INIT)
|
||||
{
|
||||
nfc_state_init();
|
||||
}
|
||||
@@ -750,7 +912,7 @@ int nfc_loop()
|
||||
// ams_print_int1(ams.regs.int1);
|
||||
}
|
||||
|
||||
if ((ams.regs.int0 & AMS_INT_RXE))
|
||||
if (ams.regs.int0 & AMS_INT_RXE || old_int0 & AMS_INT_RXE)
|
||||
{
|
||||
if (ams.regs.buffer_status2)
|
||||
{
|
||||
@@ -779,6 +941,7 @@ int nfc_loop()
|
||||
printf1(TAG_NFC, "NFC_CMD_WUPA\r\n");
|
||||
break;
|
||||
case NFC_CMD_HLTA:
|
||||
ams_write_command(AMS_CMD_SLEEP);
|
||||
printf1(TAG_NFC, "HLTA/Halt\r\n");
|
||||
break;
|
||||
case NFC_CMD_RATS:
|
||||
|
@@ -40,6 +40,8 @@ typedef struct
|
||||
#define NFC_CMD_SBLOCK 0xc0
|
||||
#define IS_SBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_SBLOCK) && (((x) & 0x02) == 0x02) )
|
||||
|
||||
extern uint8_t p14443_block_offset(uint8_t pcb);
|
||||
|
||||
#define NFC_SBLOCK_DESELECT 0x30
|
||||
#define NFC_SBLOCK_WTX 0x30
|
||||
|
||||
|
Reference in New Issue
Block a user