static bool encode_read_by_grp_type_rsp(struct gatt_db *db, struct queue *q, struct bt_att *att, uint16_t mtu, uint8_t *pdu, uint16_t *len) { int iter = 0; uint16_t start_handle, end_handle; struct iovec value; uint8_t data_val_len; *len = 0; while (queue_peek_head(q)) { struct gatt_db_attribute *attrib = queue_pop_head(q); value.iov_base = NULL; value.iov_len = 0; /* * This should never be deferred to the read callback for * primary/secondary service declarations. */ if (!gatt_db_attribute_read(attrib, 0, BT_ATT_OP_READ_BY_GRP_TYPE_REQ, att, attribute_read_cb, &value) || !value.iov_len) return false; /* * Use the first attribute to determine the length of each * attribute data unit. Stop the list when a different attribute * value is seen. */ if (iter == 0) { data_val_len = MIN(MIN((unsigned)mtu - 6, 251), value.iov_len); pdu[0] = data_val_len + 4; iter++; } else if (value.iov_len != data_val_len) break; /* Stop if this unit would surpass the MTU */ if (iter + data_val_len + 4 > mtu - 1) break; gatt_db_attribute_get_service_handles(attrib, &start_handle, &end_handle); put_le16(start_handle, pdu + iter); put_le16(end_handle, pdu + iter + 2); memcpy(pdu + iter + 4, value.iov_base, data_val_len); iter += data_val_len + 4; } *len = iter; return true; }
static void log_service_event(struct gatt_db_attribute *attr, const char *str) { char uuid_str[MAX_LEN_UUID_STR]; bt_uuid_t uuid; uint16_t start, end; gatt_db_attribute_get_service_uuid(attr, &uuid); bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); gatt_db_attribute_get_service_handles(attr, &start, &end); PRLOG("%s - UUID: %s start: 0x%04x end: 0x%04x\n", str, uuid_str, start, end); }
void btd_gatt_client_service_removed(struct btd_gatt_client *client, struct gatt_db_attribute *attrib) { uint16_t start_handle, end_handle; if (!client || !attrib || !client->ready) return; gatt_db_attribute_get_service_handles(attrib, &start_handle, &end_handle); DBG("GATT Services Removed - start: 0x%04x, end: 0x%04x", start_handle, end_handle); queue_remove_all(client->services, match_service_handle, UINT_TO_PTR(start_handle), unregister_service); }