characteristic/cccd r/w; not tested

This commit is contained in:
Dan Halbert 2020-08-10 19:46:18 -04:00
parent 0f4b969d62
commit 74034d6b9d
7 changed files with 193 additions and 240 deletions

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -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();

View File

@ -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;
// 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);
// characteristic->writeCccdValue(bleDevice, 0x0000);
// }
// }
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();
characteristic_declaration_t *char_decl = (characteristic_declaration_t *) rsp->r.value;
// // 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);
// 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;
// // 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;
// }
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;
// uint16_t value_length = characteristic->value_length();
} else {
// Read characteristic value.
// if (offset >= value_length) {
// send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
// return;
// }
if ((characteristic->props & CHAR_PROP_READ) == 0) {
send_error(conn_handle, opcode, handle, BT_ATT_ERR_READ_NOT_PERMITTED);
return;
}
// value_length = min(mtu - response_length, value_length - offset);
mp_buffer_info_t bufinfo;
mp_get_buffer(characteristic->value, &bufinfo, MP_BUFFER_READ);
// 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 (offset >= bufinfo.len) {
send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
return;
}
// uint16_t value_length = descriptor->valueSize();
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);
// if (offset >= value_length) {
// send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
// return;
// }
mp_buffer_info_t bufinfo;
mp_get_buffer(descriptor->value, &bufinfo, MP_BUFFER_READ);
// value_length = min(mtu - response_length, value_length - offset);
if (offset >= bufinfo.len) {
send_error(conn_handle, opcode, handle, BT_ATT_ERR_INVALID_OFFSET);
return;
}
// memcpy(&response[response_length], descriptor->value() + offset, value_length);
// response_length += value_length;
// }
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, response_length, response);
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;
// }
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;
}
// uint8_t value_length = dlen - sizeof(req->handle);
// uint8_t* value = &data[sizeof(req->handle)];
size_t value_length = dlen - sizeof(struct bt_att_write_req);
// BLELocalAttribute* attribute = GATT.attribute(req->handle - 1);
mp_buffer_info_t bufinfo;
bufinfo.buf = req->value;
bufinfo.len = value_length;
// if (attribute->type() == BLE_TYPE_CHARACTERISTIC) {
// BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
mp_obj_t attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, req->handle);
// 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;
// }
if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
// 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;
// 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;
}
// // 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;
// }
common_hal_bleio_characteristic_set_value(characteristic, &bufinfo);
// // get the previous handle, should be the characteristic for the CCCD
// attribute = GATT.attribute(handle - 2);
} 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;
}
// 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;
// }
// BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
// 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;
// There's no data in the response. We just indicate the write happened.
struct bt_att_hdr rsp = {
.code = BT_ATT_OP_READ_REQ,
};
response[0] = BT_ATT_OP_WRITE_RSP;
response_length = 1;
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:

View File

@ -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);