mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-21 12:02:19 +00:00
feat(core/prodtest): add BLE testing
[no changelog]
This commit is contained in:
parent
d7d236d382
commit
2ca8d093c6
@ -9,7 +9,7 @@ PRODUCTION = ARGUMENTS.get('PRODUCTION', '0') == '1'
|
||||
BOOTLOADER_DEVEL = ARGUMENTS.get('BOOTLOADER_DEVEL', '0') == '1'
|
||||
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
|
||||
|
||||
FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "usb", "consumption_mask", "optiga", "haptic"]
|
||||
FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "usb", "consumption_mask", "optiga", "haptic", "ble"]
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
CPPPATH_MOD = []
|
||||
@ -99,6 +99,7 @@ SOURCE_PRODTEST = [
|
||||
'embed/projects/prodtest/header.S',
|
||||
'embed/projects/prodtest/main.c',
|
||||
'embed/projects/prodtest/cmd/prodtest_boardloader.c',
|
||||
'embed/projects/prodtest/cmd/prodtest_ble.c',
|
||||
'embed/projects/prodtest/cmd/prodtest_bootloader.c',
|
||||
'embed/projects/prodtest/cmd/prodtest_button.c',
|
||||
'embed/projects/prodtest/cmd/prodtest_display.c',
|
||||
|
@ -41,10 +41,14 @@ typedef enum {
|
||||
BLE_REJECT_PAIRING = 6, // Reject pairing request
|
||||
} ble_command_type_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t name[BLE_ADV_NAME_LEN];
|
||||
bool static_mac;
|
||||
} ble_adv_start_cmd_data_t;
|
||||
|
||||
typedef union {
|
||||
uint8_t raw[32];
|
||||
uint8_t name[BLE_ADV_NAME_LEN];
|
||||
|
||||
ble_adv_start_cmd_data_t adv_start;
|
||||
} ble_command_data_t;
|
||||
|
||||
typedef struct {
|
||||
@ -73,6 +77,7 @@ typedef struct {
|
||||
bool connectable;
|
||||
bool pairing;
|
||||
bool pairing_requested;
|
||||
bool state_known;
|
||||
uint8_t peer_count;
|
||||
} ble_state_t;
|
||||
|
||||
@ -139,4 +144,10 @@ bool ble_can_read(void);
|
||||
// Returns the number of bytes actually read.
|
||||
uint32_t ble_read(uint8_t *data, uint16_t max_len);
|
||||
|
||||
// Read MAC address of the device
|
||||
//
|
||||
// When not using static address, the address is random and may not correspond
|
||||
// to what is actually used for advertising
|
||||
bool ble_get_mac(uint8_t *mac, uint16_t max_len);
|
||||
|
||||
#endif
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <io/ble.h>
|
||||
#include <io/nrf.h>
|
||||
#include <sys/irq.h>
|
||||
#include <sys/systick.h>
|
||||
#include <sys/systimer.h>
|
||||
#include <util/tsqueue.h>
|
||||
#include <util/unit_properties.h>
|
||||
@ -66,7 +67,9 @@ typedef struct {
|
||||
tsqueue_entry_t ts_queue_entries[TX_QUEUE_LEN];
|
||||
tsqueue_t tx_queue;
|
||||
|
||||
char adv_name[BLE_ADV_NAME_LEN];
|
||||
ble_adv_start_cmd_data_t adv_cmd;
|
||||
uint8_t mac[6];
|
||||
bool mac_ready;
|
||||
systimer_t *timer;
|
||||
uint16_t ping_cntr;
|
||||
} ble_driver_t;
|
||||
@ -90,8 +93,11 @@ static bool ble_send_advertising_on(ble_driver_t *drv, bool whitelist) {
|
||||
.cmd_id = INTERNAL_CMD_ADVERTISING_ON,
|
||||
.whitelist = whitelist ? 1 : 0,
|
||||
.color = props.color,
|
||||
.static_addr = drv->adv_cmd.static_mac,
|
||||
.device_code = HW_MODEL,
|
||||
};
|
||||
memcpy(data.name, drv->adv_name, BLE_ADV_NAME_LEN);
|
||||
|
||||
memcpy(data.name, drv->adv_cmd.name, BLE_ADV_NAME_LEN);
|
||||
|
||||
return nrf_send_msg(NRF_SERVICE_BLE_MANAGER, (uint8_t *)&data, sizeof(data),
|
||||
NULL, NULL) >= 0;
|
||||
@ -142,6 +148,13 @@ static bool ble_send_pairing_accept(ble_driver_t *drv) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool ble_send_mac_request(ble_driver_t *drv) {
|
||||
(void)drv;
|
||||
uint8_t cmd = INTERNAL_CMD_MAC_REQUEST;
|
||||
|
||||
return nrf_send_msg(NRF_SERVICE_BLE_MANAGER, &cmd, sizeof(cmd), NULL, NULL);
|
||||
}
|
||||
|
||||
static void ble_process_rx_msg_status(const uint8_t *data, uint32_t len) {
|
||||
ble_driver_t *drv = &g_ble_driver;
|
||||
|
||||
@ -233,6 +246,16 @@ static void ble_process_rx_msg_pairing_cancelled(const uint8_t *data,
|
||||
drv->pairing_requested = false;
|
||||
}
|
||||
|
||||
static void ble_process_rx_msg_mac(const uint8_t *data, uint32_t len) {
|
||||
ble_driver_t *drv = &g_ble_driver;
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
drv->mac_ready = true;
|
||||
memcpy(drv->mac, &data[1], sizeof(drv->mac));
|
||||
}
|
||||
|
||||
static void ble_process_rx_msg(const uint8_t *data, uint32_t len) {
|
||||
if (len < 1) {
|
||||
return;
|
||||
@ -248,6 +271,8 @@ static void ble_process_rx_msg(const uint8_t *data, uint32_t len) {
|
||||
case INTERNAL_EVENT_PAIRING_CANCELLED:
|
||||
ble_process_rx_msg_pairing_cancelled(data, len);
|
||||
break;
|
||||
case INTERNAL_EVENT_MAC:
|
||||
ble_process_rx_msg_mac(data, len);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -525,11 +550,11 @@ bool ble_issue_command(ble_command_t *command) {
|
||||
drv->mode_requested = BLE_MODE_OFF;
|
||||
break;
|
||||
case BLE_SWITCH_ON:
|
||||
memcpy(drv->adv_name, command->data.name, sizeof(drv->adv_name));
|
||||
memcpy(&drv->adv_cmd, &command->data.adv_start, sizeof(drv->adv_cmd));
|
||||
drv->mode_requested = BLE_MODE_CONNECTABLE;
|
||||
break;
|
||||
case BLE_PAIRING_MODE:
|
||||
memcpy(drv->adv_name, command->data.name, sizeof(drv->adv_name));
|
||||
memcpy(&drv->adv_cmd, &command->data.adv_start, sizeof(drv->adv_cmd));
|
||||
drv->mode_requested = BLE_MODE_PAIRING;
|
||||
break;
|
||||
case BLE_DISCONNECT:
|
||||
@ -585,8 +610,36 @@ void ble_get_state(ble_state_t *state) {
|
||||
state->pairing = drv->mode_current == BLE_MODE_PAIRING;
|
||||
state->connectable = drv->mode_current == BLE_MODE_CONNECTABLE;
|
||||
state->pairing_requested = drv->pairing_requested;
|
||||
state->state_known = drv->status_valid;
|
||||
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
bool ble_get_mac(uint8_t *mac, uint16_t max_len) {
|
||||
ble_driver_t *drv = &g_ble_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
memset(mac, 0, max_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
drv->mac_ready = false;
|
||||
|
||||
if (!ble_send_mac_request(drv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t timeout = ticks_timeout(100);
|
||||
|
||||
while (!ticks_expired(timeout)) {
|
||||
if (drv->mac_ready) {
|
||||
memcpy(mac, drv->mac, max_len);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
memset(mac, 0, max_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -45,6 +45,7 @@ typedef enum {
|
||||
INTERNAL_EVENT_STATUS = 0x01,
|
||||
INTERNAL_EVENT_PAIRING_REQUEST = 0x04,
|
||||
INTERNAL_EVENT_PAIRING_CANCELLED = 0x05,
|
||||
INTERNAL_EVENT_MAC = 0x06,
|
||||
} internal_event_t;
|
||||
|
||||
typedef enum {
|
||||
@ -56,11 +57,14 @@ typedef enum {
|
||||
INTERNAL_CMD_ACK = 0x05,
|
||||
INTERNAL_CMD_ALLOW_PAIRING = 0x06,
|
||||
INTERNAL_CMD_REJECT_PAIRING = 0x07,
|
||||
INTERNAL_CMD_MAC_REQUEST = 0x09,
|
||||
} internal_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t cmd_id;
|
||||
uint8_t whitelist;
|
||||
uint8_t color;
|
||||
uint8_t static_addr;
|
||||
uint32_t device_code;
|
||||
uint8_t name[BLE_ADV_NAME_LEN];
|
||||
} cmd_advertising_on_t;
|
||||
|
215
core/embed/projects/prodtest/cmd/prodtest_ble.c
Normal file
215
core/embed/projects/prodtest/cmd/prodtest_ble.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/systick.h>
|
||||
#ifdef USE_BLE
|
||||
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <io/ble.h>
|
||||
#include <rtl/cli.h>
|
||||
#include <sys/systimer.h>
|
||||
|
||||
void ble_timer_cb(void* context) {
|
||||
ble_event_t e = {0};
|
||||
ble_command_t cmd = {0};
|
||||
|
||||
bool event_received = ble_get_event(&e);
|
||||
|
||||
if (event_received) {
|
||||
switch (e.type) {
|
||||
case BLE_PAIRING_REQUEST:
|
||||
cmd.cmd_type = BLE_ALLOW_PAIRING;
|
||||
ble_issue_command(&cmd);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void prodtest_ble_init(void) {
|
||||
systimer_t* timer = systimer_create(ble_timer_cb, NULL);
|
||||
|
||||
systimer_set_periodic(timer, 10);
|
||||
}
|
||||
|
||||
static void prodtest_ble_adv_start(cli_t* cli) {
|
||||
const char* name = cli_arg(cli, "name");
|
||||
|
||||
if (cli_arg_count(cli) > 1) {
|
||||
cli_error_arg_count(cli);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t name_len =
|
||||
strlen(name) > BLE_ADV_NAME_LEN ? BLE_ADV_NAME_LEN : strlen(name);
|
||||
|
||||
ble_command_t cmd = {0};
|
||||
cmd.cmd_type = BLE_PAIRING_MODE;
|
||||
cmd.data_len = sizeof(cmd.data.adv_start);
|
||||
cmd.data.adv_start.static_mac = true;
|
||||
memcpy(cmd.data.adv_start.name, name, name_len);
|
||||
|
||||
ble_issue_command(&cmd);
|
||||
|
||||
uint32_t timeout = ticks_timeout(1000);
|
||||
|
||||
bool result = false;
|
||||
while (!ticks_expired(timeout)) {
|
||||
ble_state_t state = {0};
|
||||
ble_get_state(&state);
|
||||
|
||||
if (state.pairing) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
cli_error(cli, CLI_ERROR, "could not start advertising");
|
||||
return;
|
||||
}
|
||||
|
||||
cli_ok(cli, "advertising started");
|
||||
}
|
||||
|
||||
static void prodtest_ble_adv_stop(cli_t* cli) {
|
||||
if (cli_arg_count(cli) > 0) {
|
||||
cli_error_arg_count(cli);
|
||||
return;
|
||||
}
|
||||
|
||||
ble_command_t cmd = {0};
|
||||
cmd.cmd_type = BLE_SWITCH_OFF;
|
||||
cmd.data_len = 0;
|
||||
|
||||
ble_issue_command(&cmd);
|
||||
|
||||
uint32_t timeout = ticks_timeout(1000);
|
||||
|
||||
bool result = false;
|
||||
while (!ticks_expired(timeout)) {
|
||||
ble_state_t state = {0};
|
||||
ble_get_state(&state);
|
||||
|
||||
if (!state.pairing && !state.connectable) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
cli_error(cli, CLI_ERROR, "could not stop advertising");
|
||||
return;
|
||||
}
|
||||
|
||||
cli_ok(cli, "advertising stopped");
|
||||
}
|
||||
|
||||
static void prodtest_ble_info(cli_t* cli) {
|
||||
if (cli_arg_count(cli) > 0) {
|
||||
cli_error_arg_count(cli);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t mac[6] = {0};
|
||||
|
||||
ble_get_mac(mac, 6);
|
||||
|
||||
cli_trace(cli, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[5], mac[4], mac[3],
|
||||
mac[2], mac[1], mac[0]);
|
||||
cli_ok(cli, "");
|
||||
}
|
||||
|
||||
bool prodtest_ble_erase_bonds(void) {
|
||||
ble_command_t cmd = {0};
|
||||
cmd.cmd_type = BLE_ERASE_BONDS;
|
||||
|
||||
ble_state_t state = {0};
|
||||
ble_issue_command(&cmd);
|
||||
|
||||
uint32_t timeout = ticks_timeout(100);
|
||||
|
||||
while (!ticks_expired(timeout)) {
|
||||
ble_get_state(&state);
|
||||
if (state.peer_count == 0 && state.state_known) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void prodtest_ble_erase_bonds_cmd(cli_t* cli) {
|
||||
if (cli_arg_count(cli) > 0) {
|
||||
cli_error_arg_count(cli);
|
||||
return;
|
||||
}
|
||||
|
||||
ble_state_t state = {0};
|
||||
|
||||
ble_get_state(&state);
|
||||
|
||||
if (!state.state_known) {
|
||||
cli_error(cli, CLI_ERROR, "BLE state unknown");
|
||||
}
|
||||
|
||||
if (state.peer_count == 0) {
|
||||
cli_ok(cli, "No bonds to erase");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prodtest_ble_erase_bonds()) {
|
||||
cli_error(cli, CLI_ERROR, "Could not erase bonds");
|
||||
}
|
||||
|
||||
cli_ok(cli, "Bonds erased");
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
PRODTEST_CLI_CMD(
|
||||
.name = "ble-adv-start",
|
||||
.func = prodtest_ble_adv_start,
|
||||
.info = "Start BLE advertising",
|
||||
.args = "<name>"
|
||||
)
|
||||
PRODTEST_CLI_CMD(
|
||||
.name = "ble-adv-stop",
|
||||
.func = prodtest_ble_adv_stop,
|
||||
.info = "Stop BLE advertising",
|
||||
.args = "<name>"
|
||||
)
|
||||
|
||||
PRODTEST_CLI_CMD(
|
||||
.name = "ble-info",
|
||||
.func = prodtest_ble_info,
|
||||
.info = "Get BLE information",
|
||||
.args = ""
|
||||
)
|
||||
|
||||
PRODTEST_CLI_CMD(
|
||||
.name = "ble-erase-bonds",
|
||||
.func = prodtest_ble_erase_bonds_cmd,
|
||||
.info = "Erase all BLE bonds",
|
||||
.args = ""
|
||||
)
|
||||
|
||||
|
||||
#endif
|
24
core/embed/projects/prodtest/cmd/prodtest_ble.h
Normal file
24
core/embed/projects/prodtest/cmd/prodtest_ble.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void prodtest_ble_init(void);
|
||||
|
||||
bool prodtest_ble_erase_bonds(void);
|
@ -24,6 +24,10 @@
|
||||
#include <rtl/cli.h>
|
||||
#include <util/fwutils.h>
|
||||
|
||||
#ifdef USE_BLE
|
||||
#include "prodtest_ble.h"
|
||||
#endif
|
||||
|
||||
#include <version.h>
|
||||
|
||||
static void prodtest_prodtest_intro(cli_t* cli) {
|
||||
@ -49,6 +53,14 @@ static void prodtest_prodtest_wipe(cli_t* cli) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_BLE
|
||||
cli_trace(cli, "Erasing BLE bonds...");
|
||||
if (!prodtest_ble_erase_bonds()) {
|
||||
cli_error(cli, CLI_ERROR, "Failed to erase BLE bonds.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
cli_trace(cli, "Invalidating the production test firmware header...");
|
||||
firmware_invalidate_header();
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <sys/system.h>
|
||||
#include <util/flash_otp.h>
|
||||
#include <util/rsod.h>
|
||||
#include <util/unit_properties.h>
|
||||
|
||||
#include "rust_ui_prodtest.h"
|
||||
|
||||
@ -71,6 +72,12 @@
|
||||
#include <sec/secure_aes.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_BLE
|
||||
#include <io/ble.h>
|
||||
#include <util/unit_properties.h>
|
||||
#include "cmd/prodtest_ble.h"
|
||||
#endif
|
||||
|
||||
#ifdef TREZOR_MODEL_T2T1
|
||||
#define MODEL_IDENTIFIER "TREZOR2-"
|
||||
#else
|
||||
@ -185,6 +192,11 @@ static void drivers_init(void) {
|
||||
#ifdef USE_RGB_LED
|
||||
rgb_led_init();
|
||||
#endif
|
||||
#ifdef USE_BLE
|
||||
unit_properties_init();
|
||||
ble_init();
|
||||
prodtest_ble_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
#define BACKLIGHT_NORMAL 150
|
||||
|
@ -8,6 +8,7 @@ pub fn connected() -> bool {
|
||||
connectable: false,
|
||||
pairing: false,
|
||||
pairing_requested: false,
|
||||
state_known: false,
|
||||
};
|
||||
ffi::ble_get_state(&mut state as _);
|
||||
|
||||
@ -26,9 +27,9 @@ pub fn pairing_mode(name: &str) {
|
||||
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());
|
||||
let len = bytes.len().min(cmd.data.adv_start.name.len());
|
||||
|
||||
cmd.data.name[..len].copy_from_slice(&bytes[..len]);
|
||||
cmd.data.adv_start.name[..len].copy_from_slice(&bytes[..len]);
|
||||
|
||||
ffi::ble_issue_command(&mut cmd as _);
|
||||
}
|
||||
|
@ -173,12 +173,13 @@ STATIC mp_obj_t mod_trezorio_BLE_start_advertising(size_t n_args,
|
||||
|
||||
ble_command_t cmd = {
|
||||
.cmd_type = whitelist_bool ? BLE_SWITCH_ON : BLE_PAIRING_MODE,
|
||||
.data_len = name.len};
|
||||
.data_len = sizeof(ble_adv_start_cmd_data_t)};
|
||||
|
||||
// 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);
|
||||
cmd.data.adv_start.static_mac = false;
|
||||
memcpy(cmd.data.adv_start.name, name_buf, len);
|
||||
|
||||
return mp_obj_new_bool(ble_issue_command(&cmd));
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||
bool advertising = false;
|
||||
bool advertising_wl = false;
|
||||
|
||||
uint8_t manufacturer_data[8] = {0xff, 0xff, 0, 0, 'T', '3', 'W', '1'};
|
||||
uint8_t manufacturer_data[8] = {0xff, 0xff, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
static struct bt_data advertising_data[2];
|
||||
|
||||
@ -61,7 +61,8 @@ void advertising_setup_wl(void) {
|
||||
bt_foreach_bond(BT_ID_DEFAULT, add_to_whitelist, NULL);
|
||||
}
|
||||
|
||||
void advertising_start(bool wl, uint8_t color, char *name, int name_len) {
|
||||
void advertising_start(bool wl, uint8_t color, uint32_t device_code,
|
||||
bool static_addr, char *name, int name_len) {
|
||||
if (advertising) {
|
||||
LOG_WRN("Restarting advertising");
|
||||
bt_le_adv_stop();
|
||||
@ -74,6 +75,10 @@ void advertising_start(bool wl, uint8_t color, char *name, int name_len) {
|
||||
}
|
||||
|
||||
manufacturer_data[3] = color;
|
||||
manufacturer_data[4] = (device_code >> 24) & 0xff;
|
||||
manufacturer_data[5] = (device_code >> 16) & 0xff;
|
||||
manufacturer_data[6] = (device_code >> 8) & 0xff;
|
||||
manufacturer_data[7] = device_code & 0xff;
|
||||
|
||||
advertising_data[0].type = BT_DATA_FLAGS;
|
||||
advertising_data[0].data_len = 1;
|
||||
@ -96,23 +101,31 @@ void advertising_start(bool wl, uint8_t color, char *name, int name_len) {
|
||||
|
||||
manufacturer_data[2] = 0x00;
|
||||
|
||||
err = bt_le_adv_start(
|
||||
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_SCANNABLE |
|
||||
BT_LE_ADV_OPT_FILTER_CONN |
|
||||
BT_LE_ADV_OPT_FILTER_SCAN_REQ,
|
||||
160, 1600, NULL),
|
||||
advertising_data, ARRAY_SIZE(advertising_data), scan_response_data,
|
||||
ARRAY_SIZE(scan_response_data));
|
||||
uint32_t options = BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_SCANNABLE |
|
||||
BT_LE_ADV_OPT_FILTER_CONN |
|
||||
BT_LE_ADV_OPT_FILTER_SCAN_REQ;
|
||||
if (static_addr) {
|
||||
LOG_ERR("Advertising with static ADDR");
|
||||
options |= BT_LE_ADV_OPT_USE_IDENTITY;
|
||||
}
|
||||
|
||||
err = bt_le_adv_start(BT_LE_ADV_PARAM(options, 160, 1600, NULL),
|
||||
advertising_data, ARRAY_SIZE(advertising_data),
|
||||
scan_response_data, ARRAY_SIZE(scan_response_data));
|
||||
} else {
|
||||
LOG_INF("Advertising no whitelist");
|
||||
|
||||
manufacturer_data[2] = 0x01;
|
||||
|
||||
err = bt_le_adv_start(
|
||||
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_SCANNABLE,
|
||||
160, 1600, NULL),
|
||||
advertising_data, ARRAY_SIZE(advertising_data), scan_response_data,
|
||||
ARRAY_SIZE(scan_response_data));
|
||||
uint32_t options = BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_SCANNABLE;
|
||||
if (static_addr) {
|
||||
LOG_ERR("Advertising with static ADDR");
|
||||
options |= BT_LE_ADV_OPT_USE_IDENTITY;
|
||||
}
|
||||
|
||||
err = bt_le_adv_start(BT_LE_ADV_PARAM(options, 160, 1600, NULL),
|
||||
advertising_data, ARRAY_SIZE(advertising_data),
|
||||
scan_response_data, ARRAY_SIZE(scan_response_data));
|
||||
}
|
||||
if (err) {
|
||||
LOG_ERR("Advertising failed to start (err %d)", err);
|
||||
@ -152,3 +165,28 @@ void advertising_init(void) {
|
||||
LOG_INF("Advertising init");
|
||||
advertising_setup_wl();
|
||||
}
|
||||
|
||||
void advertising_get_mac(uint8_t *mac, uint16_t max_len) {
|
||||
bt_addr_le_t addr[CONFIG_BT_ID_MAX] = {0};
|
||||
size_t count = 0;
|
||||
|
||||
// Get the first (default) identity address
|
||||
bt_id_get(addr, &count);
|
||||
|
||||
struct bt_le_oob oob_data;
|
||||
bt_le_oob_get_local(BT_ID_DEFAULT, &oob_data);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
char addr_str[BT_ADDR_LE_STR_LEN];
|
||||
bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
|
||||
LOG_ERR("Current BT MAC Address: %s\n", addr_str);
|
||||
}
|
||||
|
||||
char addr_str[BT_ADDR_LE_STR_LEN];
|
||||
bt_addr_le_to_str(&oob_data.addr, addr_str, sizeof(addr_str));
|
||||
LOG_ERR("Current BT MAC Address: %s\n", addr_str);
|
||||
|
||||
LOG_ERR("Num of IDS: %d", count);
|
||||
|
||||
memcpy(mac, oob_data.addr.a.val, max_len);
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ typedef enum {
|
||||
INTERNAL_EVENT_FAILURE = 0x03,
|
||||
INTERNAL_EVENT_PAIRING_REQUEST = 0x04,
|
||||
INTERNAL_EVENT_PAIRING_CANCELLED = 0x05,
|
||||
INTERNAL_EVENT_MAC = 0x06,
|
||||
} internal_event_t;
|
||||
|
||||
typedef enum {
|
||||
@ -82,6 +83,7 @@ typedef enum {
|
||||
INTERNAL_CMD_ALLOW_PAIRING = 0x06,
|
||||
INTERNAL_CMD_REJECT_PAIRING = 0x07,
|
||||
INTERNAL_CMD_UNPAIR = 0x08,
|
||||
INTERNAL_CMD_GET_MAC = 0x09,
|
||||
} internal_cmd_t;
|
||||
|
||||
// BLE management functions
|
||||
@ -106,13 +108,16 @@ bool bonds_erase_current(void);
|
||||
// Initialization
|
||||
void advertising_init(void);
|
||||
// Start advertising, with or without whitelist
|
||||
void advertising_start(bool wl, uint8_t color, char *name, int name_len);
|
||||
void advertising_start(bool wl, uint8_t color, uint32_t device_code,
|
||||
bool static_addr, char *name, int name_len);
|
||||
// Stop advertising
|
||||
void advertising_stop(void);
|
||||
// Check if advertising is active
|
||||
bool advertising_is_advertising(void);
|
||||
// Check if advertising is active with whitelist
|
||||
bool advertising_is_advertising_whitelist(void);
|
||||
// Get current MAC address
|
||||
void advertising_get_mac(uint8_t *mac, uint16_t max_len);
|
||||
|
||||
// Connection functions
|
||||
// Initialization
|
||||
|
@ -96,6 +96,13 @@ void management_send_pairing_request_event(uint8_t *data, uint16_t len) {
|
||||
trz_comm_send_msg(NRF_SERVICE_BLE_MANAGER, tx_data, sizeof(tx_data));
|
||||
}
|
||||
|
||||
void management_send_mac(uint8_t *mac) {
|
||||
uint8_t tx_data[1 + BT_ADDR_SIZE] = {0};
|
||||
tx_data[0] = INTERNAL_EVENT_MAC;
|
||||
memcpy(&tx_data[1], mac, BT_ADDR_SIZE);
|
||||
trz_comm_send_msg(NRF_SERVICE_BLE_MANAGER, tx_data, sizeof(tx_data));
|
||||
}
|
||||
|
||||
static void process_command(uint8_t *data, uint16_t len) {
|
||||
uint8_t cmd = data[0];
|
||||
bool success = true;
|
||||
@ -107,9 +114,14 @@ static void process_command(uint8_t *data, uint16_t len) {
|
||||
break;
|
||||
case INTERNAL_CMD_ADVERTISING_ON: {
|
||||
uint8_t color = data[2];
|
||||
char *name = &data[3];
|
||||
bool static_addr = data[3];
|
||||
uint32_t device_code =
|
||||
(data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
|
||||
char *name = &data[8];
|
||||
|
||||
int name_len = strnlen(name, 20);
|
||||
advertising_start(data[1] != 0, color, name, name_len);
|
||||
advertising_start(data[1] != 0, color, device_code, static_addr, name,
|
||||
name_len);
|
||||
} break;
|
||||
case INTERNAL_CMD_ADVERTISING_OFF:
|
||||
advertising_stop();
|
||||
@ -131,6 +143,12 @@ static void process_command(uint8_t *data, uint16_t len) {
|
||||
case INTERNAL_CMD_UNPAIR:
|
||||
success = bonds_erase_current();
|
||||
break;
|
||||
case INTERNAL_CMD_GET_MAC: {
|
||||
uint8_t mac[BT_ADDR_SIZE] = {0};
|
||||
advertising_get_mac(mac, BT_ADDR_SIZE);
|
||||
management_send_mac(mac);
|
||||
send_response = false;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user