diff options
Diffstat (limited to 'ports/nrf/common-hal')
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Adapter.c (renamed from ports/nrf/common-hal/bleio/Adapter.c) | 31 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Adapter.h (renamed from ports/nrf/common-hal/bleio/Adapter.h) | 0 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Attribute.c (renamed from ports/nrf/common-hal/bleio/Attribute.c) | 4 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Attribute.h (renamed from ports/nrf/common-hal/bleio/Attribute.h) | 4 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Central.c (renamed from ports/nrf/common-hal/bleio/Central.c) | 16 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Central.h (renamed from ports/nrf/common-hal/bleio/Central.h) | 4 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Characteristic.c (renamed from ports/nrf/common-hal/bleio/Characteristic.c) | 72 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Characteristic.h (renamed from ports/nrf/common-hal/bleio/Characteristic.h) | 8 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/CharacteristicBuffer.c (renamed from ports/nrf/common-hal/bleio/CharacteristicBuffer.c) | 4 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/CharacteristicBuffer.h (renamed from ports/nrf/common-hal/bleio/CharacteristicBuffer.h) | 2 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Descriptor.c (renamed from ports/nrf/common-hal/bleio/Descriptor.c) | 32 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Descriptor.h (renamed from ports/nrf/common-hal/bleio/Descriptor.h) | 4 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Peripheral.c (renamed from ports/nrf/common-hal/bleio/Peripheral.c) | 150 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Peripheral.h (renamed from ports/nrf/common-hal/bleio/Peripheral.h) | 10 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Scanner.c (renamed from ports/nrf/common-hal/bleio/Scanner.c) | 8 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Scanner.h (renamed from ports/nrf/common-hal/bleio/Scanner.h) | 0 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Service.c | 122 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/Service.h (renamed from ports/nrf/common-hal/bleio/Service.h) | 2 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/UUID.c (renamed from ports/nrf/common-hal/bleio/UUID.c) | 4 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/UUID.h (renamed from ports/nrf/common-hal/bleio/UUID.h) | 0 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/__init__.c (renamed from ports/nrf/common-hal/bleio/__init__.c) | 45 | ||||
| -rw-r--r-- | ports/nrf/common-hal/_bleio/__init__.h (renamed from ports/nrf/common-hal/bleio/__init__.h) | 6 | ||||
| -rw-r--r-- | ports/nrf/common-hal/bleio/Service.c | 169 |
23 files changed, 372 insertions, 325 deletions
diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c index 15ae8840b..a8e1f1905 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -37,8 +37,13 @@ #include "py/objstr.h" #include "py/runtime.h" #include "supervisor/usb.h" -#include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/Address.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Address.h" + +#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) +#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) +#define BLE_SLAVE_LATENCY 0 +#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { mp_raise_msg_varg(&mp_type_AssertionError, @@ -61,12 +66,14 @@ STATIC uint32_t ble_stack_enable(void) { }; uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler); - if (err_code != NRF_SUCCESS) + if (err_code != NRF_SUCCESS) { return err_code; + } err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn); - if (err_code != NRF_SUCCESS) + if (err_code != NRF_SUCCESS) { return err_code; + } // Start with no event handlers, etc. ble_drv_reset(); @@ -97,8 +104,22 @@ STATIC uint32_t ble_stack_enable(void) { return err_code; err_code = sd_ble_enable(&app_ram_start); + if (err_code != NRF_SUCCESS) + return err_code; + + ble_gap_conn_params_t gap_conn_params = { + .min_conn_interval = BLE_MIN_CONN_INTERVAL, + .max_conn_interval = BLE_MAX_CONN_INTERVAL, + .slave_latency = BLE_SLAVE_LATENCY, + .conn_sup_timeout = BLE_CONN_SUP_TIMEOUT, + }; + err_code = sd_ble_gap_ppcp_set(&gap_conn_params); + if (err_code != NRF_SUCCESS) { + return err_code; + } - return err_code; + err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN); + return err_code; } void common_hal_bleio_adapter_set_enabled(bool enabled) { diff --git a/ports/nrf/common-hal/bleio/Adapter.h b/ports/nrf/common-hal/_bleio/Adapter.h index 5dcc62540..5dcc62540 100644 --- a/ports/nrf/common-hal/bleio/Adapter.h +++ b/ports/nrf/common-hal/_bleio/Adapter.h diff --git a/ports/nrf/common-hal/bleio/Attribute.c b/ports/nrf/common-hal/_bleio/Attribute.c index fd1e7538d..c55914b10 100644 --- a/ports/nrf/common-hal/bleio/Attribute.c +++ b/ports/nrf/common-hal/_bleio/Attribute.c @@ -24,9 +24,9 @@ * THE SOFTWARE. */ -#include "shared-bindings/bleio/Attribute.h" +#include "shared-bindings/_bleio/Attribute.h" -// Convert a bleio security mode to a ble_gap_conn_sec_mode_t setting. +// Convert a _bleio security mode to a ble_gap_conn_sec_mode_t setting. void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode) { switch (security_mode) { case SECURITY_MODE_NO_ACCESS: diff --git a/ports/nrf/common-hal/bleio/Attribute.h b/ports/nrf/common-hal/_bleio/Attribute.h index 44c2fdfa1..8cc361046 100644 --- a/ports/nrf/common-hal/bleio/Attribute.h +++ b/ports/nrf/common-hal/_bleio/Attribute.h @@ -27,6 +27,8 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H -// Nothing yet. +#include "shared-module/_bleio/Attribute.h" + +extern void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode); #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H diff --git a/ports/nrf/common-hal/bleio/Central.c b/ports/nrf/common-hal/_bleio/Central.c index 3c5d97784..db67b763c 100644 --- a/ports/nrf/common-hal/bleio/Central.c +++ b/ports/nrf/common-hal/_bleio/Central.c @@ -34,9 +34,9 @@ #include "nrf_soc.h" #include "py/objstr.h" #include "py/runtime.h" -#include "shared-bindings/bleio/__init__.h" -#include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/Central.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Central.h" STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) { bleio_central_obj_t *central = (bleio_central_obj_t*)central_in; @@ -76,7 +76,7 @@ STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) { void common_hal_bleio_central_construct(bleio_central_obj_t *self) { common_hal_bleio_adapter_set_enabled(true); - self->remote_services_list = mp_obj_new_list(0, NULL); + self->remote_service_list = mp_obj_new_list(0, NULL); self->conn_handle = BLE_CONN_HANDLE_INVALID; } @@ -134,12 +134,12 @@ bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self) { mp_obj_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist) { common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist); // Convert to a tuple and then clear the list so the callee will take ownership. - mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_services_list->len, - self->remote_services_list->items); - mp_obj_list_clear(self->remote_services_list); + mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_service_list->len, + self->remote_service_list->items); + mp_obj_list_clear(self->remote_service_list); return services_tuple; } mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) { - return self->remote_services_list; + return self->remote_service_list; } diff --git a/ports/nrf/common-hal/bleio/Central.h b/ports/nrf/common-hal/_bleio/Central.h index b7a9050b8..01f7faca7 100644 --- a/ports/nrf/common-hal/bleio/Central.h +++ b/ports/nrf/common-hal/_bleio/Central.h @@ -31,14 +31,14 @@ #include <stdbool.h> #include "py/objlist.h" -#include "shared-module/bleio/Address.h" +#include "shared-module/_bleio/Address.h" typedef struct { mp_obj_base_t base; volatile bool waiting_to_connect; volatile uint16_t conn_handle; // Services discovered after connecting to a remote peripheral. - mp_obj_list_t *remote_services_list; + mp_obj_list_t *remote_service_list; } bleio_central_obj_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c index 604d24d73..e8454d528 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.c +++ b/ports/nrf/common-hal/_bleio/Characteristic.c @@ -27,10 +27,10 @@ #include "py/runtime.h" -#include "shared-bindings/bleio/__init__.h" -#include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/Descriptor.h" -#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" static volatile bleio_characteristic_obj_t *m_read_characteristic; @@ -124,15 +124,14 @@ STATIC void characteristic_gattc_read(bleio_characteristic_obj_t *characteristic ble_drv_remove_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic); } -void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_obj_list_t *descriptor_list) { - self->service = MP_OBJ_NULL; +void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) { + self->service = service; self->uuid = uuid; - self->value = mp_const_empty_bytes; self->handle = BLE_GATT_HANDLE_INVALID; self->props = props; self->read_perm = read_perm; self->write_perm = write_perm; - self->descriptor_list = descriptor_list; + self->descriptor_list = mp_obj_new_list(0, NULL); const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX; if (max_length < 0 || max_length > max_length_max) { @@ -142,11 +141,7 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, self->max_length = max_length; self->fixed_length = fixed_length; - for (size_t descriptor_idx = 0; descriptor_idx < descriptor_list->len; ++descriptor_idx) { - bleio_descriptor_obj_t *descriptor = - MP_OBJ_TO_PTR(descriptor_list->items[descriptor_idx]); - descriptor->characteristic = self; - } + common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo); } mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) { @@ -173,6 +168,15 @@ mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *s } void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { + if (self->fixed_length && bufinfo->len != self->max_length) { + mp_raise_ValueError(translate("Value length != required fixed length")); + } + if (bufinfo->len > self->max_length) { + mp_raise_ValueError(translate("Value length > max_length")); + } + + self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len); + // Do GATT operations only if this characteristic has been added to a registered service. if (self->handle != BLE_GATT_HANDLE_INVALID) { uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); @@ -182,12 +186,6 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, (self->props & CHAR_PROP_WRITE_NO_RESPONSE)); } else { - if (self->fixed_length && bufinfo->len != self->max_length) { - mp_raise_ValueError(translate("Value length != required fixed length")); - } - if (bufinfo->len > self->max_length) { - mp_raise_ValueError(translate("Value length > max_length")); - } bool sent = false; uint16_t cccd = 0; @@ -213,8 +211,6 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, } } } - - self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len); } bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self) { @@ -225,6 +221,40 @@ bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties return self->props; } +void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor) { + ble_uuid_t desc_uuid; + bleio_uuid_convert_to_nrf_ble_uuid(descriptor->uuid, &desc_uuid); + + ble_gatts_attr_md_t desc_attr_md = { + // Data passed is not in a permanent location and should be copied. + .vloc = BLE_GATTS_VLOC_STACK, + .vlen = !descriptor->fixed_length, + }; + + bleio_attribute_gatts_set_security_mode(&desc_attr_md.read_perm, descriptor->read_perm); + bleio_attribute_gatts_set_security_mode(&desc_attr_md.write_perm, descriptor->write_perm); + + mp_buffer_info_t desc_value_bufinfo; + mp_get_buffer_raise(descriptor->value, &desc_value_bufinfo, MP_BUFFER_READ); + + ble_gatts_attr_t desc_attr = { + .p_uuid = &desc_uuid, + .p_attr_md = &desc_attr_md, + .init_len = desc_value_bufinfo.len, + .p_value = desc_value_bufinfo.buf, + .init_offs = 0, + .max_len = descriptor->max_length, + }; + + uint32_t err_code = sd_ble_gatts_descriptor_add(self->handle, &desc_attr, &descriptor->handle); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to add descriptor, err 0x%04x"), err_code); + } + + mp_obj_list_append(self->descriptor_list, MP_OBJ_FROM_PTR(descriptor)); +} + void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) { if (self->cccd_handle == BLE_GATT_HANDLE_INVALID) { mp_raise_ValueError(translate("No CCCD for this Characteristic")); diff --git a/ports/nrf/common-hal/bleio/Characteristic.h b/ports/nrf/common-hal/_bleio/Characteristic.h index fb6a4c6ce..3a7691d07 100644 --- a/ports/nrf/common-hal/bleio/Characteristic.h +++ b/ports/nrf/common-hal/_bleio/Characteristic.h @@ -28,10 +28,10 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H -#include "shared-bindings/bleio/Attribute.h" -#include "shared-module/bleio/Characteristic.h" -#include "common-hal/bleio/Service.h" -#include "common-hal/bleio/UUID.h" +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-module/_bleio/Characteristic.h" +#include "common-hal/_bleio/Service.h" +#include "common-hal/_bleio/UUID.h" typedef struct { mp_obj_base_t base; diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c index 64ab5e8a7..95794feec 100644 --- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c +++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c @@ -37,8 +37,8 @@ #include "tick.h" -#include "shared-bindings/bleio/__init__.h" -#include "common-hal/bleio/CharacteristicBuffer.h" +#include "shared-bindings/_bleio/__init__.h" +#include "common-hal/_bleio/CharacteristicBuffer.h" STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) { // Push all the data onto the ring buffer. diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.h b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h index db8fd2fad..f0949251c 100644 --- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.h +++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h @@ -30,7 +30,7 @@ #include "nrf_soc.h" #include "py/ringbuf.h" -#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/_bleio/Characteristic.h" typedef struct { mp_obj_base_t base; diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/_bleio/Descriptor.c index 2a2019277..137f004ba 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.c +++ b/ports/nrf/common-hal/_bleio/Descriptor.c @@ -28,17 +28,16 @@ #include "py/runtime.h" -#include "shared-bindings/bleio/__init__.h" -#include "shared-bindings/bleio/Descriptor.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-bindings/bleio/UUID.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" static volatile bleio_descriptor_obj_t *m_read_descriptor; -void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length) { - self->characteristic = MP_OBJ_NULL; +void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_characteristic_obj_t *characteristic, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) { + self->characteristic = characteristic; self->uuid = uuid; - self->value = mp_const_empty_bytes; self->handle = BLE_GATT_HANDLE_INVALID; self->read_perm = read_perm; self->write_perm = write_perm; @@ -50,6 +49,8 @@ void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_u } self->max_length = max_length; self->fixed_length = fixed_length; + + common_hal_bleio_descriptor_set_value(self, initial_value_bufinfo); } bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { @@ -119,6 +120,15 @@ mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self) { } void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo) { + if (self->fixed_length && bufinfo->len != self->max_length) { + mp_raise_ValueError(translate("Value length != required fixed length")); + } + if (bufinfo->len > self->max_length) { + mp_raise_ValueError(translate("Value length > max_length")); + } + + self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len); + // Do GATT operations only if this descriptor has been registered. if (self->handle != BLE_GATT_HANDLE_INVALID) { uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->characteristic->service->device); @@ -126,16 +136,8 @@ void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buff // false means WRITE_REQ, not write-no-response common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, false); } else { - if (self->fixed_length && bufinfo->len != self->max_length) { - mp_raise_ValueError(translate("Value length != required fixed length")); - } - if (bufinfo->len > self->max_length) { - mp_raise_ValueError(translate("Value length > max_length")); - } - common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); } } - self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len); } diff --git a/ports/nrf/common-hal/bleio/Descriptor.h b/ports/nrf/common-hal/_bleio/Descriptor.h index 6db4d7be3..3adb0df18 100644 --- a/ports/nrf/common-hal/bleio/Descriptor.h +++ b/ports/nrf/common-hal/_bleio/Descriptor.h @@ -31,8 +31,8 @@ #include "py/obj.h" -#include "shared-bindings/bleio/Characteristic.h" -#include "common-hal/bleio/UUID.h" +#include "common-hal/_bleio/Characteristic.h" +#include "common-hal/_bleio/UUID.h" typedef struct { mp_obj_base_t base; diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/_bleio/Peripheral.c index ed35516fc..9b0f96d48 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/_bleio/Peripheral.c @@ -36,24 +36,20 @@ #include "py/objlist.h" #include "py/objstr.h" #include "py/runtime.h" -#include "shared-bindings/bleio/__init__.h" -#include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/Peripheral.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-bindings/bleio/UUID.h" - -#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) -#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS) -#define BLE_SLAVE_LATENCY 0 -#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Peripheral.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" #define BLE_ADV_LENGTH_FIELD_SIZE 1 #define BLE_ADV_AD_TYPE_FIELD_SIZE 1 #define BLE_AD_TYPE_FLAGS_DATA_SIZE 1 static const ble_gap_sec_params_t pairing_sec_params = { - .bond = 0, // TODO: add bonding + .bond = 1, .mitm = 0, .lesc = 0, .keypress = 0, @@ -80,10 +76,18 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { switch (ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: { // Central has connected. - ble_gap_conn_params_t conn_params; + ble_gap_evt_connected_t* connected = &ble_evt->evt.gap_evt.params.connected; + self->conn_handle = ble_evt->evt.gap_evt.conn_handle; + + // See if connection interval set by Central is out of range. + // If so, negotiate our preferred range. + ble_gap_conn_params_t conn_params; sd_ble_gap_ppcp_get(&conn_params); - sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params); + if (conn_params.min_conn_interval < connected->conn_params.min_conn_interval || + conn_params.min_conn_interval > connected->conn_params.max_conn_interval) { + sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params); + } break; } @@ -102,21 +106,16 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { } case BLE_GAP_EVT_ADV_SET_TERMINATED: - // Someday may handle timeouts or limit reached. - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: { - ble_gap_evt_conn_param_update_request_t *request = - &ble_evt->evt.gap_evt.params.conn_param_update_request; - sd_ble_gap_conn_param_update(self->conn_handle, &request->conn_params); + // TODO: Someday may handle timeouts or limit reached. break; - } case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: + // SoftDevice will respond to a length update request. sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL); break; case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: { + // We only handle MTU of size BLE_GATT_ATT_MTU_DEFAULT. sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT); break; } @@ -125,9 +124,27 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0); break; - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &pairing_sec_params, NULL); + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: { + ble_gap_sec_keyset_t keyset = { + .keys_own = { + .p_enc_key = &self->bonding_keys.own_enc, + .p_id_key = NULL, + .p_sign_key = NULL, + .p_pk = NULL + }, + + .keys_peer = { + .p_enc_key = &self->bonding_keys.peer_enc, + .p_id_key = &self->bonding_keys.peer_id, + .p_sign_key = NULL, + .p_pk = NULL + } + }; + + sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, + &pairing_sec_params, &keyset); break; + } case BLE_GAP_EVT_LESC_DHKEY_REQUEST: // TODO for LESC pairing: @@ -138,15 +155,30 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { // Pairing process completed ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status; if (BLE_GAP_SEC_STATUS_SUCCESS == status->auth_status) { - // mp_printf(&mp_plat_print, "Pairing succeeded, status: 0x%04x\n", status->auth_status); + // TODO _ediv = bonding_keys->own_enc.master_id.ediv; self->pair_status = PAIR_PAIRED; } else { - // mp_printf(&mp_plat_print, "Pairing failed, status: 0x%04x\n", status->auth_status); self->pair_status = PAIR_NOT_PAIRED; } break; } + case BLE_GAP_EVT_SEC_INFO_REQUEST: { + // Peer asks for the stored keys. + // - load key and return if bonded previously. + // - Else return NULL --> Initiate key exchange + ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request; + (void) sec_info_request; + //if ( bond_load_keys(_role, sec_req->master_id.ediv, &bkeys) ) { + //sd_ble_gap_sec_info_reply(_conn_hdl, &bkeys.own_enc.enc_info, &bkeys.peer_id.id_info, NULL); + // + //_ediv = bkeys.own_enc.master_id.ediv; + // } else { + sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL); + // } + break; + } + case BLE_GAP_EVT_CONN_SEC_UPDATE: { ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec; if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) { @@ -156,11 +188,13 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { // mode >=1 and/or level >=1 means encryption is set up self->pair_status = PAIR_NOT_PAIRED; } else { - // TODO: see Bluefruit lib - // if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) { - // sd_ble_gatts_sys_attr_set(_conn_hdl, NULL, 0, 0); - // } - self->pair_status = PAIR_PAIRED; + //if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) { + if (true) { // TODO: no bonding yet + // Initialize system attributes fresh. + sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0); + } + // Not quite paired yet: wait for BLE_GAP_EVT_AUTH_STATUS SUCCESS. + self->ediv = self->bonding_keys.own_enc.master_id.ediv; } break; } @@ -173,46 +207,40 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { } } -void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *services_list, mp_obj_t name) { +void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_t name) { common_hal_bleio_adapter_set_enabled(true); - self->services_list = services_list; + self->service_list = mp_obj_new_list(0, NULL); // Used only for discovery when acting as a client. - self->remote_services_list = mp_obj_new_list(0, NULL); + self->remote_service_list = mp_obj_new_list(0, NULL); self->name = name; self->conn_handle = BLE_CONN_HANDLE_INVALID; self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; self->pair_status = PAIR_NOT_PAIRED; - // Add all the services. - - for (size_t service_idx = 0; service_idx < services_list->len; ++service_idx) { - bleio_service_obj_t *service = MP_OBJ_TO_PTR(services_list->items[service_idx]); - - service->device = MP_OBJ_FROM_PTR(self); + memset(&self->bonding_keys, 0, sizeof(self->bonding_keys)); +} - ble_uuid_t uuid; - bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid); +void common_hal_bleio_peripheral_add_service(bleio_peripheral_obj_t *self, bleio_service_obj_t *service) { + ble_uuid_t uuid; + bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid); - uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; - if (common_hal_bleio_service_get_is_secondary(service)) { - service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; - } - - const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle); - if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg_varg(translate("Failed to add service, err 0x%04x"), err_code); - } + uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; + if (common_hal_bleio_service_get_is_secondary(service)) { + service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; + } - // Once the service has been registered, its characteristics can be added. - common_hal_bleio_service_add_all_characteristics(service); + const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to add service, err 0x%04x"), err_code); } -} + mp_obj_list_append(self->service_list, MP_OBJ_FROM_PTR(service)); +} mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self) { - return self->services_list; + return self->service_list; } bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) { @@ -237,9 +265,9 @@ void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, GET_STR_DATA_LEN(self->name, name_data, name_len); if (name_len > 0) { + // Set device name, and make it available to anyone. ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); - err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len); if (err_code != NRF_SUCCESS) { mp_raise_OSError_msg_varg(translate("Failed to set device name, err 0x%04x"), err_code); @@ -306,9 +334,9 @@ void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *self) { mp_obj_tuple_t *common_hal_bleio_peripheral_discover_remote_services(bleio_peripheral_obj_t *self, mp_obj_t service_uuids_whitelist) { common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist); // Convert to a tuple and then clear the list so the callee will take ownership. - mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_services_list->len, - self->remote_services_list->items); - mp_obj_list_clear(self->remote_services_list); + mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_service_list->len, + self->remote_service_list->items); + mp_obj_list_clear(self->remote_service_list); return services_tuple; } @@ -322,10 +350,12 @@ void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *self) { } while (self->pair_status == PAIR_WAITING) { - MICROPY_VM_HOOK_LOOP; + RUN_BACKGROUND_TASKS; } if (self->pair_status == PAIR_NOT_PAIRED) { mp_raise_OSError_msg(translate("Failed to pair")); } + + } diff --git a/ports/nrf/common-hal/bleio/Peripheral.h b/ports/nrf/common-hal/_bleio/Peripheral.h index e75a1641a..a4f62d288 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.h +++ b/ports/nrf/common-hal/_bleio/Peripheral.h @@ -35,7 +35,8 @@ #include "py/obj.h" #include "py/objlist.h" -#include "shared-module/bleio/Address.h" +#include "common-hal/_bleio/__init__.h" +#include "shared-module/_bleio/Address.h" typedef enum { PAIR_NOT_PAIRED, @@ -48,12 +49,15 @@ typedef struct { mp_obj_t name; volatile uint16_t conn_handle; // Services provided by this peripheral. - mp_obj_list_t *services_list; + mp_obj_list_t *service_list; // Remote services discovered when this peripheral is acting as a client. - mp_obj_list_t *remote_services_list; + mp_obj_list_t *remote_service_list; // The advertising data and scan response buffers are held by us, not by the SD, so we must // maintain them and not change it. If we need to change the contents during advertising, // there are tricks to get the SD to notice (see DevZone - TBS). + // EDIV: Encrypted Diversifier: Identifies LTK during legacy pairing. + bonding_keys_t bonding_keys; + uint16_t ediv; uint8_t* advertising_data; uint8_t* scan_response_data; uint8_t adv_handle; diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/_bleio/Scanner.c index 57ce940ab..ec73f7eb8 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/_bleio/Scanner.c @@ -33,10 +33,10 @@ #include "py/mphal.h" #include "py/objlist.h" #include "py/runtime.h" -#include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/ScanEntry.h" -#include "shared-bindings/bleio/Scanner.h" -#include "shared-module/bleio/ScanEntry.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/ScanEntry.h" +#include "shared-bindings/_bleio/Scanner.h" +#include "shared-module/_bleio/ScanEntry.h" static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN]; diff --git a/ports/nrf/common-hal/bleio/Scanner.h b/ports/nrf/common-hal/_bleio/Scanner.h index 3768a52cb..3768a52cb 100644 --- a/ports/nrf/common-hal/bleio/Scanner.h +++ b/ports/nrf/common-hal/_bleio/Scanner.h diff --git a/ports/nrf/common-hal/_bleio/Service.c b/ports/nrf/common-hal/_bleio/Service.c new file mode 100644 index 000000000..650cdc4ec --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Service.c @@ -0,0 +1,122 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "ble_drv.h" +#include "ble.h" +#include "py/runtime.h" +#include "common-hal/_bleio/__init__.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Peripheral.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/Adapter.h" + +void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_peripheral_obj_t *peripheral, bleio_uuid_obj_t *uuid, bool is_secondary) { + self->device = MP_OBJ_FROM_PTR(peripheral); + self->handle = 0xFFFF; + self->uuid = uuid; + self->characteristic_list = mp_obj_new_list(0, NULL); + self->is_remote = false; + self->is_secondary = is_secondary; +} + +bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) { + return self->uuid; +} + +mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self) { + return self->characteristic_list; +} + +bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self) { + return self->is_remote; +} + +bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) { + return self->is_secondary; +} + +void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) { + ble_gatts_char_md_t char_md = { + .char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0, + .char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0, + .char_props.write_wo_resp = (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) ? 1 : 0, + .char_props.write = (characteristic->props & CHAR_PROP_WRITE) ? 1 : 0, + .char_props.notify = (characteristic->props & CHAR_PROP_NOTIFY) ? 1 : 0, + .char_props.indicate = (characteristic->props & CHAR_PROP_INDICATE) ? 1 : 0, + }; + + ble_gatts_attr_md_t cccd_md = { + .vloc = BLE_GATTS_VLOC_STACK, + }; + + ble_uuid_t char_uuid; + bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &char_uuid); + + ble_gatts_attr_md_t char_attr_md = { + .vloc = BLE_GATTS_VLOC_STACK, + .vlen = !characteristic->fixed_length, + }; + + if (char_md.char_props.notify || char_md.char_props.indicate) { + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + // Make CCCD write permission match characteristic read permission. + bleio_attribute_gatts_set_security_mode(&cccd_md.write_perm, characteristic->read_perm); + + char_md.p_cccd_md = &cccd_md; + } + + bleio_attribute_gatts_set_security_mode(&char_attr_md.read_perm, characteristic->read_perm); + bleio_attribute_gatts_set_security_mode(&char_attr_md.write_perm, characteristic->write_perm); + + mp_buffer_info_t char_value_bufinfo; + mp_get_buffer_raise(characteristic->value, &char_value_bufinfo, MP_BUFFER_READ); + + ble_gatts_attr_t char_attr = { + .p_uuid = &char_uuid, + .p_attr_md = &char_attr_md, + .init_len = char_value_bufinfo.len, + .p_value = char_value_bufinfo.buf, + .init_offs = 0, + .max_len = characteristic->max_length, + }; + + ble_gatts_char_handles_t char_handles; + + uint32_t err_code; + err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &char_attr, &char_handles); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code); + } + + characteristic->user_desc_handle = char_handles.user_desc_handle; + characteristic->cccd_handle = char_handles.cccd_handle; + characteristic->sccd_handle = char_handles.sccd_handle; + characteristic->handle = char_handles.value_handle; + + mp_obj_list_append(self->characteristic_list, MP_OBJ_FROM_PTR(characteristic)); +} diff --git a/ports/nrf/common-hal/bleio/Service.h b/ports/nrf/common-hal/_bleio/Service.h index 03ac2bca8..a4614b9f5 100644 --- a/ports/nrf/common-hal/bleio/Service.h +++ b/ports/nrf/common-hal/_bleio/Service.h @@ -29,7 +29,7 @@ #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SERVICE_H #include "py/objlist.h" -#include "common-hal/bleio/UUID.h" +#include "common-hal/_bleio/UUID.h" typedef struct { mp_obj_base_t base; diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/_bleio/UUID.c index ebd6b6d1f..0e65b7d58 100644 --- a/ports/nrf/common-hal/bleio/UUID.c +++ b/ports/nrf/common-hal/_bleio/UUID.c @@ -29,8 +29,8 @@ #include <string.h> #include "py/runtime.h" -#include "common-hal/bleio/UUID.h" -#include "shared-bindings/bleio/Adapter.h" +#include "common-hal/_bleio/UUID.h" +#include "shared-bindings/_bleio/Adapter.h" #include "ble.h" #include "ble_drv.h" diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/_bleio/UUID.h index 7d3a6204e..7d3a6204e 100644 --- a/ports/nrf/common-hal/bleio/UUID.h +++ b/ports/nrf/common-hal/_bleio/UUID.h diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c index 2e26ac07d..553044190 100644 --- a/ports/nrf/common-hal/bleio/__init__.c +++ b/ports/nrf/common-hal/_bleio/__init__.c @@ -27,16 +27,16 @@ */ #include "py/runtime.h" -#include "shared-bindings/bleio/__init__.h" -#include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/Central.h" -#include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/Descriptor.h" -#include "shared-bindings/bleio/Peripheral.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-bindings/bleio/UUID.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Central.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Peripheral.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" -#include "common-hal/bleio/__init__.h" +#include "common-hal/_bleio/__init__.h" static volatile bool m_discovery_in_process; static volatile bool m_discovery_successful; @@ -51,7 +51,7 @@ void bleio_reset() { } } -// The singleton bleio.Adapter object, bound to bleio.adapter +// The singleton _bleio.Adapter object, bound to _bleio.adapter // It currently only has properties and no state const super_adapter_obj_t common_hal_bleio_adapter_obj = { .base = { @@ -75,11 +75,11 @@ uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) { } } -mp_obj_list_t *common_hal_bleio_device_get_remote_services_list(mp_obj_t device) { +mp_obj_list_t *common_hal_bleio_device_get_remote_service_list(mp_obj_t device) { if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) { - return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->remote_services_list; + return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->remote_service_list; } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) { - return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->remote_services_list; + return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->remote_service_list; } else { return NULL; } @@ -158,9 +158,8 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res service->base.type = &bleio_service_type; // Initialize several fields at once. - common_hal_bleio_service_construct(service, NULL, mp_obj_new_list(0, NULL), false); + common_hal_bleio_service_construct(service, device, NULL, false); - service->device = device; service->is_remote = true; service->start_handle = gattc_service->handle_range.start_handle; service->end_handle = gattc_service->handle_range.end_handle; @@ -179,7 +178,7 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res service->uuid = NULL; } - mp_obj_list_append(common_hal_bleio_device_get_remote_services_list(device), service); + mp_obj_list_append(common_hal_bleio_device_get_remote_service_list(device), service); } if (response->count > 0) { @@ -218,11 +217,10 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_ob // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. common_hal_bleio_characteristic_construct( - characteristic, uuid, props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, + characteristic, m_char_discovery_service, uuid, props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc mp_obj_new_list(0, NULL)); characteristic->handle = gattc_char->handle_value; - characteristic->service = m_char_discovery_service; mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic)); } @@ -274,10 +272,11 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_ob // For now, just leave the UUID as NULL. } - common_hal_bleio_descriptor_construct(descriptor, uuid, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, - GATT_MAX_DATA_LENGTH, false); + common_hal_bleio_descriptor_construct( + descriptor, m_desc_discovery_characteristic, uuid, + SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, + GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes); descriptor->handle = gattc_desc->handle; - descriptor->characteristic = m_desc_discovery_characteristic; mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor)); } @@ -316,12 +315,12 @@ STATIC void discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t device) { void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist) { - mp_obj_list_t *remote_services_list = common_hal_bleio_device_get_remote_services_list(device); + mp_obj_list_t *remote_services_list = common_hal_bleio_device_get_remote_service_list(device); ble_drv_add_event_handler(discovery_on_ble_evt, device); // Start over with an empty list. - mp_obj_list_clear(MP_OBJ_FROM_PTR(common_hal_bleio_device_get_remote_services_list(device))); + mp_obj_list_clear(MP_OBJ_FROM_PTR(common_hal_bleio_device_get_remote_service_list(device))); if (service_uuids_whitelist == mp_const_none) { // List of service UUID's not given, so discover all available services. diff --git a/ports/nrf/common-hal/bleio/__init__.h b/ports/nrf/common-hal/_bleio/__init__.h index c0bba3799..cf1a06945 100644 --- a/ports/nrf/common-hal/bleio/__init__.h +++ b/ports/nrf/common-hal/_bleio/__init__.h @@ -29,6 +29,12 @@ void bleio_reset(void); +typedef struct { + ble_gap_enc_key_t own_enc; + ble_gap_enc_key_t peer_enc; + ble_gap_id_key_t peer_id; +} bonding_keys_t; + // We assume variable length data. // 20 bytes max (23 - 3). #define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3) diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c deleted file mode 100644 index a7a3a6db0..000000000 --- a/ports/nrf/common-hal/bleio/Service.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2019 Dan Halbert for Adafruit Industries - * Copyright (c) 2018 Artur Pacholec - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "ble_drv.h" -#include "ble.h" -#include "py/runtime.h" -#include "common-hal/bleio/__init__.h" -#include "shared-bindings/bleio/Characteristic.h" -#include "shared-bindings/bleio/Descriptor.h" -#include "shared-bindings/bleio/Service.h" -#include "shared-bindings/bleio/Adapter.h" - -void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, mp_obj_list_t *characteristic_list, bool is_secondary) { - self->device = mp_const_none; - self->handle = 0xFFFF; - self->uuid = uuid; - self->characteristic_list = characteristic_list; - self->is_remote = false; - self->is_secondary = is_secondary; - - for (size_t characteristic_idx = 0; characteristic_idx < characteristic_list->len; ++characteristic_idx) { - bleio_characteristic_obj_t *characteristic = - MP_OBJ_TO_PTR(characteristic_list->items[characteristic_idx]); - characteristic->service = self; - } -} - -bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) { - return self->uuid; -} - -mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self) { - return self->characteristic_list; -} - -bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self) { - return self->is_remote; -} - -bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) { - return self->is_secondary; -} - -// Call this after the Service has been added to the Peripheral. -void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self) { - // Add all the characteristics. - for (size_t characteristic_idx = 0; characteristic_idx < self->characteristic_list->len; ++characteristic_idx) { - bleio_characteristic_obj_t *characteristic = - MP_OBJ_TO_PTR(self->characteristic_list->items[characteristic_idx]); - - if (characteristic->handle != BLE_GATT_HANDLE_INVALID) { - mp_raise_ValueError(translate("Characteristic already in use by another Service.")); - } - - ble_gatts_char_md_t char_md = { - .char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0, - .char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0, - .char_props.write_wo_resp = (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) ? 1 : 0, - .char_props.write = (characteristic->props & CHAR_PROP_WRITE) ? 1 : 0, - .char_props.notify = (characteristic->props & CHAR_PROP_NOTIFY) ? 1 : 0, - .char_props.indicate = (characteristic->props & CHAR_PROP_INDICATE) ? 1 : 0, - }; - - ble_gatts_attr_md_t cccd_md = { - .vloc = BLE_GATTS_VLOC_STACK, - }; - - if (char_md.char_props.notify || char_md.char_props.indicate) { - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); - - char_md.p_cccd_md = &cccd_md; - } - - ble_uuid_t char_uuid; - bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &char_uuid); - - ble_gatts_attr_md_t char_attr_md = { - .vloc = BLE_GATTS_VLOC_STACK, - .vlen = !characteristic->fixed_length, - }; - - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_attr_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_attr_md.write_perm); - - mp_buffer_info_t char_value_bufinfo; - mp_get_buffer_raise(characteristic->value, &char_value_bufinfo, MP_BUFFER_READ); - - ble_gatts_attr_t char_attr = { - .p_uuid = &char_uuid, - .p_attr_md = &char_attr_md, - .init_len = char_value_bufinfo.len, - .p_value = char_value_bufinfo.buf, - .init_offs = 0, - .max_len = characteristic->max_length, - }; - - ble_gatts_char_handles_t char_handles; - - uint32_t err_code; - err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &char_attr, &char_handles); - if (err_code != NRF_SUCCESS) { - mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code); - } - - characteristic->user_desc_handle = char_handles.user_desc_handle; - characteristic->cccd_handle = char_handles.cccd_handle; - characteristic->sccd_handle = char_handles.sccd_handle; - characteristic->handle = char_handles.value_handle; - - // Add the descriptors for this characteristic. - for (size_t descriptor_idx = 0; descriptor_idx < characteristic->descriptor_list->len; ++descriptor_idx) { - bleio_descriptor_obj_t *descriptor = - MP_OBJ_TO_PTR(characteristic->descriptor_list->items[descriptor_idx]); - - ble_uuid_t desc_uuid; - bleio_uuid_convert_to_nrf_ble_uuid(descriptor->uuid, &desc_uuid); - - ble_gatts_attr_md_t desc_attr_md = { - // Data passed is not in a permanent location and should be copied. - .vloc = BLE_GATTS_VLOC_STACK, - .vlen = !descriptor->fixed_length, - }; - - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_attr_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_attr_md.write_perm); - - mp_buffer_info_t desc_value_bufinfo; - mp_get_buffer_raise(descriptor->value, &desc_value_bufinfo, MP_BUFFER_READ); - - ble_gatts_attr_t desc_attr = { - .p_uuid = &desc_uuid, - .p_attr_md = &desc_attr_md, - .init_len = desc_value_bufinfo.len, - .p_value = desc_value_bufinfo.buf, - .init_offs = 0, - .max_len = descriptor->max_length, - }; - - err_code = sd_ble_gatts_descriptor_add(characteristic->handle, &desc_attr, &descriptor->handle); - - } // loop over descriptors - - } // loop over characteristics -} |
