summaryrefslogtreecommitdiff
path: root/ports/nrf/common-hal
diff options
context:
space:
mode:
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.c122
-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.c169
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
-}