diff --git a/core/embed/io/ble/stm32/ble.c b/core/embed/io/ble/stm32/ble.c index 9dac29b4716..68c2f57c03a 100644 --- a/core/embed/io/ble/stm32/ble.c +++ b/core/embed/io/ble/stm32/ble.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -385,7 +386,13 @@ bool ble_connected(void) { return false; } - return drv->connected && nrf_is_running(); + irq_key_t key = irq_lock(); + + bool connected = drv->connected && nrf_is_running(); + + irq_unlock(key); + + return connected; } void ble_start(void) { @@ -395,7 +402,11 @@ void ble_start(void) { return; } + irq_key_t key = irq_lock(); + drv->accept_msgs = true; + + irq_unlock(key); } void ble_stop(void) { @@ -405,8 +416,12 @@ void ble_stop(void) { return; } + irq_key_t key = irq_lock(); + drv->accept_msgs = false; tsqueue_reset(&drv->rx_queue); + + irq_unlock(key); } bool ble_can_write(void) { @@ -416,11 +431,18 @@ bool ble_can_write(void) { return false; } + irq_key_t key = irq_lock(); + if (!drv->connected || !drv->accept_msgs) { + irq_unlock(key); return false; } - return !tsqueue_full(&drv->tx_queue); + bool full = !tsqueue_full(&drv->tx_queue); + + irq_unlock(key); + + return full; } bool ble_write(const uint8_t *data, uint16_t len) { @@ -430,7 +452,10 @@ bool ble_write(const uint8_t *data, uint16_t len) { return false; } + irq_key_t key = irq_lock(); + if (!drv->connected || !drv->accept_msgs) { + irq_unlock(key); return false; } @@ -438,9 +463,11 @@ bool ble_write(const uint8_t *data, uint16_t len) { if (!sent) { bool queued = tsqueue_enqueue(&drv->tx_queue, data, len, NULL); + irq_unlock(key); return queued; } + irq_unlock(key); return true; } @@ -451,7 +478,13 @@ bool ble_can_read(void) { return false; } - return !tsqueue_empty(&drv->rx_queue); + irq_key_t key = irq_lock(); + + bool result = !tsqueue_empty(&drv->rx_queue); + + irq_unlock(key); + + return result; } uint32_t ble_read(uint8_t *data, uint16_t max_len) { @@ -461,12 +494,16 @@ uint32_t ble_read(uint8_t *data, uint16_t max_len) { return 0; } + irq_key_t key = irq_lock(); + tsqueue_t *queue = &drv->rx_queue; uint16_t read_len = 0; tsqueue_dequeue(queue, data, max_len, &read_len, NULL); + irq_unlock(key); + return read_len; } @@ -477,6 +514,8 @@ bool ble_issue_command(ble_command_t command) { return false; } + irq_key_t key = irq_lock(); + bool result = false; switch (command) { @@ -502,10 +541,11 @@ bool ble_issue_command(ble_command_t command) { result = ble_send_pairing_reject(drv); break; default: - // unknown command - return false; + break; } + irq_unlock(key); + return result; } @@ -516,8 +556,14 @@ bool ble_get_event(ble_event_t *event) { return false; } - return tsqueue_dequeue(&drv->event_queue, (uint8_t *)event, sizeof(*event), - NULL, NULL); + irq_key_t key = irq_lock(); + + bool result = tsqueue_dequeue(&drv->event_queue, (uint8_t *)event, + sizeof(*event), NULL, NULL); + + irq_unlock(key); + + return result; } void ble_get_state(ble_state_t *state) { @@ -528,11 +574,15 @@ void ble_get_state(ble_state_t *state) { return; } + irq_key_t key = irq_lock(); + state->connected = drv->connected; state->peer_count = drv->peer_count; state->pairing = drv->mode_current == BLE_MODE_PAIRING; state->connectable = drv->mode_current == BLE_MODE_CONNECTABLE; state->pairing_requested = drv->pairing_requested; + + irq_unlock(key); } #endif