2011-12-30 11:45:06

by Santiago Carot

[permalink] [raw]
Subject: [PATCH 1/4] attrib-server: Move GAP attributes inside gatt_server struct

---
src/attrib-server.c | 30 ++++++++++++++++++------------
1 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/src/attrib-server.c b/src/attrib-server.c
index 623c91a..36a398f 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -62,6 +62,8 @@ struct gatt_server {
uint32_t gap_sdp_handle;
GSList *database;
GSList *clients;
+ uint16_t name_handle;
+ uint16_t appearance_handle;
};

struct gatt_channel {
@@ -82,10 +84,6 @@ struct group_elem {
uint16_t len;
};

-/* GAP attribute handles */
-static uint16_t name_handle = 0x0000;
-static uint16_t appearance_handle = 0x0000;
-
static bt_uuid_t prim_uuid = {
.type = BT_UUID16,
.value.u16 = GATT_PRIM_SVC_UUID
@@ -1138,24 +1136,24 @@ static gboolean register_core_services(struct gatt_server *server)
atval, 2);

/* GAP service: device name characteristic */
- name_handle = 0x0006;
+ server->name_handle = 0x0006;
bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
atval[0] = ATT_CHAR_PROPER_READ;
- att_put_u16(name_handle, &atval[1]);
+ att_put_u16(server->name_handle, &atval[1]);
att_put_u16(GATT_CHARAC_DEVICE_NAME, &atval[3]);
attrib_db_add_new(server, 0x0004, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
atval, 5);

/* GAP service: device name attribute */
bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
- attrib_db_add_new(server, name_handle, &uuid, ATT_NONE,
+ attrib_db_add_new(server, server->name_handle, &uuid, ATT_NONE,
ATT_NOT_PERMITTED, NULL, 0);

/* GAP service: device appearance characteristic */
- appearance_handle = 0x0008;
+ server->appearance_handle = 0x0008;
bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
atval[0] = ATT_CHAR_PROPER_READ;
- att_put_u16(appearance_handle, &atval[1]);
+ att_put_u16(server->appearance_handle, &atval[1]);
att_put_u16(GATT_CHARAC_APPEARANCE, &atval[3]);
attrib_db_add_new(server, 0x0007, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
atval, 5);
@@ -1163,7 +1161,7 @@ static gboolean register_core_services(struct gatt_server *server)
/* GAP service: device appearance attribute */
bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
att_put_u16(appearance, &atval[0]);
- attrib_db_add_new(server, appearance_handle, &uuid, ATT_NONE,
+ attrib_db_add_new(server, server->appearance_handle, &uuid, ATT_NONE,
ATT_NOT_PERMITTED, atval, 2);
server->gap_sdp_handle = attrib_create_sdp_new(server, 0x0001,
"Generic Access Profile");
@@ -1392,16 +1390,24 @@ int attrib_db_del(struct btd_adapter *adapter, uint16_t handle)
int attrib_gap_set(struct btd_adapter *adapter, uint16_t uuid,
const uint8_t *value, int len)
{
+ struct gatt_server *server;
uint16_t handle;
+ GSList *l;
+
+ l = g_slist_find_custom(servers, adapter, adapter_cmp);
+ if (l == NULL)
+ return -ENOENT;
+
+ server = l->data;

/* FIXME: Missing Privacy and Reconnection Address */

switch (uuid) {
case GATT_CHARAC_DEVICE_NAME:
- handle = name_handle;
+ handle = server->name_handle;
break;
case GATT_CHARAC_APPEARANCE:
- handle = appearance_handle;
+ handle = server->appearance_handle;
break;
default:
return -ENOSYS;
--
1.7.8.1



2011-12-30 11:45:09

by Santiago Carot

[permalink] [raw]
Subject: [PATCH 4/4] gatt-example: Fix memory leak.

Remove the example-plugin data element from the list whenever an adapter
is removed.
---
plugins/gatt-example.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/plugins/gatt-example.c b/plugins/gatt-example.c
index 5af07ea..701c1d7 100644
--- a/plugins/gatt-example.c
+++ b/plugins/gatt-example.c
@@ -541,6 +541,7 @@ static void gatt_example_adapter_remove(struct btd_adapter *adapter)
return;

gadapter = l->data;
+ adapters = g_slist_remove(adapters, gadapter);
gatt_example_adapter_free(gadapter);
}

--
1.7.8.1


2011-12-30 11:45:08

by Santiago Carot

[permalink] [raw]
Subject: [PATCH 3/4] gatt-service: Add missing user_data parameter for callbacks

---
attrib/gatt-service.c | 4 ++++
plugins/gatt-example.c | 7 ++++---
time/server.c | 4 ++--
3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/attrib/gatt-service.c b/attrib/gatt-service.c
index 93cbf74..bfefdee 100644
--- a/attrib/gatt-service.c
+++ b/attrib/gatt-service.c
@@ -52,6 +52,7 @@ struct gatt_info {
struct attrib_cb {
attrib_event_t event;
void *fn;
+ void *user_data;
};

static GSList *parse_opts(gatt_option opt1, va_list args)
@@ -86,6 +87,7 @@ static GSList *parse_opts(gatt_option opt1, va_list args)
cb = g_new0(struct attrib_cb, 1);
cb->event = va_arg(args, attrib_event_t);
cb->fn = va_arg(args, void *);
+ cb->user_data = va_arg(args, void *);
info->callbacks = g_slist_append(info->callbacks, cb);
break;
case GATT_OPT_CHR_VALUE_GET_HANDLE:
@@ -219,6 +221,8 @@ static gboolean add_characteristic(struct btd_adapter *adapter,
a->write_cb = cb->fn;
break;
}
+
+ a->cb_user_data = cb->user_data;
}

if (info->value_handle != NULL)
diff --git a/plugins/gatt-example.c b/plugins/gatt-example.c
index ae9d41d..5af07ea 100644
--- a/plugins/gatt-example.c
+++ b/plugins/gatt-example.c
@@ -94,11 +94,11 @@ static gint adapter_cmp(gconstpointer a, gconstpointer b)

static uint8_t battery_state_read(struct attribute *a, gpointer user_data)
{
+ struct btd_adapter *adapter = user_data;
uint8_t value;

value = 0x04;
- /* FIXME: Provide the adapter in next function */
- attrib_db_update(NULL, a->handle, NULL, &value, sizeof(value), NULL);
+ attrib_db_update(adapter, a->handle, NULL, &value, sizeof(value), NULL);

return 0;
}
@@ -111,7 +111,8 @@ static gboolean register_battery_service(struct btd_adapter *adapter)
GATT_OPT_CHR_UUID, BATTERY_STATE_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
ATT_CHAR_PROPER_NOTIFY,
- GATT_OPT_CHR_VALUE_CB, ATTRIB_READ, battery_state_read,
+ GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
+ battery_state_read, adapter,

GATT_OPT_INVALID);
}
diff --git a/time/server.c b/time/server.c
index 4ed9cf2..0730fbb 100644
--- a/time/server.c
+++ b/time/server.c
@@ -123,13 +123,13 @@ static void register_current_time_service(void)
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
ATT_CHAR_PROPER_NOTIFY,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
- current_time_read,
+ current_time_read, NULL,

/* Local Time Information characteristic */
GATT_OPT_CHR_UUID, LOCAL_TIME_INFO_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
- local_time_info_read,
+ local_time_info_read, NULL,

GATT_OPT_INVALID);
}
--
1.7.8.1


