Merge branch 'master' into fix_cdc_interfaces
This commit is contained in:
commit
21489658a7
@ -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
|
||||||
|
@ -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)
|
||||||
@ -90,6 +106,21 @@ void EXTI0_IRQHandler(void)
|
|||||||
__last_button_press_time = millis();
|
__last_button_press_time = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// Global USB interrupt handler
|
||||||
void USB_IRQHandler(void)
|
void USB_IRQHandler(void)
|
||||||
{
|
{
|
||||||
@ -499,6 +530,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 +572,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 +585,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
|
|
||||||
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;
|
if (ret) return ret;
|
||||||
}
|
ret = wait_for_button_release(up_delay);
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user