Merge branch 'master' into fix_cdc_interfaces

This commit is contained in:
Conor Patrick 2019-08-15 17:38:57 +08:00 committed by GitHub
commit 21489658a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 136 additions and 65 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)
{ {