Compare commits
15 Commits
cache_butt
...
fix_cdc_in
Author | SHA1 | Date | |
---|---|---|---|
3be8611fcf | |||
21489658a7 | |||
a07a3dee8d | |||
416da63a9a | |||
027fa791a3 | |||
3e52d7b42b | |||
301e18c6a2 | |||
44205141eb | |||
6e1110ca9b | |||
9105b988e2 | |||
14c94ea8f5 | |||
435b908c17 | |||
78280e570b | |||
36aec9f20b | |||
02a51454b7 |
@ -32,7 +32,7 @@ Source code can be downloaded from:
|
|||||||
- from python programs [repository](https://pypi.org/project/solo-python/) `pip install solo-python`
|
- from python programs [repository](https://pypi.org/project/solo-python/) `pip install solo-python`
|
||||||
- from installing prerequisites `pip3 install -r tools/requirements.txt`
|
- from installing prerequisites `pip3 install -r tools/requirements.txt`
|
||||||
- github repository: [repository](https://github.com/solokeys/solo-python)
|
- github repository: [repository](https://github.com/solokeys/solo-python)
|
||||||
- installation python enviroment witn command `make venv` from root directory of source code
|
- installation python enviroment with command `make venv` from root directory of source code
|
||||||
|
|
||||||
## Compilation
|
## Compilation
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ Environment: Fedora 29 x64, Linux 4.19.9
|
|||||||
|
|
||||||
See <https://docs.solokeys.io/solo/building/> for the original guide. Here details not included there will be covered.
|
See <https://docs.solokeys.io/solo/building/> for the original guide. Here details not included there will be covered.
|
||||||
|
|
||||||
### Install ARM tools
|
### Install ARM tools Linux
|
||||||
|
|
||||||
1. Download current [ARM tools] package: [gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2].
|
1. Download current [ARM tools] package: [gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2].
|
||||||
|
|
||||||
@ -75,6 +75,13 @@ See <https://docs.solokeys.io/solo/building/> for the original guide. Here detai
|
|||||||
3. Add full path to the `./bin` directory as first entry to the `$PATH` variable,
|
3. Add full path to the `./bin` directory as first entry to the `$PATH` variable,
|
||||||
as in `~/gcc-arm/gcc-arm-none-eabi-8-2018-q4-major/bin/:$PATH`.
|
as in `~/gcc-arm/gcc-arm-none-eabi-8-2018-q4-major/bin/:$PATH`.
|
||||||
|
|
||||||
|
### Install ARM tools OsX using brew package manager
|
||||||
|
|
||||||
|
```bash
|
||||||
|
brew tap ArmMbed/homebrew-formulae
|
||||||
|
brew install arm-none-eabi-gcc
|
||||||
|
```
|
||||||
|
|
||||||
### Install flashing software
|
### Install flashing software
|
||||||
|
|
||||||
ST provides a CLI flashing tool - `STM32_Programmer_CLI`. It can be downloaded directly from the vendor's site:
|
ST provides a CLI flashing tool - `STM32_Programmer_CLI`. It can be downloaded directly from the vendor's site:
|
||||||
@ -114,8 +121,8 @@ Do not use it, if you do not plan to do so.
|
|||||||
```bash
|
```bash
|
||||||
# while in the main project directory
|
# while in the main project directory
|
||||||
# create Python virtual environment with required packages, and activate
|
# create Python virtual environment with required packages, and activate
|
||||||
make env3
|
make venv
|
||||||
. env3/bin/activate
|
. venv/bin/activate
|
||||||
# Run flashing
|
# Run flashing
|
||||||
cd ./targets/stm32l432
|
cd ./targets/stm32l432
|
||||||
make flash
|
make flash
|
||||||
@ -178,8 +185,8 @@ make fido2-test
|
|||||||
|
|
||||||
#### FIDO2 test sites
|
#### FIDO2 test sites
|
||||||
|
|
||||||
1. <https://webauthn.bin.coffee/>
|
1. <https://www.passwordless.dev/overview>
|
||||||
2. <https://github.com/apowers313/fido2-server-demo/>
|
2. <https://webauthn.bin.coffee/>
|
||||||
3. <https://webauthn.org/>
|
3. <https://webauthn.org/>
|
||||||
|
|
||||||
#### U2F test sites
|
#### U2F test sites
|
||||||
|
@ -26,151 +26,173 @@ static uint8_t *USBD_Composite_GetOtherSpeedCfgDesc (uint16_t *length);
|
|||||||
|
|
||||||
static uint8_t *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length);
|
static uint8_t *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length);
|
||||||
|
|
||||||
#define NUM_INTERFACES 2
|
#define NUM_CLASSES 2
|
||||||
|
#define NUM_INTERFACES 3
|
||||||
|
|
||||||
#if NUM_INTERFACES>1
|
#if NUM_INTERFACES>1
|
||||||
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (90)
|
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (90 + 8+9 + 4)
|
||||||
#else
|
#else
|
||||||
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (41)
|
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (41)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HID_INTF_NUM 0
|
#define HID_INTF_NUM 0
|
||||||
#define CDC_INTF_NUM 1
|
#define CDC_MASTER_INTF_NUM 1
|
||||||
|
#define CDC_SLAVE_INTF_NUM 2
|
||||||
__ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_SIZE] __ALIGN_END =
|
__ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_SIZE] __ALIGN_END =
|
||||||
{
|
{
|
||||||
/*Configuration Descriptor*/
|
/*Configuration Descriptor*/
|
||||||
0x09, /* bLength: Configuration Descriptor size */
|
0x09, /* bLength: Configuration Descriptor size */
|
||||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||||
COMPOSITE_CDC_HID_DESCRIPTOR_SIZE, /* wTotalLength:no of returned bytes */
|
COMPOSITE_CDC_HID_DESCRIPTOR_SIZE, /* wTotalLength:no of returned bytes */
|
||||||
0x00,
|
0x00,
|
||||||
NUM_INTERFACES, /* bNumInterfaces: 1 interface */
|
NUM_INTERFACES, /* bNumInterfaces */
|
||||||
0x01, /* bConfigurationValue: Configuration value */
|
0x01, /* bConfigurationValue: Configuration value */
|
||||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||||
0x80, /* bmAttributes: self powered */
|
0x80, /* bmAttributes: self powered */
|
||||||
0x32, /* MaxPower 100 mA */
|
0x32, /* MaxPower 100 mA */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
/* HID */
|
/* HID */
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
/************** Descriptor of Joystick Mouse interface ****************/
|
/************** Descriptor of Joystick Mouse interface ****************/
|
||||||
0x09, /*bLength: Interface Descriptor size*/
|
0x09, /*bLength: Interface Descriptor size*/
|
||||||
USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
|
USB_DESC_TYPE_INTERFACE, /*bDescriptorType: Interface descriptor type*/
|
||||||
HID_INTF_NUM, /*bInterfaceNumber: Number of Interface*/
|
HID_INTF_NUM, /*bInterfaceNumber: Number of Interface*/
|
||||||
0x00, /*bAlternateSetting: Alternate setting*/
|
0x00, /*bAlternateSetting: Alternate setting*/
|
||||||
0x02, /*bNumEndpoints*/
|
0x02, /*bNumEndpoints*/
|
||||||
0x03, /*bInterfaceClass: HID*/
|
0x03, /*bInterfaceClass: HID*/
|
||||||
0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
|
0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
|
||||||
0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
|
0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
|
||||||
2, /*iInterface: Index of string descriptor*/
|
2, /*iInterface: Index of string descriptor*/
|
||||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||||
0x09, /*bLength: HID Descriptor size*/
|
0x09, /*bLength: HID Descriptor size*/
|
||||||
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
||||||
0x11, /*bcdHID: HID Class Spec release number*/
|
0x11, /*bcdHID: HID Class Spec release number*/
|
||||||
0x01,
|
0x01,
|
||||||
0x00, /*bCountryCode: Hardware target country*/
|
0x00, /*bCountryCode: Hardware target country*/
|
||||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||||
0x22, /*bDescriptorType*/
|
0x22, /*bDescriptorType*/
|
||||||
HID_FIDO_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
|
HID_FIDO_REPORT_DESC_SIZE, /*wItemLength: Total length of Report descriptor*/
|
||||||
0,
|
0,
|
||||||
/******************** Descriptor of Mouse endpoint ********************/
|
/******************** Descriptor of Mouse endpoint ********************/
|
||||||
0x07, /*bLength: Endpoint Descriptor size*/
|
0x07, /*bLength: Endpoint Descriptor size*/
|
||||||
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
|
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
|
||||||
HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
|
HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
|
||||||
0x03, /*bmAttributes: Interrupt endpoint*/
|
0x03, /*bmAttributes: Interrupt endpoint*/
|
||||||
HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */
|
HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */
|
||||||
0x00,
|
0x00,
|
||||||
HID_BINTERVAL, /*bInterval: Polling Interval */
|
HID_BINTERVAL, /*bInterval: Polling Interval */
|
||||||
|
|
||||||
0x07, /*bLength: Endpoint Descriptor size*/
|
0x07, /*bLength: Endpoint Descriptor size*/
|
||||||
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
|
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
|
||||||
HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
|
HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
|
||||||
0x03, /*bmAttributes: Interrupt endpoint*/
|
0x03, /*bmAttributes: Interrupt endpoint*/
|
||||||
HID_EPOUT_SIZE, /*wMaxPacketSize: 4 Byte max */
|
HID_EPOUT_SIZE, /*wMaxPacketSize: 4 Byte max */
|
||||||
0x00,
|
0x00,
|
||||||
HID_BINTERVAL, /*bInterval: Polling Interval */
|
HID_BINTERVAL, /*bInterval: Polling Interval */
|
||||||
|
|
||||||
|
#if NUM_INTERFACES > 1
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* 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
|
||||||
|
|
||||||
#if NUM_INTERFACES>1
|
/*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*/
|
||||||
/* CDC */
|
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 */
|
||||||
|
|
||||||
/*Interface Descriptor */
|
/*ACM Functional Descriptor*/
|
||||||
0x09, /* bLength: Interface Descriptor size */
|
0x04, /* bFunctionLength */
|
||||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
/* Interface descriptor type */
|
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||||
/*!*/ CDC_INTF_NUM, /* bInterfaceNumber: Number of Interface */
|
0x02, /* bmCapabilities */
|
||||||
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*/
|
/*Union Functional Descriptor*/
|
||||||
0x05, /* bLength: Endpoint Descriptor size */
|
0x05, /* bFunctionLength */
|
||||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
0x00, /* bDescriptorSubtype: Header Func Desc */
|
0x06, /* bDescriptorSubtype: Union func desc */
|
||||||
0x10, /* bcdCDC: spec release number */
|
/*!*/ CDC_MASTER_INTF_NUM, /* bMasterInterface: Communication class interface */
|
||||||
0x01,
|
/*!*/ CDC_SLAVE_INTF_NUM, /* bSlaveInterface0: Data Class Interface */
|
||||||
|
|
||||||
/*Call Management Functional Descriptor*/
|
/* Control Endpoint Descriptor*/
|
||||||
0x05, /* bFunctionLength */
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
CDC_CMD_EP, /* bEndpointAddress */
|
||||||
0x00, /* bmCapabilities: D0+D1 */
|
0x03, /* bmAttributes: Interrupt */
|
||||||
/*!*/ CDC_INTF_NUM, /* bDataInterface: 0 */
|
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
|
HIBYTE(CDC_CMD_PACKET_SIZE),
|
||||||
|
0x10, /* bInterval: */
|
||||||
|
|
||||||
/*ACM Functional Descriptor*/
|
/* Interface descriptor */
|
||||||
0x04, /* bFunctionLength */
|
0x09, /* bLength */
|
||||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
|
||||||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
CDC_SLAVE_INTF_NUM, /* bInterfaceNumber */
|
||||||
0x02, /* bmCapabilities */
|
0x00, /* bAlternateSetting */
|
||||||
|
0x02, /* bNumEndpoints */
|
||||||
|
0x0A, /* bInterfaceClass: Communication class data */
|
||||||
|
0x00, /* bInterfaceSubClass */
|
||||||
|
0x00, /* bInterfaceProtocol */
|
||||||
|
0x00,
|
||||||
|
|
||||||
/*Union Functional Descriptor*/
|
/*Endpoint OUT Descriptor*/
|
||||||
0x05, /* bFunctionLength */
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
0x06, /* bDescriptorSubtype: Union func desc */
|
CDC_OUT_EP, /* bEndpointAddress */
|
||||||
/*!*/ CDC_INTF_NUM, /* bMasterInterface: Communication class interface */
|
0x02, /* bmAttributes: Bulk */
|
||||||
/*!*/ CDC_INTF_NUM, /* bSlaveInterface0: Data Class Interface */
|
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
|
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||||
|
0x00, /* bInterval: ignore for Bulk transfer */
|
||||||
|
|
||||||
/*Endpoint 2 Descriptor*/
|
/*Endpoint IN Descriptor*/
|
||||||
0x07, /* bLength: Endpoint Descriptor size */
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
CDC_CMD_EP, /* bEndpointAddress */
|
CDC_IN_EP, /* bEndpointAddress */
|
||||||
0x03, /* bmAttributes: Interrupt */
|
0x02, /* bmAttributes: Bulk */
|
||||||
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
|
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
HIBYTE(CDC_CMD_PACKET_SIZE),
|
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||||
0x10, /* bInterval: */
|
0x00, /* bInterval: ignore for Bulk transfer */
|
||||||
|
|
||||||
/*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
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
USBD_ClassTypeDef USBD_Composite =
|
USBD_ClassTypeDef USBD_Composite =
|
||||||
{
|
{
|
||||||
USBD_Composite_Init,
|
USBD_Composite_Init,
|
||||||
@ -195,14 +217,27 @@ int in_endpoint_to_class[MAX_ENDPOINTS];
|
|||||||
|
|
||||||
int out_endpoint_to_class[MAX_ENDPOINTS];
|
int out_endpoint_to_class[MAX_ENDPOINTS];
|
||||||
|
|
||||||
void USBD_Composite_Set_Classes(USBD_ClassTypeDef *class0, USBD_ClassTypeDef *class1) {
|
void USBD_Composite_Set_Classes(USBD_ClassTypeDef *hid_class, USBD_ClassTypeDef *cdc_class) {
|
||||||
USBD_Classes[0] = class0;
|
USBD_Classes[0] = hid_class;
|
||||||
USBD_Classes[1] = class1;
|
USBD_Classes[1] = cdc_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
static USBD_ClassTypeDef * getClass(uint8_t index)
|
||||||
|
{
|
||||||
|
switch(index)
|
||||||
|
{
|
||||||
|
case HID_INTF_NUM:
|
||||||
|
return USBD_Classes[0];
|
||||||
|
case CDC_MASTER_INTF_NUM:
|
||||||
|
case CDC_SLAVE_INTF_NUM:
|
||||||
|
return USBD_Classes[1];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
|
static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < NUM_INTERFACES; i++) {
|
for(i = 0; i < NUM_CLASSES; i++) {
|
||||||
if (USBD_Classes[i]->Init(pdev, cfgidx) != USBD_OK) {
|
if (USBD_Classes[i]->Init(pdev, cfgidx) != USBD_OK) {
|
||||||
return USBD_FAIL;
|
return USBD_FAIL;
|
||||||
}
|
}
|
||||||
@ -213,7 +248,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) {
|
static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
|
||||||
int i;
|
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) {
|
if (USBD_Classes[i]->DeInit(pdev, cfgidx) != USBD_OK) {
|
||||||
return USBD_FAIL;
|
return USBD_FAIL;
|
||||||
}
|
}
|
||||||
@ -224,10 +259,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) {
|
static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) {
|
||||||
int i;
|
int i;
|
||||||
|
USBD_ClassTypeDef * device_class;
|
||||||
|
device_class = getClass(req->wIndex);
|
||||||
|
|
||||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||||
case USB_REQ_TYPE_CLASS :
|
case USB_REQ_TYPE_CLASS :
|
||||||
if (req->wIndex < NUM_INTERFACES)
|
if (device_class != NULL)
|
||||||
return USBD_Classes[req->wIndex]->Setup(pdev, req);
|
return device_class->Setup(pdev, req);
|
||||||
else
|
else
|
||||||
return USBD_FAIL;
|
return USBD_FAIL;
|
||||||
|
|
||||||
@ -236,7 +274,7 @@ static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqType
|
|||||||
switch (req->bRequest) {
|
switch (req->bRequest) {
|
||||||
|
|
||||||
case USB_REQ_GET_DESCRIPTOR :
|
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) {
|
if (USBD_Classes[i]->Setup(pdev, req) != USBD_OK) {
|
||||||
return USBD_FAIL;
|
return USBD_FAIL;
|
||||||
}
|
}
|
||||||
@ -246,8 +284,8 @@ static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqType
|
|||||||
|
|
||||||
case USB_REQ_GET_INTERFACE :
|
case USB_REQ_GET_INTERFACE :
|
||||||
case USB_REQ_SET_INTERFACE :
|
case USB_REQ_SET_INTERFACE :
|
||||||
if (req->wIndex < NUM_INTERFACES)
|
if (device_class != NULL)
|
||||||
return USBD_Classes[req->wIndex]->Setup(pdev, req);
|
return device_class->Setup(pdev, req);
|
||||||
else
|
else
|
||||||
return USBD_FAIL;
|
return USBD_FAIL;
|
||||||
}
|
}
|
||||||
@ -274,7 +312,7 @@ static uint8_t USBD_Composite_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum)
|
|||||||
|
|
||||||
static uint8_t USBD_Composite_EP0_RxReady (USBD_HandleTypeDef *pdev) {
|
static uint8_t USBD_Composite_EP0_RxReady (USBD_HandleTypeDef *pdev) {
|
||||||
int i;
|
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 != NULL) {
|
||||||
if (USBD_Classes[i]->EP0_RxReady(pdev) != USBD_OK) {
|
if (USBD_Classes[i]->EP0_RxReady(pdev) != USBD_OK) {
|
||||||
return USBD_FAIL;
|
return USBD_FAIL;
|
||||||
|
@ -39,6 +39,7 @@ void wait_for_usb_tether();
|
|||||||
|
|
||||||
uint32_t __90_ms = 0;
|
uint32_t __90_ms = 0;
|
||||||
uint32_t __last_button_press_time = 0;
|
uint32_t __last_button_press_time = 0;
|
||||||
|
uint32_t __last_button_bounce_time = 0;
|
||||||
uint32_t __device_status = 0;
|
uint32_t __device_status = 0;
|
||||||
uint32_t __last_update = 0;
|
uint32_t __last_update = 0;
|
||||||
extern PCD_HandleTypeDef hpcd;
|
extern PCD_HandleTypeDef hpcd;
|
||||||
@ -76,6 +77,21 @@ void TIM6_DAC_IRQHandler()
|
|||||||
ctaphid_update_status(__device_status);
|
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
|
#ifndef IS_BOOTLOADER
|
||||||
// NFC sending WTX if needs
|
// NFC sending WTX if needs
|
||||||
if (device_is_nfc() == NFC_IS_ACTIVE)
|
if (device_is_nfc() == NFC_IS_ACTIVE)
|
||||||
@ -84,10 +100,20 @@ void TIM6_DAC_IRQHandler()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interrupt on rising edge of button (button released)
|
||||||
void EXTI0_IRQHandler(void)
|
void EXTI0_IRQHandler(void)
|
||||||
{
|
{
|
||||||
EXTI->PR1 = EXTI->PR1;
|
EXTI->PR1 = EXTI->PR1;
|
||||||
__last_button_press_time = millis();
|
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
|
// Global USB interrupt handler
|
||||||
@ -499,6 +525,41 @@ static int handle_packets()
|
|||||||
return 0;
|
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 ctap_user_presence_test(uint32_t up_delay)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -506,12 +567,7 @@ int ctap_user_presence_test(uint32_t up_delay)
|
|||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// "cache" button presses for 2 seconds.
|
|
||||||
if (millis() - __last_button_press_time < 2000)
|
|
||||||
{
|
|
||||||
__last_button_press_time = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#if SKIP_BUTTON_CHECK_WITH_DELAY
|
#if SKIP_BUTTON_CHECK_WITH_DELAY
|
||||||
int i=500;
|
int i=500;
|
||||||
while(i--)
|
while(i--)
|
||||||
@ -524,53 +580,41 @@ int ctap_user_presence_test(uint32_t up_delay)
|
|||||||
#elif SKIP_BUTTON_CHECK_FAST
|
#elif SKIP_BUTTON_CHECK_FAST
|
||||||
delay(2);
|
delay(2);
|
||||||
ret = handle_packets();
|
ret = handle_packets();
|
||||||
if (ret) return ret;
|
if (ret)
|
||||||
|
return ret;
|
||||||
goto done;
|
goto done;
|
||||||
#endif
|
#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);
|
led_rgb(0xff3520);
|
||||||
|
|
||||||
if (IS_BUTTON_PRESSED == is_touch_button_pressed)
|
// Block and wait for some time.
|
||||||
{
|
ret = wait_for_button_activate(up_delay);
|
||||||
// Wait for user to release touch button if it's already pressed
|
if (ret) return ret;
|
||||||
while (IS_BUTTON_PRESSED())
|
ret = wait_for_button_release(up_delay);
|
||||||
{
|
|
||||||
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();
|
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
}
|
|
||||||
while (! IS_BUTTON_PRESSED());
|
|
||||||
|
|
||||||
led_rgb(0x001040);
|
// If button was pressed within last [2] seconds, succeed.
|
||||||
|
if (__last_button_press_time && (millis() - __last_button_press_time < 2000))
|
||||||
delay(50);
|
{
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
#if SKIP_BUTTON_CHECK_WITH_DELAY || SKIP_BUTTON_CHECK_FAST
|
|
||||||
done:
|
done:
|
||||||
#endif
|
ret = wait_for_button_release(up_delay);
|
||||||
return 1;
|
__last_button_press_time = 0;
|
||||||
|
return 1;
|
||||||
|
|
||||||
fail:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ctap_generate_rng(uint8_t * dst, size_t num)
|
int ctap_generate_rng(uint8_t * dst, size_t num)
|
||||||
|
@ -92,19 +92,27 @@ int nfc_init()
|
|||||||
return NFC_IS_NA;
|
return NFC_IS_NA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t gl_int0 = 0;
|
||||||
void process_int0(uint8_t int0)
|
void process_int0(uint8_t int0)
|
||||||
{
|
{
|
||||||
|
gl_int0 = int0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ams_wait_for_tx(uint32_t timeout_ms)
|
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();
|
uint32_t tstart = millis();
|
||||||
while (tstart + timeout_ms > millis())
|
while (tstart + timeout_ms > millis())
|
||||||
{
|
{
|
||||||
uint8_t int0 = ams_read_reg(AMS_REG_INT0);
|
uint8_t int0 = ams_read_reg(AMS_REG_INT0);
|
||||||
if (int0) process_int0(int0);
|
process_int0(int0);
|
||||||
if (int0 & AMS_INT_TXE)
|
if (int0 & AMS_INT_TXE || int0 & AMS_INT_RXE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
delay(1);
|
delay(1);
|
||||||
@ -121,8 +129,13 @@ bool ams_receive_with_timeout(uint32_t timeout_ms, uint8_t * data, int maxlen, i
|
|||||||
uint32_t tstart = millis();
|
uint32_t tstart = millis();
|
||||||
while (tstart + timeout_ms > millis())
|
while (tstart + timeout_ms > millis())
|
||||||
{
|
{
|
||||||
uint8_t int0 = ams_read_reg(AMS_REG_INT0);
|
uint8_t int0 = 0;
|
||||||
if (int0) process_int0(int0);
|
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);
|
uint8_t buffer_status2 = ams_read_reg(AMS_REG_BUF2);
|
||||||
|
|
||||||
if (buffer_status2 && (int0 & AMS_INT_RXE))
|
if (buffer_status2 && (int0 & AMS_INT_RXE))
|
||||||
@ -196,7 +209,6 @@ bool nfc_write_response(uint8_t req0, uint16_t resp)
|
|||||||
void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
|
void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
|
||||||
{
|
{
|
||||||
uint8_t res[32 + 2];
|
uint8_t res[32 + 2];
|
||||||
int sendlen = 0;
|
|
||||||
uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 0x0f);
|
uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 0x0f);
|
||||||
uint8_t block_offset = p14443_block_offset(req0);
|
uint8_t block_offset = p14443_block_offset(req0);
|
||||||
|
|
||||||
@ -208,6 +220,7 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
|
|||||||
memcpy(&res[block_offset], data, len);
|
memcpy(&res[block_offset], data, len);
|
||||||
nfc_write_frame(res, len + block_offset);
|
nfc_write_frame(res, len + block_offset);
|
||||||
} else {
|
} else {
|
||||||
|
int sendlen = 0;
|
||||||
do {
|
do {
|
||||||
// transmit I block
|
// transmit I block
|
||||||
int vlen = MIN(32 - block_offset, len - sendlen);
|
int vlen = MIN(32 - block_offset, len - sendlen);
|
||||||
@ -227,11 +240,11 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
|
|||||||
sendlen += vlen;
|
sendlen += vlen;
|
||||||
|
|
||||||
// wait for transmit (32 bytes aprox 2,5ms)
|
// wait for transmit (32 bytes aprox 2,5ms)
|
||||||
// if (!ams_wait_for_tx(10))
|
if (!ams_wait_for_tx(5))
|
||||||
// {
|
{
|
||||||
// printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen);
|
printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen);
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if needs to receive R block (not a last block)
|
// if needs to receive R block (not a last block)
|
||||||
if (res[0] & 0x10)
|
if (res[0] & 0x10)
|
||||||
@ -316,7 +329,7 @@ bool WTX_off()
|
|||||||
void WTX_timer_exec()
|
void WTX_timer_exec()
|
||||||
{
|
{
|
||||||
// condition: (timer on) or (not expired[300ms])
|
// condition: (timer on) or (not expired[300ms])
|
||||||
if ((WTX_timer <= 0) || WTX_timer + 300 > millis())
|
if ((WTX_timer == 0) || WTX_timer + 300 > millis())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WTX_process(10);
|
WTX_process(10);
|
||||||
@ -327,12 +340,12 @@ void WTX_timer_exec()
|
|||||||
// read timeout must be 10 ms to call from interrupt
|
// read timeout must be 10 ms to call from interrupt
|
||||||
bool WTX_process(int read_timeout)
|
bool WTX_process(int read_timeout)
|
||||||
{
|
{
|
||||||
uint8_t wtx[] = {0xf2, 0x01};
|
|
||||||
if (WTX_fail)
|
if (WTX_fail)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!WTX_sent)
|
if (!WTX_sent)
|
||||||
{
|
{
|
||||||
|
uint8_t wtx[] = {0xf2, 0x01};
|
||||||
nfc_write_frame(wtx, sizeof(wtx));
|
nfc_write_frame(wtx, sizeof(wtx));
|
||||||
WTX_sent = true;
|
WTX_sent = true;
|
||||||
return true;
|
return true;
|
||||||
@ -618,7 +631,7 @@ void nfc_process_iblock(uint8_t * buf, int len)
|
|||||||
if (!WTX_off())
|
if (!WTX_off())
|
||||||
return;
|
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)
|
if (status == CTAP1_ERR_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -779,6 +792,8 @@ int nfc_loop()
|
|||||||
|
|
||||||
|
|
||||||
read_reg_block(&ams);
|
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;
|
uint8_t state = AMS_STATE_MASK & ams.regs.rfid_status;
|
||||||
|
|
||||||
if (state != AMS_STATE_SELECTED && state != AMS_STATE_SELECTEDX)
|
if (state != AMS_STATE_SELECTED && state != AMS_STATE_SELECTEDX)
|
||||||
@ -792,7 +807,7 @@ int nfc_loop()
|
|||||||
// if (state != AMS_STATE_SENSE)
|
// if (state != AMS_STATE_SENSE)
|
||||||
// printf1(TAG_NFC," %s x%02x\r\n", ams_get_state_string(ams.regs.rfid_status), state);
|
// 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();
|
nfc_state_init();
|
||||||
}
|
}
|
||||||
@ -801,7 +816,7 @@ int nfc_loop()
|
|||||||
// ams_print_int1(ams.regs.int1);
|
// 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)
|
if (ams.regs.buffer_status2)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user