mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-06 06:42:33 +00:00
feat(core/ble): improved cooperation between stm and nrf, divided ble_firmware source files
[no changelog]
This commit is contained in:
parent
ae86dc93ca
commit
e402adc13e
@ -287,6 +287,10 @@ SOURCE_BLE_FIRMWARE = [
|
|||||||
'embed/ble_firmware/ble_nus.c',
|
'embed/ble_firmware/ble_nus.c',
|
||||||
'embed/ble_firmware/int_comm.c',
|
'embed/ble_firmware/int_comm.c',
|
||||||
'embed/ble_firmware/dis.c',
|
'embed/ble_firmware/dis.c',
|
||||||
|
'embed/ble_firmware/pm.c',
|
||||||
|
'embed/ble_firmware/power.c',
|
||||||
|
'embed/ble_firmware/advertising.c',
|
||||||
|
'embed/ble_firmware/connection.c',
|
||||||
'embed/bootloader/protob/messages.pb.c',
|
'embed/bootloader/protob/messages.pb.c',
|
||||||
'embed/lib/protob_helpers.c',
|
'embed/lib/protob_helpers.c',
|
||||||
]
|
]
|
||||||
|
196
core/embed/ble_firmware/advertising.c
Normal file
196
core/embed/ble_firmware/advertising.c
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
#include "ble_gap.h"
|
||||||
|
|
||||||
|
#include "advertising.h"
|
||||||
|
#include "ble_advdata.h"
|
||||||
|
#include "ble_advertising.h"
|
||||||
|
#include "ble_nus.h"
|
||||||
|
#include "bsp.h"
|
||||||
|
#include "bsp_btn_ble.h"
|
||||||
|
#include "connection.h"
|
||||||
|
#include "defs.h"
|
||||||
|
#include "nrf_log.h"
|
||||||
|
#include "pm.h"
|
||||||
|
#include "power.h"
|
||||||
|
|
||||||
|
#define APP_ADV_INTERVAL \
|
||||||
|
64 /**< The advertising interval (in units of 0.625 ms. This value \
|
||||||
|
corresponds to 40 ms). */
|
||||||
|
|
||||||
|
#define APP_ADV_DURATION \
|
||||||
|
18000 /**< The advertising duration (180 seconds) in units of 10 \
|
||||||
|
milliseconds. */
|
||||||
|
|
||||||
|
#define NUS_SERVICE_UUID_TYPE \
|
||||||
|
BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service \
|
||||||
|
(vendor specific). */
|
||||||
|
|
||||||
|
static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */
|
||||||
|
{{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}};
|
||||||
|
|
||||||
|
BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */
|
||||||
|
|
||||||
|
/**@brief Function for handling advertising events.
|
||||||
|
*
|
||||||
|
* @details This function will be called for advertising events which are passed
|
||||||
|
* to the application.
|
||||||
|
*
|
||||||
|
* @param[in] ble_adv_evt Advertising event.
|
||||||
|
*/
|
||||||
|
static void on_adv_evt(ble_adv_evt_t ble_adv_evt) {
|
||||||
|
uint32_t err_code;
|
||||||
|
|
||||||
|
switch (ble_adv_evt) {
|
||||||
|
case BLE_ADV_EVT_DIRECTED_HIGH_DUTY:
|
||||||
|
NRF_LOG_INFO("High Duty Directed advertising.");
|
||||||
|
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_DIRECTED);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_ADV_EVT_DIRECTED:
|
||||||
|
NRF_LOG_INFO("Directed advertising.");
|
||||||
|
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_DIRECTED);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_ADV_EVT_FAST:
|
||||||
|
NRF_LOG_INFO("Fast advertising.");
|
||||||
|
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_ADV_EVT_SLOW:
|
||||||
|
NRF_LOG_INFO("Slow advertising.");
|
||||||
|
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_SLOW);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_ADV_EVT_FAST_WHITELIST:
|
||||||
|
NRF_LOG_INFO("Fast advertising with whitelist.");
|
||||||
|
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_WHITELIST);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_ADV_EVT_SLOW_WHITELIST:
|
||||||
|
NRF_LOG_INFO("Slow advertising with whitelist.");
|
||||||
|
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_WHITELIST);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_ADV_EVT_IDLE:
|
||||||
|
// sleep_mode_enter();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_ADV_EVT_WHITELIST_REQUEST: {
|
||||||
|
ble_gap_addr_t whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
|
||||||
|
ble_gap_irk_t whitelist_irks[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
|
||||||
|
uint32_t addr_cnt = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
|
||||||
|
uint32_t irk_cnt = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
|
||||||
|
|
||||||
|
err_code = pm_whitelist_get(whitelist_addrs, &addr_cnt, whitelist_irks,
|
||||||
|
&irk_cnt);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
NRF_LOG_DEBUG(
|
||||||
|
"pm_whitelist_get returns %d addr in whitelist and %d irk whitelist",
|
||||||
|
addr_cnt, irk_cnt);
|
||||||
|
|
||||||
|
// Set the correct identities list (no excluding peers with no Central
|
||||||
|
// Address Resolution).
|
||||||
|
identities_set(PM_PEER_ID_LIST_SKIP_NO_IRK);
|
||||||
|
|
||||||
|
// Apply the whitelist.
|
||||||
|
err_code = ble_advertising_whitelist_reply(
|
||||||
|
&m_advertising, whitelist_addrs, addr_cnt, whitelist_irks, irk_cnt);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
} break; // BLE_ADV_EVT_WHITELIST_REQUEST
|
||||||
|
|
||||||
|
case BLE_ADV_EVT_PEER_ADDR_REQUEST: {
|
||||||
|
pm_peer_data_bonding_t peer_bonding_data;
|
||||||
|
|
||||||
|
// Only Give peer address if we have a handle to the bonded peer.
|
||||||
|
if (get_peer_id() != PM_PEER_ID_INVALID) {
|
||||||
|
err_code = pm_peer_data_bonding_load(get_peer_id(), &peer_bonding_data);
|
||||||
|
if (err_code != NRF_ERROR_NOT_FOUND) {
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
|
// Manipulate identities to exclude peers with no Central Address
|
||||||
|
// Resolution.
|
||||||
|
identities_set(PM_PEER_ID_LIST_SKIP_ALL);
|
||||||
|
|
||||||
|
ble_gap_addr_t *p_peer_addr =
|
||||||
|
&(peer_bonding_data.peer_ble_id.id_addr_info);
|
||||||
|
err_code =
|
||||||
|
ble_advertising_peer_addr_reply(&m_advertising, p_peer_addr);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break; // BLE_ADV_EVT_PEER_ADDR_REQUEST
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void advertising_init(void) {
|
||||||
|
uint32_t err_code;
|
||||||
|
uint8_t adv_flags;
|
||||||
|
ble_advertising_init_t init;
|
||||||
|
|
||||||
|
memset(&init, 0, sizeof(init));
|
||||||
|
|
||||||
|
adv_flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
|
||||||
|
init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
|
||||||
|
init.advdata.include_appearance = true;
|
||||||
|
init.advdata.flags = adv_flags;
|
||||||
|
init.advdata.uuids_complete.uuid_cnt =
|
||||||
|
sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
|
||||||
|
init.advdata.uuids_complete.p_uuids = m_adv_uuids;
|
||||||
|
|
||||||
|
init.config.ble_adv_whitelist_enabled = true;
|
||||||
|
init.config.ble_adv_directed_high_duty_enabled = true;
|
||||||
|
init.config.ble_adv_directed_enabled = false;
|
||||||
|
init.config.ble_adv_directed_interval = 0;
|
||||||
|
init.config.ble_adv_directed_timeout = 0;
|
||||||
|
init.config.ble_adv_fast_enabled = true;
|
||||||
|
init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
|
||||||
|
init.config.ble_adv_fast_timeout = APP_ADV_DURATION;
|
||||||
|
|
||||||
|
init.evt_handler = on_adv_evt;
|
||||||
|
|
||||||
|
err_code = ble_advertising_init(&m_advertising, &init);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
|
ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void advertising_start(bool whitelist) {
|
||||||
|
m_advertising.adv_modes_config.ble_adv_on_disconnect_disabled = false;
|
||||||
|
if (m_advertising.adv_mode_current != BLE_ADV_MODE_FAST &&
|
||||||
|
get_connection_handle() == BLE_CONN_HANDLE_INVALID) {
|
||||||
|
whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
|
||||||
|
|
||||||
|
ret_code_t ret = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
|
||||||
|
APP_ERROR_CHECK(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!whitelist) {
|
||||||
|
ret_code_t ret = ble_advertising_restart_without_whitelist(&m_advertising);
|
||||||
|
APP_ERROR_CHECK(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void advertising_stop(void) {
|
||||||
|
m_advertising.adv_modes_config.ble_adv_on_disconnect_disabled = true;
|
||||||
|
ret_code_t ret = ble_advertising_start(&m_advertising, BLE_ADV_MODE_IDLE);
|
||||||
|
APP_ERROR_CHECK(ret);
|
||||||
|
// ret =sd_ble_gap_disconnect(get_connection_handle(),
|
||||||
|
// BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void advertising_restart_without_whitelist(void) {
|
||||||
|
ret_code_t ret = ble_advertising_restart_without_whitelist(&m_advertising);
|
||||||
|
APP_ERROR_CHECK(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_advertising(void) {
|
||||||
|
return m_advertising.adv_mode_current != BLE_ADV_MODE_IDLE;
|
||||||
|
}
|
16
core/embed/ble_firmware/advertising.h
Normal file
16
core/embed/ble_firmware/advertising.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef __ADVERTISING__
|
||||||
|
#define __ADVERTISING__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void advertising_init(void);
|
||||||
|
|
||||||
|
void advertising_start(bool whitelist);
|
||||||
|
|
||||||
|
void advertising_stop(void);
|
||||||
|
|
||||||
|
void advertising_restart_without_whitelist(void);
|
||||||
|
|
||||||
|
bool is_advertising(void);
|
||||||
|
|
||||||
|
#endif
|
10
core/embed/ble_firmware/connection.c
Normal file
10
core/embed/ble_firmware/connection.c
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#include "ble_gap.h"
|
||||||
|
|
||||||
|
#include "connection.h"
|
||||||
|
|
||||||
|
static uint16_t m_conn_handle =
|
||||||
|
BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
|
||||||
|
|
||||||
|
void set_connection_handle(uint16_t val) { m_conn_handle = val; }
|
||||||
|
uint16_t get_connection_handle(void) { return m_conn_handle; }
|
9
core/embed/ble_firmware/connection.h
Normal file
9
core/embed/ble_firmware/connection.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef BLE_CONNECTION_H__
|
||||||
|
#define BLE_CONNECTION_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void set_connection_handle(uint16_t val);
|
||||||
|
uint16_t get_connection_handle(void);
|
||||||
|
|
||||||
|
#endif
|
3
core/embed/ble_firmware/defs.h
Normal file
3
core/embed/ble_firmware/defs.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
#define APP_BLE_CONN_CFG_TAG \
|
||||||
|
1 /**< A tag identifying the SoftDevice BLE configuration. */
|
@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef __DIS__
|
#ifndef __DIS__
|
||||||
#define __DIS__
|
#define __DIS__
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
|
||||||
#include "int_comm.h"
|
#include "int_comm.h"
|
||||||
|
#include "advertising.h"
|
||||||
#include "app_error.h"
|
#include "app_error.h"
|
||||||
#include "app_uart.h"
|
#include "app_uart.h"
|
||||||
|
#include "ble_advertising.h"
|
||||||
#include "ble_nus.h"
|
#include "ble_nus.h"
|
||||||
|
#include "connection.h"
|
||||||
#include "messages.pb.h"
|
#include "messages.pb.h"
|
||||||
#include "nrf_drv_spi.h"
|
#include "nrf_drv_spi.h"
|
||||||
#include "nrf_log.h"
|
#include "nrf_log.h"
|
||||||
|
#include "pm.h"
|
||||||
#include "protob_helpers.h"
|
#include "protob_helpers.h"
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "trezorhal/ble/int_comm_defs.h"
|
#include "trezorhal/ble/int_comm_defs.h"
|
||||||
@ -19,7 +23,6 @@
|
|||||||
static uint8_t m_uart_rx_data[BLE_NUS_MAX_DATA_LEN];
|
static uint8_t m_uart_rx_data[BLE_NUS_MAX_DATA_LEN];
|
||||||
static uint8_t m_spi_tx_data[BLE_PACKET_SIZE];
|
static uint8_t m_spi_tx_data[BLE_PACKET_SIZE];
|
||||||
static bool m_uart_rx_data_ready_internal = false;
|
static bool m_uart_rx_data_ready_internal = false;
|
||||||
static uint16_t *m_p_conn_handle = NULL;
|
|
||||||
|
|
||||||
BLE_NUS_DEF(m_nus,
|
BLE_NUS_DEF(m_nus,
|
||||||
NRF_SDH_BLE_TOTAL_LINK_COUNT); /**< BLE NUS service instance. */
|
NRF_SDH_BLE_TOTAL_LINK_COUNT); /**< BLE NUS service instance. */
|
||||||
@ -48,8 +51,7 @@ void spi_init(void) {
|
|||||||
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
|
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
void nus_init(uint16_t *p_conn_handle) {
|
void nus_init() {
|
||||||
m_p_conn_handle = p_conn_handle;
|
|
||||||
uint32_t err_code;
|
uint32_t err_code;
|
||||||
|
|
||||||
ble_nus_init_t nus_init;
|
ble_nus_init_t nus_init;
|
||||||
@ -60,8 +62,6 @@ void nus_init(uint16_t *p_conn_handle) {
|
|||||||
|
|
||||||
err_code = ble_nus_init(&m_nus, &nus_init);
|
err_code = ble_nus_init(&m_nus, &nus_init);
|
||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
*p_conn_handle = BLE_CONN_HANDLE_INVALID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_byte(uint8_t byte) {
|
void send_byte(uint8_t byte) {
|
||||||
@ -177,11 +177,15 @@ void process_command(uint8_t *data, uint16_t len) {
|
|||||||
uint8_t cmd = data[0];
|
uint8_t cmd = data[0];
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case INTERNAL_CMD_SEND_STATE:
|
case INTERNAL_CMD_SEND_STATE:
|
||||||
if (*m_p_conn_handle != BLE_CONN_HANDLE_INVALID) {
|
send_status_event();
|
||||||
send_connected_event();
|
break;
|
||||||
} else {
|
case INTERNAL_CMD_ADVERTISING_ON:
|
||||||
send_disconnected_event();
|
advertising_start(true);
|
||||||
}
|
send_status_event();
|
||||||
|
break;
|
||||||
|
case INTERNAL_CMD_ADVERTISING_OFF:
|
||||||
|
advertising_stop();
|
||||||
|
send_status_event();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -289,7 +293,7 @@ void uart_event_handle(app_uart_evt_t *p_event) {
|
|||||||
do {
|
do {
|
||||||
uint16_t length = (uint16_t)len - OVERHEAD_SIZE;
|
uint16_t length = (uint16_t)len - OVERHEAD_SIZE;
|
||||||
err_code = ble_nus_data_send(&m_nus, m_uart_rx_data, &length,
|
err_code = ble_nus_data_send(&m_nus, m_uart_rx_data, &length,
|
||||||
*m_p_conn_handle);
|
get_connection_handle());
|
||||||
if ((err_code != NRF_ERROR_INVALID_STATE) &&
|
if ((err_code != NRF_ERROR_INVALID_STATE) &&
|
||||||
(err_code != NRF_ERROR_RESOURCES) &&
|
(err_code != NRF_ERROR_RESOURCES) &&
|
||||||
(err_code != NRF_ERROR_NOT_FOUND)) {
|
(err_code != NRF_ERROR_NOT_FOUND)) {
|
||||||
@ -341,16 +345,12 @@ void nus_data_handler(ble_nus_evt_t *p_evt) {
|
|||||||
}
|
}
|
||||||
/**@snippet [Handling the data received over BLE] */
|
/**@snippet [Handling the data received over BLE] */
|
||||||
|
|
||||||
void send_connected_event(void) {
|
void send_status_event(void) {
|
||||||
uint8_t tx_data[] = {
|
uint8_t tx_data[] = {
|
||||||
INTERNAL_EVENT_CONNECTED,
|
INTERNAL_EVENT_STATUS,
|
||||||
};
|
(get_connection_handle() != BLE_CONN_HANDLE_INVALID) ? 1
|
||||||
send_packet(INTERNAL_EVENT, tx_data, sizeof(tx_data));
|
: 0, // connected
|
||||||
}
|
is_advertising() ? 1 : 0, // advertising
|
||||||
|
|
||||||
void send_disconnected_event(void) {
|
|
||||||
uint8_t tx_data[] = {
|
|
||||||
INTERNAL_EVENT_DISCONNECTED,
|
|
||||||
};
|
};
|
||||||
send_packet(INTERNAL_EVENT, tx_data, sizeof(tx_data));
|
send_packet(INTERNAL_EVENT, tx_data, sizeof(tx_data));
|
||||||
}
|
}
|
||||||
@ -415,10 +415,3 @@ bool send_repair_request(void) {
|
|||||||
|
|
||||||
return result == sectrue;
|
return result == sectrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_initialized(void) {
|
|
||||||
uint8_t tx_data[] = {
|
|
||||||
INTERNAL_EVENT_INITIALIZED,
|
|
||||||
};
|
|
||||||
send_packet(INTERNAL_EVENT, tx_data, sizeof(tx_data));
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
#ifndef __INT_COMM__
|
#ifndef __INT_COMM__
|
||||||
#define __INT_COMM__
|
#define __INT_COMM__
|
||||||
|
|
||||||
@ -8,15 +7,13 @@
|
|||||||
|
|
||||||
void spi_init(void);
|
void spi_init(void);
|
||||||
|
|
||||||
void nus_init(uint16_t *p_conn_handle);
|
void nus_init(void);
|
||||||
|
|
||||||
void nus_data_handler(ble_nus_evt_t *p_evt);
|
void nus_data_handler(ble_nus_evt_t *p_evt);
|
||||||
|
|
||||||
void uart_event_handle(app_uart_evt_t *p_event);
|
void uart_event_handle(app_uart_evt_t *p_event);
|
||||||
|
|
||||||
void send_connected_event(void);
|
void send_status_event(void);
|
||||||
|
|
||||||
void send_disconnected_event(void);
|
|
||||||
|
|
||||||
bool send_auth_key_request(uint8_t *p_key, uint8_t p_key_len);
|
bool send_auth_key_request(uint8_t *p_key, uint8_t p_key_len);
|
||||||
|
|
||||||
|
@ -56,23 +56,17 @@
|
|||||||
#include "app_timer.h"
|
#include "app_timer.h"
|
||||||
#include "app_uart.h"
|
#include "app_uart.h"
|
||||||
#include "app_util_platform.h"
|
#include "app_util_platform.h"
|
||||||
#include "ble_advdata.h"
|
|
||||||
#include "ble_advertising.h"
|
|
||||||
#include "ble_conn_params.h"
|
#include "ble_conn_params.h"
|
||||||
#include "ble_hci.h"
|
#include "ble_hci.h"
|
||||||
#include "ble_nus.h"
|
|
||||||
#include "bsp_btn_ble.h"
|
#include "bsp_btn_ble.h"
|
||||||
#include "nordic_common.h"
|
#include "nordic_common.h"
|
||||||
#include "nrf.h"
|
#include "nrf.h"
|
||||||
#include "nrf_ble_gatt.h"
|
#include "nrf_ble_gatt.h"
|
||||||
#include "nrf_ble_qwr.h"
|
#include "nrf_ble_qwr.h"
|
||||||
#include "nrf_drv_spi.h"
|
|
||||||
#include "nrf_pwr_mgmt.h"
|
#include "nrf_pwr_mgmt.h"
|
||||||
#include "nrf_sdh.h"
|
#include "nrf_sdh.h"
|
||||||
#include "nrf_sdh_ble.h"
|
#include "nrf_sdh_ble.h"
|
||||||
#include "nrf_sdh_soc.h"
|
#include "nrf_sdh_soc.h"
|
||||||
#include "peer_manager.h"
|
|
||||||
#include "peer_manager_handler.h"
|
|
||||||
|
|
||||||
#if defined(UART_PRESENT)
|
#if defined(UART_PRESENT)
|
||||||
#include "nrf_uart.h"
|
#include "nrf_uart.h"
|
||||||
@ -85,31 +79,23 @@
|
|||||||
#include "nrf_log_ctrl.h"
|
#include "nrf_log_ctrl.h"
|
||||||
#include "nrf_log_default_backends.h"
|
#include "nrf_log_default_backends.h"
|
||||||
|
|
||||||
|
#include "advertising.h"
|
||||||
|
#include "ble_nus.h"
|
||||||
|
#include "connection.h"
|
||||||
|
#include "defs.h"
|
||||||
#include "dis.h"
|
#include "dis.h"
|
||||||
#include "int_comm.h"
|
#include "int_comm.h"
|
||||||
|
#include "pm.h"
|
||||||
#define APP_BLE_CONN_CFG_TAG \
|
#include "power.h"
|
||||||
1 /**< A tag identifying the SoftDevice BLE configuration. */
|
|
||||||
|
|
||||||
#define DEVICE_NAME \
|
#define DEVICE_NAME \
|
||||||
"Trezor" /**< Name of device. Will be included in the advertising data. \
|
"Trezor" /**< Name of device. Will be included in the advertising data. \
|
||||||
*/
|
*/
|
||||||
#define NUS_SERVICE_UUID_TYPE \
|
|
||||||
BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service \
|
|
||||||
(vendor specific). */
|
|
||||||
|
|
||||||
#define APP_BLE_OBSERVER_PRIO \
|
#define APP_BLE_OBSERVER_PRIO \
|
||||||
3 /**< Application's BLE observer priority. You shouldn't need to modify \
|
3 /**< Application's BLE observer priority. You shouldn't need to modify \
|
||||||
this value. */
|
this value. */
|
||||||
|
|
||||||
#define APP_ADV_INTERVAL \
|
|
||||||
64 /**< The advertising interval (in units of 0.625 ms. This value \
|
|
||||||
corresponds to 40 ms). */
|
|
||||||
|
|
||||||
#define APP_ADV_DURATION \
|
|
||||||
18000 /**< The advertising duration (180 seconds) in units of 10 \
|
|
||||||
milliseconds. */
|
|
||||||
|
|
||||||
#define MIN_CONN_INTERVAL \
|
#define MIN_CONN_INTERVAL \
|
||||||
MSEC_TO_UNITS( \
|
MSEC_TO_UNITS( \
|
||||||
7.5, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), \
|
7.5, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), \
|
||||||
@ -145,17 +131,6 @@
|
|||||||
|
|
||||||
NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */
|
NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */
|
||||||
NRF_BLE_QWR_DEF(m_qwr); /**< Context for the Queued Write module.*/
|
NRF_BLE_QWR_DEF(m_qwr); /**< Context for the Queued Write module.*/
|
||||||
BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */
|
|
||||||
|
|
||||||
#define SEC_PARAM_BOND 1 /**< Perform bonding. */
|
|
||||||
#define SEC_PARAM_MITM 0 /**< Man In The Middle protection not required. */
|
|
||||||
#define SEC_PARAM_LESC 0 /**< LE Secure Connections not enabled. */
|
|
||||||
#define SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */
|
|
||||||
#define SEC_PARAM_IO_CAPABILITIES \
|
|
||||||
BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY /**< No I/O capabilities. */
|
|
||||||
#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */
|
|
||||||
#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */
|
|
||||||
#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */
|
|
||||||
|
|
||||||
#define SCHED_MAX_EVENT_DATA_SIZE \
|
#define SCHED_MAX_EVENT_DATA_SIZE \
|
||||||
APP_TIMER_SCHED_EVENT_DATA_SIZE /**< Maximum size of scheduler events. */
|
APP_TIMER_SCHED_EVENT_DATA_SIZE /**< Maximum size of scheduler events. */
|
||||||
@ -168,16 +143,10 @@ BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */
|
|||||||
10 /**< Maximum number of events in the scheduler queue. */
|
10 /**< Maximum number of events in the scheduler queue. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static pm_peer_id_t
|
|
||||||
m_peer_id; /**< Device reference handle to the current bonded central. */
|
|
||||||
static uint16_t m_conn_handle =
|
|
||||||
BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
|
|
||||||
static uint16_t m_ble_nus_max_data_len =
|
static uint16_t m_ble_nus_max_data_len =
|
||||||
BLE_GATT_ATT_MTU_DEFAULT -
|
BLE_GATT_ATT_MTU_DEFAULT -
|
||||||
3; /**< Maximum length of data (in bytes) that can be transmitted to the
|
3; /**< Maximum length of data (in bytes) that can be transmitted to the
|
||||||
peer by the Nordic UART service module. */
|
peer by the Nordic UART service module. */
|
||||||
static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */
|
|
||||||
{{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}};
|
|
||||||
|
|
||||||
/**@brief Function for assert macro callback.
|
/**@brief Function for assert macro callback.
|
||||||
*
|
*
|
||||||
@ -258,7 +227,7 @@ static void services_init(void) {
|
|||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
dis_init();
|
dis_init();
|
||||||
nus_init(&m_conn_handle);
|
nus_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@brief Function for handling errors from the Connection Parameters module.
|
/**@brief Function for handling errors from the Connection Parameters module.
|
||||||
@ -291,141 +260,6 @@ static void conn_params_init(void) {
|
|||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@brief Function for putting the chip into sleep mode.
|
|
||||||
*
|
|
||||||
* @note This function will not return.
|
|
||||||
*/
|
|
||||||
static void sleep_mode_enter(void) {
|
|
||||||
uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
// Prepare wakeup buttons.
|
|
||||||
err_code = bsp_btn_ble_sleep_mode_prepare();
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
// Go to system-off mode (this function will not return; wakeup will cause a
|
|
||||||
// reset).
|
|
||||||
err_code = sd_power_system_off();
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for setting filtered device identities.
|
|
||||||
*
|
|
||||||
* @param[in] skip Filter passed to @ref pm_peer_id_list.
|
|
||||||
*/
|
|
||||||
static void identities_set(pm_peer_id_list_skip_t skip) {
|
|
||||||
pm_peer_id_t peer_ids[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT];
|
|
||||||
uint32_t peer_id_count = BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT;
|
|
||||||
|
|
||||||
ret_code_t err_code =
|
|
||||||
pm_peer_id_list(peer_ids, &peer_id_count, PM_PEER_ID_INVALID, skip);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
err_code = pm_device_identities_list_set(peer_ids, peer_id_count);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for handling advertising events.
|
|
||||||
*
|
|
||||||
* @details This function will be called for advertising events which are passed
|
|
||||||
* to the application.
|
|
||||||
*
|
|
||||||
* @param[in] ble_adv_evt Advertising event.
|
|
||||||
*/
|
|
||||||
static void on_adv_evt(ble_adv_evt_t ble_adv_evt) {
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
switch (ble_adv_evt) {
|
|
||||||
case BLE_ADV_EVT_DIRECTED_HIGH_DUTY:
|
|
||||||
NRF_LOG_INFO("High Duty Directed advertising.");
|
|
||||||
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_DIRECTED);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_ADV_EVT_DIRECTED:
|
|
||||||
NRF_LOG_INFO("Directed advertising.");
|
|
||||||
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_DIRECTED);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_ADV_EVT_FAST:
|
|
||||||
NRF_LOG_INFO("Fast advertising.");
|
|
||||||
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_ADV_EVT_SLOW:
|
|
||||||
NRF_LOG_INFO("Slow advertising.");
|
|
||||||
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_SLOW);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_ADV_EVT_FAST_WHITELIST:
|
|
||||||
NRF_LOG_INFO("Fast advertising with whitelist.");
|
|
||||||
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_WHITELIST);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_ADV_EVT_SLOW_WHITELIST:
|
|
||||||
NRF_LOG_INFO("Slow advertising with whitelist.");
|
|
||||||
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_WHITELIST);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_ADV_EVT_IDLE:
|
|
||||||
sleep_mode_enter();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_ADV_EVT_WHITELIST_REQUEST: {
|
|
||||||
ble_gap_addr_t whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
|
|
||||||
ble_gap_irk_t whitelist_irks[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
|
|
||||||
uint32_t addr_cnt = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
|
|
||||||
uint32_t irk_cnt = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
|
|
||||||
|
|
||||||
err_code = pm_whitelist_get(whitelist_addrs, &addr_cnt, whitelist_irks,
|
|
||||||
&irk_cnt);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
NRF_LOG_DEBUG(
|
|
||||||
"pm_whitelist_get returns %d addr in whitelist and %d irk whitelist",
|
|
||||||
addr_cnt, irk_cnt);
|
|
||||||
|
|
||||||
// Set the correct identities list (no excluding peers with no Central
|
|
||||||
// Address Resolution).
|
|
||||||
identities_set(PM_PEER_ID_LIST_SKIP_NO_IRK);
|
|
||||||
|
|
||||||
// Apply the whitelist.
|
|
||||||
err_code = ble_advertising_whitelist_reply(
|
|
||||||
&m_advertising, whitelist_addrs, addr_cnt, whitelist_irks, irk_cnt);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
} break; // BLE_ADV_EVT_WHITELIST_REQUEST
|
|
||||||
|
|
||||||
case BLE_ADV_EVT_PEER_ADDR_REQUEST: {
|
|
||||||
pm_peer_data_bonding_t peer_bonding_data;
|
|
||||||
|
|
||||||
// Only Give peer address if we have a handle to the bonded peer.
|
|
||||||
if (m_peer_id != PM_PEER_ID_INVALID) {
|
|
||||||
err_code = pm_peer_data_bonding_load(m_peer_id, &peer_bonding_data);
|
|
||||||
if (err_code != NRF_ERROR_NOT_FOUND) {
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
// Manipulate identities to exclude peers with no Central Address
|
|
||||||
// Resolution.
|
|
||||||
identities_set(PM_PEER_ID_LIST_SKIP_ALL);
|
|
||||||
|
|
||||||
ble_gap_addr_t *p_peer_addr =
|
|
||||||
&(peer_bonding_data.peer_ble_id.id_addr_info);
|
|
||||||
err_code =
|
|
||||||
ble_advertising_peer_addr_reply(&m_advertising, p_peer_addr);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break; // BLE_ADV_EVT_PEER_ADDR_REQUEST
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for handling BLE events.
|
/**@brief Function for handling BLE events.
|
||||||
*
|
*
|
||||||
* @param[in] p_ble_evt Bluetooth stack event.
|
* @param[in] p_ble_evt Bluetooth stack event.
|
||||||
@ -440,17 +274,18 @@ static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) {
|
|||||||
err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
|
err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
|
||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
send_connected_event();
|
uint16_t handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||||
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
set_connection_handle(handle);
|
||||||
err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
|
send_status_event();
|
||||||
|
err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, handle);
|
||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLE_GAP_EVT_DISCONNECTED:
|
case BLE_GAP_EVT_DISCONNECTED:
|
||||||
NRF_LOG_INFO("Disconnected");
|
NRF_LOG_INFO("Disconnected");
|
||||||
// LED indication will be changed when advertising starts.
|
bsp_indication_set(BSP_INDICATE_IDLE);
|
||||||
send_disconnected_event();
|
send_status_event();
|
||||||
m_conn_handle = BLE_CONN_HANDLE_INVALID;
|
set_connection_handle(BLE_CONN_HANDLE_INVALID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
|
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
|
||||||
@ -533,7 +368,7 @@ static void ble_stack_init(void) {
|
|||||||
|
|
||||||
/**@brief Function for handling events from the GATT library. */
|
/**@brief Function for handling events from the GATT library. */
|
||||||
void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt) {
|
void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt) {
|
||||||
if ((m_conn_handle == p_evt->conn_handle) &&
|
if ((get_connection_handle() == p_evt->conn_handle) &&
|
||||||
(p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) {
|
(p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) {
|
||||||
m_ble_nus_max_data_len =
|
m_ble_nus_max_data_len =
|
||||||
p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
|
p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
|
||||||
@ -570,18 +405,15 @@ void bsp_event_handler(bsp_event_t event) {
|
|||||||
|
|
||||||
case BSP_EVENT_DISCONNECT:
|
case BSP_EVENT_DISCONNECT:
|
||||||
err_code = sd_ble_gap_disconnect(
|
err_code = sd_ble_gap_disconnect(
|
||||||
m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
|
get_connection_handle(), BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
|
||||||
if (err_code != NRF_ERROR_INVALID_STATE) {
|
if (err_code != NRF_ERROR_INVALID_STATE) {
|
||||||
APP_ERROR_CHECK(err_code);
|
APP_ERROR_CHECK(err_code);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BSP_EVENT_WHITELIST_OFF:
|
case BSP_EVENT_WHITELIST_OFF:
|
||||||
if (m_conn_handle == BLE_CONN_HANDLE_INVALID) {
|
if (get_connection_handle() == BLE_CONN_HANDLE_INVALID) {
|
||||||
err_code = ble_advertising_restart_without_whitelist(&m_advertising);
|
advertising_restart_without_whitelist();
|
||||||
if (err_code != NRF_ERROR_INVALID_STATE) {
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -615,38 +447,6 @@ static void uart_init(void) {
|
|||||||
}
|
}
|
||||||
/**@snippet [UART Initialization] */
|
/**@snippet [UART Initialization] */
|
||||||
|
|
||||||
static void advertising_init(void) {
|
|
||||||
uint32_t err_code;
|
|
||||||
uint8_t adv_flags;
|
|
||||||
ble_advertising_init_t init;
|
|
||||||
|
|
||||||
memset(&init, 0, sizeof(init));
|
|
||||||
|
|
||||||
adv_flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
|
|
||||||
init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
|
|
||||||
init.advdata.include_appearance = true;
|
|
||||||
init.advdata.flags = adv_flags;
|
|
||||||
init.advdata.uuids_complete.uuid_cnt =
|
|
||||||
sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
|
|
||||||
init.advdata.uuids_complete.p_uuids = m_adv_uuids;
|
|
||||||
|
|
||||||
init.config.ble_adv_whitelist_enabled = true;
|
|
||||||
init.config.ble_adv_directed_high_duty_enabled = true;
|
|
||||||
init.config.ble_adv_directed_enabled = false;
|
|
||||||
init.config.ble_adv_directed_interval = 0;
|
|
||||||
init.config.ble_adv_directed_timeout = 0;
|
|
||||||
init.config.ble_adv_fast_enabled = true;
|
|
||||||
init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
|
|
||||||
init.config.ble_adv_fast_timeout = APP_ADV_DURATION;
|
|
||||||
|
|
||||||
init.evt_handler = on_adv_evt;
|
|
||||||
|
|
||||||
err_code = ble_advertising_init(&m_advertising, &init);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for initializing buttons and leds.
|
/**@brief Function for initializing buttons and leds.
|
||||||
*
|
*
|
||||||
* @param[out] p_erase_bonds Will be true if the clear bonding button was
|
* @param[out] p_erase_bonds Will be true if the clear bonding button was
|
||||||
@ -694,135 +494,6 @@ static void idle_state_handle(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@brief Function for setting filtered whitelist.
|
|
||||||
*
|
|
||||||
* @param[in] skip Filter passed to @ref pm_peer_id_list.
|
|
||||||
*/
|
|
||||||
static void whitelist_set(pm_peer_id_list_skip_t skip) {
|
|
||||||
pm_peer_id_t peer_ids[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
|
|
||||||
uint32_t peer_id_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
|
|
||||||
|
|
||||||
ret_code_t err_code =
|
|
||||||
pm_peer_id_list(peer_ids, &peer_id_count, PM_PEER_ID_INVALID, skip);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
NRF_LOG_INFO("\tm_whitelist_peer_cnt %d, MAX_PEERS_WLIST %d",
|
|
||||||
peer_id_count + 1, BLE_GAP_WHITELIST_ADDR_MAX_COUNT);
|
|
||||||
|
|
||||||
err_code = pm_whitelist_set(peer_ids, peer_id_count);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
///**@brief Clear bond information from persistent storage. */
|
|
||||||
static void delete_bonds(void) {
|
|
||||||
ret_code_t err_code;
|
|
||||||
|
|
||||||
NRF_LOG_INFO("Erase bonds!");
|
|
||||||
|
|
||||||
err_code = pm_peers_delete();
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void advertising_start(bool erase_bonds) {
|
|
||||||
if (erase_bonds == true) {
|
|
||||||
delete_bonds();
|
|
||||||
// Advertising is started by PM_EVT_PEERS_DELETE_SUCCEEDED event.
|
|
||||||
} else {
|
|
||||||
whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
|
|
||||||
|
|
||||||
ret_code_t ret = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
|
|
||||||
APP_ERROR_CHECK(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for handling Peer Manager events.
|
|
||||||
*
|
|
||||||
* @param[in] p_evt Peer Manager event.
|
|
||||||
*/
|
|
||||||
static void pm_evt_handler(pm_evt_t const *p_evt) {
|
|
||||||
pm_handler_on_pm_evt(p_evt);
|
|
||||||
pm_handler_disconnect_on_sec_failure(p_evt);
|
|
||||||
pm_handler_flash_clean(p_evt);
|
|
||||||
|
|
||||||
switch (p_evt->evt_id) {
|
|
||||||
case PM_EVT_CONN_SEC_SUCCEEDED:
|
|
||||||
m_peer_id = p_evt->peer_id;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PM_EVT_PEERS_DELETE_SUCCEEDED:
|
|
||||||
advertising_start(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
|
|
||||||
if (p_evt->params.peer_data_update_succeeded.flash_changed &&
|
|
||||||
(p_evt->params.peer_data_update_succeeded.data_id ==
|
|
||||||
PM_PEER_DATA_ID_BONDING)) {
|
|
||||||
NRF_LOG_INFO("New Bond, add the peer to the whitelist if possible");
|
|
||||||
// Note: You should check on what kind of white list policy your
|
|
||||||
// application should use.
|
|
||||||
|
|
||||||
whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PM_EVT_CONN_SEC_CONFIG_REQ: {
|
|
||||||
bool ok = send_repair_request();
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
// Allow pairing request from an already bonded peer.
|
|
||||||
pm_conn_sec_config_t conn_sec_config = {.allow_repairing = true};
|
|
||||||
pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
|
|
||||||
} else {
|
|
||||||
// Reject pairing request from an already bonded peer.
|
|
||||||
pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
|
|
||||||
pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
|
|
||||||
}
|
|
||||||
|
|
||||||
} break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for the Peer Manager initialization.
|
|
||||||
*/
|
|
||||||
static void peer_manager_init(void) {
|
|
||||||
ble_gap_sec_params_t sec_param;
|
|
||||||
pm_privacy_params_t privacy_params;
|
|
||||||
ret_code_t err_code;
|
|
||||||
|
|
||||||
err_code = pm_init();
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
|
|
||||||
|
|
||||||
// Security parameters to be used for all security procedures.
|
|
||||||
sec_param.bond = SEC_PARAM_BOND;
|
|
||||||
sec_param.mitm = SEC_PARAM_MITM;
|
|
||||||
sec_param.lesc = SEC_PARAM_LESC;
|
|
||||||
sec_param.keypress = SEC_PARAM_KEYPRESS;
|
|
||||||
sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES;
|
|
||||||
sec_param.oob = SEC_PARAM_OOB;
|
|
||||||
sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
|
|
||||||
sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
|
|
||||||
sec_param.kdist_own.enc = 1;
|
|
||||||
sec_param.kdist_own.id = 1;
|
|
||||||
sec_param.kdist_peer.enc = 1;
|
|
||||||
sec_param.kdist_peer.id = 1;
|
|
||||||
|
|
||||||
err_code = pm_sec_params_set(&sec_param);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
privacy_params.p_device_irk = NULL;
|
|
||||||
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY;
|
|
||||||
privacy_params.private_addr_cycle_s = 0;
|
|
||||||
privacy_params.private_addr_type =
|
|
||||||
BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
|
|
||||||
pm_privacy_set(&privacy_params);
|
|
||||||
|
|
||||||
err_code = pm_register(pm_evt_handler);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for the Event Scheduler initialization.
|
/**@brief Function for the Event Scheduler initialization.
|
||||||
*/
|
*/
|
||||||
static void scheduler_init(void) {
|
static void scheduler_init(void) {
|
||||||
@ -850,10 +521,11 @@ int main(void) {
|
|||||||
conn_params_init();
|
conn_params_init();
|
||||||
peer_manager_init();
|
peer_manager_init();
|
||||||
|
|
||||||
// Start execution.
|
send_status_event();
|
||||||
advertising_start(erase_bonds);
|
|
||||||
|
|
||||||
send_initialized();
|
if (erase_bonds) {
|
||||||
|
delete_bonds();
|
||||||
|
}
|
||||||
|
|
||||||
// Enter main loop.
|
// Enter main loop.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
155
core/embed/ble_firmware/pm.c
Normal file
155
core/embed/ble_firmware/pm.c
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "nrf_log.h"
|
||||||
|
#include "peer_manager_handler.h"
|
||||||
|
|
||||||
|
#include "int_comm.h"
|
||||||
|
#include "pm.h"
|
||||||
|
|
||||||
|
#define SEC_PARAM_BOND 1 /**< Perform bonding. */
|
||||||
|
#define SEC_PARAM_MITM 0 /**< Man In The Middle protection not required. */
|
||||||
|
#define SEC_PARAM_LESC 0 /**< LE Secure Connections not enabled. */
|
||||||
|
#define SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */
|
||||||
|
#define SEC_PARAM_IO_CAPABILITIES \
|
||||||
|
BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY /**< No I/O capabilities. */
|
||||||
|
#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */
|
||||||
|
#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */
|
||||||
|
#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */
|
||||||
|
|
||||||
|
static pm_peer_id_t
|
||||||
|
m_peer_id; /**< Device reference handle to the current bonded central. */
|
||||||
|
|
||||||
|
pm_peer_id_t get_peer_id(void) { return m_peer_id; }
|
||||||
|
|
||||||
|
/**@brief Function for setting filtered whitelist.
|
||||||
|
*
|
||||||
|
* @param[in] skip Filter passed to @ref pm_peer_id_list.
|
||||||
|
*/
|
||||||
|
void whitelist_set(pm_peer_id_list_skip_t skip) {
|
||||||
|
pm_peer_id_t peer_ids[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
|
||||||
|
uint32_t peer_id_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
|
||||||
|
|
||||||
|
ret_code_t err_code =
|
||||||
|
pm_peer_id_list(peer_ids, &peer_id_count, PM_PEER_ID_INVALID, skip);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
|
NRF_LOG_INFO("\tm_whitelist_peer_cnt %d, MAX_PEERS_WLIST %d",
|
||||||
|
peer_id_count + 1, BLE_GAP_WHITELIST_ADDR_MAX_COUNT);
|
||||||
|
|
||||||
|
err_code = pm_whitelist_set(peer_ids, peer_id_count);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@brief Function for handling Peer Manager events.
|
||||||
|
*
|
||||||
|
* @param[in] p_evt Peer Manager event.
|
||||||
|
*/
|
||||||
|
void pm_evt_handler(pm_evt_t const *p_evt) {
|
||||||
|
pm_handler_on_pm_evt(p_evt);
|
||||||
|
pm_handler_disconnect_on_sec_failure(p_evt);
|
||||||
|
pm_handler_flash_clean(p_evt);
|
||||||
|
|
||||||
|
switch (p_evt->evt_id) {
|
||||||
|
case PM_EVT_CONN_SEC_SUCCEEDED:
|
||||||
|
m_peer_id = p_evt->peer_id;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PM_EVT_PEERS_DELETE_SUCCEEDED:
|
||||||
|
// advertising_start(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
|
||||||
|
if (p_evt->params.peer_data_update_succeeded.flash_changed &&
|
||||||
|
(p_evt->params.peer_data_update_succeeded.data_id ==
|
||||||
|
PM_PEER_DATA_ID_BONDING)) {
|
||||||
|
NRF_LOG_INFO("New Bond, add the peer to the whitelist if possible");
|
||||||
|
// Note: You should check on what kind of white list policy your
|
||||||
|
// application should use.
|
||||||
|
|
||||||
|
whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PM_EVT_CONN_SEC_CONFIG_REQ: {
|
||||||
|
bool ok = send_repair_request();
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
// Allow pairing request from an already bonded peer.
|
||||||
|
pm_conn_sec_config_t conn_sec_config = {.allow_repairing = true};
|
||||||
|
pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
|
||||||
|
} else {
|
||||||
|
// Reject pairing request from an already bonded peer.
|
||||||
|
pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
|
||||||
|
pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@brief Function for the Peer Manager initialization.
|
||||||
|
*/
|
||||||
|
void peer_manager_init(void) {
|
||||||
|
ble_gap_sec_params_t sec_param;
|
||||||
|
pm_privacy_params_t privacy_params;
|
||||||
|
ret_code_t err_code;
|
||||||
|
|
||||||
|
err_code = pm_init();
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
|
memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
|
||||||
|
|
||||||
|
// Security parameters to be used for all security procedures.
|
||||||
|
sec_param.bond = SEC_PARAM_BOND;
|
||||||
|
sec_param.mitm = SEC_PARAM_MITM;
|
||||||
|
sec_param.lesc = SEC_PARAM_LESC;
|
||||||
|
sec_param.keypress = SEC_PARAM_KEYPRESS;
|
||||||
|
sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES;
|
||||||
|
sec_param.oob = SEC_PARAM_OOB;
|
||||||
|
sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
|
||||||
|
sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
|
||||||
|
sec_param.kdist_own.enc = 1;
|
||||||
|
sec_param.kdist_own.id = 1;
|
||||||
|
sec_param.kdist_peer.enc = 1;
|
||||||
|
sec_param.kdist_peer.id = 1;
|
||||||
|
|
||||||
|
err_code = pm_sec_params_set(&sec_param);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
|
privacy_params.p_device_irk = NULL;
|
||||||
|
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY;
|
||||||
|
privacy_params.private_addr_cycle_s = 0;
|
||||||
|
privacy_params.private_addr_type =
|
||||||
|
BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
|
||||||
|
pm_privacy_set(&privacy_params);
|
||||||
|
|
||||||
|
err_code = pm_register(pm_evt_handler);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@brief Function for setting filtered device identities.
|
||||||
|
*
|
||||||
|
* @param[in] skip Filter passed to @ref pm_peer_id_list.
|
||||||
|
*/
|
||||||
|
void identities_set(pm_peer_id_list_skip_t skip) {
|
||||||
|
pm_peer_id_t peer_ids[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT];
|
||||||
|
uint32_t peer_id_count = BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT;
|
||||||
|
|
||||||
|
ret_code_t err_code =
|
||||||
|
pm_peer_id_list(peer_ids, &peer_id_count, PM_PEER_ID_INVALID, skip);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
|
err_code = pm_device_identities_list_set(peer_ids, peer_id_count);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////**@brief Clear bond information from persistent storage. */
|
||||||
|
void delete_bonds(void) {
|
||||||
|
ret_code_t err_code;
|
||||||
|
|
||||||
|
NRF_LOG_INFO("Erase bonds!");
|
||||||
|
|
||||||
|
err_code = pm_peers_delete();
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
}
|
18
core/embed/ble_firmware/pm.h
Normal file
18
core/embed/ble_firmware/pm.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef __PEER_MANAGER__
|
||||||
|
#define __PEER_MANAGER__
|
||||||
|
|
||||||
|
#include "peer_manager.h"
|
||||||
|
|
||||||
|
pm_peer_id_t get_peer_id(void);
|
||||||
|
|
||||||
|
void whitelist_set(pm_peer_id_list_skip_t skip);
|
||||||
|
|
||||||
|
void identities_set(pm_peer_id_list_skip_t skip);
|
||||||
|
|
||||||
|
/**@brief Function for the Peer Manager initialization.
|
||||||
|
*/
|
||||||
|
void peer_manager_init(void);
|
||||||
|
|
||||||
|
void delete_bonds(void);
|
||||||
|
|
||||||
|
#endif
|
21
core/embed/ble_firmware/power.c
Normal file
21
core/embed/ble_firmware/power.c
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "power.h"
|
||||||
|
#include "app_error.h"
|
||||||
|
#include "bsp_btn_ble.h"
|
||||||
|
|
||||||
|
/**@brief Function for putting the chip into sleep mode.
|
||||||
|
*
|
||||||
|
* @note This function will not return.
|
||||||
|
*/
|
||||||
|
void sleep_mode_enter(void) {
|
||||||
|
uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
|
// Prepare wakeup buttons.
|
||||||
|
err_code = bsp_btn_ble_sleep_mode_prepare();
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
|
||||||
|
// Go to system-off mode (this function will not return; wakeup will cause a
|
||||||
|
// reset).
|
||||||
|
err_code = sd_power_system_off();
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
}
|
6
core/embed/ble_firmware/power.h
Normal file
6
core/embed/ble_firmware/power.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef __POWER__
|
||||||
|
#define __POWER__
|
||||||
|
|
||||||
|
void sleep_mode_enter(void);
|
||||||
|
|
||||||
|
#endif
|
@ -51,6 +51,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLE
|
#ifdef USE_BLE
|
||||||
#include "ble/comm.h"
|
#include "ble/comm.h"
|
||||||
|
#include "ble/state.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
@ -123,11 +124,27 @@ static void usb_init_all(secbool usb21_landing) {
|
|||||||
usb_start();
|
usb_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
|
void start_comm(secbool usb21_landing) {
|
||||||
const image_header *const hdr) {
|
|
||||||
// if both are NULL, we don't have a firmware installed
|
// if both are NULL, we don't have a firmware installed
|
||||||
// let's show a webusb landing page in this case
|
// let's show a webusb landing page in this case
|
||||||
usb_init_all((vhdr == NULL && hdr == NULL) ? sectrue : secfalse);
|
usb_init_all(usb21_landing);
|
||||||
|
#ifdef USE_BLE
|
||||||
|
start_advertising();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_comm(void) {
|
||||||
|
hal_delay(100);
|
||||||
|
usb_stop();
|
||||||
|
usb_deinit();
|
||||||
|
#ifdef USE_BLE
|
||||||
|
stop_advertising();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
|
||||||
|
const image_header *const hdr) {
|
||||||
|
start_comm((vhdr == NULL && hdr == NULL) ? sectrue : secfalse);
|
||||||
|
|
||||||
uint8_t buf_usb[USB_PACKET_SIZE];
|
uint8_t buf_usb[USB_PACKET_SIZE];
|
||||||
#ifdef USE_BLE
|
#ifdef USE_BLE
|
||||||
@ -164,6 +181,8 @@ static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
|
|||||||
buf = ble_buf;
|
buf = ble_buf;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ble_event_poll();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,9 +216,7 @@ static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
|
|||||||
case MessageType_MessageType_PairingRequest: // pairing request
|
case MessageType_MessageType_PairingRequest: // pairing request
|
||||||
response = process_msg_Pairing(active_iface, msg_size, ble_buf);
|
response = process_msg_Pairing(active_iface, msg_size, ble_buf);
|
||||||
if (response != INPUT_CONFIRM) {
|
if (response != INPUT_CONFIRM) {
|
||||||
hal_delay(100);
|
stop_comm();
|
||||||
usb_stop();
|
|
||||||
usb_deinit();
|
|
||||||
return RETURN;
|
return RETURN;
|
||||||
}
|
}
|
||||||
screen_connect();
|
screen_connect();
|
||||||
@ -209,9 +226,7 @@ static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
|
|||||||
case MessageType_MessageType_RepairRequest: // repairing request
|
case MessageType_MessageType_RepairRequest: // repairing request
|
||||||
response = process_msg_Repair(active_iface, msg_size, ble_buf);
|
response = process_msg_Repair(active_iface, msg_size, ble_buf);
|
||||||
if (response != INPUT_CONFIRM) {
|
if (response != INPUT_CONFIRM) {
|
||||||
hal_delay(100);
|
stop_comm();
|
||||||
usb_stop();
|
|
||||||
usb_deinit();
|
|
||||||
return RETURN;
|
return RETURN;
|
||||||
}
|
}
|
||||||
// screen_connect();
|
// screen_connect();
|
||||||
@ -277,9 +292,7 @@ static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
|
|||||||
response = ui_screen_wipe_confirm();
|
response = ui_screen_wipe_confirm();
|
||||||
if (INPUT_CANCEL == response) {
|
if (INPUT_CANCEL == response) {
|
||||||
send_user_abort(active_iface, "Wipe cancelled");
|
send_user_abort(active_iface, "Wipe cancelled");
|
||||||
hal_delay(100);
|
stop_comm();
|
||||||
usb_stop();
|
|
||||||
usb_deinit();
|
|
||||||
return RETURN;
|
return RETURN;
|
||||||
}
|
}
|
||||||
ui_screen_wipe();
|
ui_screen_wipe();
|
||||||
@ -287,13 +300,11 @@ static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
|
|||||||
process_msg_WipeDevice(active_iface, msg_size, buf);
|
process_msg_WipeDevice(active_iface, msg_size, buf);
|
||||||
if (upload_response < 0) { // error
|
if (upload_response < 0) { // error
|
||||||
screen_wipe_fail();
|
screen_wipe_fail();
|
||||||
usb_stop();
|
stop_comm();
|
||||||
usb_deinit();
|
|
||||||
return SHUTDOWN;
|
return SHUTDOWN;
|
||||||
} else { // success
|
} else { // success
|
||||||
screen_wipe_success();
|
screen_wipe_success();
|
||||||
usb_stop();
|
stop_comm();
|
||||||
usb_deinit();
|
|
||||||
return SHUTDOWN;
|
return SHUTDOWN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -307,13 +318,10 @@ static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
|
|||||||
upload_response !=
|
upload_response !=
|
||||||
UPLOAD_ERR_USER_ABORT) { // error, but not user abort
|
UPLOAD_ERR_USER_ABORT) { // error, but not user abort
|
||||||
ui_screen_fail();
|
ui_screen_fail();
|
||||||
usb_stop();
|
stop_comm();
|
||||||
usb_deinit();
|
|
||||||
return SHUTDOWN;
|
return SHUTDOWN;
|
||||||
} else if (upload_response == UPLOAD_ERR_USER_ABORT) {
|
} else if (upload_response == UPLOAD_ERR_USER_ABORT) {
|
||||||
hal_delay(100);
|
stop_comm();
|
||||||
usb_stop();
|
|
||||||
usb_deinit();
|
|
||||||
return RETURN;
|
return RETURN;
|
||||||
} else if (upload_response == 0) { // last chunk received
|
} else if (upload_response == 0) { // last chunk received
|
||||||
ui_screen_install_progress_upload(1000);
|
ui_screen_install_progress_upload(1000);
|
||||||
@ -324,8 +332,7 @@ static usb_result_t bootloader_comm_loop(const vendor_header *const vhdr,
|
|||||||
hal_delay(1000);
|
hal_delay(1000);
|
||||||
ui_screen_done(1, secfalse);
|
ui_screen_done(1, secfalse);
|
||||||
hal_delay(1000);
|
hal_delay(1000);
|
||||||
usb_stop();
|
stop_comm();
|
||||||
usb_deinit();
|
|
||||||
ui_screen_boot_empty(true);
|
ui_screen_boot_empty(true);
|
||||||
return CONTINUE;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLE
|
#ifdef USE_BLE
|
||||||
#include "ble/comm.h"
|
#include "ble/comm.h"
|
||||||
|
#include "ble/state.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SYSTEM_VIEW
|
#ifdef SYSTEM_VIEW
|
||||||
@ -149,6 +150,7 @@ int main(void) {
|
|||||||
|
|
||||||
#ifdef USE_BLE
|
#ifdef USE_BLE
|
||||||
ble_comm_init();
|
ble_comm_init();
|
||||||
|
start_advertising();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined TREZOR_MODEL_1
|
#if !defined TREZOR_MODEL_1
|
||||||
@ -250,6 +252,10 @@ void SVC_C_Handler(uint32_t *stack) {
|
|||||||
;
|
;
|
||||||
break;
|
break;
|
||||||
case SVC_REBOOT_TO_BOOTLOADER:
|
case SVC_REBOOT_TO_BOOTLOADER:
|
||||||
|
#ifdef USE_BLE
|
||||||
|
stop_advertising();
|
||||||
|
// TODO: make sure that no answer is pending from NRF
|
||||||
|
#endif
|
||||||
ensure_compatible_settings();
|
ensure_compatible_settings();
|
||||||
mpu_config_bootloader();
|
mpu_config_bootloader();
|
||||||
__asm__ volatile("msr control, %0" ::"r"(0x0));
|
__asm__ volatile("msr control, %0" ::"r"(0x0));
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "buffers.h"
|
#include "buffers.h"
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
#include "int_comm_defs.h"
|
#include "int_comm_defs.h"
|
||||||
|
#include "messages.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
|
|
||||||
#define SPI_QUEUE_SIZE 10
|
#define SPI_QUEUE_SIZE 10
|
||||||
@ -152,18 +153,14 @@ void process_poll(uint8_t *data, uint32_t len) {
|
|||||||
uint8_t cmd = data[0];
|
uint8_t cmd = data[0];
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case INTERNAL_EVENT_INITIALIZED: {
|
// case INTERNAL_EVENT_INITIALIZED: {
|
||||||
set_connected(false);
|
// set_connected(false);
|
||||||
set_initialized(true);
|
// set_initialized(true);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case INTERNAL_EVENT_CONNECTED: {
|
case INTERNAL_EVENT_STATUS: {
|
||||||
set_connected(true);
|
set_connected(data[1]);
|
||||||
set_initialized(true);
|
set_advertising(data[2]);
|
||||||
break;
|
|
||||||
}
|
|
||||||
case INTERNAL_EVENT_DISCONNECTED: {
|
|
||||||
set_connected(false);
|
|
||||||
set_initialized(true);
|
set_initialized(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -249,8 +246,7 @@ void ble_event_poll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ble_initialized()) {
|
if (!ble_initialized()) {
|
||||||
uint8_t cmd = INTERNAL_CMD_SEND_STATE;
|
send_state_request();
|
||||||
ble_int_comm_send(&cmd, sizeof(cmd), INTERNAL_EVENT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,13 @@
|
|||||||
#define EXTERNAL_MESSAGE (0xA1)
|
#define EXTERNAL_MESSAGE (0xA1)
|
||||||
#define INTERNAL_MESSAGE (0xA0)
|
#define INTERNAL_MESSAGE (0xA0)
|
||||||
|
|
||||||
#define INTERNAL_EVENT_INITIALIZED (0x00)
|
typedef enum {
|
||||||
#define INTERNAL_EVENT_CONNECTED (0x01)
|
INTERNAL_EVENT_STATUS = 0x01,
|
||||||
#define INTERNAL_EVENT_DISCONNECTED (0x02)
|
} InternalEvent_t;
|
||||||
|
|
||||||
#define INTERNAL_CMD_SEND_STATE (0x00)
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
INTERNAL_CMD_SEND_STATE = 0x00,
|
||||||
|
INTERNAL_CMD_ADVERTISING_ON = 0x01,
|
||||||
|
INTERNAL_CMD_ADVERTISING_OFF = 0x02,
|
||||||
|
} InternalCmd_t;
|
||||||
#endif
|
#endif
|
||||||
|
20
core/embed/trezorhal/ble/messages.c
Normal file
20
core/embed/trezorhal/ble/messages.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "comm.h"
|
||||||
|
#include "messages.h"
|
||||||
|
|
||||||
|
void send_state_request(void) {
|
||||||
|
uint8_t cmd = INTERNAL_CMD_SEND_STATE;
|
||||||
|
ble_int_comm_send(&cmd, sizeof(cmd), INTERNAL_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_advertising_on(void) {
|
||||||
|
uint8_t cmd = INTERNAL_CMD_ADVERTISING_ON;
|
||||||
|
ble_int_comm_send(&cmd, sizeof(cmd), INTERNAL_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_advertising_off(void) {
|
||||||
|
uint8_t cmd = INTERNAL_CMD_ADVERTISING_OFF;
|
||||||
|
ble_int_comm_send(&cmd, sizeof(cmd), INTERNAL_EVENT);
|
||||||
|
}
|
10
core/embed/trezorhal/ble/messages.h
Normal file
10
core/embed/trezorhal/ble/messages.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef __BLE_MESSAGES__
|
||||||
|
#define __BLE_MESSAGES__
|
||||||
|
|
||||||
|
void send_state_request(void);
|
||||||
|
|
||||||
|
void send_advertising_on(void);
|
||||||
|
|
||||||
|
void send_advertising_off(void);
|
||||||
|
|
||||||
|
#endif
|
@ -1,14 +1,42 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "ble/state.h"
|
#include "ble/state.h"
|
||||||
|
#include "messages.h"
|
||||||
|
|
||||||
static bool ble_state_connected = false;
|
static bool ble_state_connected = false;
|
||||||
static bool ble_state_initialized = false;
|
static bool ble_state_initialized = false;
|
||||||
|
static bool ble_advertising_wanted = false;
|
||||||
|
static bool ble_advertising = false;
|
||||||
|
|
||||||
bool ble_connected(void) { return ble_state_connected; }
|
bool ble_connected(void) { return ble_state_connected; }
|
||||||
|
|
||||||
void set_connected(bool connected) { ble_state_connected = connected; }
|
void set_connected(bool connected) { ble_state_connected = connected; }
|
||||||
|
|
||||||
|
void set_advertising(bool advertising) {
|
||||||
|
if (ble_advertising_wanted != advertising) {
|
||||||
|
if (ble_advertising_wanted) {
|
||||||
|
send_advertising_on();
|
||||||
|
} else {
|
||||||
|
send_advertising_off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ble_advertising = advertising;
|
||||||
|
}
|
||||||
|
|
||||||
void set_initialized(bool initialized) { ble_state_initialized = initialized; }
|
void set_initialized(bool initialized) { ble_state_initialized = initialized; }
|
||||||
|
|
||||||
bool ble_initialized(void) { return ble_state_initialized; }
|
bool ble_initialized(void) { return ble_state_initialized; }
|
||||||
|
|
||||||
|
void start_advertising(void) {
|
||||||
|
ble_advertising_wanted = true;
|
||||||
|
if (!ble_advertising) {
|
||||||
|
send_advertising_on();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_advertising(void) {
|
||||||
|
ble_advertising_wanted = false;
|
||||||
|
if (ble_advertising) {
|
||||||
|
send_advertising_off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,6 +11,12 @@ void set_initialized(bool initialized);
|
|||||||
|
|
||||||
bool ble_connected(void);
|
bool ble_connected(void);
|
||||||
|
|
||||||
|
void set_advertising(bool advertising);
|
||||||
|
|
||||||
void set_connected(bool connected);
|
void set_connected(bool connected);
|
||||||
|
|
||||||
|
void start_advertising(void);
|
||||||
|
|
||||||
|
void stop_advertising(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,7 @@ def configure(env, features_wanted, defines, sources):
|
|||||||
sources += ['embed/trezorhal/ble/dfu.c', ]
|
sources += ['embed/trezorhal/ble/dfu.c', ]
|
||||||
sources += ['embed/trezorhal/ble/fwu.c', ]
|
sources += ['embed/trezorhal/ble/fwu.c', ]
|
||||||
sources += ['embed/trezorhal/ble/state.c', ]
|
sources += ['embed/trezorhal/ble/state.c', ]
|
||||||
|
sources += ['embed/trezorhal/ble/messages.c', ]
|
||||||
features_available.append("ble")
|
features_available.append("ble")
|
||||||
|
|
||||||
if "dma2d" in features_wanted:
|
if "dma2d" in features_wanted:
|
||||||
|
Loading…
Reference in New Issue
Block a user