This commit is contained in:
Dan Halbert 2020-07-28 11:56:00 -04:00
parent f6f45c82a1
commit 9572f306d3
5 changed files with 206 additions and 167 deletions

View File

@ -238,6 +238,9 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
self->extended_advertising = false;
self->circuitpython_advertising = false;
self->advertising_timeout_msecs = 0;
// Reset list of known attributes.
self->attributes = mp_obj_new_list(0, NULL);
}
bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) {

View File

@ -67,6 +67,9 @@ typedef struct _bleio_adapter_obj_t {
uint16_t max_adv_data_len;
uint8_t features[8]; // Supported BLE features.
// All the local attributes for this device. The index into the list
// corresponds to the handle.
mp_obj_list_t *attributes;
} bleio_adapter_obj_t;
void bleio_adapter_background(bleio_adapter_obj_t* adapter);

View File

@ -40,24 +40,18 @@ uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uu
self->connection = NULL;
self->is_secondary = is_secondary;
//FIX
// ble_uuid_t nordic_uuid;
// bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nordic_uuid);
// uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
// if (is_secondary) {
// service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
// }
vm_used_ble = true;
//FIX return sd_ble_gatts_service_add(service_type, &nordic_uuid, &self->handle);
return 0;
uint32_t status;
self->handle = bleio_adapter_add_attribute(
is_secondary ? BLE_TYPE_SECONDARY_SERVICE : BLE_TYPE_PRIMARY_SERVICE,
uuid, &status);
return status;
}
void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary) {
//FIX check_nrf_error(_common_hal_bleio_service_construct(self, uuid, is_secondary,
// mp_obj_new_list(0, NULL)));
check_hci_error(_common_hal_bleio_service_construct(self, uuid, is_secondary,
mp_obj_new_list(0, NULL)));
}
void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection) {
@ -88,6 +82,30 @@ bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) {
void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
bleio_characteristic_obj_t *characteristic,
mp_buffer_info_t *initial_value_bufinfo) {
common_hal_bleio_adapter_obj
//FIX how it's done by ArduinoBLE when a service is added.
// uint16_t startHandle = attributeCount();
// for (unsigned int i = 0; i < service->characteristicCount(); i++) {
// BLELocalCharacteristic* characteristic = service->characteristic(i);
// characteristic->retain();
// _attributes.add(characteristic);
// characteristic->setHandle(attributeCount());
// // add the characteristic again to make space of the characteristic value handle
// _attributes.add(characteristic);
// for (unsigned int j = 0; j < characteristic->descriptorCount(); j++) {
// BLELocalDescriptor* descriptor = characteristic->descriptor(j);
// descriptor->retain();
// _attributes.add(descriptor);
// descriptor->setHandle(attributeCount());
// }
// }
service->setHandles(startHandle, attributeCount());
// 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,
@ -101,9 +119,6 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
// .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,

View File

@ -43,7 +43,7 @@ enum ble_attribute_type {
STATIC uint16_t max_mtu = BT_ATT_DEFAULT_LE_MTU; // 23
STATIC unsigned long timeout = 5000;
STATIC volatile bool cnf;
STATIC volatile bool confirm;
STATIC uint16_t long_write_handle = 0x0000;
STATIC uint8_t* long_write_value = NULL;
@ -75,7 +75,11 @@ STATIC void send_error(uint16_t conn_handle, uint8_t opcode, uint16_t handle, ui
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *) &rsp);
}
STATIC int send_req_wait_for_rsp(uint16_t conn_handle, int request_length, uint8_t* request_buffer, uint8_t response_buffer[]) {
STATIC void send_req(uint16_t conn_handle, size_t request_length, uint8_t* request_buffer) {
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, request_length, request_buffer);
}
STATIC int send_req_wait_for_rsp(uint16_t conn_handle, size_t request_length, uint8_t* request_buffer, uint8_t response_buffer[]) {
// We expect a particular kind of response after this request.
expected_rsp.conn_handle = conn_handle;
// The response opcode is the request opcode + 1.
@ -83,7 +87,7 @@ STATIC int send_req_wait_for_rsp(uint16_t conn_handle, int request_length, uint
expected_rsp.buffer = response_buffer;
expected_rsp.length = 0;
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, request_length, request_buffer);
send_req(conn_handle, request_length, request_buffer);
if (response_buffer == NULL) {
// not expecting a response.
@ -450,7 +454,7 @@ void att_add_connection(uint16_t handle, uint8_t role, bt_addr_le_t *peer_addr,
bleio_connections[peer_index].conn_handle = handle;
bleio_connections[peer_index].role = role;
bleio_connections[peer_index].mtu = 23;
bleio_connections[peer_index].mtu = BT_ATT_DEFAULT_LE_MTU;
memcpy(&bleio_connections[peer_index].addr, peer_addr, sizeof(bleio_connections[peer_index].addr));
//FIX if (event_handlers[BLEConnected]) {
@ -506,7 +510,7 @@ void att_remove_connection(uint16_t handle, uint8_t reason) {
bleio_connections[peer_index].conn_handle = 0xffff;
bleio_connections[peer_index].role = 0x00;
memset(&bleio_connections[peer_index].addr, 0x00, sizeof(bleio_connections[peer_index].addr));
bleio_connections[peer_index].mtu = 23;
bleio_connections[peer_index].mtu = BT_ATT_DEFAULT_LE_MTU;
//FIX if (bleio_connections[peer_index].device) {
//FIX delete bleio_connections[peer_index].device;
@ -569,7 +573,7 @@ uint16_t att_mtu(uint16_t handle) {
}
}
return 23;
return BT_ATT_DEFAULT_LE_MTU;
}
bool att_disconnect_all(void) {
@ -590,7 +594,7 @@ bool att_disconnect_all(void) {
bleio_connections[i].role = 0x00;
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 = 23;
bleio_connections[i].mtu = BT_ATT_DEFAULT_LE_MTU;
//FIX
// if (bleio_connections[i].device) {
@ -645,7 +649,7 @@ bool att_handle_notify(uint16_t handle, const uint8_t* value, int length) {
return (num_notifications > 0);
}
bool att_handle_ind(uint16_t handle, const uint8_t* value, int length) {
bool att_handle_indicate(uint16_t handle, const uint8_t* value, int length) {
int num_indications = 0;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
@ -666,11 +670,11 @@ bool att_handle_ind(uint16_t handle, const uint8_t* value, int length) {
memcpy(&indication[indication_length], value, length);
indication_length += length;
cnf = false;
confirm = false;
hci_send_acl_pkt(bleio_connections[i].conn_handle, BT_L2CAP_CID_ATT, indication_length, indication);
while (!cnf) {
while (!confirm) {
hci_poll_for_incoming_pkt();
if (!att_address_is_connected(&bleio_connections[i].addr)) {
@ -1214,7 +1218,7 @@ int att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t e
return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer);
}
void att_read_by_type_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
STATIC void process_read_by_type_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
if (dlen < 1) {
return; // invalid, drop
}
@ -1223,8 +1227,10 @@ void att_read_by_type_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
}
// Handles BT_ATT_OP_WRITE_REQ or BT_ATT_OP_WRITE_
STATIC void process_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t op, uint8_t dlen, uint8_t data[]) {
boolean with_response = (op == BT_ATT_OP_WRITE_REQ);
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;
bool with_response = (op == BT_ATT_OP_WRITE_REQ);
if (dlen < sizeof(struct bt_att_write_req)) {
if (with_response) {
@ -1233,24 +1239,23 @@ STATIC void process_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t op, u
return;
}
uint16_t handle = *(uint16_t*)data;
// if ((uint16_t)(handle - 1) > GATT.attributeCount()) {
//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(handle);
// uint8_t* value = &data[sizeof(handle)];
// uint8_t value_length = dlen - sizeof(req->handle);
// uint8_t* value = &data[sizeof(req->handle)];
// BLELocalAttribute* attribute = GATT.attribute(handle - 1);
// BLELocalAttribute* attribute = GATT.attribute(req->handle - 1);
// if (attribute->type() == BLE_TYPE_CHARACTERISTIC) {
// BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
// if (handle != characteristic->value_handle() ||
// if (req->handle != characteristic->value_handle() ||
// withResponse ? ((characteristic->properties() & BLEWrite) == 0) :
// ((characteristic->properties() & BLEWriteWithoutResponse) == 0)) {
// if (withResponse) {
@ -1301,7 +1306,7 @@ STATIC void process_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t op, u
// return;
// }
if (withResponse) {
if (with_response) {
uint8_t response[mtu];
uint16_t response_length;
@ -1320,88 +1325,85 @@ STATIC void process_write_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]
check_and_save_expected_rsp(conn_handle, BT_ATT_OP_WRITE_RSP, dlen, data);
}
STATIC void process_prep_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
struct __attribute__ ((packed)) PrepWriteReq {
uint16_t handle;
uint16_t offset;
} *prepWriteReq = (PrepWriteReq*)data;
STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
//FIX struct bt_att_prepare_write_req *req = (struct bt_att_prepare_write_req *) data;
if (dlen < sizeof(PrepWriteReq)) {
send_error(conn_handle, BT_ATT_OP_PREP_WRITE_REQ, 0x0000, BT_ATT_ERR_INVALID_PDU);
if (dlen < sizeof(struct bt_att_prepare_write_req)) {
send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, 0x0000, BT_ATT_ERR_INVALID_PDU);
return;
}
uint16_t handle = prepWriteReq->handle;
uint16_t offset = prepWriteReq->offset;
// uint16_t handle = req->handle;
// uint16_t offset = req->offset;
if ((uint16_t)(handle - 1) > GATT.attributeCount()) {
send_error(conn_handle, BT_ATT_OP_PREP_WRITE_REQ, handle, BT_ATT_ERR_ATTR_NOT_FOUND);
return;
}
// if ((uint16_t)(handle - 1) > GATT.attributeCount()) {
// send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTR_NOT_FOUND);
// return;
// }
BLELocalAttribute* attribute = GATT.attribute(handle - 1);
// BLELocalAttribute* attribute = GATT.attribute(handle - 1);
if (attribute->type() != BLE_TYPE_CHARACTERISTIC) {
send_error(conn_handle, BT_ATT_OP_PREP_WRITE_REQ, handle, BT_ATT_ERR_ATTR_NOT_LONG);
return;
}
// if (attribute->type() != BLE_TYPE_CHARACTERISTIC) {
// send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTR_NOT_LONG);
// return;
// }
BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
// BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
if (handle != characteristic->value_handle()) {
send_error(conn_handle, BT_ATT_OP_PREP_WRITE_REQ, handle, BT_ATT_ERR_ATTR_NOT_LONG);
return;
}
// if (handle != characteristic->value_handle()) {
// send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTR_NOT_LONG);
// return;
// }
if ((characteristic->properties() & BLEWrqite) == 0) {
send_error(conn_handle, BT_ATT_OP_PREP_WRITE_REQ, handle, BT_ATT_ERR_WRITE_NOT_PERM);
return;
}
// if ((characteristic->properties() & BLEWrqite) == 0) {
// send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_WRITE_NOT_PERM);
// return;
// }
if (long_write_handle == 0) {
int valueSize = characteristic->valueSize();
// if (long_write_handle == 0) {
// int valueSize = characteristic->valueSize();
long_write_value = (uint8_t*)realloc(long_write_value, valueSize);
long_write_value_length = 0;
long_write_handle = handle;
// long_write_value = (uint8_t*)realloc(long_write_value, valueSize);
// long_write_value_length = 0;
// long_write_handle = handle;
memset(long_write_value, 0x00, valueSize);
} else if (long_write_handle != handle) {
send_error(conn_handle, BT_ATT_OP_PREP_WRITE_REQ, handle, BT_ATT_ERR_UNLIKELY);
return;
}
// memset(long_write_value, 0x00, valueSize);
// } else if (long_write_handle != handle) {
// send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_UNLIKELY);
// return;
// }
uint8_t value_length = dlen - sizeof(PrepWriteReq);
uint8_t* value = &data[sizeof(PrepWriteReq)];
// uint8_t value_length = dlen - sizeof(struct bt_att_prepare_write_req);
// uint8_t* value = &data[sizeof(struct bt_att_prepare_write_req)];
if ((offset != long_write_value_length) || ((offset + value_length) > (uint16_t)characteristic->valueSize())) {
send_error(conn_handle, BT_ATT_OP_PREP_WRITE_REQ, handle, BT_ATT_ERR_INVALID_OFFSET);
return;
}
// if ((offset != long_write_value_length) || ((offset + value_length) > (uint16_t)characteristic->valueSize())) {
// send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_INVALID_OFFSET);
// return;
// }
memcpy(long_write_value + offset, value, value_length);
long_write_value_length += value_length;
// memcpy(long_write_value + offset, value, value_length);
// long_write_value_length += value_length;
uint8_t response[mtu];
uint16_t response_length;
// uint8_t response[mtu];
// uint16_t response_length;
response[0] = BT_ATT_OP_PREP_WRITE_RSP;
memcpy(&response[1], data, dlen);
response_length = dlen + 1;
// response[0] = BT_ATT_OP_PREP_WRITE_RSP;
// memcpy(&response[1], data, dlen);
// response_length = dlen + 1;
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
// hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
}
STATIC void process_exec_write_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
if (dlen != sizeof(uint8_t)) {
struct bt_att_exec_write_req *req = (struct bt_att_exec_write_req *) data;
if (dlen != sizeof(struct bt_att_exec_write_req)) {
send_error(conn_handle, BT_ATT_OP_EXEC_WRITE_REQ, 0x0000, BT_ATT_ERR_INVALID_PDU);
return;
}
uint8_t flag = data[0];
if (long_write_handle && (flag & 0x01)) {
BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)GATT.attribute(long_write_handle - 1);
if (long_write_handle && (req->flags & 0x01)) {
//FIX BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)GATT.attribute(long_write_handle - 1);
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
if (bleio_connections[i].conn_handle == conn_handle) {
@ -1423,107 +1425,123 @@ 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_ind(uint16_t conn_handle, uint8_t opcode, uint8_t dlen, uint8_t data[]) {
STATIC void process_handle_notify_or_indicate(uint16_t conn_handle, uint8_t opcode, uint8_t dlen, uint8_t data[]) {
if (dlen < 2) {
return; // drop
}
struct __attribute__ ((packed)) _handleNotifyOrInd {
uint16_t handle;
} *handleNotifyOrInd = (_handleNotifyOrInd*)data;
// struct bt_att_notify and bt_att_indicate are identical.
//FIXunused struct bt_att_notify *req = (struct bt_att_notify *) data;
uint8_t handle = handleNotifyOrInd->handle;
//FIXunused uint8_t handle = req->handle;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
if (bleio_connections[i].conn_handle != conn_handle) {
continue;
}
BLERemoteDevice* device = bleio_connections[i].device;
//FIX BLERemoteDevice* device = bleio_connections[i].device;
if (!device) {
break;
}
// if (!device) {
// break;
// }
int serviceCount = device->serviceCount();
// int serviceCount = device->serviceCount();
for (size_t i = 0; i < serviceCount; i++) {
BLERemoteService* s = device->service(i);
// for (size_t i = 0; i < serviceCount; i++) {
// BLERemoteService* s = device->service(i);
if (s->start_handle() < handle && s->end_handle() >= handle) {
int characteristicCount = s->characteristicCount();
// if (s->start_handle() < handle && s->end_handle() >= handle) {
// int characteristicCount = s->characteristicCount();
for (int j = 0; j < characteristicCount; j++) {
BLERemoteCharacteristic* c = s->characteristic(j);
// for (int j = 0; j < characteristicCount; j++) {
// BLERemoteCharacteristic* c = s->characteristic(j);
if (c->value_handle() == handle) {
//FIX c->writeValue(BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address), &data[2], dlen - 2);
}
}
// if (c->value_handle() == handle) {
// //FIX c->writeValue(BLEDevice(bleio_connections[i].address_type, bleio_connections[i].address), &data[2], dlen - 2);
// }
// }
break;
}
}
// break;
// }
// }
}
if (opcode == BT_ATT_OP_HANDLE_IND) {
// send CNF for IND
if (opcode == BT_ATT_OP_INDICATE) {
// send CONFIRM for INDICATE
uint8_t cnf = BT_ATT_OP_HANDLE_CNF;
uint8_t op_confirm = BT_ATT_OP_CONFIRM;
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(cnf), &cnf);
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(op_confirm), &op_confirm);
}
}
STATIC void process_handle_cnf(uint16_t /*conn_handle*/, uint8_t /*dlen*/, uint8_t /*data*/[]) {
cnf = true;
STATIC void process_handle_confirm(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
(void) conn_handle;
(void) dlen;
(void) data;
confirm = true;
}
bool att_exchange_mtu(uint16_t conn_handle) {
uint8_t response_buffer[max_mtu];
struct bt_att_exchange_mtu_req req;
req->mtu = max_mtu;
return send_req_wait_for_rsp(conn_handle, BT_ATT_OP_MTU_REQ, &req, sizeof(req), response_buffer);
struct bt_att_exchange_mtu_req req = {
.mtu = max_mtu,
};
return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer);
}
void att_set_event_handler(BLEDeviceEvent event, BLEDeviceEventHandler event_handler) {
if (event < (sizeof(event_handlers) / (sizeof(event_handlers[0])))) {
event_handlers[event] = event_handler;
}
}
//FIX void att_set_event_handler(BLEDeviceEvent event, BLEDeviceEventHandler event_handler) {
// if (event < (sizeof(event_handlers) / (sizeof(event_handlers[0])))) {
// event_handlers[event] = event_handler;
// }
// }
int att_read_req(uint16_t conn_handle, uint16_t handle, uint8_t response_buffer[]) {
struct __attribute__ ((packed)) {
uint8_t op;
uint16_t handle;
} read_req = { BT_ATT_OP_READ_REQ, handle };
struct __packed {
struct bt_att_hdr h;
struct bt_att_read_req r;
} req = { {
.code = BT_ATT_OP_READ_REQ,
}, {
.handle = handle,
}
};
return send_req_wait_for_rsp(conn_handle, &read_req, sizeof(read_req), response_buffer);
return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer);
}
int att_write_req(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len, uint8_t response_buffer[]) {
struct __attribute__ ((packed)) {
uint8_t op;
uint16_t handle;
uint8_t data[255];
} write_req;
struct __packed {
struct bt_att_hdr h;
struct bt_att_write_req r;
} req = { {
.code = BT_ATT_OP_WRITE_REQ,
}, {
.handle = handle,
}
};
memcpy(req.r.value, data, data_len);
write_req.opcode = BT_ATT_OP_WRITE_REQ;
write_req.handle = handle;
memcpy(write_req.data, data, data_len);
return send_req_wait_for_rsp(conn_handle, &write_req, 3 + data_len, response_buffer);
return send_req_wait_for_rsp(conn_handle, sizeof(req) + data_len, (uint8_t *) &req, response_buffer);
}
void att_write_cmd(uint16_t conn_handle, uint16_t handle, const uint8_t* data, uint8_t data_len) {
struct bt_att_write_cmd req = {
.handle = handle,
struct __packed {
struct bt_att_hdr h;
struct bt_att_write_cmd r;
} req = { {
.code = BT_ATT_OP_WRITE_CMD,
}, {
.handle = handle,
}
};
memcpy(req.value, data, data_len);
memcpy(req.r.value, data, data_len);
send_req_wait_for_rsp(conn_handle, &req, data_len + sizeof(req), NULL);
return send_req(conn_handle, sizeof(req) + data_len, (uint8_t *) &req);
}
void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
@ -1534,7 +1552,7 @@ void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
dlen--;
data++;
uint16_t mtu = this->mtu(conn_handle);
uint16_t mtu = att_mtu(conn_handle);
switch (opcode) {
case BT_ATT_OP_ERROR_RSP:
@ -1557,24 +1575,24 @@ void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
process_find_info_rsp(conn_handle, dlen, data);
break;
case BT_ATT_OP_FIND_BY_TYPE_REQ:
case BT_ATT_OP_FIND_TYPE_REQ:
process_find_by_type_req(conn_handle, mtu, dlen, data);
break;
case BT_ATT_OP_READ_BY_TYPE_REQ:
case BT_ATT_OP_READ_TYPE_REQ:
process_read_by_type_req(conn_handle, mtu, dlen, data);
break;
case BT_ATT_OP_READ_BY_TYPE_RSP:
case BT_ATT_OP_READ_TYPE_RSP:
process_read_by_type_rsp(conn_handle, dlen, data);
break;
case BT_ATT_OP_READ_BY_GROUP_REQ:
att_read_by_group_req(conn_handle, mtu, dlen, data);
case BT_ATT_OP_READ_GROUP_REQ:
process_read_by_group_req(conn_handle, mtu, dlen, data);
break;
case BT_ATT_OP_READ_BY_GROUP_RSP:
prcoess_read_by_group_rsp(conn_handle, dlen, data);
case BT_ATT_OP_READ_GROUP_RSP:
process_read_by_group_rsp(conn_handle, dlen, data);
break;
case BT_ATT_OP_READ_REQ:
@ -1595,27 +1613,27 @@ void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
process_write_rsp(conn_handle, dlen, data);
break;
case BT_ATT_OP_PREP_WRITE_REQ:
process_prep_write_req(conn_handle, mtu, dlen, data);
case BT_ATT_OP_PREPARE_WRITE_REQ:
process_prepare_write_req(conn_handle, mtu, dlen, data);
break;
case BT_ATT_OP_EXEC_WRITE_REQ:
process_exec_write_req(conn_handle, mtu, dlen, data);
break;
case BT_ATT_OP_HANDLE_NOTIFY:
case BT_ATT_OP_HANDLE_IND:
process_handle_notify_or_ind(conn_handle, opcode, dlen, data);
case BT_ATT_OP_NOTIFY:
case BT_ATT_OP_INDICATE:
process_handle_notify_or_indicate(conn_handle, opcode, dlen, data);
break;
case BT_ATT_OP_HANDLE_CNF:
process_handle_cnf(conn_handle, dlen, data);
case BT_ATT_OP_CONFIRM:
process_handle_confirm(conn_handle, dlen, data);
break;
case BT_ATT_OP_READ_MULTI_REQ:
case BT_ATT_OP_READ_MULT_REQ:
case BT_ATT_OP_SIGNED_WRITE_CMD:
default:
send_error(conn_handle, opcode, 0x00, BT_ATT_ERR_REQ_NOT_SUPP);
send_error(conn_handle, opcode, 0x00, BT_ATT_ERR_NOT_SUPPORTED);
break;
}
}

View File

@ -39,7 +39,7 @@ bool att_disconnect_all(void);
bool att_disconnect_from_address(bt_addr_le_t *addr);
bool att_discover_attributes(bt_addr_le_t *addr, const char* service_uuid_filter);
bool att_exchange_mtu(uint16_t conn_handle);
bool att_handle_ind(uint16_t handle, const uint8_t* value, int length);
bool att_handle_indicate(uint16_t handle, const uint8_t* value, int length);
bool att_handle_is_connected(uint16_t handle);
bool att_handle_notify(uint16_t handle, const uint8_t* value, int length);
bool att_is_connected(void);