extmod/btstack: Check that BLE is active before performing operations.

Otherwise it can easily lead to a hard crash.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2021-06-23 14:58:39 +10:00
parent 0fc0f7536b
commit 6ed5b843cf
1 changed files with 69 additions and 0 deletions

View File

@ -849,6 +849,11 @@ int mp_bluetooth_gap_set_device_name(const uint8_t *buf, size_t len) {
int mp_bluetooth_gap_advertise_start(bool connectable, int32_t interval_us, const uint8_t *adv_data, size_t adv_data_len, const uint8_t *sr_data, size_t sr_data_len) {
DEBUG_printf("mp_bluetooth_gap_advertise_start\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
uint16_t adv_int_min = interval_us / 625;
uint16_t adv_int_max = interval_us / 625;
uint8_t adv_type = connectable ? 0 : 2;
@ -885,6 +890,11 @@ int mp_bluetooth_gap_advertise_start(bool connectable, int32_t interval_us, cons
void mp_bluetooth_gap_advertise_stop(void) {
DEBUG_printf("mp_bluetooth_gap_advertise_stop\n");
if (!mp_bluetooth_is_active()) {
return;
}
gap_advertisements_enable(false);
MP_STATE_PORT(bluetooth_btstack_root_pointers)->adv_data_alloc = 0;
MP_STATE_PORT(bluetooth_btstack_root_pointers)->adv_data = NULL;
@ -892,6 +902,11 @@ void mp_bluetooth_gap_advertise_stop(void) {
int mp_bluetooth_gatts_register_service_begin(bool append) {
DEBUG_printf("mp_bluetooth_gatts_register_service_begin\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
if (!append) {
// This will reset the DB.
// Becase the DB is statically allocated, there's no problem with just re-initing it.
@ -1064,16 +1079,27 @@ int mp_bluetooth_gatts_register_service_end(void) {
int mp_bluetooth_gatts_read(uint16_t value_handle, uint8_t **value, size_t *value_len) {
DEBUG_printf("mp_bluetooth_gatts_read\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
return mp_bluetooth_gatts_db_read(MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db, value_handle, value, value_len);
}
int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t value_len) {
DEBUG_printf("mp_bluetooth_gatts_write\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
return mp_bluetooth_gatts_db_write(MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db, value_handle, value, value_len);
}
int mp_bluetooth_gatts_notify(uint16_t conn_handle, uint16_t value_handle) {
DEBUG_printf("mp_bluetooth_gatts_notify\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
// Note: btstack doesn't appear to support sending a notification without a value, so include the stored value.
uint8_t *data = NULL;
size_t len = 0;
@ -1084,6 +1110,10 @@ int mp_bluetooth_gatts_notify(uint16_t conn_handle, uint16_t value_handle) {
int mp_bluetooth_gatts_notify_send(uint16_t conn_handle, uint16_t value_handle, const uint8_t *value, size_t value_len) {
DEBUG_printf("mp_bluetooth_gatts_notify_send\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
// Attempt to send immediately. If it succeeds, btstack will copy the buffer.
MICROPY_PY_BLUETOOTH_ENTER
int err = att_server_notify(conn_handle, value_handle, value, value_len);
@ -1110,6 +1140,10 @@ int mp_bluetooth_gatts_notify_send(uint16_t conn_handle, uint16_t value_handle,
int mp_bluetooth_gatts_indicate(uint16_t conn_handle, uint16_t value_handle) {
DEBUG_printf("mp_bluetooth_gatts_indicate\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
uint8_t *data = NULL;
size_t len = 0;
mp_bluetooth_gatts_db_read(MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db, value_handle, &data, &len);
@ -1142,6 +1176,9 @@ int mp_bluetooth_gatts_indicate(uint16_t conn_handle, uint16_t value_handle) {
int mp_bluetooth_gatts_set_buffer(uint16_t value_handle, size_t len, bool append) {
DEBUG_printf("mp_bluetooth_gatts_set_buffer\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
return mp_bluetooth_gatts_db_resize(MP_STATE_PORT(bluetooth_btstack_root_pointers)->gatts_db, value_handle, len, append);
}
@ -1165,6 +1202,9 @@ int mp_bluetooth_set_preferred_mtu(uint16_t mtu) {
int mp_bluetooth_gap_disconnect(uint16_t conn_handle) {
DEBUG_printf("mp_bluetooth_gap_disconnect\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
gap_disconnect(conn_handle);
return 0;
}
@ -1195,6 +1235,10 @@ STATIC void scan_duration_timeout_handler(btstack_timer_source_t *ds) {
int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_t window_us, bool active_scan) {
DEBUG_printf("mp_bluetooth_gap_scan_start\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
if (duration_ms > 0) {
btstack_run_loop_set_timer(&scan_duration_timeout, duration_ms);
btstack_run_loop_set_timer_handler(&scan_duration_timeout, scan_duration_timeout_handler);
@ -1209,6 +1253,9 @@ int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_
int mp_bluetooth_gap_scan_stop(void) {
DEBUG_printf("mp_bluetooth_gap_scan_stop\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
btstack_run_loop_remove_timer(&scan_duration_timeout);
gap_stop_scan();
mp_bluetooth_gap_on_scan_complete();
@ -1240,6 +1287,11 @@ int mp_bluetooth_gap_peripheral_connect(uint8_t addr_type, const uint8_t *addr,
int mp_bluetooth_gattc_discover_primary_services(uint16_t conn_handle, const mp_obj_bluetooth_uuid_t *uuid) {
DEBUG_printf("mp_bluetooth_gattc_discover_primary_services\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
uint8_t err;
if (uuid) {
if (uuid->type == MP_BLUETOOTH_UUID_TYPE_16) {
@ -1260,6 +1312,11 @@ int mp_bluetooth_gattc_discover_primary_services(uint16_t conn_handle, const mp_
int mp_bluetooth_gattc_discover_characteristics(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, const mp_obj_bluetooth_uuid_t *uuid) {
DEBUG_printf("mp_bluetooth_gattc_discover_characteristics\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
gatt_client_service_t service = {
// Only start/end handles needed for gatt_client_discover_characteristics_for_service.
.start_group_handle = start_handle,
@ -1287,6 +1344,11 @@ int mp_bluetooth_gattc_discover_characteristics(uint16_t conn_handle, uint16_t s
int mp_bluetooth_gattc_discover_descriptors(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) {
DEBUG_printf("mp_bluetooth_gattc_discover_descriptors\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
gatt_client_characteristic_t characteristic = {
// Only start/end handles needed for gatt_client_discover_characteristic_descriptors.
.start_handle = start_handle,
@ -1301,12 +1363,19 @@ int mp_bluetooth_gattc_discover_descriptors(uint16_t conn_handle, uint16_t start
int mp_bluetooth_gattc_read(uint16_t conn_handle, uint16_t value_handle) {
DEBUG_printf("mp_bluetooth_gattc_read\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
return btstack_error_to_errno(gatt_client_read_value_of_characteristic_using_value_handle(&btstack_packet_handler_read, conn_handle, value_handle));
}
int mp_bluetooth_gattc_write(uint16_t conn_handle, uint16_t value_handle, const uint8_t *value, size_t *value_len, unsigned int mode) {
DEBUG_printf("mp_bluetooth_gattc_write\n");
if (!mp_bluetooth_is_active()) {
return ERRNO_BLUETOOTH_NOT_ACTIVE;
}
// We should be distinguishing between gatt_client_write_value_of_characteristic vs
// gatt_client_write_characteristic_descriptor_using_descriptor_handle.
// However both are implemented using send_gatt_write_attribute_value_request under the hood,