summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2019-07-02 22:34:54 -0400
committerDan Halbert <halbert@halwitz.org>2019-07-02 22:34:54 -0400
commitbf8a35b2f835fbc97d54867f8e21b486a46c245b (patch)
tree97c52950ec6840fca9bca6eeb844217c6efa93c4
parent6ea01ea9b0334a175419f9d449be25a5838627da (diff)
WIP: CharacteristicBuffer for Central; not working: need to set remote Characteristic Service
-rw-r--r--ports/nrf/common-hal/bleio/Central.c73
-rw-r--r--ports/nrf/common-hal/bleio/Characteristic.c47
-rw-r--r--ports/nrf/common-hal/bleio/CharacteristicBuffer.c45
-rw-r--r--ports/nrf/common-hal/bleio/Peripheral.c93
-rw-r--r--shared-bindings/bleio/Central.c26
-rw-r--r--shared-bindings/bleio/Central.h1
-rw-r--r--shared-bindings/bleio/CharacteristicBuffer.c9
-rw-r--r--shared-bindings/bleio/Peripheral.c1
-rw-r--r--shared-bindings/bleio/Service.c2
9 files changed, 171 insertions, 126 deletions
diff --git a/ports/nrf/common-hal/bleio/Central.c b/ports/nrf/common-hal/bleio/Central.c
index 0eedd2b56..5bd5a6321 100644
--- a/ports/nrf/common-hal/bleio/Central.c
+++ b/ports/nrf/common-hal/bleio/Central.c
@@ -162,40 +162,41 @@ 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;
switch (ble_evt->header.evt_id) {
- case BLE_GAP_EVT_CONNECTED:
- central->conn_handle = ble_evt->evt.gap_evt.conn_handle;
- central->waiting_to_connect = false;
- break;
-
- case BLE_GAP_EVT_TIMEOUT:
- // Handle will be invalid.
- central->waiting_to_connect = false;
- break;
-
- case BLE_GAP_EVT_DISCONNECTED:
- central->conn_handle = BLE_CONN_HANDLE_INVALID;
- m_discovery_successful = false;
- m_discovery_in_process = false;
- break;
-
- case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
- on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, central);
- break;
-
- case BLE_GATTC_EVT_CHAR_DISC_RSP:
- on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, central);
- break;
-
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
- sd_ble_gap_sec_params_reply(central->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
- 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(central->conn_handle, &request->conn_params);
- break;
- }
+ case BLE_GAP_EVT_CONNECTED:
+ central->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+ central->waiting_to_connect = false;
+ break;
+
+ case BLE_GAP_EVT_TIMEOUT:
+ // Handle will be invalid.
+ central->waiting_to_connect = false;
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ central->conn_handle = BLE_CONN_HANDLE_INVALID;
+ m_discovery_successful = false;
+ m_discovery_in_process = false;
+ break;
+
+ case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+ on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, central);
+ break;
+
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, central);
+ break;
+
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ sd_ble_gap_sec_params_reply(central->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
+ 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(central->conn_handle, &request->conn_params);
+ break;
+ }
}
}
@@ -319,6 +320,10 @@ void common_hal_bleio_central_disconnect(bleio_central_obj_t *self) {
sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
}
+bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self) {
+ return self->conn_handle != BLE_CONN_HANDLE_INVALID;
+}
+
mp_obj_t common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) {
return self->service_list;
}
diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c
index ea43d8a8a..c00d8c30b 100644
--- a/ports/nrf/common-hal/bleio/Characteristic.c
+++ b/ports/nrf/common-hal/bleio/Characteristic.c
@@ -249,34 +249,35 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
uint16_t cccd = 0;
switch (common_hal_bleio_device_get_gatt_role(self->service->device)) {
- case GATT_ROLE_SERVER:
- if (self->props.notify || self->props.indicate) {
- cccd = get_cccd(self);
- }
- // It's possible that both notify and indicate are set.
- if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
- gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION);
- sent = true;
- }
- if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
- gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION);
- sent = true;
- }
- if (!sent) {
- gatts_write(self, bufinfo);
- }
- break;
+ case GATT_ROLE_SERVER:
+ if (self->props.notify || self->props.indicate) {
+ cccd = get_cccd(self);
+ }
+ // It's possible that both notify and indicate are set.
+ if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
+ gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION);
+ sent = true;
+ }
+ if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
+ gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION);
+ sent = true;
+ }
+ if (!sent) {
+ gatts_write(self, bufinfo);
+ }
+ break;
- case GATT_ROLE_CLIENT:
- gattc_write(self, bufinfo);
- break;
+ case GATT_ROLE_CLIENT:
+ gattc_write(self, bufinfo);
+ break;
- default:
- mp_raise_RuntimeError(translate("bad GATT role"));
- break;
+ default:
+ mp_raise_RuntimeError(translate("bad GATT role"));
+ break;
}
}
+
bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self) {
return self->uuid;
}
diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c
index 19b3b85ea..59eaaf02b 100644
--- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c
+++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c
@@ -40,25 +40,42 @@
#include "common-hal/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.
+ uint8_t is_nested_critical_region;
+ sd_nvic_critical_region_enter(&is_nested_critical_region);
+ for (size_t i = 0; i < len; i++) {
+ ringbuf_put(&self->ringbuf, data[i]);
+ }
+ sd_nvic_critical_region_exit(is_nested_critical_region);
+}
+
STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
bleio_characteristic_buffer_obj_t *self = (bleio_characteristic_buffer_obj_t *) param;
switch (ble_evt->header.evt_id) {
- case BLE_GATTS_EVT_WRITE: {
- ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
- // Event handle must match the handle for my characteristic.
- if (evt_write->handle == self->characteristic->handle) {
- // Push all the data onto the ring buffer.
- uint8_t is_nested_critical_region;
- sd_nvic_critical_region_enter(&is_nested_critical_region);
- for (size_t i = 0; i < evt_write->len; i++) {
- ringbuf_put(&self->ringbuf, evt_write->data[i]);
+ case BLE_GATTS_EVT_WRITE: {
+ // A client wrote to this server characteristic.
+
+ ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
+ // Event handle must match the handle for my characteristic.
+ if (evt_write->handle == self->characteristic->handle) {
+ write_to_ringbuf(self, evt_write->data, evt_write->len);
}
- sd_nvic_critical_region_exit(is_nested_critical_region);
break;
}
- }
- }
+ case BLE_GATTC_EVT_HVX: {
+ // A remote service wrote to this characteristic.
+
+ ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
+ // Must be a notification, and event handle must match the handle for my characteristic.
+ if (evt_hvx->type == BLE_GATT_HVX_NOTIFICATION &&
+ evt_hvx->handle == self->characteristic->handle) {
+ write_to_ringbuf(self, evt_hvx->data, evt_hvx->len);
+ }
+ break;
+ }
+ }
}
// Assumes that timeout and buffer_size have been validated before call.
@@ -82,13 +99,11 @@ int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_
// Wait for all bytes received or timeout
while ( (ringbuf_count(&self->ringbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) {
-#ifdef MICROPY_VM_HOOK_LOOP
- MICROPY_VM_HOOK_LOOP ;
+ MICROPY_VM_HOOK_LOOP;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
return 0;
}
-#endif
}
// Copy received data. Lock out write interrupt handler while copying.
diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c
index 69e75ff27..fc9a146c3 100644
--- a/ports/nrf/common-hal/bleio/Peripheral.c
+++ b/ports/nrf/common-hal/bleio/Peripheral.c
@@ -62,60 +62,61 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
bleio_peripheral_obj_t *self = (bleio_peripheral_obj_t*)self_in;
switch (ble_evt->header.evt_id) {
- case BLE_GAP_EVT_CONNECTED: {
- // Central has connected.
- ble_gap_conn_params_t conn_params;
- self->conn_handle = ble_evt->evt.gap_evt.conn_handle;
- sd_ble_gap_ppcp_get(&conn_params);
- sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
- break;
- }
+ case BLE_GAP_EVT_CONNECTED: {
+ // Central has connected.
+ ble_gap_conn_params_t conn_params;
+ self->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+ sd_ble_gap_ppcp_get(&conn_params);
+ sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
+ break;
+ }
- case BLE_GAP_EVT_DISCONNECTED:
- // Central has disconnected.
- self->conn_handle = BLE_CONN_HANDLE_INVALID;
- break;
-
- case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
- ble_gap_phys_t const phys = {
- .rx_phys = BLE_GAP_PHY_AUTO,
- .tx_phys = BLE_GAP_PHY_AUTO,
- };
- sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys);
- break;
- }
+ case BLE_GAP_EVT_DISCONNECTED:
+ // Central has disconnected.
+ self->conn_handle = BLE_CONN_HANDLE_INVALID;
+ break;
+
+ case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
+ ble_gap_phys_t const phys = {
+ .rx_phys = BLE_GAP_PHY_AUTO,
+ .tx_phys = BLE_GAP_PHY_AUTO,
+ };
+ sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys);
+ break;
+ }
- case BLE_GAP_EVT_ADV_SET_TERMINATED:
- // Someday may handle timeouts or limit reached.
- break;
+ case BLE_GAP_EVT_ADV_SET_TERMINATED:
+ // Someday may handle timeouts or limit reached.
+ break;
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
- sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
- break;
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
+ 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);
- 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);
+ break;
+ }
- case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
- sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL);
- break;
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL);
+ break;
- case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
- sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
- break;
- }
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
+ sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
+ break;
+ }
- case BLE_GATTS_EVT_SYS_ATTR_MISSING:
- sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
- break;
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
+ break;
- default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
- break;
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
}
}
diff --git a/shared-bindings/bleio/Central.c b/shared-bindings/bleio/Central.c
index dd2dd0d50..efadcbb2a 100644
--- a/shared-bindings/bleio/Central.c
+++ b/shared-bindings/bleio/Central.c
@@ -141,6 +141,25 @@ STATIC mp_obj_t bleio_central_disconnect(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_disconnect_obj, bleio_central_disconnect);
+//| .. attribute:: connected
+//|
+//| True if connected to a remove peripheral.
+//|
+STATIC mp_obj_t bleio_central_get_connected(mp_obj_t self_in) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_central_get_connected(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_connected_obj, bleio_central_get_connected);
+
+const mp_obj_property_t bleio_central_connected_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_central_get_connected_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+
//| .. attribute:: remote_services (read-only)
//|
//| Empty until connected, then a list of services provided by the remote peripheral.
@@ -161,11 +180,12 @@ const mp_obj_property_t bleio_central_remote_services_obj = {
STATIC const mp_rom_map_elem_t bleio_central_locals_dict_table[] = {
// Methods
- { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) },
- { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) },
// Properties
- { MP_ROM_QSTR(MP_QSTR_remote_services), MP_ROM_PTR(&bleio_central_remote_services_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_central_connected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remote_services), MP_ROM_PTR(&bleio_central_remote_services_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_central_locals_dict, bleio_central_locals_dict_table);
diff --git a/shared-bindings/bleio/Central.h b/shared-bindings/bleio/Central.h
index 542ba8fa2..2ca423945 100644
--- a/shared-bindings/bleio/Central.h
+++ b/shared-bindings/bleio/Central.h
@@ -36,6 +36,7 @@ extern const mp_obj_type_t bleio_central_type;
extern void common_hal_bleio_central_construct(bleio_central_obj_t *self);
extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, mp_obj_t service_uuids);
extern void common_hal_bleio_central_disconnect(bleio_central_obj_t *self);
+extern bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self);
extern mp_obj_t common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
diff --git a/shared-bindings/bleio/CharacteristicBuffer.c b/shared-bindings/bleio/CharacteristicBuffer.c
index 827f4947b..26f9e012b 100644
--- a/shared-bindings/bleio/CharacteristicBuffer.c
+++ b/shared-bindings/bleio/CharacteristicBuffer.c
@@ -49,10 +49,13 @@ STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self
//|
//| .. class:: CharacteristicBuffer(characteristic, *, timeout=1, buffer_size=64)
//|
-//| Create a new Characteristic object identified by the specified UUID.
+//| Monitor the given Characteristic. Each time a new value is written to the Characteristic
+//| add the newly-written bytes to a FIFO buffer.
//|
-//| :param bleio.Characteristic characteristic: The characteristic to monitor
-//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters.//|
+//| :param bleio.Characteristic characteristic: The Characteristic to monitor.
+//| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic
+//| in a remote Service that a Central has connected to.
+//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters.
//| :param int buffer_size: Size of ring buffer that stores incoming data coming from client.
//| Must be >= 1.
//|
diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c
index 37a765ae9..665f5baaf 100644
--- a/shared-bindings/bleio/Peripheral.c
+++ b/shared-bindings/bleio/Peripheral.c
@@ -140,7 +140,6 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar
STATIC mp_obj_t bleio_peripheral_get_connected(mp_obj_t self_in) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
- // Return list as a tuple so user won't be able to change it.
return mp_obj_new_bool(common_hal_bleio_peripheral_get_connected(self));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_connected_obj, bleio_peripheral_get_connected);
diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c
index e6bb7dcc3..f8993ef61 100644
--- a/shared-bindings/bleio/Service.c
+++ b/shared-bindings/bleio/Service.c
@@ -80,7 +80,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
// Copy the characteristics list and validate its items.
mp_obj_t char_list_obj = mp_obj_new_list(0, NULL);
- mp_obj_list_t *char_list = MP_OBJ_FROM_PTR(char_list);
+ mp_obj_list_t *char_list = MP_OBJ_TO_PTR(char_list_obj);
while ((characteristic_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
if (!MP_OBJ_IS_TYPE(characteristic_obj, &bleio_characteristic_type)) {