WIP: CharacteristicBuffer for Central; not working: need to set remote Characteristic Service
This commit is contained in:
parent
6ea01ea9b0
commit
bf8a35b2f8
@ -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_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_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_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_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_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_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_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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
sd_nvic_critical_region_exit(is_nested_critical_region);
|
||||
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.
|
||||
|
@ -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_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_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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
//|
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user