2011-12-30 11:45:07

by Santiago Carot

[permalink] [raw]
Subject: [PATCH 2/4] gatt-service: Delete attributes when service registration fails.

Whenever a regitration operation fails, the attributes stored in
the data base of handles remain. This patches removes all attributes
registered by a service when the operation is not succesful. In this
way, either all service attributes are registered or none of them
are stored in the data base.
---
attrib/gatt-service.c | 29 +++++++++++++++++++++++++----
1 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/attrib/gatt-service.c b/attrib/gatt-service.c
index 3bfa565..93cbf74 100644
--- a/attrib/gatt-service.c
+++ b/attrib/gatt-service.c
@@ -198,12 +198,16 @@ static gboolean add_characteristic(struct btd_adapter *adapter,
atval[0] = info->props;
att_put_u16(h + 1, &atval[1]);
att_put_u16(info->uuid.value.u16, &atval[3]);
- attrib_db_add(adapter, h++, &bt_uuid, ATT_NONE, ATT_NOT_PERMITTED,
- atval, sizeof(atval));
+ if (attrib_db_add(adapter, h++, &bt_uuid, ATT_NONE, ATT_NOT_PERMITTED,
+ atval, sizeof(atval)) == NULL)
+ return FALSE;

/* characteristic value */
a = attrib_db_add(adapter, h++, &info->uuid, read_reqs, write_reqs,
NULL, 0);
+ if (a == NULL)
+ return FALSE;
+
for (l = info->callbacks; l != NULL; l = l->next) {
struct attrib_cb *cb = l->data;

@@ -229,6 +233,8 @@ static gboolean add_characteristic(struct btd_adapter *adapter,
cfg_val[1] = 0x00;
a = attrib_db_add(adapter, h++, &bt_uuid, ATT_NONE,
ATT_AUTHENTICATION, cfg_val, sizeof(cfg_val));
+ if (a == NULL)
+ return FALSE;

if (info->ccc_handle != NULL)
*info->ccc_handle = a->handle;
@@ -247,6 +253,16 @@ static void free_gatt_info(void *data)
g_free(info);
}

+static void service_attr_del(struct btd_adapter *adapter, uint16_t start_handle,
+ uint16_t end_handle)
+{
+ uint16_t handle;
+
+ for (handle = start_handle; handle <= end_handle; handle++)
+ if (attrib_db_del(adapter, handle) < 0)
+ error("Can't delete handle 0x%04x", handle);
+}
+
gboolean gatt_service_add(struct btd_adapter *adapter, uint16_t uuid,
uint16_t svc_uuid, gatt_option opt1, ...)
{
@@ -279,14 +295,19 @@ gboolean gatt_service_add(struct btd_adapter *adapter, uint16_t uuid,
h = start_handle;
bt_uuid16_create(&bt_uuid, uuid);
att_put_u16(svc_uuid, &atval[0]);
- attrib_db_add(adapter, h++, &bt_uuid, ATT_NONE, ATT_NOT_PERMITTED,
- atval, sizeof(atval));
+ if (attrib_db_add(adapter, h++, &bt_uuid, ATT_NONE, ATT_NOT_PERMITTED,
+ atval, sizeof(atval)) == NULL) {
+ g_slist_free_full(chrs, free_gatt_info);
+ return FALSE;
+ }
+
for (l = chrs; l != NULL; l = l->next) {
struct gatt_info *info = l->data;

DBG("New characteristic: handle 0x%04x", h);
if (!add_characteristic(adapter, &h, info)) {
g_slist_free_full(chrs, free_gatt_info);
+ service_attr_del(adapter, start_handle, h - 1);
return FALSE;
}
}
--
1.7.8.1


2012-01-09 12:29:11

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH 1/4] attrib-server: Move GAP attributes inside gatt_server struct

Hi Santiago,

On Fri, Dec 30, 2011, Santiago Carot-Nemesio wrote:
> ---
> src/attrib-server.c | 30 ++++++++++++++++++------------
> 1 files changed, 18 insertions(+), 12 deletions(-)

All four patches have been applied. Thanks.

Johan