diff --git a/android/gatt.c b/android/gatt.c
index 6db2d9f..77c3b02 100644
--- a/android/gatt.c
+++ b/android/gatt.c
#include "utils.h"
#include "src/shared/util.h"
#include "src/shared/queue.h"
+#include "src/shared/att.h"
#include "src/shared/gatt-db.h"
#include "attrib/gattrib.h"
#include "attrib/att.h"
{
struct pending_request *resp_data = data;
struct request_processing_data *process_data = user_data;
+ struct bt_att *att = g_attrib_get_att(process_data->device->attrib);
struct gatt_db_attribute *attrib;
uint32_t permissions;
uint8_t error;
}
gatt_db_attribute_read(attrib, resp_data->offset, process_data->opcode,
- &process_data->device->bdaddr,
- attribute_read_cb, resp_data);
+ att, attribute_read_cb, resp_data);
}
static void process_dev_pending_requests(struct gatt_device *device,
return transaction;
}
+static bool get_dst_addr(struct bt_att *att, bdaddr_t *dst)
+{
+ GIOChannel *io = NULL;
+ GError *gerr = NULL;
+
+ io = g_io_channel_unix_new(bt_att_get_fd(att));
+ if (!io)
+ return false;
+
+ bt_io_get(io, &gerr, BT_IO_OPT_DEST_BDADDR, dst, BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("gatt: bt_io_get: %s", gerr->message);
+ g_error_free(gerr);
+ g_io_channel_unref(io);
+ return false;
+ }
+
+ g_io_channel_unref(io);
+ return true;
+}
+
static void read_cb(struct gatt_db_attribute *attrib, unsigned int id,
- uint16_t offset, uint8_t opcode, bdaddr_t *bdaddr,
+ uint16_t offset, uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct pending_trans_data *transaction;
struct gatt_app *app;
struct app_connection *conn;
int32_t app_id = PTR_TO_INT(user_data);
+ bdaddr_t bdaddr;
DBG("id %u", id);
goto failed;
}
- conn = find_conn(bdaddr, app->id);
+ if (!get_dst_addr(att, &bdaddr)) {
+ error("gatt: read_cb, could not obtain dst BDADDR");
+ goto failed;
+ }
+
+ conn = find_conn(&bdaddr, app->id);
if (!conn) {
error("gatt: read_cb, cound not found connection");
goto failed;
if (!transaction)
goto failed;
- bdaddr2android(bdaddr, ev.bdaddr);
+ bdaddr2android(&bdaddr, ev.bdaddr);
ev.conn_id = conn->id;
ev.attr_handle = gatt_db_attribute_get_handle(attrib);
ev.offset = offset;
static void write_cb(struct gatt_db_attribute *attrib, unsigned int id,
uint16_t offset, const uint8_t *value, size_t len,
- uint8_t opcode, bdaddr_t *bdaddr, void *user_data)
+ uint8_t opcode, struct bt_att *att, void *user_data)
{
uint8_t buf[IPC_MTU];
struct hal_ev_gatt_server_request_write *ev = (void *) buf;
struct gatt_app *app;
int32_t app_id = PTR_TO_INT(user_data);
struct app_connection *conn;
+ bdaddr_t bdaddr;
DBG("id %u", id);
goto failed;
}
- conn = find_conn(bdaddr, app->id);
+ if (!get_dst_addr(att, &bdaddr)) {
+ error("gatt: write_cb, could not obtain dst BDADDR");
+ goto failed;
+ }
+
+ conn = find_conn(&bdaddr, app->id);
if (!conn) {
error("gatt: write_cb could not found connection");
goto failed;
memset(ev, 0, sizeof(*ev));
- bdaddr2android(bdaddr, &ev->bdaddr);
+ bdaddr2android(&bdaddr, &ev->bdaddr);
ev->attr_handle = gatt_db_attribute_get_handle(attrib);
ev->offset = offset;
if (check_device_permissions(dev, cmd[0], permissions))
return;
- gatt_db_attribute_write(attrib, 0, value, vlen, cmd[0], &dev->bdaddr,
- write_confirm, NULL);
+ gatt_db_attribute_write(attrib, 0, value, vlen, cmd[0],
+ g_attrib_get_att(dev->attrib),
+ write_confirm, NULL);
}
static void write_signed_cmd_request(const uint8_t *cmd, uint16_t cmd_len,
/* Signature OK, proceed with write */
bt_update_sign_counter(&dev->bdaddr, REMOTE_CSRK, r_sign_cnt);
gatt_db_attribute_write(attrib, 0, value, vlen, cmd[0],
- &dev->bdaddr, write_confirm, NULL);
+ g_attrib_get_att(dev->attrib),
+ write_confirm, NULL);
}
}
}
if (!gatt_db_attribute_write(attrib, 0, value, vlen, cmd[0],
- &dev->bdaddr, attribute_write_cb,
- data)) {
+ g_attrib_get_att(dev->attrib),
+ attribute_write_cb, data)) {
queue_remove(dev->pending_requests, data);
free(data);
return ATT_ECODE_UNLIKELY;
data->length = vlen;
if (!gatt_db_attribute_write(attrib, offset, value, vlen, cmd[0],
- &dev->bdaddr, attribute_write_cb,
- data)) {
+ g_attrib_get_att(dev->attrib),
+ attribute_write_cb, data)) {
queue_remove(dev->pending_requests, data);
g_free(data->value);
free(data);
static void device_name_read_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
const char *name = bt_get_adapter_name();
static void device_info_read_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
char *buf = user_data;
static void device_info_read_system_id_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
uint8_t pdu[8];
static void device_info_read_pnp_id_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
uint8_t pdu[7];
static void gatt_srvc_change_write_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct gatt_device *dev;
+ bdaddr_t bdaddr;
- dev = find_device_by_addr(bdaddr);
+ if (!get_dst_addr(att, &bdaddr)) {
+ error("gatt: srvc_change_write_cb, could not obtain BDADDR");
+ return;
+ }
+
+ dev = find_device_by_addr(&bdaddr);
if (!dev) {
error("gatt: Could not find device ?!");
return;
}
- if (!bt_device_is_bonded(bdaddr)) {
+ if (!bt_device_is_bonded(&bdaddr)) {
gatt_db_attribute_write_result(attrib, id,
ATT_ECODE_AUTHORIZATION);
return;
}
/* Set services changed indication value */
- bt_store_gatt_ccc(bdaddr, get_le16(value));
+ bt_store_gatt_ccc(&bdaddr, get_le16(value));
gatt_db_attribute_write_result(attrib, id, 0);
}
static void gatt_srvc_change_read_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct gatt_device *dev;
uint8_t pdu[2];
+ bdaddr_t bdaddr;
- dev = find_device_by_addr(bdaddr);
+ if (!get_dst_addr(att, &bdaddr)) {
+ error("gatt: srvc_change_read_cb, could not obtain BDADDR");
+ return;
+ }
+
+ dev = find_device_by_addr(&bdaddr);
if (!dev) {
error("gatt: Could not find device ?!");
return;
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index f72d58e..42ce5c2 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
#include "src/shared/util.h"
#include "src/shared/queue.h"
#include "src/shared/timeout.h"
+#include "src/shared/att.h"
#include "src/shared/gatt-db.h"
-#include "src/shared/att-types.h"
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
}
bool gatt_db_attribute_read(struct gatt_db_attribute *attrib, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
gatt_db_attribute_read_t func, void *user_data)
{
uint8_t *value;
queue_push_tail(attrib->pending_reads, p);
- attrib->read_func(attrib, p->id, offset, opcode, bdaddr,
+ attrib->read_func(attrib, p->id, offset, opcode, att,
attrib->user_data);
return true;
}
bool gatt_db_attribute_write(struct gatt_db_attribute *attrib, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
gatt_db_attribute_write_t func,
void *user_data)
{
queue_push_tail(attrib->pending_writes, p);
attrib->write_func(attrib, p->id, offset, value, len, opcode,
- bdaddr, attrib->user_data);
+ att, attrib->user_data);
return true;
}
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index 37df4d5..75f0668 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
typedef void (*gatt_db_read_t) (struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data);
typedef void (*gatt_db_write_t) (struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data);
struct gatt_db_attribute *
size_t length, void *user_data);
bool gatt_db_attribute_read(struct gatt_db_attribute *attrib, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
gatt_db_attribute_read_t func, void *user_data);
bool gatt_db_attribute_read_result(struct gatt_db_attribute *attrib,
bool gatt_db_attribute_write(struct gatt_db_attribute *attrib, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
gatt_db_attribute_write_t func,
void *user_data);
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 0652d3d..41b2494 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
}
static bool encode_read_by_grp_type_rsp(struct gatt_db *db, struct queue *q,
- uint16_t mtu,
- uint8_t *pdu, uint16_t *len)
+ struct bt_att *att,
+ uint16_t mtu, uint8_t *pdu,
+ uint16_t *len)
{
int iter = 0;
uint16_t start_handle, end_handle;
*/
if (!gatt_db_attribute_read(attrib, 0,
BT_ATT_OP_READ_BY_GRP_TYPE_REQ,
- NULL, attribute_read_cb,
+ att, attribute_read_cb,
&value) || !value.iov_len)
return false;
goto error;
}
- if (!encode_read_by_grp_type_rsp(server->db, q, mtu, rsp_pdu,
- &rsp_len)) {
+ if (!encode_read_by_grp_type_rsp(server->db, q, server->att, mtu,
+ rsp_pdu, &rsp_len)) {
ecode = BT_ATT_ERROR_UNLIKELY;
goto error;
}
goto error;
}
- if (gatt_db_attribute_read(attr, 0, op->opcode, NULL,
- read_by_type_read_complete_cb, op))
+ if (gatt_db_attribute_read(attr, 0, op->opcode, server->att,
+ read_by_type_read_complete_cb, op))
return;
ecode = BT_ATT_ERROR_UNLIKELY;
server->pending_write_op = op;
if (gatt_db_attribute_write(attr, 0, pdu + 2, length - 2, opcode,
- NULL, write_complete_cb, op))
+ server->att,
+ write_complete_cb, op))
return;
if (op)
op->server = server;
server->pending_read_op = op;
- if (gatt_db_attribute_read(attr, offset, opcode, NULL,
+ if (gatt_db_attribute_read(attr, offset, opcode, server->att,
read_complete_cb, op))
return;
struct read_multiple_resp_data *data = user_data;
struct gatt_db_attribute *next_attr;
uint32_t perm;
-
uint16_t handle = gatt_db_attribute_get_handle(attr);
if (err != 0) {
return;
}
- if (!gatt_db_attribute_read(next_attr, 0, BT_ATT_OP_READ_MULT_REQ, NULL,
+ if (!gatt_db_attribute_read(next_attr, 0, BT_ATT_OP_READ_MULT_REQ,
+ data->server->att,
read_multiple_complete_cb, data)) {
bt_att_send_error_rsp(data->server->att,
BT_ATT_OP_READ_MULT_REQ,
goto error;
}
- if (gatt_db_attribute_read(attr, 0, opcode, NULL,
+ if (gatt_db_attribute_read(attr, 0, opcode, server->att,
read_multiple_complete_cb, &data))
return;
status = gatt_db_attribute_write(attr, next->offset,
next->value, next->length,
- BT_ATT_OP_EXEC_WRITE_REQ, NULL,
+ BT_ATT_OP_EXEC_WRITE_REQ,
+ server->att,
exec_write_complete_cb, server);
prep_write_data_destroy(next);
diff --git a/tools/btgatt-server.c b/tools/btgatt-server.c
index 5eab548..4d7ea6c 100644
--- a/tools/btgatt-server.c
+++ b/tools/btgatt-server.c
static void gap_device_name_read_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct server *server = user_data;
static void gap_device_name_write_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct server *server = user_data;
static void gap_device_name_ext_prop_read_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
uint8_t value[2];
static void gatt_service_changed_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
PRLOG("Service Changed Read called\n");
static void gatt_svc_chngd_ccc_read_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct server *server = user_data;
static void gatt_svc_chngd_ccc_write_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct server *server = user_data;
static void hr_msrmt_ccc_read_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct server *server = user_data;
static void hr_msrmt_ccc_write_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct server *server = user_data;
static void hr_control_point_write_cb(struct gatt_db_attribute *attrib,
unsigned int id, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t opcode, bdaddr_t *bdaddr,
+ uint8_t opcode, struct bt_att *att,
void *user_data)
{
struct server *server = user_data;
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 6c98cfa..cabf752 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
g_assert(attrib != NULL);
- gatt_db_attribute_write(attrib, 0, value, len, 0x00, NULL, att_write_cb,
- NULL);
+ gatt_db_attribute_write(attrib, 0, value, len, 0x00, NULL,
+ att_write_cb, NULL);
return attrib;
}