feat(core): ble in bootloader

[no changelog]
tychovrahe/bluetooth/unification2
tychovrahe 1 year ago
parent e1381f901b
commit f04d8da661

@ -20,7 +20,7 @@ if TREZOR_MODEL in ('1', ):
)
Return()
FEATURES_WANTED = ["input", "rgb_led"]
FEATURES_WANTED = ["input", "rgb_led", "ble"]
CCFLAGS_MOD = ''
CPPPATH_MOD = []
@ -34,9 +34,9 @@ if TREZOR_MODEL in ('1', 'R'):
FONT_MONO='Font_PixelOperatorMono_Regular_8'
if TREZOR_MODEL in ('T', 'DISC1', ):
FONT_NORMAL='Font_TTHoves_Regular_21'
FONT_DEMIBOLD=None
FONT_DEMIBOLD='Font_TTHoves_Regular_21'
FONT_BOLD='Font_TTHoves_Bold_17'
FONT_MONO=None
FONT_MONO='Font_TTHoves_Regular_21'
# modtrezorcrypto
CCFLAGS_MOD += '-Wno-sequence-point '
@ -104,6 +104,7 @@ SOURCE_STMHAL = [
'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c',
'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c',
'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c',
'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c',
'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c',
'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c',
'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c',
@ -126,6 +127,7 @@ SOURCE_BOOTLOADER = [
SOURCE_TREZORHAL = [
'embed/trezorhal/common.c',
'embed/trezorhal/dma.c',
'embed/trezorhal/image.c',
'embed/trezorhal/flash.c',
'embed/trezorhal/mini_printf.c',

@ -49,11 +49,16 @@
#ifdef USE_RGB_LED
#include "rgb_led.h"
#endif
#ifdef USE_BLE
#include "ble/comm.h"
#endif
#include "usb.h"
#include "version.h"
#include "bootui.h"
#include "messages.h"
#include "messages.pb.h"
#include "rust_ui.h"
const uint8_t BOOTLOADER_KEY_M = 2;
@ -71,8 +76,6 @@ static const uint8_t * const BOOTLOADER_KEYS[] = {
#endif
};
#define USB_IFACE_NUM 0
typedef enum {
CONTINUE = 0,
RETURN = 1,
@ -119,98 +122,221 @@ static void usb_init_all(secbool usb21_landing) {
usb_start();
}
static usb_result_t bootloader_usb_loop(const vendor_header *const vhdr,
const image_header *const hdr) {
static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
const image_header *const hdr) {
// if both are NULL, we don't have a firmware installed
// let's show a webusb landing page in this case
usb_init_all((vhdr == NULL && hdr == NULL) ? sectrue : secfalse);
uint8_t buf[USB_PACKET_SIZE];
uint8_t buf_usb[USB_PACKET_SIZE];
#ifdef USE_BLE
uint8_t ble_buf[BLE_PACKET_SIZE];
#endif
uint8_t *buf = NULL;
uint8_t active_iface = 0;
int r = 0;
for (;;) {
for (;;) {
#ifdef TREZOR_EMULATOR
emulator_poll_events();
emulator_poll_events();
#endif
int r = usb_webusb_read_blocking(USB_IFACE_NUM, buf, USB_PACKET_SIZE,
USB_TIMEOUT);
if (r != USB_PACKET_SIZE) {
continue;
}
uint16_t msg_id;
uint32_t msg_size;
uint32_t response;
if (sectrue != msg_parse_header(buf, &msg_id, &msg_size)) {
// invalid header -> discard
continue;
}
switch (msg_id) {
case 0: // Initialize
process_msg_Initialize(USB_IFACE_NUM, msg_size, buf, vhdr, hdr);
r = usb_webusb_read_blocking(USB_IFACE_NUM, buf_usb, USB_PACKET_SIZE, 20);
if (r == USB_PACKET_SIZE) {
active_iface = USB_IFACE_NUM;
buf = buf_usb;
break;
case 1: // Ping
process_msg_Ping(USB_IFACE_NUM, msg_size, buf);
}
#ifdef USE_BLE
r = ble_ext_comm_receive(ble_buf, sizeof(ble_buf));
if (r == BLE_PACKET_SIZE) {
active_iface = BLE_EXT_IFACE_NUM;
buf = ble_buf;
break;
}
r = ble_int_comm_receive(ble_buf, sizeof(ble_buf));
if (r != 0) {
active_iface = BLE_INT_IFACE_NUM;
buf = ble_buf;
break;
case 5: // WipeDevice
response = ui_screen_wipe_confirm();
if (INPUT_CANCEL == response) {
send_user_abort(USB_IFACE_NUM, "Wipe cancelled");
hal_delay(100);
usb_stop();
usb_deinit();
return RETURN;
}
#endif
}
#ifdef USE_BLE
if (active_iface == BLE_INT_IFACE_NUM) {
for (;;) {
bool next = false;
if (r == 0) {
if (active_iface == BLE_INT_IFACE_NUM) {
r = ble_int_comm_receive(ble_buf, sizeof(ble_buf));
if (r == 0) {
continue;
}
} else {
// unknown interface
return CONTINUE;
}
}
ui_screen_wipe();
r = process_msg_WipeDevice(USB_IFACE_NUM, msg_size, buf);
if (r < 0) { // error
screen_wipe_fail();
hal_delay(100);
usb_stop();
usb_deinit();
return SHUTDOWN;
} else { // success
screen_wipe_success();
hal_delay(100);
usb_stop();
usb_deinit();
return SHUTDOWN;
r = 0;
uint16_t msg_id;
uint32_t msg_size;
uint32_t response;
if (sectrue != msg_parse_header(buf, &msg_id, &msg_size)) {
// invalid header -> discard
continue;
}
break;
case 6: // FirmwareErase
process_msg_FirmwareErase(USB_IFACE_NUM, msg_size, buf);
break;
case 7: // FirmwareUpload
r = process_msg_FirmwareUpload(USB_IFACE_NUM, msg_size, buf);
if (r < 0 && r != UPLOAD_ERR_USER_ABORT) { // error, but not user abort
ui_screen_fail();
usb_stop();
usb_deinit();
return SHUTDOWN;
} else if (r == UPLOAD_ERR_USER_ABORT) {
hal_delay(100);
usb_stop();
usb_deinit();
return RETURN;
} else if (r == 0) { // last chunk received
ui_screen_install_progress_upload(1000);
ui_screen_done(4, sectrue);
ui_screen_done(3, secfalse);
hal_delay(1000);
ui_screen_done(2, secfalse);
hal_delay(1000);
ui_screen_done(1, secfalse);
hal_delay(1000);
usb_stop();
usb_deinit();
ui_screen_boot_empty(true);
return CONTINUE;
switch (msg_id) {
case MessageType_MessageType_PairingRequest: // pairing request
response = process_msg_Pairing(active_iface, msg_size, ble_buf);
if (response != INPUT_CONFIRM) {
hal_delay(100);
usb_stop();
usb_deinit();
return RETURN;
}
screen_connect();
next = true;
break;
case MessageType_MessageType_RepairRequest: // repairing request
response = process_msg_Repair(active_iface, msg_size, ble_buf);
if (response != INPUT_CONFIRM) {
hal_delay(100);
usb_stop();
usb_deinit();
return RETURN;
}
// screen_connect();
// todo - screen connect or timeout?
break;
default:
process_msg_unknown(active_iface, msg_size, ble_buf);
break;
}
break;
case 55: // GetFeatures
process_msg_GetFeatures(USB_IFACE_NUM, msg_size, buf, vhdr, hdr);
break;
default:
process_msg_unknown(USB_IFACE_NUM, msg_size, buf);
break;
if (next) {
break;
}
}
}
#endif
if (active_iface == USB_IFACE_NUM || active_iface == BLE_EXT_IFACE_NUM) {
for (;;) {
#ifdef TREZOR_EMULATOR
emulator_poll_events();
#endif
if (r == 0) {
if (active_iface == USB_IFACE_NUM) {
r = usb_webusb_read_blocking(active_iface, buf_usb, USB_PACKET_SIZE,
USB_TIMEOUT);
if (r != USB_PACKET_SIZE) {
continue;
}
}
#ifdef USE_BLE
else if (active_iface == BLE_EXT_IFACE_NUM) {
r = ble_ext_comm_receive(ble_buf, sizeof(ble_buf));
if (r != BLE_PACKET_SIZE) {
continue;
}
}
#endif
else {
// unknown interface
return CONTINUE;
}
}
r = 0;
uint16_t msg_id;
uint32_t msg_size;
uint32_t response;
int32_t upload_response;
if (sectrue != msg_parse_header(buf, &msg_id, &msg_size)) {
// invalid header -> discard
continue;
}
switch (msg_id) {
case 0: // Initialize
process_msg_Initialize(active_iface, msg_size, buf, vhdr, hdr);
break;
case 1: // Ping
process_msg_Ping(active_iface, msg_size, buf);
break;
case 5: // WipeDevice
response = ui_screen_wipe_confirm();
if (INPUT_CANCEL == response) {
send_user_abort(active_iface, "Wipe cancelled");
hal_delay(100);
usb_stop();
usb_deinit();
return RETURN;
}
ui_screen_wipe();
upload_response =
process_msg_WipeDevice(active_iface, msg_size, buf);
if (upload_response < 0) { // error
screen_wipe_fail();
usb_stop();
usb_deinit();
return SHUTDOWN;
} else { // success
screen_wipe_success();
usb_stop();
usb_deinit();
return SHUTDOWN;
}
break;
case 6: // FirmwareErase
process_msg_FirmwareErase(active_iface, msg_size, buf);
break;
case 7: // FirmwareUpload
upload_response =
process_msg_FirmwareUpload(active_iface, msg_size, buf);
if (upload_response < 0 &&
upload_response !=
UPLOAD_ERR_USER_ABORT) { // error, but not user abort
ui_screen_fail();
usb_stop();
usb_deinit();
return SHUTDOWN;
} else if (upload_response == UPLOAD_ERR_USER_ABORT) {
hal_delay(100);
usb_stop();
usb_deinit();
return RETURN;
} else if (upload_response == 0) { // last chunk received
ui_screen_install_progress_upload(1000);
ui_screen_done(4, sectrue);
ui_screen_done(3, secfalse);
hal_delay(1000);
ui_screen_done(2, secfalse);
hal_delay(1000);
ui_screen_done(1, secfalse);
hal_delay(1000);
usb_stop();
usb_deinit();
ui_screen_boot_empty(true);
return CONTINUE;
}
break;
case 55: // GetFeatures
process_msg_GetFeatures(active_iface, msg_size, buf, vhdr, hdr);
break;
default:
process_msg_unknown(active_iface, msg_size, buf);
break;
}
}
}
}
}
@ -343,6 +469,9 @@ int bootloader_main(void) {
#ifdef USE_RGB_LED
rgb_led_init();
#endif
#ifdef USE_BLE
ble_comm_init();
#endif
#if PRODUCTION
check_bootloader_version();
@ -402,7 +531,7 @@ int bootloader_main(void) {
NULL);
// and start the usb loop
if (bootloader_usb_loop(NULL, NULL) != CONTINUE) {
if (bootloader_comm_loop(NULL, NULL) != CONTINUE) {
return 1;
}
}
@ -461,7 +590,7 @@ int bootloader_main(void) {
break;
case SCREEN_WAIT_FOR_HOST:
screen_connect();
switch (bootloader_usb_loop(&vhdr, hdr)) {
switch (bootloader_comm_loop(&vhdr, hdr)) {
case CONTINUE:
continue_to_firmware = true;
break;

@ -24,6 +24,11 @@
#include <pb_encode.h>
#include "messages.pb.h"
#include TREZOR_BOARD
#ifdef USE_BLE
#include "ble/comm.h"
#endif
#include "common.h"
#include "flash.h"
#include "image.h"
@ -36,6 +41,7 @@
#include "rust_ui.h"
#include "memzero.h"
#include STM32_HAL_H
#ifdef TREZOR_EMULATOR
#include "emulator.h"
@ -59,12 +65,11 @@ typedef struct {
uint8_t packet_index;
uint8_t packet_pos;
uint8_t buf[USB_PACKET_SIZE];
} usb_write_state;
} write_state;
/* we don't use secbool/sectrue/secfalse here as it is a nanopb api */
static bool _usb_write(pb_ostream_t *stream, const pb_byte_t *buf,
size_t count) {
usb_write_state *state = (usb_write_state *)(stream->state);
static bool _write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) {
write_state *state = (write_state *)(stream->state);
size_t written = 0;
// while we have data left
@ -84,9 +89,20 @@ static bool _usb_write(pb_ostream_t *stream, const pb_byte_t *buf,
USB_PACKET_SIZE - state->packet_pos);
written += USB_PACKET_SIZE - state->packet_pos;
// send packet
int r = usb_webusb_write_blocking(state->iface_num, state->buf,
USB_PACKET_SIZE, USB_TIMEOUT);
ensure(sectrue * (r == USB_PACKET_SIZE), NULL);
if (state->iface_num == USB_IFACE_NUM) {
int r = usb_webusb_write_blocking(state->iface_num, state->buf,
USB_PACKET_SIZE, USB_TIMEOUT);
ensure(sectrue * (r == USB_PACKET_SIZE), NULL);
}
#ifdef USE_BLE
else if (state->iface_num == BLE_INT_IFACE_NUM) {
ble_int_comm_send(state->buf, USB_PACKET_SIZE, INTERNAL_MESSAGE);
} else if (state->iface_num == BLE_EXT_IFACE_NUM) {
ble_int_comm_send(state->buf, USB_PACKET_SIZE, EXTERNAL_MESSAGE);
}
#endif
// prepare new packet
state->packet_index++;
memzero(state->buf, USB_PACKET_SIZE);
@ -98,7 +114,7 @@ static bool _usb_write(pb_ostream_t *stream, const pb_byte_t *buf,
return true;
}
static void _usb_write_flush(usb_write_state *state) {
static void _write_flush(write_state *state) {
// if packet is not filled up completely
if (state->packet_pos < USB_PACKET_SIZE) {
// pad it with zeroes
@ -106,9 +122,18 @@ static void _usb_write_flush(usb_write_state *state) {
USB_PACKET_SIZE - state->packet_pos);
}
// send packet
int r = usb_webusb_write_blocking(state->iface_num, state->buf,
USB_PACKET_SIZE, USB_TIMEOUT);
ensure(sectrue * (r == USB_PACKET_SIZE), NULL);
if (state->iface_num == USB_IFACE_NUM) {
int r = usb_webusb_write_blocking(state->iface_num, state->buf,
USB_PACKET_SIZE, USB_TIMEOUT);
ensure(sectrue * (r == USB_PACKET_SIZE), NULL);
}
#ifdef USE_BLE
else if (state->iface_num == BLE_INT_IFACE_NUM) {
ble_int_comm_send(state->buf, USB_PACKET_SIZE, INTERNAL_MESSAGE);
} else if (state->iface_num == BLE_EXT_IFACE_NUM) {
ble_int_comm_send(state->buf, USB_PACKET_SIZE, EXTERNAL_MESSAGE);
}
#endif
}
static secbool _send_msg(uint8_t iface_num, uint16_t msg_id,
@ -124,7 +149,7 @@ static secbool _send_msg(uint8_t iface_num, uint16_t msg_id,
}
const uint32_t msg_size = sizestream.bytes_written;
usb_write_state state = {
write_state state = {
.iface_num = iface_num,
.packet_index = 0,
.packet_pos = MSG_HEADER1_LEN,
@ -142,7 +167,7 @@ static secbool _send_msg(uint8_t iface_num, uint16_t msg_id,
},
};
pb_ostream_t stream = {.callback = &_usb_write,
pb_ostream_t stream = {.callback = _write,
.state = &state,
.max_size = SIZE_MAX,
.bytes_written = 0,
@ -152,9 +177,17 @@ static secbool _send_msg(uint8_t iface_num, uint16_t msg_id,
return secfalse;
}
_usb_write_flush(&state);
_write_flush(&state);
return secfalse;
}
return sectrue;
/* we don't use secbool/sectrue/secfalse here as it is a nanopb api */
static bool _write_authkey(pb_ostream_t *stream, const pb_field_iter_t *field,
void *const *arg) {
uint8_t *key = (uint8_t *)(*arg);
if (!pb_encode_tag_for_field(stream, field)) return false;
return pb_encode_string(stream, (uint8_t *)key, 6);
}
#define MSG_SEND_INIT(TYPE) TYPE msg_send = TYPE##_init_default
@ -185,6 +218,11 @@ static secbool _send_msg(uint8_t iface_num, uint16_t msg_id,
MIN(LEN, sizeof(msg_send.FIELD.bytes))); \
msg_send.FIELD.size = MIN(LEN, sizeof(msg_send.FIELD.bytes)); \
}
#define MSG_SEND_CALLBACK(FIELD, CALLBACK, ARGUMENT) \
{ \
msg_send.FIELD.funcs.encode = &CALLBACK; \
msg_send.FIELD.arg = (void *)ARGUMENT; \
}
#define MSG_SEND(TYPE) \
_send_msg(iface_num, MessageType_MessageType_##TYPE, TYPE##_fields, &msg_send)
@ -192,8 +230,9 @@ typedef struct {
uint8_t iface_num;
uint8_t packet_index;
uint8_t packet_pos;
uint16_t packet_size;
uint8_t *buf;
} usb_read_state;
} read_state;
static void _usb_webusb_read_retry(uint8_t iface_num, uint8_t *buf) {
for (int retry = 0;; retry++) {
@ -213,16 +252,54 @@ static void _usb_webusb_read_retry(uint8_t iface_num, uint8_t *buf) {
}
}
#ifdef USE_BLE
static void _ble_read_retry(uint8_t iface_num, uint8_t *buf) {
for (int retry = 0;; retry++) {
int r = ble_ext_comm_receive(buf, BLE_PACKET_SIZE);
if (r != BLE_PACKET_SIZE) { // reading failed
if (r == 0 && retry < 500) {
// only timeout => let's try again
HAL_Delay(10);
continue;
} else {
// error
error_shutdown("BLE ERROR",
"Error reading from BLE. Try different BLE cable.");
}
}
return; // success
}
}
static void _ble_read_retry_int(uint8_t iface_num, uint8_t *buf) {
for (int retry = 0;; retry++) {
int r = ble_int_comm_receive(buf, USB_PACKET_SIZE);
if (r == 0) { // reading failed
if (retry < 500) {
// only timeout => let's try again
HAL_Delay(10);
continue;
} else {
// error
error_shutdown("BLE ERROR",
"Error reading from BLE. Try different BLE cable.");
}
}
return; // success
}
}
#endif
/* we don't use secbool/sectrue/secfalse here as it is a nanopb api */
static bool _usb_read(pb_istream_t *stream, uint8_t *buf, size_t count) {
usb_read_state *state = (usb_read_state *)(stream->state);
static bool _read(pb_istream_t *stream, uint8_t *buf, size_t count) {
read_state *state = (read_state *)(stream->state);
size_t read = 0;
// while we have data left
while (read < count) {
size_t remaining = count - read;
// if all remaining data fit into our packet
if (state->packet_pos + remaining <= USB_PACKET_SIZE) {
if (state->packet_pos + remaining <= state->packet_size) {
// append data from buf to state->buf
memcpy(buf + read, state->buf + state->packet_pos, remaining);
// advance position
@ -232,10 +309,19 @@ static bool _usb_read(pb_istream_t *stream, uint8_t *buf, size_t count) {
} else {
// append data that fits
memcpy(buf + read, state->buf + state->packet_pos,
USB_PACKET_SIZE - state->packet_pos);
read += USB_PACKET_SIZE - state->packet_pos;
state->packet_size - state->packet_pos);
read += state->packet_size - state->packet_pos;
// read next packet (with retry)
_usb_webusb_read_retry(state->iface_num, state->buf);
#ifdef USE_BLE
if (state->iface_num == BLE_EXT_IFACE_NUM) {
_ble_read_retry(state->iface_num, state->buf);
} else if (state->iface_num == BLE_INT_IFACE_NUM) {
_ble_read_retry_int(state->iface_num, state->buf);
} else
#endif
{
_usb_webusb_read_retry(state->iface_num, state->buf);
}
// prepare next packet
state->packet_index++;
state->packet_pos = MSG_HEADER2_LEN;
@ -245,16 +331,24 @@ static bool _usb_read(pb_istream_t *stream, uint8_t *buf, size_t count) {
return true;
}
static void _usb_read_flush(usb_read_state *state) { (void)state; }
static void _read_flush(read_state *state) { (void)state; }
static secbool _recv_msg(uint8_t iface_num, uint32_t msg_size, uint8_t *buf,
const pb_msgdesc_t *fields, void *msg) {
usb_read_state state = {.iface_num = iface_num,
.packet_index = 0,
.packet_pos = MSG_HEADER1_LEN,
.buf = buf};
uint16_t packet_size = USB_PACKET_SIZE;
#ifdef USE_BLE
if (iface_num == BLE_EXT_IFACE_NUM) {
packet_size = BLE_PACKET_SIZE;
}
#endif
pb_istream_t stream = {.callback = &_usb_read,
read_state state = {.iface_num = iface_num,
.packet_index = 0,
.packet_pos = MSG_HEADER1_LEN,
.packet_size = packet_size,
.buf = buf};
pb_istream_t stream = {.callback = &_read,
.state = &state,
.bytes_left = msg_size,
.errmsg = NULL};
@ -263,7 +357,7 @@ static secbool _recv_msg(uint8_t iface_num, uint32_t msg_size, uint8_t *buf,
return secfalse;
}
_usb_read_flush(&state);
_read_flush(&state);
return sectrue;
}
@ -306,6 +400,39 @@ static void send_msg_features(uint8_t iface_num,
MSG_SEND(Features);
}
uint32_t process_msg_Pairing(uint8_t iface_num, uint32_t msg_size,
uint8_t *buf) {
uint8_t buffer[6];
MSG_RECV_INIT(PairingRequest);
MSG_RECV(PairingRequest);
uint32_t result = screen_pairing_confirm(buffer);
if (result == INPUT_CONFIRM) {
MSG_SEND_INIT(AuthKey);
MSG_SEND_CALLBACK(key, _write_authkey, buffer);
MSG_SEND(AuthKey);
} else {
send_user_abort(iface_num, "Pairing cancelled");
}
return result;
}
uint32_t process_msg_Repair(uint8_t iface_num, uint32_t msg_size,
uint8_t *buf) {
MSG_RECV_INIT(RepairRequest);
MSG_RECV(RepairRequest);
uint32_t result = screen_repair_confirm();
if (result == INPUT_CONFIRM) {
MSG_SEND_INIT(Success);
MSG_SEND(Success);
} else {
send_user_abort(iface_num, "Pairing cancelled");
}
return result;
}
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf,
const vendor_header *const vhdr,
const image_header *const hdr) {

@ -24,6 +24,9 @@
#include "image.h"
#include "secbool.h"
#define USB_IFACE_NUM 0
#define BLE_INT_IFACE_NUM 16
#define BLE_EXT_IFACE_NUM 17
#define USB_TIMEOUT 500
#define USB_PACKET_SIZE 64
@ -68,4 +71,9 @@ void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
secbool bootloader_WipeDevice(void);
uint32_t process_msg_Pairing(uint8_t iface_num, uint32_t msg_size,
uint8_t *buf);
uint32_t process_msg_Repair(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
#endif

@ -39,6 +39,15 @@ PB_BIND(FirmwareRequest, FirmwareRequest, AUTO)
PB_BIND(FirmwareUpload, FirmwareUpload, AUTO)
PB_BIND(PairingRequest, PairingRequest, AUTO)
PB_BIND(AuthKey, AuthKey, AUTO)
PB_BIND(RepairRequest, RepairRequest, AUTO)

@ -10,121 +10,136 @@
#endif
/* Enum definitions */
typedef enum _MessageType {
MessageType_MessageType_Initialize = 0,
MessageType_MessageType_Ping = 1,
MessageType_MessageType_Success = 2,
MessageType_MessageType_Failure = 3,
MessageType_MessageType_FirmwareErase = 6,
MessageType_MessageType_FirmwareUpload = 7,
MessageType_MessageType_FirmwareRequest = 8,
MessageType_MessageType_Features = 17,
MessageType_MessageType_ButtonRequest = 26,
MessageType_MessageType_ButtonAck = 27,
MessageType_MessageType_GetFeatures = 55
typedef enum _MessageType {
MessageType_MessageType_Initialize = 0,
MessageType_MessageType_Ping = 1,
MessageType_MessageType_Success = 2,
MessageType_MessageType_Failure = 3,
MessageType_MessageType_FirmwareErase = 6,
MessageType_MessageType_FirmwareUpload = 7,
MessageType_MessageType_FirmwareRequest = 8,
MessageType_MessageType_Features = 17,
MessageType_MessageType_ButtonRequest = 26,
MessageType_MessageType_ButtonAck = 27,
MessageType_MessageType_GetFeatures = 55,
MessageType_MessageType_PairingRequest = 8003,
MessageType_MessageType_AuthKey = 8004,
MessageType_MessageType_RepairRequest = 8005
} MessageType;
typedef enum _FailureType {
FailureType_Failure_UnexpectedMessage = 1,
FailureType_Failure_DataError = 3,
FailureType_Failure_ActionCancelled = 4,
FailureType_Failure_ProcessError = 9
typedef enum _FailureType {
FailureType_Failure_UnexpectedMessage = 1,
FailureType_Failure_DataError = 3,
FailureType_Failure_ActionCancelled = 4,
FailureType_Failure_ProcessError = 9
} FailureType;
typedef enum _ButtonRequestType {
ButtonRequestType_ButtonRequest_Other = 1
typedef enum _ButtonRequestType {
ButtonRequestType_ButtonRequest_Other = 1
} ButtonRequestType;
/* Struct definitions */
typedef struct _ButtonAck {
typedef struct _AuthKey {
pb_callback_t key;
} AuthKey;
typedef struct _ButtonAck {
char dummy_field;
} ButtonAck;
typedef struct _GetFeatures {
typedef struct _GetFeatures {
char dummy_field;
} GetFeatures;
typedef struct _Initialize {
typedef struct _Initialize {
char dummy_field;
} Initialize;
typedef struct _ButtonRequest {
typedef struct _PairingRequest {
char dummy_field;
} PairingRequest;
typedef struct _RepairRequest {
char dummy_field;
} RepairRequest;
typedef struct _ButtonRequest {
bool has_code;
ButtonRequestType code;
ButtonRequestType code;
} ButtonRequest;
typedef struct _Failure {
typedef struct _Failure {
bool has_code;
FailureType code;
FailureType code;
bool has_message;
char message[256];
char message[256];
} Failure;
typedef PB_BYTES_ARRAY_T(20) Features_revision_t;
typedef struct _Features {
typedef struct _Features {
bool has_vendor;
char vendor[33];
uint32_t major_version;
uint32_t minor_version;
uint32_t patch_version;
char vendor[33];
uint32_t major_version;
uint32_t minor_version;
uint32_t patch_version;
bool has_bootloader_mode;
bool bootloader_mode;
bool bootloader_mode;
bool has_device_id;
char device_id[25];
char device_id[25];
bool has_language;
char language[17];
char language[17];
bool has_label;
char label[33];
char label[33];
bool has_initialized;
bool initialized;
bool initialized;
bool has_revision;
Features_revision_t revision;
Features_revision_t revision;
bool has_firmware_present;
bool firmware_present;
bool firmware_present;
bool has_model;
char model[17];
char model[17];
bool has_fw_major;
uint32_t fw_major;
uint32_t fw_major;
bool has_fw_minor;
uint32_t fw_minor;
uint32_t fw_minor;
bool has_fw_patch;
uint32_t fw_patch;
uint32_t fw_patch;
bool has_fw_vendor;
char fw_vendor[256];
char fw_vendor[256];
} Features;
typedef struct _FirmwareErase {
typedef struct _FirmwareErase {
bool has_length;
uint32_t length;
uint32_t length;
} FirmwareErase;
typedef struct _FirmwareRequest {
uint32_t offset;
uint32_t length;
typedef struct _FirmwareRequest {
uint32_t offset;
uint32_t length;
} FirmwareRequest;
typedef PB_BYTES_ARRAY_T(32) FirmwareUpload_hash_t;
typedef struct _FirmwareUpload {
pb_callback_t payload;
typedef struct _FirmwareUpload {
pb_callback_t payload;
bool has_hash;
FirmwareUpload_hash_t hash;
FirmwareUpload_hash_t hash;
} FirmwareUpload;
typedef struct _Ping {
typedef struct _Ping {
bool has_message;
char message[256];
char message[256];
} Ping;
typedef struct _Success {
typedef struct _Success {
bool has_message;
char message[256];
char message[256];
} Success;
/* Helper constants for enums */
#define _MessageType_MIN MessageType_MessageType_Initialize
#define _MessageType_MAX MessageType_MessageType_GetFeatures
#define _MessageType_ARRAYSIZE ((MessageType)(MessageType_MessageType_GetFeatures+1))
#define _MessageType_MAX MessageType_MessageType_RepairRequest
#define _MessageType_ARRAYSIZE ((MessageType)(MessageType_MessageType_RepairRequest+1))
#define _FailureType_MIN FailureType_Failure_UnexpectedMessage
#define _FailureType_MAX FailureType_Failure_ProcessError
@ -151,6 +166,9 @@ extern "C" {
#define FirmwareErase_init_default {false, 0}
#define FirmwareRequest_init_default {0, 0}
#define FirmwareUpload_init_default {{{NULL}, NULL}, false, {0, {0}}}
#define PairingRequest_init_default {0}
#define AuthKey_init_default {{{NULL}, NULL}}
#define RepairRequest_init_default {0}
#define Initialize_init_zero {0}
#define GetFeatures_init_zero {0}
#define Features_init_zero {false, "", 0, 0, 0, false, 0, false, "", false, "", false, "", false, 0, false, {0, {0}}, false, 0, false, "", false, 0, false, 0, false, 0, false, ""}
@ -162,8 +180,12 @@ extern "C" {
#define FirmwareErase_init_zero {false, 0}
#define FirmwareRequest_init_zero {0, 0}
#define FirmwareUpload_init_zero {{{NULL}, NULL}, false, {0, {0}}}
#define PairingRequest_init_zero {0}
#define AuthKey_init_zero {{{NULL}, NULL}}
#define RepairRequest_init_zero {0}
/* Field tags (for use in manual encoding/decoding) */
#define AuthKey_key_tag 1
#define ButtonRequest_code_tag 1
#define Failure_code_tag 1
#define Failure_message_tag 2
@ -265,6 +287,21 @@ X(a, STATIC, OPTIONAL, BYTES, hash, 2)
#define FirmwareUpload_CALLBACK pb_default_field_callback
#define FirmwareUpload_DEFAULT NULL
#define PairingRequest_FIELDLIST(X, a) \
#define PairingRequest_CALLBACK NULL
#define PairingRequest_DEFAULT NULL
#define AuthKey_FIELDLIST(X, a) \
X(a, CALLBACK, REQUIRED, BYTES, key, 1)
#define AuthKey_CALLBACK pb_default_field_callback
#define AuthKey_DEFAULT NULL
#define RepairRequest_FIELDLIST(X, a) \
#define RepairRequest_CALLBACK NULL
#define RepairRequest_DEFAULT NULL
extern const pb_msgdesc_t Initialize_msg;
extern const pb_msgdesc_t GetFeatures_msg;
extern const pb_msgdesc_t Features_msg;
@ -276,6 +313,9 @@ extern const pb_msgdesc_t ButtonAck_msg;
extern const pb_msgdesc_t FirmwareErase_msg;
extern const pb_msgdesc_t FirmwareRequest_msg;
extern const pb_msgdesc_t FirmwareUpload_msg;
extern const pb_msgdesc_t PairingRequest_msg;
extern const pb_msgdesc_t AuthKey_msg;
extern const pb_msgdesc_t RepairRequest_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define Initialize_fields &Initialize_msg
@ -289,9 +329,13 @@ extern const pb_msgdesc_t FirmwareUpload_msg;
#define FirmwareErase_fields &FirmwareErase_msg
#define FirmwareRequest_fields &FirmwareRequest_msg
#define FirmwareUpload_fields &FirmwareUpload_msg
#define PairingRequest_fields &PairingRequest_msg
#define AuthKey_fields &AuthKey_msg
#define RepairRequest_fields &RepairRequest_msg
/* Maximum encoded size of messages (where known) */
/* FirmwareUpload_size depends on runtime parameters */
/* AuthKey_size depends on runtime parameters */
#define ButtonAck_size 0
#define ButtonRequest_size 2
#define Failure_size 260
@ -300,7 +344,9 @@ extern const pb_msgdesc_t FirmwareUpload_msg;
#define FirmwareRequest_size 12
#define GetFeatures_size 0
#define Initialize_size 0
#define PairingRequest_size 0
#define Ping_size 258
#define RepairRequest_size 0
#define Success_size 258
#ifdef __cplusplus

@ -16,6 +16,9 @@ enum MessageType {
MessageType_ButtonRequest = 26;
MessageType_ButtonAck = 27;
MessageType_GetFeatures = 55;
MessageType_PairingRequest = 8003;
MessageType_AuthKey = 8004;
MessageType_RepairRequest = 8005;
}
/**
@ -140,3 +143,32 @@ message FirmwareUpload {
required bytes payload = 1; // firmware to be loaded into device
optional bytes hash = 2; // hash of the payload
}
/**
* Request: initiates new pairing request
* @start
* @next AuthKey
* @next Failure
*/
message PairingRequest {
}
/**
* Request: confirms pairing request with auth key entered on the device
* @end
*/
message AuthKey {
required bytes key = 1;
}
/**
* Request: initiates repairing request
* @start
* @next Success
* @next Failure
*/
message RepairRequest {
}

@ -26,4 +26,7 @@ void screen_welcome_model(void);
void screen_welcome(void);
void screen_boot_empty(bool fading);
uint32_t screen_pairing_confirm(uint8_t* buffer);
uint32_t screen_repair_confirm(void);
void display_image(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen);

@ -14,17 +14,19 @@ use crate::{
theme::{
button_bld, button_confirm, button_wipe_cancel, button_wipe_confirm, BLD_BG,
BLD_FG, BLD_WIPE_COLOR, CHECK24, CHECK40, DOWNLOAD32, FIRE32, FIRE40,
LOGO_EMPTY, TEXT_WIPE_BOLD, TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, X24,
LOGO_EMPTY, TEXT_NORMAL, TEXT_WIPE_BOLD, TEXT_WIPE_NORMAL, WARNING40,
WELCOME_COLOR, X24,
},
welcome::Welcome,
},
component::{Button, ResultScreen, WelcomeScreen},
component::{Button, PinKeyboard, ResultScreen, WelcomeScreen},
constant,
theme::{BACKLIGHT_DIM, BACKLIGHT_NORMAL, BLACK, FG, WHITE},
},
util::{from_c_array, from_c_str},
},
};
use core::slice;
use heapless::String;
use num_traits::ToPrimitive;
@ -72,13 +74,16 @@ fn fadeout() {
display::fade_backlight_duration(BACKLIGHT_DIM, 150);
}
fn run<F>(frame: &mut F) -> u32
fn run<F>(frame: &mut F, clear: bool) -> u32
where
F: Component,
F::Msg: ReturnToC,
{
frame.place(constant::screen());
fadeout();
if clear {
display::rect_fill(screen(), BLACK);
}
display::sync();
frame.paint();
fadein();
@ -191,7 +196,7 @@ extern "C" fn screen_install_confirm(
Some(("FW FINGERPRINT", fingerprint_str)),
);
run(&mut frame)
run(&mut frame, false)
}
#[no_mangle]
@ -222,12 +227,12 @@ extern "C" fn screen_wipe_confirm() -> u32 {
None,
);
run(&mut frame)
run(&mut frame, false)
}
#[no_mangle]
extern "C" fn screen_menu() -> u32 {
run(&mut Menu::new())
run(&mut Menu::new(), false)
}
#[no_mangle]
@ -253,7 +258,7 @@ extern "C" fn screen_intro(
let mut frame = Intro::new(title_str.as_str(), version_str.as_str());
run(&mut frame)
run(&mut frame, false)
}
fn screen_progress(
@ -419,3 +424,41 @@ extern "C" fn screen_welcome() {
let mut frame = Welcome::new();
show(&mut frame, true);
}
#[no_mangle]
extern "C" fn screen_pairing_confirm(buffer: *const cty::uint8_t) -> u32 {
let pin_slice = unsafe { slice::from_raw_parts_mut(buffer as *mut u8, 6) };
let mut pin = PinKeyboard::new("Enter passkey", "", None, true);
let res = run(&mut pin, true);
if res == 2 {
let pin = pin.pin().as_bytes();
if pin.len() == 6 {
pin_slice.copy_from_slice(&pin[0..6]);
}
}
res
}
#[no_mangle]
extern "C" fn screen_repair_confirm() -> u32 {
let msg = Label::new("Allow repair?", Alignment::Center, TEXT_NORMAL);
let right = Button::with_text("ALLOW").styled(button_confirm());
let left = Button::with_text("DENY").styled(button_bld());
let title = Label::new("REPAIR", Alignment::Start, theme::TEXT_BOLD)
.vertically_aligned(Alignment::Center);
let mut frame = Confirm::new(
BLD_BG,
left,
right,
ConfirmTitle::Text(title),
msg,
None,
None,
);
run(&mut frame, true)
}

@ -230,6 +230,8 @@ pub fn button_bld() -> ButtonStyleSheet {
}
}
pub const TEXT_NORMAL_BLACK: TextStyle = TextStyle::new(Font::NORMAL, WHITE, BLACK, WHITE, WHITE);
pub const TEXT_TITLE: TextStyle = TextStyle::new(
Font::BOLD,
BLD_TITLE_COLOR,

@ -19,9 +19,10 @@ use crate::{
},
};
#[derive(Copy, Clone, ToPrimitive)]
pub enum PinKeyboardMsg {
Confirmed,
Cancelled,
Cancelled = 1,
Confirmed = 2,
}
const MAX_LENGTH: usize = 50;

@ -22,6 +22,7 @@
#include "comm.h"
#include <string.h>
#include "buffers.h"
#include "dma.h"
#include "int_comm_defs.h"
#include "state.h"
@ -40,7 +41,7 @@ typedef struct {
bool ready;
} spi_buffer_t;
spi_buffer_t spi_queue[SPI_QUEUE_SIZE];
BUFFER_SECTION spi_buffer_t spi_queue[SPI_QUEUE_SIZE];
static int head = 0, tail = 0;
static bool overrun = false;
volatile uint16_t overrun_count = 0;

Loading…
Cancel
Save