Skip to content

Commit

Permalink
Add BLESettings::initiate_security to always request pairing
Browse files Browse the repository at this point in the history
Update parameters in BTstack BLE backend
  • Loading branch information
tttapa committed Jun 9, 2024
1 parent e376b53 commit 748fad2
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 9 deletions.
5 changes: 5 additions & 0 deletions src/MIDI_Interfaces/BLEMIDI/BLEAPI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ struct BLESettings {
uint16_t minimum = 0x000C;
uint16_t maximum = 0x000C;
} connection_interval {};
/// Set to true if you want the Arduino to always initiate the Bluetooth
/// bonding or secure connection. As a result, it will show up as a "paired"
/// device on your computer/phone/tablet. If set to false, security is still
/// supported, but the central device should take the initiative.
bool initiate_security = false;
};

END_CS_NAMESPACE
Expand Down
12 changes: 12 additions & 0 deletions src/MIDI_Interfaces/BLEMIDI/BTstack/gatt_midi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ constexpr uint16_t midi_cccd_handle =
ATT_CHARACTERISTIC_7772E5DB_3868_4112_A1A9_F2669D106BF3_01_CLIENT_CONFIGURATION_HANDLE;

MIDIBLEInstance *instance = nullptr;
BLESettings settings;
btstack_packet_callback_registration_t hci_event_callback_registration;
btstack_packet_callback_registration_t sm_event_callback_registration;

