46 #define MIN(a, b) ((a) < (b) ? (a) : (b))
71 result->
pdu = malloc(pdu_len);
82 memcpy(result->
pdu, pdu, pdu_len);
103 unsigned int count = 0;
163 unsigned int count = 0;
181 for (cur = result; cur; cur = cur->
next)
190 if (!iter || !result)
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
201 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
258 uint16_t *handle, uint16_t *start_handle,
259 uint16_t *end_handle, uint8_t uuid[16])
266 if (!iter || !iter->
result || !handle || !start_handle || !end_handle
276 if (op->
uuid.
type != BT_UUID_UNSPEC)
293 *start_handle =
get_le16(pdu_ptr + 2);
294 *end_handle =
get_le16(pdu_ptr + 4);
308 *start_handle =
get_le16(pdu_ptr + 2);
309 *end_handle =
get_le16(pdu_ptr + 4);
310 read_result = iter->
result;
317 for (read_result = read_result->
next; read_result; i++) {
321 read_result = read_result->
next;
345 if (!iter || !iter->
result || !start_handle || !end_handle || !uuid)
354 *end_handle =
get_le16(pdu_ptr + 2);
359 *end_handle =
get_le16(pdu_ptr + 2);
380 uint16_t *value_handle, uint8_t *properties,
386 if (!iter || !iter->
result || !start_handle || !end_handle ||
387 !value_handle || !properties || !uuid)
395 if (op->
uuid.
type != BT_UUID_UNSPEC)
410 *properties = ((uint8_t *) pdu_ptr)[2];
411 *value_handle =
get_le16(pdu_ptr + 3);
435 if (!iter || !iter->
result || !handle || !uuid)
456 uint16_t *handle, uint16_t *length,
457 const uint8_t **value)
462 if (!iter || !iter->
result || !handle || !length || !value)
473 if (op->
uuid.
type == BT_UUID_UNSPEC)
480 *value = pdu_ptr + 2;
518 return error_pdu->
ecode;
533 uint8_t att_ecode = 0;
534 uint16_t server_rx_mtu;
591 if (!att || !client_rx_mtu)
619 return (uuid->
type == BT_UUID16) ? 2 : 16;
627 __sync_fetch_and_add(&req->
ref_count, 1);
637 if (__sync_sub_and_fetch(&req->
ref_count, 1))
692 uint8_t att_ecode = 0;
716 data_length = ((uint8_t *) pdu)[0];
717 list_length = length - 1;
719 if ((data_length != 6 && data_length != 20) ||
720 (list_length % data_length)) {
728 cur_result =
result_append(opcode, pdu + 1, list_length, data_length,
735 last_end =
get_le16(pdu + length - data_length + 2);
741 if (last_end < op->start_handle) {
748 if (last_end < op->end_handle) {
772 if (last_end == 0xffff && last_end != op->
end_handle)
774 cur_result->
pdu + length - data_length + 1);
783 uint16_t length,
void *user_data)
787 uint8_t att_ecode = 0;
816 last_end =
get_le16(pdu + length - 2);
857 uint16_t start, uint16_t end,
897 if (uuid->
type == BT_UUID_UNSPEC) {
938 uint16_t start, uint16_t end,
949 uint16_t start, uint16_t end,
981 __sync_fetch_and_add(&data->
ref_count, 1);
990 if (__sync_sub_and_fetch(&read_data->
ref_count, 1))
999 uint16_t length,
void *user_data);
1002 uint16_t length,
void *user_data)
1006 uint8_t att_ecode = 0;
1007 uint8_t read_pdu[2];
1036 uint16_t last_handle;
1062 memcpy(read_pdu, data->
result->
pdu + data->
pos + 2,
sizeof(uint16_t));
1083 memcpy(pdu, data->
result->
pdu + 2,
sizeof(uint16_t));
1104 uint8_t att_ecode = 0;
1105 uint16_t last_handle;
1120 data_length = ((
const uint8_t *) pdu)[0];
1131 if ((data_length != 8 && data_length != 6) ||
1132 (length - 1) % data_length) {
1137 cur_result =
result_append(opcode, pdu + 1, length - 1, data_length,
1144 if (data_length == 6) {
1157 last_handle =
get_le16(pdu + length - data_length);
1163 if (last_handle < op->start_handle) {
1195 uint16_t start, uint16_t end,
1237 uint8_t att_ecode = 0;
1239 uint16_t last_handle;
1260 data_length = ((uint8_t *) pdu)[0];
1262 if ((data_length != 7 && data_length != 21) ||
1263 ((length - 1) % data_length)) {
1273 last_handle =
get_le16(pdu + length - data_length);
1312 uint16_t start, uint16_t end,
1354 uint8_t att_ecode = 0;
1356 uint16_t last_handle;
1370 data_length = ((uint8_t *) pdu)[0];
1371 if (((length - 1) % data_length)) {
1377 if (!
result_append(opcode, pdu + 1, length - 1, data_length, op)) {
1383 last_handle =
get_le16(pdu + length - data_length);
1430 if (!att || !uuid || uuid->
type == BT_UUID_UNSPEC)
1465 uint8_t att_ecode = 0;
1467 uint16_t last_handle;
1487 format = ((uint8_t *) pdu)[0];
1491 else if (format == 0x02)
1498 if ((length - 1) % data_length) {
1503 if (!
result_append(opcode, pdu + 1, length - 1, data_length, op)) {
1508 last_handle =
get_le16(pdu + length - data_length);
1545 uint16_t start, uint16_t end,
#define BT_ATT_OP_READ_BY_TYPE_REQ
static struct bt_gatt_result * result_append(uint8_t opcode, const void *pdu, uint16_t pdu_len, uint16_t data_len, struct bt_gatt_request *op)
void bt_gatt_request_unref(struct bt_gatt_request *req)
static unsigned int result_element_count(struct bt_gatt_result *result)
#define BT_ATT_OP_READ_RSP
#define BT_ATT_OP_READ_BY_TYPE_RSP
bool bt_gatt_read_by_type(struct bt_att *att, uint16_t start, uint16_t end, const bt_uuid_t *uuid, bt_gatt_request_callback_t callback, void *user_data, bt_gatt_destroy_func_t destroy)
void(* bt_gatt_request_callback_t)(bool success, uint8_t att_ecode, struct bt_gatt_result *result, void *user_data)
struct bt_gatt_result * result_tail
bt_gatt_result_callback_t callback
struct bt_gatt_result * result
static void async_req_unref(void *data)
static void discovery_op_complete(struct bt_gatt_request *op, bool success, uint8_t ecode)
void bt_uuid_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst)
#define GATT_PRIM_SVC_UUID
struct bt_gatt_request * bt_gatt_discover_characteristics(struct bt_att *att, uint16_t start, uint16_t end, bt_gatt_request_callback_t callback, void *user_data, bt_gatt_destroy_func_t destroy)
#define GATT_INCLUDE_UUID
struct bt_gatt_request * bt_gatt_discover_included_services(struct bt_att *att, uint16_t start, uint16_t end, bt_gatt_request_callback_t callback, void *user_data, bt_gatt_destroy_func_t destroy)
static void destroy_mtu_op(void *user_data)
void(* bt_gatt_result_callback_t)(bool success, uint8_t att_ecode, void *user_data)
bool bt_gatt_iter_next_characteristic(struct bt_gatt_iter *iter, uint16_t *start_handle, uint16_t *end_handle, uint16_t *value_handle, uint8_t *properties, uint8_t uuid[16])
union bt_uuid_t::@8 value
#define BT_ATT_OP_MTU_REQ
struct bt_gatt_result * next
struct bt_gatt_result * result_head
static void discover_included_cb(uint8_t opcode, const void *pdu, uint16_t length, void *user_data)
static void put_le16(uint16_t val, void *dst)
void(* bt_gatt_destroy_func_t)(void *user_data)
#define BT_ATT_OP_FIND_INFO_RSP
struct bt_gatt_request * bt_gatt_discover_descriptors(struct bt_att *att, uint16_t start, uint16_t end, bt_gatt_request_callback_t callback, void *user_data, bt_gatt_destroy_func_t destroy)
struct bt_gatt_request * op
static void read_included_unref(void *data)
static void read_by_grp_type_cb(uint8_t opcode, const void *pdu, uint16_t length, void *user_data)
struct bt_gatt_request * bt_gatt_request_ref(struct bt_gatt_request *req)
bool bt_att_set_mtu(struct bt_att *att, uint16_t mtu)
static struct read_incl_data * new_read_included(struct bt_gatt_result *res)
bt_gatt_request_callback_t callback
static void discover_chrcs_cb(uint8_t opcode, const void *pdu, uint16_t length, void *user_data)
static bool convert_uuid_le(const uint8_t *src, size_t len, uint8_t dst[16])
bool bt_att_cancel(struct bt_att *att, unsigned int id)
bool bt_gatt_iter_next_included_service(struct bt_gatt_iter *iter, uint16_t *handle, uint16_t *start_handle, uint16_t *end_handle, uint8_t uuid[16])
#define BT_ATT_OP_MTU_RSP
static void mtu_cb(uint8_t opcode, const void *pdu, uint16_t length, void *user_data)
#define BT_ATT_OP_READ_BY_GRP_TYPE_REQ
#define BT_ATT_OP_ERROR_RSP
bool bt_gatt_iter_init(struct bt_gatt_iter *iter, struct bt_gatt_result *result)
static void bswap_128(const void *src, void *dst)
#define BT_ATT_OP_FIND_BY_TYPE_VAL_REQ
#define BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND
static void find_by_type_val_cb(uint8_t opcode, const void *pdu, uint16_t length, void *user_data)
struct bt_gatt_result * result
struct bt_gatt_request * bt_gatt_discover_secondary_services(struct bt_att *att, bt_uuid_t *uuid, uint16_t start, uint16_t end, bt_gatt_request_callback_t callback, void *user_data, bt_gatt_destroy_func_t destroy)
unsigned int bt_gatt_result_descriptor_count(struct bt_gatt_result *result)
#define BT_ATT_OP_READ_BY_GRP_TYPE_RSP
static void discover_descs_cb(uint8_t opcode, const void *pdu, uint16_t length, void *user_data)
static void result_destroy(struct bt_gatt_result *result)
static struct bt_gatt_request * discover_services(struct bt_att *att, bt_uuid_t *uuid, uint16_t start, uint16_t end, bt_gatt_request_callback_t callback, void *user_data, bt_gatt_destroy_func_t destroy, bool primary)
static int get_uuid_len(const bt_uuid_t *uuid)
#define BT_ATT_OP_FIND_BY_TYPE_VAL_RSP
int bt_uuid_to_le(const bt_uuid_t *src, void *dst)
unsigned int bt_gatt_result_characteristic_count(struct bt_gatt_result *result)
struct bt_gatt_request * bt_gatt_discover_primary_services(struct bt_att *att, bt_uuid_t *uuid, uint16_t start, uint16_t end, bt_gatt_request_callback_t callback, void *user_data, bt_gatt_destroy_func_t destroy)
bool bt_gatt_iter_next_descriptor(struct bt_gatt_iter *iter, uint16_t *handle, uint8_t uuid[16])
static void read_by_type_cb(uint8_t opcode, const void *pdu, uint16_t length, void *user_data)
static const uint8_t bt_base_uuid[16]
bool bt_gatt_iter_next_service(struct bt_gatt_iter *iter, uint16_t *start_handle, uint16_t *end_handle, uint8_t uuid[16])
static uint16_t get_le16(const void *ptr)
static void read_included_cb(uint8_t opcode, const void *pdu, uint16_t length, void *user_data)
static uint8_t process_error(const void *pdu, uint16_t length)
unsigned int bt_gatt_exchange_mtu(struct bt_att *att, uint16_t client_rx_mtu, bt_gatt_result_callback_t callback, void *user_data, bt_gatt_destroy_func_t destroy)
bt_gatt_destroy_func_t destroy
#define BT_ATT_OP_READ_REQ
#define BT_ATT_OP_FIND_INFO_REQ
static struct bt_gatt_result * result_create(uint8_t opcode, const void *pdu, uint16_t pdu_len, uint16_t data_len, void *op)
static struct read_incl_data * read_included_ref(struct read_incl_data *data)
void bt_gatt_request_cancel(struct bt_gatt_request *req)
unsigned int bt_gatt_result_service_count(struct bt_gatt_result *result)
unsigned int bt_att_send(struct bt_att *att, uint8_t opcode, const void *pdu, uint16_t length, bt_att_response_func_t callback, void *user_data, bt_att_destroy_func_t destroy)
unsigned int bt_gatt_result_included_count(struct bt_gatt_result *result)
#define GATT_SND_SVC_UUID
bt_gatt_destroy_func_t destroy
bool bt_gatt_iter_next_read_by_type(struct bt_gatt_iter *iter, uint16_t *handle, uint16_t *length, const uint8_t **value)
static void read_included(struct read_incl_data *data)
struct bt_gatt_request * bt_gatt_discover_all_primary_services(struct bt_att *att, bt_uuid_t *uuid, bt_gatt_request_callback_t callback, void *user_data, bt_gatt_destroy_func_t destroy)