Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions ports/espressif/common-hal/_bleio/Adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ static void _on_sync(void) {
xTaskNotifyGive(cp_task);
}

// All examples have this. It'd make sense in a header.
void ble_store_config_init(void);

void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled) {
const bool is_enabled = common_hal_bleio_adapter_get_enabled(self);

Expand All @@ -93,6 +96,20 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
ble_hs_cfg.sync_cb = _on_sync;
// ble_hs_cfg.store_status_cb = ble_store_util_status_rr;

ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_NO_IO;
ble_hs_cfg.sm_bonding = 1;
/* Enable the appropriate bit masks to make sure the keys
* that are needed are exchanged
*/
ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC;
ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC;

ble_hs_cfg.sm_mitm = 1;
ble_hs_cfg.sm_sc = 1;
/* Stores the IRK */
ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;
ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;

ble_svc_gap_init();
ble_svc_gatt_init();
ble_svc_ans_init();
Expand All @@ -115,6 +132,8 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
connection->conn_handle = BLEIO_HANDLE_INVALID;
}

ble_store_config_init();

cp_task = xTaskGetCurrentTaskHandle();

nimble_port_freertos_init(nimble_host_task);
Expand Down Expand Up @@ -277,10 +296,13 @@ static int _mtu_reply(uint16_t conn_handle,
const struct ble_gatt_error *error,
uint16_t mtu, void *arg) {
bleio_connection_internal_t *connection = (bleio_connection_internal_t *)arg;
if (conn_handle != connection->conn_handle || error->status != 0) {
if (conn_handle != connection->conn_handle) {
return 0;
}
connection->mtu = mtu;
if (error->status == 0) {
connection->mtu = mtu;
}
xTaskNotify(cp_task, conn_handle, eSetValueWithOverwrite);
return 0;
}

Expand Down Expand Up @@ -324,11 +346,11 @@ static int _connect_event(struct ble_gap_event *event, void *self_in) {
switch (event->type) {
case BLE_GAP_EVENT_CONNECT:
if (event->connect.status == 0) {
// This triggers an MTU exchange. Its reply will unblock CP.
_new_connection(event->connect.conn_handle);
// Set connections objs back to NULL since we have a new
// connection and need a new tuple.
self->connection_objs = NULL;
xTaskNotify(cp_task, event->connect.conn_handle, eSetValueWithOverwrite);
} else {
xTaskNotify(cp_task, -event->connect.status, eSetValueWithOverwrite);
}
Expand Down Expand Up @@ -663,7 +685,7 @@ bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self) {
bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) {
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
bleio_connection_internal_t *connection = &bleio_connections[i];
if (connection->conn_handle != BLEIO_HANDLE_INVALID) {
if (connection->conn_handle != BLEIO_HANDLE_INVALID && connection->mtu != 0) {
return true;
}
}
Expand All @@ -678,7 +700,7 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
mp_obj_t items[BLEIO_TOTAL_CONNECTION_COUNT];
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
bleio_connection_internal_t *connection = &bleio_connections[i];
if (connection->conn_handle != BLEIO_HANDLE_INVALID) {
if (connection->conn_handle != BLEIO_HANDLE_INVALID && connection->mtu != 0) {
if (connection->connection_obj == mp_const_none) {
connection->connection_obj = bleio_connection_new_from_internal(connection);
}
Expand All @@ -691,14 +713,13 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
}

void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self) {
mp_raise_NotImplementedError(NULL);
// bonding_erase_storage();
ble_store_clear();
}

bool common_hal_bleio_adapter_is_bonded_to_central(bleio_adapter_obj_t *self) {
mp_raise_NotImplementedError(NULL);
// return bonding_peripheral_bond_count() > 0;
return false;
int count;
ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
return count > 0;
}

void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter) {
Expand Down
65 changes: 51 additions & 14 deletions ports/espressif/common-hal/_bleio/Connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,31 @@ int bleio_connection_event_cb(struct ble_gap_event *event, void *connection_in)
}

case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: {
#if CIRCUITPY_VERBOSE_BLE
mp_printf(&mp_plat_print, "TODO connection event: PHY update complete\n");
#endif
// Nothing to do here. CircuitPython doesn't tell the user what PHY
// we're on.
break;
}

case BLE_GAP_EVENT_CONN_UPDATE: {
#if CIRCUITPY_VERBOSE_BLE
mp_printf(&mp_plat_print, "TODO connection event: connection update\n");
#endif
struct ble_gap_conn_desc desc;
int rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
assert(rc == 0);
connection->conn_params_updating = false;
break;
}
case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: {
#if CIRCUITPY_VERBOSE_BLE
mp_printf(&mp_plat_print, "TODO connection event: l2cap update request\n");
#endif
case BLE_GAP_EVENT_ENC_CHANGE: {
struct ble_gap_conn_desc desc;
ble_gap_conn_find(event->enc_change.conn_handle, &desc);
if (desc.sec_state.encrypted) {
connection->pair_status = PAIR_PAIRED;
}
break;
}
case BLE_GAP_EVENT_MTU: {
if (event->mtu.conn_handle != connection->conn_handle) {
return 0;
}
connection->mtu = event->mtu.value;
break;
}

Expand Down Expand Up @@ -113,15 +122,34 @@ void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self) {
}

void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond) {
// TODO: Implement this.
// We may already be trying to pair if we just reconnected to a peer we're
// bonded with.
while (self->pair_status == PAIR_WAITING && !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
}
if (self->pair_status == PAIR_PAIRED) {
return;
}
self->pair_status = PAIR_WAITING;
CHECK_NIMBLE_ERROR(ble_gap_security_initiate(self->conn_handle));
while (self->pair_status == PAIR_WAITING && !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
}
if (mp_hal_is_interrupted()) {
return;
}
}

mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self) {
// TODO: Implement this.
while (self->conn_params_updating && !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
}
return 0;
if (mp_hal_is_interrupted()) {
return 0;
}
struct ble_gap_conn_desc desc;
CHECK_NIMBLE_ERROR(ble_gap_conn_find(self->conn_handle, &desc));
return 1.25f * desc.conn_itvl;
}

// Return the current negotiated MTU length, minus overhead.
Expand All @@ -131,7 +159,16 @@ mp_int_t common_hal_bleio_connection_get_max_packet_length(bleio_connection_inte

void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval) {
self->conn_params_updating = true;
// TODO: Implement this.
struct ble_gap_conn_desc desc;
CHECK_NIMBLE_ERROR(ble_gap_conn_find(self->conn_handle, &desc));
uint16_t interval = new_interval / 1.25f;
struct ble_gap_upd_params updated = {
.itvl_min = interval,
.itvl_max = interval,
.latency = desc.conn_latency,
.supervision_timeout = desc.supervision_timeout
};
CHECK_NIMBLE_ERROR(ble_gap_update_params(self->conn_handle, &updated));
}

static volatile int _last_discovery_status;
Expand Down
6 changes: 6 additions & 0 deletions ports/espressif/common-hal/_bleio/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ void check_ble_error(int error_code, const char *file, size_t line) {
return;
}
switch (error_code) {
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Insufficient authentication"));
return;
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Insufficient encryption"));
return;
default:
#if CIRCUITPY_VERBOSE_BLE
if (file) {
Expand Down