extmod/btstack: Implement key storage to enable pairing/bonding.

Btstack offers two abstraction layers for secret storage, one
called "device db" and another called "tlv". Pairing information
is stored in the "device db", additional secrets (like own keys)
are stored directly in the tlv. Luckily there is a "device db"
implementation using tlv, so we only need to provide one interface.

Additionally, I've removed some btstack files from compilation that
were not referenced.
This commit is contained in:
Felix Dörre
2023-04-08 21:42:40 +00:00
parent 75f8bf822b
commit 6634fea239
5 changed files with 89 additions and 29 deletions

View File

@@ -16,45 +16,45 @@ target_include_directories(micropy_extmod_btstack INTERFACE
target_sources(micropy_extmod_btstack INTERFACE
${BTSTACK_LIB_DIR}/platform/embedded/hci_dump_embedded_stdout.c
${BTSTACK_LIB_DIR}/src/ad_parser.c
#${BTSTACK_LIB_DIR}/src/ad_parser.c
${BTSTACK_LIB_DIR}/src/ble/gatt-service/ancs_client.c
${BTSTACK_LIB_DIR}/src/ble/att_db.c
${BTSTACK_LIB_DIR}/src/ble/att_db_util.c
${BTSTACK_LIB_DIR}/src/ble/att_dispatch.c
${BTSTACK_LIB_DIR}/src/ble/att_server.c
${BTSTACK_LIB_DIR}/src/ble/gatt-service/battery_service_server.c
${BTSTACK_LIB_DIR}/src/ble/gatt-service/cycling_power_service_server.c
${BTSTACK_LIB_DIR}/src/ble/gatt-service/cycling_speed_and_cadence_service_server.c
${BTSTACK_LIB_DIR}/src/ble/gatt-service/device_information_service_server.c
${BTSTACK_LIB_DIR}/src/ble/gatt-service/heart_rate_service_server.c
${BTSTACK_LIB_DIR}/src/ble/gatt-service/hids_device.c
${BTSTACK_LIB_DIR}/src/mesh/gatt-service/mesh_provisioning_service_server.c
${BTSTACK_LIB_DIR}/src/mesh/gatt-service/mesh_proxy_service_server.c
${BTSTACK_LIB_DIR}/src/ble/gatt-service/nordic_spp_service_server.c
${BTSTACK_LIB_DIR}/src/ble/gatt-service/ublox_spp_service_server.c
#${BTSTACK_LIB_DIR}/src/ble/gatt-service/battery_service_server.c
#${BTSTACK_LIB_DIR}/src/ble/gatt-service/cycling_power_service_server.c
#${BTSTACK_LIB_DIR}/src/ble/gatt-service/cycling_speed_and_cadence_service_server.c
#${BTSTACK_LIB_DIR}/src/ble/gatt-service/device_information_service_server.c
#${BTSTACK_LIB_DIR}/src/ble/gatt-service/heart_rate_service_server.c
#${BTSTACK_LIB_DIR}/src/ble/gatt-service/hids_device.c
#${BTSTACK_LIB_DIR}/src/mesh/gatt-service/mesh_provisioning_service_server.c
#${BTSTACK_LIB_DIR}/src/mesh/gatt-service/mesh_proxy_service_server.c
#${BTSTACK_LIB_DIR}/src/ble/gatt-service/nordic_spp_service_server.c
#${BTSTACK_LIB_DIR}/src/ble/gatt-service/ublox_spp_service_server.c
${BTSTACK_LIB_DIR}/src/ble/gatt_client.c
${BTSTACK_LIB_DIR}/src/ble/le_device_db_memory.c
${BTSTACK_LIB_DIR}/src/ble/le_device_db_tlv.c
${BTSTACK_LIB_DIR}/src/ble/sm.c
${BTSTACK_LIB_DIR}/src/btstack_audio.c
${BTSTACK_LIB_DIR}/src/btstack_base64_decoder.c
#${BTSTACK_LIB_DIR}/src/btstack_audio.c
#${BTSTACK_LIB_DIR}/src/btstack_base64_decoder.c
${BTSTACK_LIB_DIR}/src/btstack_crypto.c
${BTSTACK_LIB_DIR}/src/btstack_hid_parser.c
#${BTSTACK_LIB_DIR}/src/btstack_hid_parser.c
${BTSTACK_LIB_DIR}/src/btstack_linked_list.c
${BTSTACK_LIB_DIR}/src/btstack_memory.c
${BTSTACK_LIB_DIR}/src/btstack_memory_pool.c
${BTSTACK_LIB_DIR}/src/btstack_resample.c
${BTSTACK_LIB_DIR}/src/btstack_ring_buffer.c
#${BTSTACK_LIB_DIR}/src/btstack_resample.c
#${BTSTACK_LIB_DIR}/src/btstack_ring_buffer.c
${BTSTACK_LIB_DIR}/src/btstack_run_loop.c
${BTSTACK_LIB_DIR}/src/btstack_run_loop_base.c
${BTSTACK_LIB_DIR}/src/btstack_slip.c
#${BTSTACK_LIB_DIR}/src/btstack_slip.c
${BTSTACK_LIB_DIR}/src/btstack_tlv.c
${BTSTACK_LIB_DIR}/src/btstack_tlv_none.c
#${BTSTACK_LIB_DIR}/src/btstack_tlv_none.c
${BTSTACK_LIB_DIR}/src/btstack_util.c
${BTSTACK_LIB_DIR}/src/hci.c
${BTSTACK_LIB_DIR}/src/hci_cmd.c
${BTSTACK_LIB_DIR}/src/hci_dump.c
${BTSTACK_LIB_DIR}/src/hci_transport_em9304_spi.c
${BTSTACK_LIB_DIR}/src/hci_transport_h4.c
#${BTSTACK_LIB_DIR}/src/hci_transport_em9304_spi.c
#${BTSTACK_LIB_DIR}/src/hci_transport_h4.c
${BTSTACK_LIB_DIR}/src/l2cap.c
${BTSTACK_LIB_DIR}/src/l2cap_signaling.c
)

View File

@@ -34,7 +34,7 @@ INC += -I$(BTSTACK_DIR)/3rd-party/yxml
SRC_BTSTACK_C = \
$(addprefix lib/btstack/src/, $(SRC_FILES)) \
$(addprefix lib/btstack/src/ble/, $(filter-out %_tlv.c, $(SRC_BLE_FILES))) \
$(addprefix lib/btstack/src/ble/, $(filter-out le_device_db_memory.c, $(SRC_BLE_FILES))) \
lib/btstack/platform/embedded/hci_dump_embedded_stdout.c \
ifeq ($(MICROPY_BLUETOOTH_BTSTACK_USB),1)

View File

@@ -35,7 +35,7 @@
#define MAX_NR_LE_DEVICE_DB_ENTRIES 4
// Link Key DB and LE Device DB using TLV on top of Flash Sector interface
// #define NVM_NUM_DEVICE_DB_ENTRIES 16
#define NVM_NUM_DEVICE_DB_ENTRIES 16
// We don't give btstack a malloc, so use a fixed-size ATT DB.
#define MAX_ATT_DB_SIZE 512

View File

@@ -34,6 +34,8 @@
#include "extmod/modbluetooth.h"
#include "lib/btstack/src/btstack.h"
#include "lib/btstack/src/ble/le_device_db_tlv.h"
#include "lib/btstack/src/btstack_tlv.h"
#define DEBUG_printf(...) // printf("btstack: " __VA_ARGS__)
@@ -300,6 +302,12 @@ static void btstack_packet_handler_generic(uint8_t packet_type, uint16_t channel
desc->sm_connection_authenticated,
desc->sm_le_db_index != -1,
desc->sm_actual_encryption_key_size);
} else if (event_type == SM_EVENT_PASSKEY_DISPLAY_NUMBER) {
mp_bluetooth_gap_on_passkey_action(sm_event_passkey_display_number_get_handle(packet), MP_BLUETOOTH_PASSKEY_ACTION_DISPLAY, sm_event_passkey_display_number_get_passkey(packet));
} else if (event_type == SM_EVENT_PASSKEY_INPUT_NUMBER) {
mp_bluetooth_gap_on_passkey_action(sm_event_passkey_input_number_get_handle(packet), MP_BLUETOOTH_PASSKEY_ACTION_INPUT, 0);
} else if (event_type == SM_EVENT_NUMERIC_COMPARISON_REQUEST) {
mp_bluetooth_gap_on_passkey_action(sm_event_numeric_comparison_request_get_handle(packet), MP_BLUETOOTH_PASSKEY_ACTION_NUMERIC_COMPARISON, sm_event_numeric_comparison_request_get_passkey(packet));
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
} else if (event_type == HCI_EVENT_DISCONNECTION_COMPLETE) {
DEBUG_printf(" --> hci disconnect complete\n");
@@ -372,7 +380,10 @@ static void btstack_packet_handler_generic(uint8_t packet_type, uint16_t channel
}
}
static btstack_packet_callback_registration_t hci_event_callback_registration = {
static btstack_packet_callback_registration_t mp_hci_event_callback_registration = {
.callback = &btstack_packet_handler_generic
};
static btstack_packet_callback_registration_t mp_sm_event_callback_registration = {
.callback = &btstack_packet_handler_generic
};
@@ -590,10 +601,13 @@ static void deinit_stack(void) {
hci_deinit();
btstack_memory_deinit();
btstack_run_loop_deinit();
btstack_crypto_deinit();
MP_STATE_PORT(bluetooth_btstack_root_pointers) = NULL;
}
static const btstack_tlv_t btstack_tlv_mp;
int mp_bluetooth_init(void) {
DEBUG_printf("mp_bluetooth_init\n");
@@ -623,6 +637,8 @@ int mp_bluetooth_init(void) {
mp_bluetooth_btstack_state = MP_BLUETOOTH_BTSTACK_STATE_STARTING;
l2cap_init();
btstack_tlv_set_instance(&btstack_tlv_mp, NULL);
le_device_db_tlv_configure(&btstack_tlv_mp, NULL);
le_device_db_init();
sm_init();
@@ -641,7 +657,9 @@ int mp_bluetooth_init(void) {
#endif // MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT
// Register for HCI events.
hci_add_event_handler(&hci_event_callback_registration);
hci_add_event_handler(&mp_hci_event_callback_registration);
sm_add_event_handler(&mp_sm_event_callback_registration);
// Register for ATT server events.
att_server_register_packet_handler(&btstack_packet_handler_att_server);
@@ -771,10 +789,14 @@ void mp_bluetooth_set_address_mode(uint8_t addr_mode) {
set_random_address();
break;
}
case MP_BLUETOOTH_ADDRESS_MODE_RPA:
case MP_BLUETOOTH_ADDRESS_MODE_NRPA:
// Not yet supported.
mp_raise_OSError(MP_EINVAL);
case MP_BLUETOOTH_ADDRESS_MODE_RPA: {
gap_random_address_set_mode(GAP_RANDOM_ADDRESS_RESOLVABLE);
break;
}
case MP_BLUETOOTH_ADDRESS_MODE_NRPA: {
gap_random_address_set_mode(GAP_RANDOM_ADDRESS_NON_RESOLVABLE);
break;
}
}
}
@@ -1564,4 +1586,41 @@ int mp_bluetooth_l2cap_recvinto(uint16_t conn_handle, uint16_t cid, uint8_t *buf
MP_REGISTER_ROOT_POINTER(struct _mp_bluetooth_btstack_root_pointers_t *bluetooth_btstack_root_pointers);
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
static int btstack_tlv_mp_get_tag(void *context, uint32_t tag, uint8_t *buffer, uint32_t buffer_size) {
UNUSED(context);
const uint8_t *data;
size_t data_len;
if (!mp_bluetooth_gap_on_get_secret(0, 0, (uint8_t *)&tag, sizeof(tag), &data, &data_len)) {
return -1;
}
if (data_len > buffer_size) {
return -1;
}
memcpy(buffer, data, data_len);
return data_len;
}
static int btstack_tlv_mp_store_tag(void *context, uint32_t tag, const uint8_t *data, uint32_t data_size) {
UNUSED(context);
if (mp_bluetooth_gap_on_set_secret(0, (uint8_t *)&tag, sizeof(tag), (uint8_t *)data, data_size)) {
return 0;
} else {
return 1;
}
}
static void btstack_tlv_mp_delete_tag(void *context, uint32_t tag) {
mp_bluetooth_gap_on_set_secret(0, (uint8_t *)&tag, sizeof(tag), NULL, 0);
}
static const btstack_tlv_t btstack_tlv_mp = {
&btstack_tlv_mp_get_tag,
&btstack_tlv_mp_store_tag,
&btstack_tlv_mp_delete_tag,
};
#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
#endif // MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_BTSTACK

View File

@@ -260,6 +260,7 @@ if(MICROPY_PY_BLUETOOTH)
MICROPY_PY_BLUETOOTH=1
MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS=1
MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE=1
MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING=1
)
endif()