discovery of Nordic UART service working
This commit is contained in:
parent
ac95106b88
commit
0f4b969d62
@ -24,55 +24,26 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/_bleio/Attribute.h"
|
||||
#include "shared-bindings/_bleio/Characteristic.h"
|
||||
#include "shared-bindings/_bleio/Descriptor.h"
|
||||
#include "shared-bindings/_bleio/Service.h"
|
||||
|
||||
// Return the type of the attribute.
|
||||
ble_attribute_type_uuid bleio_attribute_type_uuid(mp_obj_t *attribute) {
|
||||
|
||||
bleio_uuid_obj_t *bleio_attribute_get_uuid(mp_obj_t *attribute) {
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
|
||||
return BLE_TYPE_CHARACTERISTIC;
|
||||
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute);
|
||||
return characteristic->uuid;
|
||||
}
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_descriptor_type)) {
|
||||
return BLE_TYPE_DESCRIPTOR;
|
||||
bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute);
|
||||
return descriptor->uuid;
|
||||
}
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) {
|
||||
bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute);
|
||||
return service->is_secondary ? BLE_TYPE_SECONDARY_SERVICE : BLE_TYPE_PRIMARY_SERVICE;
|
||||
return service->uuid;
|
||||
}
|
||||
return BLE_TYPE_UNKNOWN;
|
||||
mp_raise_RuntimeError(translate("Invalid BLE attribute"));
|
||||
}
|
||||
|
||||
// Convert a _bleio security mode to a ble_gap_conn_sec_mode_t setting.
|
||||
// void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode) {
|
||||
// switch (security_mode) {
|
||||
// case SECURITY_MODE_NO_ACCESS:
|
||||
// BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(perm);
|
||||
// break;
|
||||
|
||||
// case SECURITY_MODE_OPEN:
|
||||
// BLE_GAP_CONN_SEC_MODE_SET_OPEN(perm);
|
||||
// break;
|
||||
|
||||
// case SECURITY_MODE_ENC_NO_MITM:
|
||||
// BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(perm);
|
||||
// break;
|
||||
|
||||
// case SECURITY_MODE_ENC_WITH_MITM:
|
||||
// BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(perm);
|
||||
// break;
|
||||
|
||||
// case SECURITY_MODE_LESC_ENC_WITH_MITM:
|
||||
// BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(perm);
|
||||
// break;
|
||||
|
||||
// case SECURITY_MODE_SIGNED_NO_MITM:
|
||||
// BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(perm);
|
||||
// break;
|
||||
|
||||
// case SECURITY_MODE_SIGNED_WITH_MITM:
|
||||
// BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(perm);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
@ -28,23 +28,23 @@
|
||||
#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ATTRIBUTE_H
|
||||
|
||||
#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_PRIMARY_SERVICE = 0x2800,
|
||||
BLE_TYPE_SECONDARY_SERVICE = 0x2801,
|
||||
BLE_TYPE_CHARACTERISTIC = 0x2803,
|
||||
BLE_TYPE_DESCRIPTOR = 0x2900
|
||||
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;
|
||||
|
||||
// typedef struct
|
||||
// {
|
||||
// uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */
|
||||
// uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */
|
||||
|
||||
// } ble_gap_conn_sec_mode_t;
|
||||
|
||||
ble_attribute_type_uuid bleio_attribute_type_uuid(mp_obj_t *attribute);
|
||||
bleio_uuid_obj_t *bleio_attribute_get_uuid(mp_obj_t *attribute);
|
||||
|
||||
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_ATTRIBUTE_H
|
||||
|
@ -149,7 +149,7 @@ void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *
|
||||
}
|
||||
|
||||
descriptor->handle = bleio_adapter_add_attribute(&common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(descriptor));
|
||||
// Include this desriptor in the service handles range.
|
||||
// Include this descriptor in the service handle's range.
|
||||
self->service->end_handle = descriptor->handle;
|
||||
|
||||
// Link together all the descriptors for this characteristic.
|
||||
|
@ -99,20 +99,30 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
|
||||
self->end_handle = characteristic->handle;
|
||||
|
||||
if (characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) {
|
||||
// We need a CCCD.
|
||||
// We need a CCCD if this characteristic is doing notify or indicate.
|
||||
bleio_descriptor_obj_t *cccd = m_new_obj(bleio_descriptor_obj_t);
|
||||
cccd->base.type = &bleio_descriptor_type;
|
||||
cccd->read_perm = SECURITY_MODE_OPEN;
|
||||
// Make CCCD write permission match characteristic read permission.
|
||||
cccd->write_perm = characteristic->read_perm;
|
||||
|
||||
const uint16_t cccd_handle = bleio_adapter_add_attribute(
|
||||
&common_hal_bleio_adapter_obj, MP_OBJ_TO_PTR(cccd));
|
||||
cccd->handle = cccd_handle;
|
||||
characteristic->cccd_handle = cccd_handle;
|
||||
uint16_t zero = 0;
|
||||
mp_buffer_info_t zero_cccd = {
|
||||
.buf = &zero,
|
||||
.len = sizeof(zero),
|
||||
};
|
||||
|
||||
common_hal_bleio_descriptor_construct(
|
||||
cccd,
|
||||
characteristic,
|
||||
&cccd_uuid, // 0x2902
|
||||
SECURITY_MODE_OPEN, // CCCD read perm
|
||||
characteristic->read_perm, // Make CCCD write perm match characteristic read perm.
|
||||
2, // 2 bytes
|
||||
true, // fixed length
|
||||
&zero_cccd // Initial value is 0.
|
||||
);
|
||||
|
||||
// Adds CCCD to attribute table, and also extends self->end_handle to include the CCCD.
|
||||
common_hal_bleio_characteristic_add_descriptor(characteristic, cccd);
|
||||
|
||||
self->end_handle = cccd_handle;
|
||||
characteristic->cccd_handle = cccd->handle;
|
||||
}
|
||||
|
||||
// #if CIRCUITPY_VERBOSE_BLE
|
||||
|
@ -36,7 +36,7 @@
|
||||
// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
|
||||
// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
|
||||
// the 16-bit part goes. Those 16 bits are passed in uuid16.
|
||||
void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[16]) {
|
||||
void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[16]) {
|
||||
self->size = uuid128 == NULL ? 16 : 128;
|
||||
self->uuid16 = uuid16;
|
||||
if (uuid128) {
|
||||
|
@ -38,6 +38,9 @@
|
||||
#include "shared-bindings/_bleio/UUID.h"
|
||||
#include "supervisor/shared/bluetooth.h"
|
||||
|
||||
// UUID shared by all cccd's.
|
||||
bleio_uuid_obj_t cccd_uuid;
|
||||
|
||||
bool vm_used_ble;
|
||||
|
||||
void check_hci_error(hci_result_t result) {
|
||||
@ -112,6 +115,10 @@ void check_hci_error(hci_result_t result) {
|
||||
|
||||
// Turn off BLE on a reset or reload.
|
||||
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);
|
||||
|
||||
bleio_hci_reset();
|
||||
|
||||
if (!common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) {
|
||||
@ -123,6 +130,7 @@ void bleio_reset() {
|
||||
return;
|
||||
}
|
||||
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
|
||||
|
||||
//FIX bonding_reset();
|
||||
supervisor_start_bluetooth();
|
||||
}
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "shared-bindings/_bleio/UUID.h"
|
||||
|
||||
#include "hci.h"
|
||||
|
||||
void bleio_background(void);
|
||||
@ -59,4 +61,7 @@ void check_sec_status(uint8_t sec_status);
|
||||
// Track if the user code modified the BLE state to know if we need to undo it on reload.
|
||||
extern bool vm_used_ble;
|
||||
|
||||
// UUID shared by all CCCD's.
|
||||
extern bleio_uuid_obj_t cccd_uuid;
|
||||
|
||||
#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "common-hal/_bleio/Attribute.h"
|
||||
#include "shared-bindings/_bleio/__init__.h"
|
||||
#include "shared-bindings/_bleio/Characteristic.h"
|
||||
#include "shared-bindings/_bleio/Descriptor.h"
|
||||
#include "shared-bindings/_bleio/Service.h"
|
||||
#include "shared-bindings/_bleio/UUID.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
@ -54,8 +56,63 @@ STATIC struct {
|
||||
uint8_t length; // Length of response packet.
|
||||
} expected_rsp;
|
||||
|
||||
// A characteristic declaration has this data, in this order:
|
||||
// See Bluetooth v5.1 spec, section 3.3.1 Characteristic declaration.
|
||||
typedef struct __packed {
|
||||
uint8_t properties;
|
||||
uint16_t value_handle;
|
||||
uint8_t uuid[0]; // 2 or 16 bytes
|
||||
} characteristic_declaration_t;
|
||||
|
||||
//FIX BLEDeviceEventHandler event_handlers[2];
|
||||
|
||||
STATIC uint8_t bleio_properties_to_ble_spec_properties(uint8_t bleio_properties) {
|
||||
uint8_t ble_spec_properties = 0;
|
||||
if (bleio_properties & CHAR_PROP_BROADCAST) {
|
||||
ble_spec_properties |= BT_GATT_CHRC_BROADCAST;
|
||||
}
|
||||
if (bleio_properties & CHAR_PROP_INDICATE) {
|
||||
ble_spec_properties |= BT_GATT_CHRC_INDICATE;
|
||||
}
|
||||
if (bleio_properties & CHAR_PROP_NOTIFY) {
|
||||
ble_spec_properties |= BT_GATT_CHRC_NOTIFY;
|
||||
}
|
||||
if (bleio_properties & CHAR_PROP_READ) {
|
||||
ble_spec_properties |= BT_GATT_CHRC_READ;
|
||||
}
|
||||
if (bleio_properties & CHAR_PROP_WRITE) {
|
||||
ble_spec_properties |= BT_GATT_CHRC_WRITE;
|
||||
}
|
||||
if (bleio_properties & CHAR_PROP_WRITE_NO_RESPONSE) {
|
||||
ble_spec_properties |= BT_GATT_CHRC_WRITE_WITHOUT_RESP;
|
||||
}
|
||||
|
||||
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;
|
||||
// }
|
||||
|
||||
// return bleio_properties;
|
||||
// }
|
||||
|
||||
STATIC void send_error(uint16_t conn_handle, uint8_t opcode, uint16_t handle, uint8_t code) {
|
||||
struct __packed {
|
||||
@ -187,13 +244,13 @@ 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_PRIMARY_SERVICE, response_buffer);
|
||||
// int respLength = readByGroupReq(conn_handle, reqStart_handle, reqEnd_handle, BLE_TYPE_SERVICE_PRIMARY, response_buffer);
|
||||
|
||||
// if (respLength == 0) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// if (response_buffer[0] == BT_ATT_OP_READ_BY_GROUP_RSP) {
|
||||
// if (response_buffer[0] == BT_ATT_OP_READ_GROUP_RSP) {
|
||||
// uint16_t lengthPerService = response_buffer[1];
|
||||
// uint8_t uuidLen = lengthPerService - 4;
|
||||
|
||||
@ -254,7 +311,7 @@ bool att_disconnect_from_address(bt_addr_le_t *addr) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// if (response_buffer[0] == BT_ATT_OP_READ_BY_TYPE_RSP) {
|
||||
// if (response_buffer[0] == BT_ATT_OP_READ_TYPE_RSP) {
|
||||
// uint16_t lengthPerCharacteristic = response_buffer[1];
|
||||
// uint8_t uuidLen = lengthPerCharacteristic - 5;
|
||||
|
||||
@ -759,56 +816,88 @@ STATIC void process_find_info_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
|
||||
return;
|
||||
}
|
||||
|
||||
//FIX
|
||||
// uint8_t response[mtu];
|
||||
// uint16_t response_length;
|
||||
typedef struct __packed {
|
||||
struct bt_att_hdr h;
|
||||
struct bt_att_find_info_rsp r;
|
||||
} rsp_t;
|
||||
|
||||
// response[0] = BT_ATT_OP_FIND_INFO_RSP;
|
||||
// response[1] = 0x00;
|
||||
// response_length = 2;
|
||||
uint8_t rsp_bytes[mtu];
|
||||
rsp_t *rsp = (rsp_t *) rsp_bytes;
|
||||
rsp->h.code = BT_ATT_OP_FIND_INFO_RSP;
|
||||
|
||||
// for (uint16_t i = (req->start_handle - 1); i < GATT.attributeCount() && i <= (req->end_handle - 1); i++) {
|
||||
// BLELocalAttribute* attribute = GATT.attribute(i);
|
||||
// uint16_t handle = (i + 1);
|
||||
// bool is_value_handle = (attribute->type() == BLE_TYPE_CHARACTERISTIC) && (((BLELocalCharacteristic*)attribute)->valueHandle() == handle);
|
||||
// int uuid_len = is_value_handle ? 2 : attribute->uuid_length();
|
||||
// size_t info_type = (uuidLen == 2) ? 0x01 : 0x02;
|
||||
// Keeps track of total length of the response.
|
||||
size_t rsp_length = sizeof(rsp_t);
|
||||
|
||||
// if (response[1] == 0) {
|
||||
// response[1] = info_type;
|
||||
// }
|
||||
bool no_data = true;
|
||||
|
||||
// if (response[1] != info_type) {
|
||||
// // different type
|
||||
// break;
|
||||
// }
|
||||
// All the data chunks must have uuid's that are the same size.
|
||||
// Keep track of the first one to make sure.
|
||||
size_t sizeof_first_uuid = 0;
|
||||
|
||||
// // add the handle
|
||||
// memcpy(&response[response_length], &handle, sizeof(handle));
|
||||
// response_length += sizeof(handle);
|
||||
const uint16_t max_attribute_handle = bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj);
|
||||
for (uint16_t handle = req->start_handle;
|
||||
handle <= max_attribute_handle && handle <= req->end_handle;
|
||||
handle++) {
|
||||
|
||||
// if (is_value_handle || attribute->type() == BLE_TYPE_DESCRIPTOR) {
|
||||
// // add the UUID
|
||||
// memcpy(&response[response_length], attribute->uuid_data(), uuid_len);
|
||||
// response_length += uuidLen;
|
||||
// } else {
|
||||
// // add the type
|
||||
// uint16_t type = attribute->type();
|
||||
mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
|
||||
|
||||
// memcpy(&response[response_length], &type, sizeof(type));
|
||||
// response_length += sizeof(type);
|
||||
// }
|
||||
// Fetch the uuid for the given attribute, which might be a characteristic or a descriptor.
|
||||
bleio_uuid_obj_t *uuid;
|
||||
|
||||
// if ((response_length + (2 + uuidLen)) > mtu) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
|
||||
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
|
||||
if (characteristic->handle != handle) {
|
||||
// If the handles don't match, this is the characteristic definition attribute.
|
||||
// Skip it. We want the characteristic value attribute.
|
||||
continue;
|
||||
}
|
||||
uuid = characteristic->uuid;
|
||||
|
||||
// if (response_length == 2) {
|
||||
// send_error(conn_handle, BT_ATT_OP_FIND_INFO_REQ, findInfoReq->start_handle, BT_ATT_ERR_ATTR_NOT_FOUND);
|
||||
// } else {
|
||||
// hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
|
||||
// }
|
||||
} else {
|
||||
uuid = bleio_attribute_get_uuid(attribute_obj);
|
||||
}
|
||||
|
||||
const uint32_t sizeof_uuid = common_hal_bleio_uuid_get_size(uuid) / 8;
|
||||
if (sizeof_first_uuid == 0) {
|
||||
sizeof_first_uuid = sizeof_uuid;
|
||||
// All the uuids in the response will be the same size.
|
||||
rsp->r.format = sizeof_uuid == 2 ? BT_ATT_INFO_16 : BT_ATT_INFO_128;
|
||||
}
|
||||
|
||||
if (sizeof_uuid != sizeof_first_uuid) {
|
||||
// Previous UUID was a different size. We can't mix sizes.
|
||||
// Stop and send what we have so far.
|
||||
break;
|
||||
}
|
||||
|
||||
if (rsp_length + sizeof_uuid > mtu) {
|
||||
// No remaining room in response for this uuid.
|
||||
break;
|
||||
}
|
||||
|
||||
if (sizeof_uuid == 2) {
|
||||
struct bt_att_info_16 *info_16 = (struct bt_att_info_16 *) &rsp_bytes[rsp_length];
|
||||
info_16->handle = handle;
|
||||
info_16->uuid = common_hal_bleio_uuid_get_uuid16(uuid);
|
||||
|
||||
rsp_length += sizeof(struct bt_att_info_16);
|
||||
} else {
|
||||
struct bt_att_info_128 *info_128 = (struct bt_att_info_128 *) &rsp_bytes[rsp_length];
|
||||
info_128->handle = handle;
|
||||
common_hal_bleio_uuid_get_uuid128(uuid, info_128->uuid);
|
||||
|
||||
rsp_length += sizeof(struct bt_att_info_128);
|
||||
}
|
||||
|
||||
no_data =false;
|
||||
} // end for
|
||||
|
||||
|
||||
if (no_data) {
|
||||
send_error(conn_handle, BT_ATT_OP_FIND_INFO_REQ, req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
|
||||
} else {
|
||||
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
int att_find_info_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, uint8_t response_buffer[]) {
|
||||
@ -834,7 +923,7 @@ STATIC void process_find_info_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t da
|
||||
check_and_save_expected_rsp(conn_handle, BT_ATT_OP_FIND_INFO_RSP, dlen, data);
|
||||
}
|
||||
|
||||
STATIC void process_find_by_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
|
||||
STATIC void process_find_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
|
||||
struct bt_att_find_type_req *req = (struct bt_att_find_type_req *) data;
|
||||
|
||||
if (dlen < sizeof(struct bt_att_find_type_req)) {
|
||||
@ -849,11 +938,11 @@ STATIC void process_find_by_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t
|
||||
response_length = 1;
|
||||
|
||||
//FIX
|
||||
// if (find_by_type_req->type == BLE_TYPE_PRIMARY_SERVICE) {
|
||||
// for (uint16_t i = (find_by_type_req->start_handle - 1); i < GATT.attributeCount() && i <= (find_by_type_req->end_handle - 1); i++) {
|
||||
// if (find_type_req->type == BLE_TYPE_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);
|
||||
|
||||
// if ((attribute->type() == find_by_type_req->type) && (attribute->uuidLength() == value_length) && memcmp(attribute->uuidData(), value, value_length) == 0) {
|
||||
// if ((attribute->type() == find_type_req->type) && (attribute->uuidLength() == value_length) && memcmp(attribute->uuidData(), value, value_length) == 0) {
|
||||
// BLELocalService* service = (BLELocalService*)attribute;
|
||||
|
||||
// // add the start handle
|
||||
@ -880,15 +969,15 @@ STATIC void process_find_by_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t
|
||||
}
|
||||
}
|
||||
|
||||
void process_read_by_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
|
||||
void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
|
||||
struct bt_att_read_group_req *req = (struct bt_att_read_group_req *) data;
|
||||
uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8);
|
||||
|
||||
// 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_PRIMARY_SERVICE &&
|
||||
type_uuid != BLE_TYPE_SECONDARY_SERVICE)) {
|
||||
(type_uuid != BLE_TYPE_SERVICE_PRIMARY &&
|
||||
type_uuid != BLE_TYPE_SERVICE_SECONDARY)) {
|
||||
send_error(conn_handle, BT_ATT_OP_READ_GROUP_REQ, req->start_handle, BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE);
|
||||
return;
|
||||
}
|
||||
@ -927,37 +1016,34 @@ void process_read_by_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen,
|
||||
}
|
||||
|
||||
mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
|
||||
if (type_uuid != bleio_attribute_type_uuid(attribute_obj)) {
|
||||
// Not a primary or secondary service.
|
||||
continue;
|
||||
if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_service_type)) {
|
||||
bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute_obj);
|
||||
|
||||
// Is this a 16-bit or a 128-bit uuid? It must match in size with any previous attribute
|
||||
// in this transmission.
|
||||
const uint32_t sizeof_service_uuid = common_hal_bleio_uuid_get_size(service->uuid) / 8;
|
||||
if (sizeof_first_service_uuid == 0) {
|
||||
sizeof_first_service_uuid = sizeof_service_uuid;
|
||||
data_length += sizeof_service_uuid;
|
||||
} else if (sizeof_first_service_uuid != sizeof_service_uuid) {
|
||||
// Mismatched sizes, which can't be in the same batch.
|
||||
// Transmit just what we have so far in this batch.
|
||||
break;
|
||||
}
|
||||
|
||||
// Pass the length of ONE bt_att_group_data chunk.
|
||||
// There may be multiple chunks in this transmission.
|
||||
rsp->r.len = data_length;
|
||||
|
||||
struct bt_att_group_data *group_data = (struct bt_att_group_data *) &rsp_bytes[rsp_length];
|
||||
|
||||
group_data->start_handle = service->start_handle;
|
||||
group_data->end_handle = service->end_handle;
|
||||
common_hal_bleio_uuid_pack_into(service->uuid, group_data->value);
|
||||
|
||||
rsp_length += data_length;
|
||||
no_data = false;
|
||||
}
|
||||
// Now we know it's a service.
|
||||
bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute_obj);
|
||||
|
||||
// Is this a 16-bit or a 128-bit uuid? It must match in size with any previous attribute
|
||||
// in this transmission.
|
||||
const uint32_t sizeof_service_uuid = common_hal_bleio_uuid_get_size(service->uuid) / 8;
|
||||
if (sizeof_first_service_uuid == 0) {
|
||||
sizeof_first_service_uuid = sizeof_service_uuid;
|
||||
data_length += sizeof_service_uuid;
|
||||
} else if (sizeof_first_service_uuid != sizeof_service_uuid) {
|
||||
// Mismatched sizes, which can't be in the same batch.
|
||||
// Transmit just what we have so far in this batch.
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Pass the length of ONE bt_att_group_data chunk. There may be multiple ones in this transmission.
|
||||
rsp->r.len = data_length;
|
||||
|
||||
struct bt_att_group_data *group_data = (struct bt_att_group_data *) &rsp_bytes[rsp_length];
|
||||
|
||||
group_data->start_handle = service->start_handle;
|
||||
group_data->end_handle = service->end_handle;
|
||||
common_hal_bleio_uuid_pack_into(service->uuid, group_data->value);
|
||||
|
||||
rsp_length += data_length;
|
||||
no_data = false;
|
||||
}
|
||||
|
||||
if (no_data) {
|
||||
@ -967,7 +1053,7 @@ void process_read_by_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen,
|
||||
}
|
||||
}
|
||||
|
||||
int att_read_by_group_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid, uint8_t response_buffer[]) {
|
||||
int att_read_group_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid, uint8_t response_buffer[]) {
|
||||
struct __packed {
|
||||
struct bt_att_hdr h;
|
||||
struct bt_att_read_group_req r;
|
||||
@ -985,7 +1071,7 @@ int att_read_by_group_req(uint16_t conn_handle, uint16_t start_handle, uint16_t
|
||||
return send_req_wait_for_rsp(conn_handle, sizeof(req), (uint8_t *) &req, response_buffer);
|
||||
}
|
||||
|
||||
STATIC void process_read_by_group_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
|
||||
STATIC void process_read_group_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
|
||||
if (dlen < 2) {
|
||||
return; // invalid, drop
|
||||
}
|
||||
@ -1040,7 +1126,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
|
||||
//FIX BLELocalAttribute* attribute = GATT.attribute(handle - 1);
|
||||
// enum BLEAttributeType attributeType = attribute->type();
|
||||
|
||||
// if (attributeType == BLE_TYPE_PRIMARY_SERVICE) {
|
||||
// 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;
|
||||
@ -1118,110 +1204,156 @@ STATIC void process_read_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[])
|
||||
check_and_save_expected_rsp(conn_handle, BT_ATT_OP_READ_RSP, dlen, data);
|
||||
}
|
||||
|
||||
STATIC void process_read_by_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
|
||||
STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, uint8_t data[]) {
|
||||
struct bt_att_read_type_req *req = (struct bt_att_read_type_req *) data;
|
||||
uint16_t type_uuid = req->uuid[0] | (req->uuid[1] << 8);
|
||||
|
||||
if (dlen != sizeof(struct bt_att_read_type_req)) {
|
||||
if (dlen != sizeof(struct bt_att_read_type_req) + sizeof(type_uuid)) {
|
||||
send_error(conn_handle, BT_ATT_OP_READ_TYPE_REQ, req->start_handle, BT_ATT_ERR_INVALID_PDU);
|
||||
return;
|
||||
}
|
||||
|
||||
// uint8_t response[mtu];
|
||||
// uint16_t response_length;
|
||||
typedef struct __packed {
|
||||
struct bt_att_hdr h;
|
||||
struct bt_att_read_type_rsp r;
|
||||
} rsp_t;
|
||||
|
||||
// response[0] = BT_ATT_OP_READ_TYPE_RSP;
|
||||
// response[1] = 0x00;
|
||||
// response_length = 2;
|
||||
uint8_t rsp_bytes[mtu];
|
||||
rsp_t *rsp = (rsp_t *) rsp_bytes;
|
||||
rsp->h.code = BT_ATT_OP_READ_TYPE_RSP;
|
||||
rsp->r.len = 0;
|
||||
|
||||
// for (uint16_t i = (req->start_handle - 1); i < GATT.attributeCount() && i <= (req->end_handle - 1); i++) {
|
||||
// BLELocalAttribute* attribute = GATT.attribute(i);
|
||||
// uint16_t handle = (i + 1);
|
||||
// Keeps track of total length of the response.
|
||||
size_t rsp_length = sizeof(rsp_t);
|
||||
|
||||
// if (attribute->type() == readByTypeReq->uuid) {
|
||||
// if (attribute->type() == BLE_TYPE_CHARACTERISTIC) {
|
||||
// BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
|
||||
bool no_data = true;
|
||||
|
||||
// if (characteristic->value_handle() == handle) {
|
||||
// // value handle, skip
|
||||
// continue;
|
||||
// }
|
||||
// All the data chunks must have uuid's that are the same size.
|
||||
// Keep track of the first one to make sure.
|
||||
size_t sizeof_first_uuid = 0;
|
||||
|
||||
// int uuidLen = attribute->uuidLength();
|
||||
// int typeSize = (uuidLen == 2) ? 7 : 21;
|
||||
// Size of a single bt_att_data chunk. Start with the initial size, and
|
||||
// add the uuid size and other data sizes in the loop below.
|
||||
size_t data_length = sizeof(struct bt_att_data);
|
||||
|
||||
// if (response[1] == 0) {
|
||||
// response[1] = typeSize;
|
||||
// }
|
||||
const uint16_t max_attribute_handle = bleio_adapter_max_attribute_handle(&common_hal_bleio_adapter_obj);
|
||||
for (uint16_t handle = req->start_handle;
|
||||
handle <= max_attribute_handle && handle <= req->end_handle;
|
||||
handle++) {
|
||||
|
||||
// if (response[1] != typeSize) {
|
||||
// // all done, wrong size
|
||||
// break;
|
||||
// }
|
||||
if (rsp_length + data_length > mtu) {
|
||||
// The next possible bt_att_data chunk won't fit. The response is full.
|
||||
break;
|
||||
}
|
||||
|
||||
// // add the handle
|
||||
// memcpy(&response[response_length], &handle, sizeof(handle));
|
||||
// response_length += sizeof(handle);
|
||||
mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
|
||||
|
||||
// // add the properties
|
||||
// response[response_length++] = characteristic->properties();
|
||||
if (type_uuid == BLE_TYPE_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);
|
||||
|
||||
// // add the value handle
|
||||
// uint16_t value_handle = (handle + 1);
|
||||
// memcpy(&response[response_length], &value_handle, sizeof(value_handle));
|
||||
// response_length += sizeof(value_handle);
|
||||
if (characteristic->handle == handle) {
|
||||
// If the characteristic's handle is this attribute's handle, skip it:
|
||||
// it's the attribute for characteristic value. We want to return the declaration
|
||||
// handle attribute instead. (It will probably get skipped below, by the
|
||||
// handle++).
|
||||
continue;
|
||||
}
|
||||
|
||||
// // add the UUID
|
||||
// memcpy(&response[response_length], characteristic->uuidData(), uuidLen);
|
||||
// response_length += uuidLen;
|
||||
// Is this a 16-bit or a 128-bit uuid? It must match in size with any previous attribute
|
||||
// in this transmission.
|
||||
const uint32_t sizeof_uuid = common_hal_bleio_uuid_get_size(characteristic->uuid) / 8;
|
||||
if (sizeof_first_uuid == 0) {
|
||||
sizeof_first_uuid = sizeof_uuid;
|
||||
data_length += sizeof_uuid;
|
||||
data_length += sizeof(characteristic_declaration_t);
|
||||
} else if (sizeof_first_uuid != sizeof_uuid) {
|
||||
// Mismatched sizes, which can't be in the same batch.
|
||||
// Transmit just what we have so far in this batch.
|
||||
break;
|
||||
}
|
||||
|
||||
// // skip the next handle, it's a value handle
|
||||
// i++;
|
||||
// Pass the length of ONE bt_att_data chunk.
|
||||
// There may be multiple chunks in this transmission.
|
||||
rsp->r.len = data_length;
|
||||
|
||||
// if ((response_length + typeSize) > mtu) {
|
||||
// break;
|
||||
// }
|
||||
// } else if (attribute->type() == 0x2902) {
|
||||
// BLELocalDescriptor* descriptor = (BLELocalDescriptor*)attribute;
|
||||
struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length];
|
||||
|
||||
// // add the handle
|
||||
// memcpy(&response[response_length], &handle, sizeof(handle));
|
||||
// response_length += sizeof(handle);
|
||||
att_data->handle = characteristic->decl_handle;
|
||||
|
||||
// // add the value
|
||||
// int valueSize = min((uint16_t)(mtu - response_length), (uint16_t)descriptor->valueSize());
|
||||
// memcpy(&response[response_length], descriptor->value(), valueSize);
|
||||
// response_length += valueSize;
|
||||
characteristic_declaration_t *char_decl = (characteristic_declaration_t *) att_data->value;
|
||||
|
||||
// response[1] = 2 + valueSize;
|
||||
// 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;
|
||||
common_hal_bleio_uuid_pack_into(characteristic->uuid, char_decl->uuid);
|
||||
|
||||
// break; // all done
|
||||
// }
|
||||
// } else if (attribute->type() == BLE_TYPE_CHARACTERISTIC && attribute->uuidLength() == 2 && memcmp(&readByTypeReq->uuid, attribute->uuidData(), 2) == 0) {
|
||||
// BLELocalCharacteristic* characteristic = (BLELocalCharacteristic*)attribute;
|
||||
// We know the next handle will be the characteristic value handle, so skip it.
|
||||
handle++;
|
||||
|
||||
// // add the handle
|
||||
// memcpy(&response[response_length], &handle, sizeof(handle));
|
||||
// response_length += sizeof(handle);
|
||||
rsp_length += data_length;
|
||||
no_data = false;
|
||||
|
||||
// // add the value
|
||||
// int value_length = min((uint16_t)(mtu - response_length), (uint16_t)characteristic->value_length());
|
||||
// memcpy(&response[response_length], characteristic->value(), value_length);
|
||||
// response_length += value_length;
|
||||
} 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) {
|
||||
|
||||
// response[1] = 2 + value_length;
|
||||
struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length];
|
||||
|
||||
// break; // all done
|
||||
// }
|
||||
// }
|
||||
att_data->handle = handle;
|
||||
|
||||
// if (response_length == 2) {
|
||||
// send_error(conn_handle, BT_ATT_OP_READ_BY_TYPE_REQ, readByTypeReq->start_handle, BT_ATT_ERR_ATTR_NOT_FOUND);
|
||||
// } else {
|
||||
// hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, response_length, response);
|
||||
// }
|
||||
mp_buffer_info_t bufinfo;
|
||||
if (!mp_get_buffer(descriptor->value, &bufinfo, MP_BUFFER_READ)) {
|
||||
break;
|
||||
}
|
||||
uint16_t value_size = MIN(mtu - rsp_length, bufinfo.len);
|
||||
memcpy(att_data->value, bufinfo.buf, value_size);
|
||||
rsp_length += value_size;
|
||||
|
||||
// Only return one descriptor value.
|
||||
no_data = false;
|
||||
break;
|
||||
}
|
||||
|
||||
} 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) {
|
||||
|
||||
struct bt_att_data *att_data = (struct bt_att_data *) &rsp_bytes[rsp_length];
|
||||
|
||||
att_data->handle = handle;
|
||||
|
||||
mp_buffer_info_t bufinfo;
|
||||
if (!mp_get_buffer(characteristic->value, &bufinfo, MP_BUFFER_READ)) {
|
||||
// This shouldn't happen. There should be a buf in characteristic->value.
|
||||
break;
|
||||
}
|
||||
uint16_t value_size = MIN(mtu - rsp_length, bufinfo.len);
|
||||
memcpy(att_data->value, bufinfo.buf, value_size);
|
||||
rsp_length += value_size;
|
||||
|
||||
// Only return one characteristic value.
|
||||
no_data = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // end for loop
|
||||
|
||||
if (no_data) {
|
||||
send_error(conn_handle, BT_ATT_OP_READ_TYPE_REQ,
|
||||
req->start_handle, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
|
||||
} else {
|
||||
hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, rsp_length, rsp_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
int att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, uint16_t type, uint8_t response_buffer[]) {
|
||||
int att_read_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, uint16_t type, uint8_t response_buffer[]) {
|
||||
struct __packed {
|
||||
struct bt_att_hdr h;
|
||||
struct bt_att_read_type_req r;
|
||||
@ -1238,7 +1370,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);
|
||||
}
|
||||
|
||||
STATIC void process_read_by_type_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
|
||||
STATIC void process_read_type_rsp(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
|
||||
if (dlen < 1) {
|
||||
return; // invalid, drop
|
||||
}
|
||||
@ -1597,23 +1729,23 @@ void att_process_data(uint16_t conn_handle, uint8_t dlen, uint8_t data[]) {
|
||||
break;
|
||||
|
||||
case BT_ATT_OP_FIND_TYPE_REQ:
|
||||
process_find_by_type_req(conn_handle, mtu, dlen, data);
|
||||
process_find_type_req(conn_handle, mtu, dlen, data);
|
||||
break;
|
||||
|
||||
case BT_ATT_OP_READ_TYPE_REQ:
|
||||
process_read_by_type_req(conn_handle, mtu, dlen, data);
|
||||
process_read_type_req(conn_handle, mtu, dlen, data);
|
||||
break;
|
||||
|
||||
case BT_ATT_OP_READ_TYPE_RSP:
|
||||
process_read_by_type_rsp(conn_handle, dlen, data);
|
||||
process_read_type_rsp(conn_handle, dlen, data);
|
||||
break;
|
||||
|
||||
case BT_ATT_OP_READ_GROUP_REQ:
|
||||
process_read_by_group_req(conn_handle, mtu, dlen, data);
|
||||
process_read_group_req(conn_handle, mtu, dlen, data);
|
||||
break;
|
||||
|
||||
case BT_ATT_OP_READ_GROUP_RSP:
|
||||
process_read_by_group_rsp(conn_handle, dlen, data);
|
||||
process_read_group_rsp(conn_handle, dlen, data);
|
||||
break;
|
||||
|
||||
case BT_ATT_OP_READ_REQ:
|
||||
|
@ -40,7 +40,7 @@
|
||||
// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
|
||||
// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
|
||||
// the 16-bit part goes. Those 16 bits are passed in uuid16.
|
||||
void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[16]) {
|
||||
void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[16]) {
|
||||
self->nrf_ble_uuid.uuid = uuid16;
|
||||
if (uuid128 == NULL) {
|
||||
self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE;
|
||||
|
@ -283,7 +283,7 @@ void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
|
||||
mp_printf(print, "UUID(0x%04x)", common_hal_bleio_uuid_get_uuid16(self));
|
||||
} else {
|
||||
uint8_t uuid128[16];
|
||||
(void) common_hal_bleio_uuid_get_uuid128(self, uuid128);
|
||||
common_hal_bleio_uuid_get_uuid128(self, uuid128);
|
||||
mp_printf(print, "UUID('"
|
||||
"%02x%02x%02x%02x-"
|
||||
"%02x%02x-"
|
||||
|
@ -36,7 +36,7 @@ extern const mp_obj_type_t bleio_uuid_type;
|
||||
|
||||
extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[16]);
|
||||
extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self);
|
||||
extern bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
|
||||
extern void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
|
||||
extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self);
|
||||
|
||||
void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf);
|
||||
|
@ -27,6 +27,9 @@
|
||||
#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
|
||||
#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
|
||||
|
||||
// These are not the Bluetooth spec values. They are what is used by the Nordic SoftDevice.
|
||||
// The bit values are in different positions.
|
||||
|
||||
typedef enum {
|
||||
CHAR_PROP_NONE = 0,
|
||||
CHAR_PROP_BROADCAST = 1u << 0,
|
||||
@ -40,4 +43,14 @@ typedef enum {
|
||||
} bleio_characteristic_properties_enum_t;
|
||||
typedef uint8_t bleio_characteristic_properties_t;
|
||||
|
||||
// Bluetooth spec property values
|
||||
#define BT_GATT_CHRC_BROADCAST 0x01
|
||||
#define BT_GATT_CHRC_READ 0x02
|
||||
#define BT_GATT_CHRC_WRITE_WITHOUT_RESP 0x04
|
||||
#define BT_GATT_CHRC_WRITE 0x08
|
||||
#define BT_GATT_CHRC_NOTIFY 0x10
|
||||
#define BT_GATT_CHRC_INDICATE 0x20
|
||||
#define BT_GATT_CHRC_AUTH 0x40
|
||||
#define BT_GATT_CHRC_EXT_PROP 0x80
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
|
||||
|
Loading…
Reference in New Issue
Block a user