extmod/modbluetooth: Persist reference to NimBLE service instances.

NimBLE doesn't actually copy this data, it requires it to stay live.
Only dereference when we register a new set of services.

Fixes #5226

This will allow incrementally adding services in the future, so
rename `reset` to `append` to make it clearer.
This commit is contained in:
Jim Mussared 2019-10-21 22:35:58 +11:00
parent c7ae8c5a99
commit f34e16dbc6
3 changed files with 12 additions and 11 deletions

View File

@ -421,9 +421,9 @@ STATIC mp_obj_t bluetooth_ble_gatts_register_services(mp_obj_t self_in, mp_obj_t
uint16_t **handles = m_new0(uint16_t*, len);
size_t *num_handles = m_new0(size_t, len);
// We always reset the service list, as Nimble has no other option.
// TODO: Add a `reset` or `clear` kwarg (defaulting to True) to make this behavior optional.
int err = mp_bluetooth_gatts_register_service_begin(true);
// TODO: Add a `append` kwarg (defaulting to False) to make this behavior optional.
bool append = false;
int err = mp_bluetooth_gatts_register_service_begin(append);
if (err != 0) {
return bluetooth_handle_errno(err);
}

View File

@ -165,7 +165,7 @@ int mp_bluetooth_gap_advertise_start(bool connectable, int32_t interval_us, cons
void mp_bluetooth_gap_advertise_stop(void);
// Start adding services. Must be called before mp_bluetooth_register_service.
int mp_bluetooth_gatts_register_service_begin(bool reset);
int mp_bluetooth_gatts_register_service_begin(bool append);
// // Add a service with the given list of characteristics to the queue to be registered.
// The value_handles won't be valid until after mp_bluetooth_register_service_end is called.
int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, mp_obj_bluetooth_uuid_t **characteristic_uuids, uint8_t *characteristic_flags, mp_obj_bluetooth_uuid_t **descriptor_uuids, uint8_t *descriptor_flags, uint8_t *num_descriptors, uint16_t *handles, size_t num_characteristics);

View File

@ -440,7 +440,7 @@ static int characteristic_access_cb(uint16_t conn_handle, uint16_t value_handle,
return BLE_ATT_ERR_UNLIKELY;
}
int mp_bluetooth_gatts_register_service_begin(bool reset) {
int mp_bluetooth_gatts_register_service_begin(bool append) {
int ret = ble_gatts_reset();
if (ret != 0) {
return ble_hs_err_to_errno(ret);
@ -452,7 +452,13 @@ int mp_bluetooth_gatts_register_service_begin(bool reset) {
// By default, just register the default gap service.
ble_svc_gap_init();
MP_STATE_PORT(bluetooth_nimble_root_pointers)->n_services = 0;
if (!append) {
// Unref any previous service definitions.
for (int i = 0; i < MP_STATE_PORT(bluetooth_nimble_root_pointers)->n_services; ++i) {
MP_STATE_PORT(bluetooth_nimble_root_pointers)->services[i] = NULL;
}
MP_STATE_PORT(bluetooth_nimble_root_pointers)->n_services = 0;
}
return 0;
}
@ -463,11 +469,6 @@ int mp_bluetooth_gatts_register_service_end() {
return ble_hs_err_to_errno(ret);
}
for (int i = 0; i < MP_STATE_PORT(bluetooth_nimble_root_pointers)->n_services; ++i) {
MP_STATE_PORT(bluetooth_nimble_root_pointers)->services[i] = NULL;
}
MP_STATE_PORT(bluetooth_nimble_root_pointers)->n_services = 0;
return 0;
}