summaryrefslogtreecommitdiff
path: root/devices
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2020-08-10 19:46:18 -0400
committerDan Halbert <halbert@halwitz.org>2020-08-10 19:46:18 -0400
commit74034d6b9d14bf70a5a65e3f001998f6716c7d46 (patch)
treedd1fdec3d989669fb68c183efd7141d5b2588f2c /devices
parent0f4b969d62b5eb933a674a23a338d9d420cf61b4 (diff)
characteristic/cccd r/w; not tested
Diffstat (limited to 'devices')
-rw-r--r--devices/ble_hci/common-hal/_bleio/Attribute.h15
-rw-r--r--devices/ble_hci/common-hal/_bleio/Service.c4
-rw-r--r--devices/ble_hci/common-hal/_bleio/UUID.c5
-rw-r--r--devices/ble_hci/common-hal/_bleio/UUID.h17
-rw-r--r--devices/ble_hci/common-hal/_bleio/__init__.c2
-rw-r--r--devices/ble_hci/common-hal/_bleio/att.c394
-rw-r--r--devices/ble_hci/common-hal/_bleio/att.h2
7 files changed, 196 insertions, 243 deletions
diff --git a/devices/ble_hci/common-hal/_bleio/Attribute.h b/devices/ble_hci/common-hal/_bleio/Attribute.h
index f4b0b7dbb..b8702cae4 100644
--- a/devices/ble_hci/common-hal/_bleio/Attribute.h
+++ b/devices/ble_hci/common-hal/_bleio/Attribute.h
@@ -30,21 +30,6 @@
#include "shared-module/_bleio/Attribute.h"
#include "shared-bindings/_bleio/UUID.h"
-// Types returned by attribute table lookups. These are UUIDs.
-typedef enum {
- BLE_TYPE_UNKNOWN = 0x0000,
- BLE_TYPE_SERVICE_PRIMARY = 0x2800,
- BLE_TYPE_SERVICE_SECONDARY = 0x2801,
- BLE_TYPE_SERVICE_INCLUDE = 0x2802, // not yet implemented by us
- BLE_TYPE_CHARACTERISTIC = 0x2803,
- BLE_TYPE_CHAR_EXTENDED_PROPS = 0x2900, // not yet implemented by us
- BLE_TYPE_CHAR_USER_DESC = 0x2901, // not yet implemented by us
- BLE_TYPE_CCCD = 0x2902,
- BLE_TYPE_SCCD = 0x2903, // not yet implemented by us
- BLE_TYPE_CHAR_PRESENTATION_FMT = 0x2904, // not yet implemented by us
- BLE_TYPE_CHAR_AGGREGATE_FMT = 0x2905, // not yet implemented by us
-} ble_attribute_type_uuid;
-
bleio_uuid_obj_t *bleio_attribute_get_uuid(mp_obj_t *attribute);
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ATTRIBUTE_H
diff --git a/devices/ble_hci/common-hal/_bleio/Service.c b/devices/ble_hci/common-hal/_bleio/Service.c
index b6963b7a4..0b6c83002 100644
--- a/devices/ble_hci/common-hal/_bleio/Service.c
+++ b/devices/ble_hci/common-hal/_bleio/Service.c
@@ -104,7 +104,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
cccd->base.type = &bleio_descriptor_type;
uint16_t zero = 0;
- mp_buffer_info_t zero_cccd = {
+ mp_buffer_info_t zero_cccd_value = {
.buf = &zero,
.len = sizeof(zero),
};
@@ -117,7 +117,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
characteristic->read_perm, // Make CCCD write perm match characteristic read perm.
2, // 2 bytes
true, // fixed length
- &zero_cccd // Initial value is 0.
+ &zero_cccd_value // Initial value is 0.
);
// Adds CCCD to attribute table, and also extends self->end_handle to include the CCCD.
diff --git a/devices/ble_hci/common-hal/_bleio/UUID.c b/devices/ble_hci/common-hal/_bleio/UUID.c
index fd8d8bfe9..a50efc3b1 100644
--- a/devices/ble_hci/common-hal/_bleio/UUID.c
+++ b/devices/ble_hci/common-hal/_bleio/UUID.c
@@ -68,3 +68,8 @@ void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf) {
common_hal_bleio_uuid_get_uuid128(self, buf);
}
}
+
+// Return a uui16 only if this is a standard uuid. Otherwise return BLE_UUID_UNKNOWN.
+uint16_t bleio_uuid_get_uuid16_or_unknown(bleio_uuid_obj_t *uuid) {
+ return uuid->size == 16 ? uuid->uuid16 : BLE_UUID_UNKNOWN;
+}
diff --git a/devices/ble_hci/common-hal/_bleio/UUID.h b/devices/ble_hci/common-hal/_bleio/UUID.h
index deaf76d5c..1a0ab91c4 100644
--- a/devices/ble_hci/common-hal/_bleio/UUID.h
+++ b/devices/ble_hci/common-hal/_bleio/UUID.h
@@ -31,6 +31,21 @@
#include "py/obj.h"
+// Types returned by attribute table lookups. These are UUIDs.
+typedef enum {
+ BLE_UUID_UNKNOWN = 0x0000,
+ BLE_UUID_SERVICE_PRIMARY = 0x2800,
+ BLE_UUID_SERVICE_SECONDARY = 0x2801,
+ BLE_UUID_SERVICE_INCLUDE = 0x2802, // not yet implemented by us
+ BLE_UUID_CHARACTERISTIC = 0x2803,
+ BLE_UUID_CHAR_EXTENDED_PROPS = 0x2900, // not yet implemented by us
+ BLE_UUID_CHAR_USER_DESC = 0x2901, // not yet implemented by us
+ BLE_UUID_CCCD = 0x2902,
+ BLE_UUID_SCCD = 0x2903, // not yet implemented by us
+ BLE_UUID_CHAR_PRESENTATION_FMT = 0x2904, // not yet implemented by us
+ BLE_UUID_CHAR_AGGREGATE_FMT = 0x2905, // not yet implemented by us
+} ble_standard_uuid;
+
typedef struct {
mp_obj_base_t base;
uint8_t size;
@@ -38,4 +53,6 @@ typedef struct {
uint8_t uuid128[16];
} bleio_uuid_obj_t;
+uint16_t bleio_uuid_get_uuid16_or_unknown(bleio_uuid_obj_t *uuid);
+
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_UUID_H
diff --git a/devices/ble_hci/common-hal/_bleio/__init__.c b/devices/ble_hci/common-hal/_bleio/__init__.c
index 16b4a26e2..e2b463af8 100644
--- a/devices/ble_hci/common-hal/_bleio/__init__.c
+++ b/devices/ble_hci/common-hal/_bleio/__init__.c
@@ -117,7 +117,7 @@ void check_hci_error(hci_result_t result) {
void bleio_reset() {
// Create a UUID object for all CCCD's.
cccd_uuid.base.type = &bleio_uuid_type;
- common_hal_bleio_uuid_construct(&cccd_uuid, BLE_TYPE_CCCD, NULL);
+ common_hal_bleio_uuid_construct(&cccd_uuid, BLE_UUID_CCCD, NULL);
bleio_hci_reset();
diff --git a/devices/ble_hci/common-hal/_bleio/att.c b/devices/ble_hci/common-hal/_bleio/att.c
index 8daddd3a9..e19a73558 100644
--- a/devices/ble_hci/common-hal/_bleio/att.c
+++ b/devices/ble_hci/common-hal/_bleio/att.c
@@ -90,29 +90,32 @@ STATIC uint8_t bleio_properties_to_ble_spec_properties(uint8_t bleio_properties)
return ble_spec_properties;
}
-// STATIC uint8_t ble_spec_properties_to_bleio_properties(uint8_t ble_spec_properties) {
-// uint8_t bleio_properties = 0;
-// if (ble_spec_properties & BT_GATT_CHRC_BROADCAST) {
-// bleio_properties |= CHAR_PROP_BROADCAST;
-// }
-// if (ble_spec_properties & BT_GATT_CHRC_INDICATE) {
-// bleio_properties |= CHAR_PROP_INDICATE;
-// }
-// if (ble_spec_properties & BT_GATT_CHRC_NOTIFY) {
-// bleio_properties |= CHAR_PROP_NOTIFY;
-// }
-// if (ble_spec_properties & BT_GATT_CHRC_READ) {
-// bleio_properties |= CHAR_PROP_READ;
-// }
-// if (ble_spec_properties & BT_GATT_CHRC_WRITE) {
-// bleio_properties |= CHAR_PROP_WRITE;
-// }
-// if (ble_spec_properties & BT_GATT_CHRC_WRITE_WITHOUT_RESP) {
-// bleio_properties |= CHAR_PROP_WRITE_NO_RESPONSE;
-// }
+//FIX not currently used; reenable when used.
+#if 0
+STATIC uint8_t ble_spec_properties_to_bleio_properties(uint8_t ble_spec_properties) {
+ uint8_t bleio_properties = 0;
+ if (ble_spec_properties & BT_GATT_CHRC_BROADCAST) {
+ bleio_properties |= CHAR_PROP_BROADCAST;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_INDICATE) {
+ bleio_properties |= CHAR_PROP_INDICATE;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_NOTIFY) {
+ bleio_properties |= CHAR_PROP_NOTIFY;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_READ) {
+ bleio_properties |= CHAR_PROP_READ;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_WRITE) {
+ bleio_properties |= CHAR_PROP_WRITE;
+ }
+ if (ble_spec_properties & BT_GATT_CHRC_WRITE_WITHOUT_RESP) {
+ bleio_properties |= CHAR_PROP_WRITE_NO_RESPONSE;
+ }
-// return bleio_properties;
-// }
+ return bleio_properties;
+}
+#endif // #if 0
STATIC void send_error(uint16_t conn_handle, uint8_t opcode, uint16_t handle, uint8_t code) {
struct __packed {
@@ -244,7 +247,7 @@ bool att_disconnect_from_address(bt_addr_le_t *addr) {
// BLEUuid serviceUuid(serviceUuidFilter);
// while (reqEnd_handle == 0xffff) {
-// int respLength = readByGroupReq(conn_handle, reqStart_handle, reqEnd_handle, BLE_TYPE_SERVICE_PRIMARY, response_buffer);
+// int respLength = readByGroupReq(conn_handle, reqStart_handle, reqEnd_handle, BLE_UUID_SERVICE_PRIMARY, response_buffer);
// if (respLength == 0) {
// return false;
@@ -305,7 +308,7 @@ bool att_disconnect_from_address(bt_addr_le_t *addr) {
// reqEnd_handle = service->end_handle();
// while (1) {
-// int respLength = readByTypeReq(conn_handle, reqStart_handle, reqEnd_handle, BLE_TYPE_CHARACTERISTIC, response_buffer);
+// int respLength = readByTypeReq(conn_handle, reqStart_handle, reqEnd_handle, BLE_UUID_CHARACTERISTIC, response_buffer);
// if (respLength == 0) {
// return false;
@@ -532,24 +535,30 @@ void att_remove_connection(uint16_t handle, uint8_t reason) {
}
if (peer_index == -1) {
- // bail not found
+ // Peer not found
return;
}
- //FIX BLEDevice bleDevice(bleio_connections[peer_index].address_type, bleio_connections[peer_index].address);
-
if (peer_count == 1) {
- //FIX
- // clear CCCD values on disconnect
- // for (uint16_t i = 0; i < GATT.attributeCount(); i++) {
- // BLELocalAttribute* attribute = GATT.attribute(i);
- // if (attribute->type() == BLE_TYPE_CHARACTERISTIC) {
- // BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
-
- // characteristic->writeCccdValue(bleDevice, 0x0000);
- // }
- // }
+ // Clear CCCD values on disconnect.
+ size_t max_attribute_handle = bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj);
+ for (size_t i = 1; handle <= max_attribute_handle; i++) {
+ mp_obj_t attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
+
+ uint16_t zero = 0;
+ mp_buffer_info_t zero_cccd_value = {
+ .buf = &zero,
+ .len = sizeof(zero),
+ };
+
+ if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
+ bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
+ if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == BLE_UUID_CCCD) {
+ common_hal_bleio_descriptor_set_value(descriptor, &zero_cccd_value);
+ }
+ }
+ }
long_write_handle = BLE_GATT_HANDLE_INVALID;
long_write_value_length = 0;
@@ -564,11 +573,6 @@ void att_remove_connection(uint16_t handle, uint8_t reason) {
bleio_connections[peer_index].role = 0x00;
memset(&bleio_connections[peer_index].addr, 0x00, sizeof(bleio_connections[peer_index].addr));
bleio_connections[peer_index].mtu = BT_ATT_DEFAULT_LE_MTU;
-
- //FIX if (bleio_connections[peer_index].device) {
- //FIX delete bleio_connections[peer_index].device;
- // }
- //FIX bleio_connections[peer_index].device = NULL;
}
uint16_t att_conn_handle(bt_addr_le_t *addr) {
@@ -582,17 +586,6 @@ uint16_t att_conn_handle(bt_addr_le_t *addr) {
return 0xffff;
}
-//FIX
-// BLERemoteDevice* att_device(uint8_t address_type, const uint8_t address[6]) {
-// for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
-// if (bleio_connections[i].addr.type == addr->type &&
-// memcmp(&bleio_connections[i].addr.a.val, addr->a.val, sizeof(addr->a.val)) == 0) {
-// }
-// }
-
-// return NULL;
-// }
-
bool att_is_connected(void) {
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
if (bleio_connections[i].conn_handle != 0xffff) {
@@ -648,30 +641,11 @@ bool att_disconnect_all(void) {
bleio_connections[i].addr.type = 0;
memset(bleio_connections[i].addr.a.val, 0, sizeof(bleio_connections[i].addr.a.val));
bleio_connections[i].mtu = BT_ATT_DEFAULT_LE_MTU;
-
- //FIX
- // if (bleio_connections[i].device) {
- // delete bleio_connections[i].device;
- // }
- // bleio_connections[i].device = NULL;
}
return (num_disconnects > 0);
}
-// FIX
-// BLEDevice att_central() {
-// for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
-// if (bleio_connections[i].conn_handle == 0xffff || bleio_connections[i].role != 0x01) {
-// continue;
-// }
-
-// return BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address);
-// }
-
-// return BLEDevice();
-// }
-
bool att_notify(uint16_t handle, const uint8_t* value, int length) {
int num_notifications = 0;
@@ -938,7 +912,7 @@ STATIC void process_find_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
response_length = 1;
//FIX
- // if (find_type_req->type == BLE_TYPE_SERVICE_PRIMARY) {
+ // if (find_type_req->type == BLE_UUID_SERVICE_PRIMARY) {
// for (uint16_t i = (find_type_req->start_handle - 1); i < GATT.attributeCount() && i <= (find_type_req->end_handle - 1); i++) {
// BLELocalAttribute* attribute = GATT.attribute(i);
@@ -976,8 +950,8 @@ void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, ui
// We only support returning services for BT_ATT_OP_READ_GROUP_REQ, which is typically used
// for service discovery.
if (dlen != sizeof(struct bt_att_read_group_req) + sizeof(type_uuid) ||
- (type_uuid != BLE_TYPE_SERVICE_PRIMARY &&
- type_uuid != BLE_TYPE_SERVICE_SECONDARY)) {
+ (type_uuid != BLE_UUID_SERVICE_PRIMARY &&
+ type_uuid != BLE_UUID_SERVICE_SECONDARY)) {
send_error(conn_handle, BT_ATT_OP_READ_GROUP_REQ, req->start_handle, BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE);
return;
}
@@ -1109,95 +1083,93 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
}
- //FIX
- (void) offset;
- (void) handle;
- //FIX if ((uint16_t)(handle - 1) > GATT.attributeCount()) {
- // send_error(conn_handle, opcode, handle, BT_ATT_ERR_ATTR_NOT_FOUND);
- // return;
- // }
+ if (handle > bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj)) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
+ return;
+ }
- uint8_t response[mtu];
- uint16_t response_length;
+ typedef struct __packed {
+ struct bt_att_hdr h;
+ struct bt_att_read_rsp r; // Same as bt_att_read_blob_rsp.
+ } rsp_t;
- response[0] = response_opcode;
- response_length = 1;
+ uint8_t rsp_bytes[mtu];
+ rsp_t *rsp = (rsp_t *) rsp_bytes;
+ rsp->h.code = response_opcode;
- //FIX BLELocalAttribute* attribute = GATT.attribute(handle - 1);
- // enum BLEAttributeType attributeType = attribute->type();
+ // Keeps track of total length of the response.
+ size_t rsp_length = sizeof(rsp_t);
- // if (attributeType == BLE_TYPE_SERVICE_PRIMARY) {
- // if (offset) {
- // send_error(conn_handle, BT_ATT_ERR_ATTR_NOT_LONG, handle, BT_ATT_ERR_INVALID_PDU);
- // return;
- // }
+ mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
+ if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_service_type)) {
+ if (offset) {
+ send_error(conn_handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG, handle, BT_ATT_ERR_INVALID_PDU);
+ return;
+ }
- // BLELocalService* service = (BLELocalService*)attribute;
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute_obj);
+ const uint32_t sizeof_service_uuid = common_hal_bleio_uuid_get_size(service->uuid) / 8;
- // // add the UUID
- // uint8_t uuidLen = service->uuidLength();
- // memcpy(&response[response_length], service->uuidData(), uuidLen);
- // response_length += uuidLen;
- // } else if (attributeType == BLE_TYPE_CHARACTERISTIC) {
- // BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
+ common_hal_bleio_uuid_pack_into(service->uuid, rsp->r.value);
+ rsp_length += sizeof_service_uuid;
- // if (characteristic->handle() == handle) {
- // if (offset) {
- // send_error(conn_handle, opcode, handle, BT_ATT_ERR_ATTR_NOT_LONG);
- // return;
- // }
+ } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
+ if (characteristic->decl_handle == handle) {
+ // Read characteristic declaration. Return properties, value handle, and uuid.
+ if (offset) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG);
+ return;
+ }
- // // add the properties
- // response[response_length++] = characteristic->properties();
-
- // // add the value handle
- // uint16_t value_handle = characteristic->value_handle();
- // memcpy(&response[response_length], &value_handle, sizeof(value_handle));
- // response_length += sizeof(value_handle);
-
- // // add the UUID
- // uint8_t uuidLen = characteristic->uuidLength();
- // memcpy(&response[response_length], characteristic->uuidData(), uuidLen);
- // response_length += uuidLen;
- // } else {
- // if ((characteristic->properties() & BLERead) == 0) {
- // send_error(conn_handle, opcode, handle, BT_ATT_ERR_READ_NOT_PERM);
- // return;
- // }
+ characteristic_declaration_t *char_decl = (characteristic_declaration_t *) rsp->r.value;
- // uint16_t value_length = characteristic->value_length();
+ // Convert from the bleio properties bit values to the BLE spec properties bit values.
+ // They are not the same :(.
+ char_decl->properties = bleio_properties_to_ble_spec_properties(characteristic->props);
+ char_decl->value_handle = characteristic->handle;
- // if (offset >= value_length) {
- // send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
- // return;
- // }
+ const uint32_t sizeof_char_uuid = common_hal_bleio_uuid_get_size(characteristic->uuid) / 8;
+ common_hal_bleio_uuid_pack_into(characteristic->uuid, char_decl->uuid);
+ rsp_length += sizeof_char_uuid;
- // value_length = min(mtu - response_length, value_length - offset);
+ } else {
+ // Read characteristic value.
- // for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
- // if (bleio_connections[i].conn_handle == conn_handle) {
- // // FIX characteristic->readValue(BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address), offset, &response[response_length], value_length);
- // response_length += value_length;
- // }
- // }
- // }
- // } else if (attributeType == BLE_TYPE_DESCRIPTOR) {
- // BLELocalDescriptor* descriptor = (BLELocalDescriptor*)attribute;
+ if ((characteristic->props & CHAR_PROP_READ) == 0) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_READ_NOT_PERMITTED);
+ return;
+ }
- // uint16_t value_length = descriptor->valueSize();
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer(characteristic->value, &bufinfo, MP_BUFFER_READ);
- // if (offset >= value_length) {
- // send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
- // return;
- // }
+ if (offset >= bufinfo.len) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
+ return;
+ }
- // value_length = min(mtu - response_length, value_length - offset);
+ size_t value_length = MIN(mtu - rsp_length, bufinfo.len - offset);
+ memcpy(rsp->r.value, bufinfo.buf + offset, value_length);
+ rsp_length += value_length;
+ }
+ } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
+ bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
- // memcpy(&response[response_length], descriptor->value() + offset, value_length);
- // response_length += value_length;
- // }
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer(descriptor->value, &bufinfo, MP_BUFFER_READ);
- hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
+ if (offset >= bufinfo.len) {
+ send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
+ return;
+ }
+
+ size_t value_length = MIN(mtu - rsp_length, bufinfo.len - offset);
+ memcpy(rsp->r.value, bufinfo.buf + offset, value_length);
+ rsp_length += value_length;
+ }
+
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes);
}
STATIC void process_read_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
@@ -1248,7 +1220,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
- if (type_uuid == BLE_TYPE_CHARACTERISTIC &&
+ if (type_uuid == BLE_UUID_CHARACTERISTIC &&
MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
// Request is for characteristic declarations.
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
@@ -1299,9 +1271,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
} else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
// See if request is for a descriptor value with a 16-bit UUID, such as the CCCD.
bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
- if (common_hal_bleio_uuid_get_size(descriptor->uuid) == 16 &&
- common_hal_bleio_uuid_get_uuid16(descriptor->uuid) == type_uuid) {
-
+ if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == type_uuid) {
struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length];
att_data->handle = handle;
@@ -1322,8 +1292,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
} else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
// See if request is for a characteristic value with a 16-bit UUID.
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
- if (common_hal_bleio_uuid_get_size(characteristic->uuid) == 16 &&
- common_hal_bleio_uuid_get_uuid16(characteristic->uuid) == type_uuid) {
+ if (bleio_uuid_get_uuid16_or_unknown(characteristic->uuid) == type_uuid) {
struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length];
@@ -1381,7 +1350,8 @@ STATIC void process_read_type_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t da
// Handles BT_ATT_OP_WRITE_REQ or BT_ATT_OP_WRITE_
STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t op, uint8_t dlen, uint8_t data[]) {
// struct bt_att_write_cmd is identical, so don't bother to split code paths based on opcode.
- //FIX REMOVE this later struct bt_att_write_req *req = (struct bt_att_write_req *) data;
+ struct bt_att_write_req *req = (struct bt_att_write_req *) data;
+
bool with_response = (op == BT_ATT_OP_WRITE_REQ);
if (dlen < sizeof(struct bt_att_write_req)) {
@@ -1391,81 +1361,59 @@ STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t
return;
}
- //FIX why cast?
- // if ((uint16_t)(req->handle - 1) > GATT.attributeCount()) {
- // if (with_response) {
- // send_error(conn_handle, BT_ATT_OP_WRITE_REQ, handle, BT_ATT_ERR_ATTR_NOT_FOUND);
- // }
- // return;
- // }
-
- // uint8_t value_length = dlen - sizeof(req->handle);
- // uint8_t* value = &data[sizeof(req->handle)];
-
- // BLELocalAttribute* attribute = GATT.attribute(req->handle - 1);
+ if (req->handle > bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj)) {
+ if (with_response) {
+ send_error(conn_handle, BT_ATT_OP_WRITE_REQ, req->handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
+ }
+ return;
+ }
- // if (attribute->type() == BLE_TYPE_CHARACTERISTIC) {
- // BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
+ size_t value_length = dlen - sizeof(struct bt_att_write_req);
- // if (req->handle != characteristic->value_handle() ||
- // withResponse ? ((characteristic->properties() & BLEWrite) == 0) :
- // ((characteristic->properties() & BLEWriteWithoutResponse) == 0)) {
- // if (withResponse) {
- // send_error(conn_handle, BT_ATT_OP_WRITE_REQ, handle, BT_ATT_ERR_WRITE_NOT_PERM);
- // }
- // return;
- // }
+ mp_buffer_info_t bufinfo;
+ bufinfo.buf = req->value;
+ bufinfo.len = value_length;
- // for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
- // if (bleio_connections[i].conn_handle == conn_handle) {
- // // FIX characteristic->writeValue(BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address), value, value_length);
- // break;
- // }
- // }
- // } else if (attribute->type() == BLE_TYPE_DESCRIPTOR) {
- // BLELocalDescriptor* descriptor = (BLELocalDescriptor*)attribute;
+ mp_obj_t attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, req->handle);
- // // only CCCD's are writable
- // if (descriptor->uuidLength() != 2 || *((uint16_t*)(descriptor->uuidData())) != 0x2902) {
- // if (withResponse) {
- // send_error(conn_handle, BT_ATT_OP_WRITE_REQ, handle, BT_ATT_ERR_WRITE_NOT_PERM);
- // }
- // return;
- // }
+ if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
- // // get the previous handle, should be the characteristic for the CCCD
- // attribute = GATT.attribute(handle - 2);
+ // Don't write the characteristic declaration.
+ // Also, this must be a writable characteristic.
+ if (req->handle != characteristic->handle ||
+ (with_response
+ ? (characteristic->props & CHAR_PROP_WRITE) == 0
+ : (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) == 0)) {
+ if (with_response) {
+ send_error(conn_handle, BT_ATT_OP_WRITE_REQ, req->handle, BT_ATT_ERR_WRITE_NOT_PERMITTED);
+ }
+ return;
+ }
- // if (attribute->type() != BLE_TYPE_CHARACTERISTIC) {
- // if (withResponse) {
- // send_error(conn_handle, BT_ATT_OP_WRITE_REQ, handle, BT_ATT_ERR_WRITE_NOT_PERM);
- // }
- // return;
- // }
+ common_hal_bleio_characteristic_set_value(characteristic, &bufinfo);
- // BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
+ } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
+ bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
+ // Only CCCD's are writable.
+ if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) != BLE_UUID_CCCD) {
+ if (with_response) {
+ send_error(conn_handle, BT_ATT_OP_WRITE_REQ, req->handle, BT_ATT_ERR_WRITE_NOT_PERMITTED);
+ }
+ return;
+ }
- // for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
- // if (bleio_connections[i].conn_handle == conn_handle) {
- // //FIX characteristic->writeCccdValue(BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address), *((uint16_t*)value));
- // break;
- // }
- // }
- // } else {
- // if (withResponse) {
- // send_error(conn_handle, BT_ATT_OP_WRITE_REQ, handle, BT_ATT_ERR_WRITE_NOT_PERM);
- // }
- // return;
- // }
+ //FIX need to set up event handlers, etc.?
+ common_hal_bleio_descriptor_set_value(descriptor, &bufinfo);
+ }
if (with_response) {
- uint8_t response[mtu];
- uint16_t response_length;
-
- response[0] = BT_ATT_OP_WRITE_RSP;
- response_length = 1;
+ // There's no data in the response. We just indicate the write happened.
+ struct bt_att_hdr rsp = {
+ .code = BT_ATT_OP_READ_REQ,
+ };
- hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
+ hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *) &rsp);
}
}
@@ -1508,7 +1456,7 @@ STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_
return;
}
- if (characteristic->props & CHAR_PROP_WRITE) {
+ if ((characteristic->props & CHAR_PROP_WRITE) == 0) {
send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_WRITE_NOT_PERMITTED);
return;
}
@@ -1578,7 +1526,7 @@ STATIC void process_exec_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t d
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
}
-STATIC void process_handle_notify_or_indicate(uint16_t conn_handle, uint8_t opcode, uint8_t dlen, uint8_t data[]) {
+STATIC void process_notify_or_indicate(uint16_t conn_handle, uint8_t opcode, uint8_t dlen, uint8_t data[]) {
if (dlen < 2) {
return; // drop
}
@@ -1629,7 +1577,7 @@ STATIC void process_handle_notify_or_indicate(uint16_t conn_handle, uint8_t opco
}
}
-STATIC void process_handle_confirm(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
+STATIC void process_confirm(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
(void) conn_handle;
(void) dlen;
(void) data;
@@ -1776,11 +1724,11 @@ void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
case BT_ATT_OP_NOTIFY:
case BT_ATT_OP_INDICATE:
- process_handle_notify_or_indicate(conn_handle, opcode, dlen, data);
+ process_notify_or_indicate(conn_handle, opcode, dlen, data);
break;
case BT_ATT_OP_CONFIRM:
- process_handle_confirm(conn_handle, dlen, data);
+ process_confirm(conn_handle, dlen, data);
break;
case BT_ATT_OP_READ_MULT_REQ:
diff --git a/devices/ble_hci/common-hal/_bleio/att.h b/devices/ble_hci/common-hal/_bleio/att.h
index 48f7836e0..820e86bfb 100644
--- a/devices/ble_hci/common-hal/_bleio/att.h
+++ b/devices/ble_hci/common-hal/_bleio/att.h
@@ -32,8 +32,6 @@
void bleio_att_reset(void);
-//FIX BLEDevice att_central(void);
-//FIX BLERemoteDevice* att_device(uint8_t address_type, const uint8_t address[6]);
//FIX void att_set_event_handler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler);
bool att_address_is_connected(bt_addr_le_t *addr);
bool att_connect_to_address(bt_addr_le_t *addr);