Expand All @@ -42,6 +43,16 @@ void connection_handler(uint8_t *packet, [[maybe_unused]] uint16_t size) {
return;
uint16_t conn_handle =
hci_subevent_le_connection_complete_get_connection_handle(packet);
// Request bonding
if (settings.initiate_security)
sm_request_pairing(conn_handle);
// Update the connection parameters
uint16_t conn_latency = 0;
uint16_t supervision_timeout = 400;
gap_request_connection_parameter_update(
conn_handle, settings.connection_interval.minimum,
settings.connection_interval.maximum, conn_latency,
supervision_timeout);
instance->handleConnect(BLEConnectionHandle {conn_handle});
}
// HCI_SUBEVENT_LE_CONNECTION_UPDATE_COMPLETE
Expand Down Expand Up @@ -251,6 +262,7 @@ btstack_context_callback_registration_t create_context_callback(F &f) {

bool init(MIDIBLEInstance &instance, BLESettings settings) {
cs::midi_ble_btstack::instance = &instance;
cs::midi_ble_btstack::settings = settings;
le_midi_setup(settings);
hci_power_control(HCI_POWER_ON);
// btstack_run_loop_execute(); // not necessary in background mode
Expand Down
1 change: 1 addition & 0 deletions src/MIDI_Interfaces/BLEMIDI/ESP32-NimBLE/app.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ inline bool init(MIDIBLEInstance &instance, BLESettings ble_settings) {

// Initialize the MIDI service and characteristic
cs_midi_ble_state.instance = &instance;
cs_midi_ble_state.settings = ble_settings;
cs::midi_ble_nimble::state = &cs_midi_ble_state;
const auto *gatt_server_services = midi_ble_get_service();
CS_CHECK_ZERO(ble_gatts_count_cfg(gatt_server_services));
Expand Down
1 change: 1 addition & 0 deletions src/MIDI_Interfaces/BLEMIDI/ESP32-NimBLE/events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct MIDIBLEState {
MIDIBLEInstance *instance = nullptr;
uint16_t midi_characteristic_handle = invalid_handle;
uint8_t address_type = 0;
BLESettings settings;
};

extern MIDIBLEState *state;
Expand Down
36 changes: 29 additions & 7 deletions src/MIDI_Interfaces/BLEMIDI/ESP32-NimBLE/events.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,23 @@ cs_midi_ble_service_register_callback(struct ble_gatt_register_ctxt *ctxt,
}
}

namespace {
inline void update_connection_params(uint16_t conn_handle,
const cs::BLESettings &settings) {
ble_gap_upd_params params {};
params.latency = 0;
params.itvl_max = settings.connection_interval.maximum;
params.itvl_min = settings.connection_interval.minimum;
params.supervision_timeout = 400;
// Connection event length
params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN;
params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN;
if (auto rc = ble_gap_update_params(conn_handle, &params); rc != 0) {
ESP_LOGE("CS-BLEMIDI", "failed to update params; rc=%d", rc);
}
}
} // namespace

/// Called for GAP events like (dis)connection, MTU updates, etc.
inline int cs_midi_ble_gap_callback(struct ble_gap_event *event, void *) {
ESP_LOGI("CS-BLEMIDI", "gap event %d", +event->type);
Expand All @@ -189,22 +206,27 @@ inline int cs_midi_ble_gap_callback(struct ble_gap_event *event, void *) {
event->connect.status);
if (event->connect.status == 0) {
auto conn_handle = event->connect.conn_handle;
const auto &settings = cs::midi_ble_nimble::state->settings;
struct ble_gap_conn_desc desc;
auto rc = ble_gap_conn_find(conn_handle, &desc);
assert(rc == 0);
cs::midi_ble_nimble::print_conn_desc(&desc);
#if 0
// TODO: is this the correct place?
// Without this, Android does not initiate bonding or SC, but
// with it, Windows starts a connect/disconnect loop on the
// second connection ...
if (auto rc = ble_gap_security_initiate(conn_handle); rc != 0) {
ESP_LOGE("CS-BLEMIDI",
"failed to initiate secure connection; rc=%d", rc);
return ble_gap_terminate(conn_handle,
BLE_ERR_REM_USER_CONN_TERM);
if (settings.initiate_security) {
if (auto rc = ble_gap_security_initiate(conn_handle);
rc != 0) {
ESP_LOGE("CS-BLEMIDI",
"failed to initiate secure connection; rc=%d",
rc);
return ble_gap_terminate(conn_handle,
BLE_ERR_REM_USER_CONN_TERM);
}
}
#endif
// Update the connection parameters
update_connection_params(conn_handle, settings);
if (auto *inst = cs::midi_ble_nimble::state->instance)
inst->handleConnect(cs::BLEConnectionHandle {conn_handle});
} else {
Expand Down
1 change: 1 addition & 0 deletions src/MIDI_Interfaces/BLEMIDI/ESP32/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ bool init(MIDIBLEInstance &instance, BLESettings settings) {
set_midi_ble_name(settings.device_name);
advertising_set_connection_interval(settings.connection_interval.minimum,
settings.connection_interval.maximum);
set_security_initiate_encryption(settings.initiate_security);
return midi_init();
}

Expand Down
12 changes: 10 additions & 2 deletions src/MIDI_Interfaces/BLEMIDI/ESP32/midi-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
#include "logging.h"
#include "midi-private.h"
#include <esp_gap_ble_api.h>
#include <stdbool.h>

static bool security_initiate_encryption = false;

void set_security_initiate_encryption(bool security_initiate_encryption_) {
security_initiate_encryption = security_initiate_encryption_;
}

void midi_handle_gatts_event(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t *param) {
Expand Down Expand Up @@ -61,8 +68,9 @@ void midi_handle_gatts_event(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
case ESP_GATTS_START_EVT: break;
case ESP_GATTS_STOP_EVT: break;
case ESP_GATTS_CONNECT_EVT:
esp_ble_set_encryption(param->connect.remote_bda,
ESP_BLE_SEC_ENCRYPT_MITM);
if (security_initiate_encryption)
esp_ble_set_encryption(param->connect.remote_bda,
ESP_BLE_SEC_ENCRYPT_MITM);
midi_handle_connect_event(gatts_if, param);
break;
case ESP_GATTS_DISCONNECT_EVT:
Expand Down
2 changes: 2 additions & 0 deletions src/MIDI_Interfaces/BLEMIDI/ESP32/midi.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ bool midi_notify(uint16_t conn_handle, uint16_t char_handle,

/// Set the name of the BLE device. Must be set before calling @ref midi_init().
void set_midi_ble_name(const char *name);
/// Configure whether the Arduino should initiate the bonding/secure connection.
void set_security_initiate_encryption(bool security_initiate_encryption_);

/// Initialize the Bluetooth stack and register the MIDI BLE application with
/// the Bluedroid driver.
Expand Down

0 comments on commit 748fad2

Please sign in to comment.