Skip to content

Commit

Permalink
feat(core): add support for setting BLE name from Trezor firmware
Browse files Browse the repository at this point in the history
[no changelog]
  • Loading branch information
TychoVrahe committed Jan 23, 2025
1 parent 205a3be commit a5809c8
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 48 deletions.
16 changes: 15 additions & 1 deletion core/embed/io/ble/inc/io/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#define BLE_RX_PACKET_SIZE 244
#define BLE_TX_PACKET_SIZE 64

#define BLE_ADV_NAME_LEN 20

typedef enum {
BLE_SWITCH_OFF = 0, // Turn off BLE advertising, disconnect
BLE_SWITCH_ON = 1, // Turn on BLE advertising
Expand All @@ -37,6 +39,18 @@ typedef enum {
BLE_ERASE_BONDS = 4, // Erase all bonding information
BLE_ALLOW_PAIRING = 5, // Accept pairing request
BLE_REJECT_PAIRING = 6, // Reject pairing request
} ble_command_type_t;

typedef union {
uint8_t raw[32];
uint8_t name[BLE_ADV_NAME_LEN];

} ble_command_data_t;

typedef struct {
ble_command_type_t cmd_type;
uint8_t data_len;
ble_command_data_t data;
} ble_command_t;

typedef enum {
Expand Down Expand Up @@ -91,7 +105,7 @@ void ble_stop(void);
// Sends a specific command to the BLE module for execution.
//
// Returns `true` if the command was successfully issued.
bool ble_issue_command(ble_command_t command);
bool ble_issue_command(ble_command_t *command);

// Reads an event from the BLE module
//
Expand Down
34 changes: 19 additions & 15 deletions core/embed/io/ble/stm32/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <sys/irq.h>
#include <sys/systimer.h>
#include <util/tsqueue.h>
#include <util/unit_properties.h>

#include "ble_comm_defs.h"

Expand Down Expand Up @@ -65,6 +66,7 @@ typedef struct {
tsqueue_entry_t ts_queue_entries[TX_QUEUE_LEN];
tsqueue_t tx_queue;

char adv_name[BLE_ADV_NAME_LEN];
systimer_t *timer;
uint16_t ping_cntr;
} ble_driver_t;
Expand All @@ -80,11 +82,19 @@ static bool ble_send_state_request(ble_driver_t *drv) {

static bool ble_send_advertising_on(ble_driver_t *drv, bool whitelist) {
(void)drv;
uint8_t data[2];
data[0] = INTERNAL_CMD_ADVERTISING_ON;
data[1] = whitelist ? 1 : 0;
return nrf_send_msg(NRF_SERVICE_BLE_MANAGER, data, sizeof(data), NULL,
NULL) >= 0;

unit_properties_t props;
unit_properties_get(&props);

cmd_advertising_on_t data = {
.cmd_id = INTERNAL_CMD_ADVERTISING_ON,
.whitelist = whitelist ? 1 : 0,
.color = props.color,
};
memcpy(data.name, drv->adv_name, BLE_ADV_NAME_LEN);

return nrf_send_msg(NRF_SERVICE_BLE_MANAGER, (uint8_t *)&data, sizeof(data),
NULL, NULL) >= 0;
}

static bool ble_send_advertising_off(ble_driver_t *drv) {
Expand Down Expand Up @@ -146,14 +156,6 @@ static void ble_process_rx_msg_status(const uint8_t *data, uint32_t len) {
event_status_msg_t msg;
memcpy(&msg, data, sizeof(event_status_msg_t));

if (!drv->status_valid) {
if (msg.peer_count > 0) {
drv->mode_requested = BLE_MODE_CONNECTABLE;
} else {
drv->mode_requested = BLE_MODE_OFF;
}
}

if (drv->connected != msg.connected) {
if (msg.connected) {
// new connection
Expand Down Expand Up @@ -507,7 +509,7 @@ uint32_t ble_read(uint8_t *data, uint16_t max_len) {
return read_len;
}

bool ble_issue_command(ble_command_t command) {
bool ble_issue_command(ble_command_t *command) {
ble_driver_t *drv = &g_ble_driver;

if (!drv->initialized) {
Expand All @@ -518,14 +520,16 @@ bool ble_issue_command(ble_command_t command) {

bool result = false;

switch (command) {
switch (command->cmd_type) {
case BLE_SWITCH_OFF:
drv->mode_requested = BLE_MODE_OFF;
break;
case BLE_SWITCH_ON:
memcpy(drv->adv_name, command->data.name, sizeof(drv->adv_name));
drv->mode_requested = BLE_MODE_CONNECTABLE;
break;
case BLE_PAIRING_MODE:
memcpy(drv->adv_name, command->data.name, sizeof(drv->adv_name));
drv->mode_requested = BLE_MODE_PAIRING;
break;
case BLE_DISCONNECT:
Expand Down
13 changes: 10 additions & 3 deletions core/embed/io/ble/stm32/ble_comm_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef TREZORHAL_BLE_COMM_DEFS_H_
#define TREZORHAL_BLE_COMM_DEFS_H_
#pragma once

#include <trezor_types.h>

#include <io/ble.h>

typedef struct {
uint8_t msg_id;
uint8_t connected;
Expand Down Expand Up @@ -56,4 +57,10 @@ typedef enum {
INTERNAL_CMD_ALLOW_PAIRING = 0x06,
INTERNAL_CMD_REJECT_PAIRING = 0x07,
} internal_cmd_t;
#endif

typedef struct {
uint8_t cmd_id;
uint8_t whitelist;
uint8_t color;
uint8_t name[BLE_ADV_NAME_LEN];
} cmd_advertising_on_t;
31 changes: 27 additions & 4 deletions core/embed/rust/src/trezorhal/ble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,43 @@ pub fn connected() -> bool {
}
}

pub fn pairing_mode() {
pub fn pairing_mode(name: &str) {
unsafe {
ffi::ble_issue_command(ffi::ble_command_t_BLE_PAIRING_MODE);
let mut cmd = ffi::ble_command_t {
cmd_type: ffi::ble_command_type_t_BLE_PAIRING_MODE,
data_len: 0,
data: ffi::ble_command_data_t { raw: [0; 32] },
};

let bytes = name.as_bytes();

// Determine how many bytes we can copy (min of buffer size and string length).
let len = bytes.len().min(cmd.data.name.len());

cmd.data.name[..len].copy_from_slice(&bytes[..len]);

ffi::ble_issue_command(&mut cmd as _);
}
}

pub fn allow_pairing() {
unsafe {
ffi::ble_issue_command(ffi::ble_command_t_BLE_ALLOW_PAIRING);
let mut cmd = ffi::ble_command_t {
cmd_type: ffi::ble_command_type_t_BLE_ALLOW_PAIRING,
data_len: 0,
data: ffi::ble_command_data_t { raw: [0; 32] },
};
ffi::ble_issue_command(&mut cmd as _);
}
}

pub fn reject_pairing() {
unsafe {
ffi::ble_issue_command(ffi::ble_command_t_BLE_REJECT_PAIRING);
let mut cmd = ffi::ble_command_t {
cmd_type: ffi::ble_command_type_t_BLE_REJECT_PAIRING,
data_len: 0,
data: ffi::ble_command_data_t { raw: [0; 32] },
};
ffi::ble_issue_command(&mut cmd as _);
}
}
4 changes: 2 additions & 2 deletions core/embed/sys/syscall/stm32/syscall_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,8 +687,8 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
} break;

case SYSCALL_BLE_ISSUE_COMMAND: {
ble_command_t command = args[0];
ble_issue_command(command);
ble_command_t *command = (ble_command_t *)args[0];
args[0] = ble_issue_command__verified(command);
} break;

case SYSCALL_BLE_GET_STATE: {
Expand Down
2 changes: 1 addition & 1 deletion core/embed/sys/syscall/stm32/syscall_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ secbool firmware_calc_hash(const uint8_t *challenge, size_t challenge_len,

void ble_start(void) { syscall_invoke0(SYSCALL_BLE_START); }

bool ble_issue_command(ble_command_t command) {
bool ble_issue_command(ble_command_t *command) {
return (bool)syscall_invoke1((uint32_t)command, SYSCALL_BLE_ISSUE_COMMAND);
}

Expand Down
12 changes: 12 additions & 0 deletions core/embed/sys/syscall/stm32/syscall_verifiers.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,18 @@ secbool firmware_get_vendor__verified(char *buff, size_t buff_size) {
// ---------------------------------------------------------------------

#ifdef USE_BLE
bool ble_issue_command__verified(ble_command_t *command) {
if (!probe_read_access(command, sizeof(*command))) {
goto access_violation;
}

return ble_issue_command(command);

access_violation:
apptask_access_violation();
return false;
}

void ble_get_state__verified(ble_state_t *state) {
if (!probe_write_access(state, sizeof(*state))) {
goto access_violation;
Expand Down
2 changes: 2 additions & 0 deletions core/embed/sys/syscall/stm32/syscall_verifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ secbool firmware_get_vendor__verified(char *buff, size_t buff_size);

#include <io/ble.h>

bool ble_issue_command__verified(ble_command_t *state);

void ble_get_state__verified(ble_state_t *state);

bool ble_get_event__verified(ble_event_t *event);
Expand Down
71 changes: 54 additions & 17 deletions core/embed/upymod/modtrezorio/modtrezorio-ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,18 @@ STATIC mp_obj_t mod_trezorio_BLE_read(size_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorio_BLE_read_obj, 1, 2,
mod_trezorio_BLE_read);

/// def erase_bonds() -> None:
/// def erase_bonds() -> bool:
/// """
/// Erases all BLE bonds
/// """
STATIC mp_obj_t mod_trezorio_BLE_erase_bonds(void) {
ble_issue_command(BLE_ERASE_BONDS);
return mp_const_none;
ble_command_t cmd = {.cmd_type = BLE_ERASE_BONDS, .data_len = 0};
return mp_obj_new_bool(ble_issue_command(&cmd));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_erase_bonds_obj,
mod_trezorio_BLE_erase_bonds);

/// def start_comm() -> None:
/// def start_comm() -> bool:
/// """
/// Start communication with BLE chip
/// """
Expand All @@ -146,41 +146,76 @@ STATIC mp_obj_t mod_trezorio_BLE_start_comm(void) {
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_start_comm_obj,
mod_trezorio_BLE_start_comm);

/// def start_advertising(whitelist: bool) -> None:
/// def start_advertising(whitelist: bool, name: str | None) -> bool:
/// """
/// Start advertising
/// """
STATIC mp_obj_t mod_trezorio_BLE_start_advertising(mp_obj_t whitelist) {
bool whitelist_bool = mp_obj_is_true(whitelist);
STATIC mp_obj_t mod_trezorio_BLE_start_advertising(size_t n_args,
const mp_obj_t *args) {
bool whitelist_bool = mp_obj_is_true(args[0]);

ble_issue_command(whitelist_bool ? BLE_SWITCH_ON : BLE_PAIRING_MODE);
return mp_const_none;
mp_buffer_info_t name = {0};

char *name_buf = NULL;
int name_len = 0;

if (n_args == 1 || !mp_get_buffer(args[1], &name, MP_BUFFER_READ)) {
name_buf = MODEL_FULL_NAME;
name_len = strlen(MODEL_FULL_NAME);
} else {
name_buf = name.buf;
name_len = name.len;
}

ble_command_t cmd = {
.cmd_type = whitelist_bool ? BLE_SWITCH_ON : BLE_PAIRING_MODE,
.data_len = name.len};

// get a minimum of the two lengths
int len = name_len < BLE_ADV_NAME_LEN ? name_len : BLE_ADV_NAME_LEN;

memcpy(cmd.data.name, name_buf, len);

return mp_obj_new_bool(ble_issue_command(&cmd));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_BLE_start_advertising_obj,
mod_trezorio_BLE_start_advertising);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mod_trezorio_BLE_start_advertising_obj, 1, 2,
mod_trezorio_BLE_start_advertising);

/// def stop_advertising(whitelist: bool) -> None:
/// def stop_advertising(whitelist: bool) -> bool:
/// """
/// Stop advertising
/// """
STATIC mp_obj_t mod_trezorio_BLE_stop_advertising(void) {
ble_issue_command(BLE_SWITCH_OFF);
return mp_const_none;
ble_command_t cmd = {.cmd_type = BLE_SWITCH_OFF, .data_len = 0};
return mp_obj_new_bool(ble_issue_command(&cmd));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_stop_advertising_obj,
mod_trezorio_BLE_stop_advertising);

/// def disconnect() -> None:
/// def disconnect() -> bool:
/// """
/// Disconnect BLE
/// """
STATIC mp_obj_t mod_trezorio_BLE_disconnect(void) {
ble_issue_command(BLE_DISCONNECT);
return mp_const_none;
ble_command_t cmd = {.cmd_type = BLE_DISCONNECT, .data_len = 0};
return mp_obj_new_bool(ble_issue_command(&cmd));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_disconnect_obj,
mod_trezorio_BLE_disconnect);

/// def peer_count() -> int:
/// """
/// Get peer count (number of bonded devices)
/// """
STATIC mp_obj_t mod_trezorio_BLE_peer_count(void) {
ble_state_t state;
ble_get_state(&state);
return MP_OBJ_NEW_SMALL_INT(state.peer_count);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_BLE_peer_count_obj,
mod_trezorio_BLE_peer_count);

STATIC const mp_rom_map_elem_t mod_trezorio_BLE_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ble)},
// {MP_ROM_QSTR(MP_QSTR_update_init),
Expand All @@ -199,6 +234,8 @@ STATIC const mp_rom_map_elem_t mod_trezorio_BLE_globals_table[] = {
MP_ROM_PTR(&mod_trezorio_BLE_stop_advertising_obj)},
{MP_ROM_QSTR(MP_QSTR_disconnect),
MP_ROM_PTR(&mod_trezorio_BLE_disconnect_obj)},
{MP_ROM_QSTR(MP_QSTR_peer_count),
MP_ROM_PTR(&mod_trezorio_BLE_peer_count_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_BLE_globals,
mod_trezorio_BLE_globals_table);
Expand Down
Loading

0 comments on commit a5809c8

Please sign in to comment.