aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen Ganir <chen.ganir@ti.com>2012-03-14 16:15:22 +0200
committerJoão Paulo Rechi Vita <jprvita@openbossa.org>2012-06-21 18:00:18 -0300
commit93729c82b026e410b7e2b2e839d7b9b11f731266 (patch)
treeb2e4b0529b0260f9853614deee5277b79d6f7af6
parent632ebaf63d962b207c5103a198759013828ee0f9 (diff)
downloadbluez-93729c82b026e410b7e2b2e839d7b9b11f731266.tar.gz
bluez-93729c82b026e410b7e2b2e839d7b9b11f731266.tar.xz
bluez-93729c82b026e410b7e2b2e839d7b9b11f731266.zip
battery: Discover Characteristic Descriptors
Discover all characteristic descriptors, and build a descriptor list
-rw-r--r--batterystate/batterystate.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/batterystate/batterystate.c b/batterystate/batterystate.c
index 79b4005c..4384a465 100644
--- a/batterystate/batterystate.c
+++ b/batterystate/batterystate.c
@@ -50,8 +50,24 @@ static GSList *servers = NULL;
struct characteristic {
struct gatt_char attr; /* Characteristic */
struct battery *batt; /* Parent Battery Service */
+ GSList *desc; /* Descriptors */
};
+struct descriptor {
+ struct characteristic *ch; /* Parent Characteristic */
+ uint16_t handle; /* Descriptor Handle */
+ bt_uuid_t uuid; /* UUID */
+};
+
+static void char_free(gpointer user_data)
+{
+ struct characteristic *c = user_data;
+
+ g_slist_free_full(c->desc, g_free);
+
+ g_free(c);
+}
+
static gint cmp_device(gconstpointer a, gconstpointer b)
{
const struct battery *batt = a;
@@ -74,12 +90,51 @@ static void batterystate_free(gpointer user_data)
g_attrib_unref(batt->attrib);
if (batt->chars != NULL)
- g_slist_free_full(batt->chars, g_free);
+ g_slist_free_full(batt->chars, char_free);
btd_device_unref(batt->dev);
g_free(batt);
}
+static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
+ gpointer user_data)
+{
+ struct characteristic *ch = user_data;
+ struct att_data_list *list;
+ uint8_t format;
+ int i;
+
+ if (status != 0) {
+ error("Discover all characteristic descriptors failed [%s]: %s",
+ ch->attr.uuid, att_ecode2str(status));
+ return;
+ }
+
+ list = dec_find_info_resp(pdu, len, &format);
+ if (list == NULL)
+ return;
+
+ for (i = 0; i < list->num; i++) {
+ struct descriptor *desc;
+ uint8_t *value;
+
+ value = list->data[i];
+ desc = g_new0(struct descriptor, 1);
+ desc->handle = att_get_u16(value);
+ desc->ch = ch;
+
+ if (format == 0x01)
+ desc->uuid = att_get_uuid16(&value[2]);
+ else
+ desc->uuid = att_get_uuid128(&value[2]);
+
+ ch->desc = g_slist_append(ch->desc, desc);
+ }
+
+ att_data_list_free(list);
+}
+
+
static void configure_batterystate_cb(GSList *characteristics, guint8 status,
gpointer user_data)
{
@@ -95,6 +150,7 @@ static void configure_batterystate_cb(GSList *characteristics, guint8 status,
for (l = characteristics; l; l = l->next) {
struct gatt_char *c = l->data;
struct characteristic *ch;
+ uint16_t start, end;
ch = g_new0(struct characteristic, 1);
ch->attr.handle = c->handle;
@@ -104,6 +160,20 @@ static void configure_batterystate_cb(GSList *characteristics, guint8 status,
ch->batt = batt;
batt->chars = g_slist_append(batt->chars, ch);
+
+ start = c->value_handle + 1;
+
+ if (l->next != NULL) {
+ struct gatt_char *c = l->next->data;
+ if (start == c->handle)
+ continue;
+ end = c->handle - 1;
+ } else if (c->value_handle != batt->svc_range->end)
+ end = batt->svc_range->end;
+ else
+ continue;
+
+ gatt_find_info(batt->attrib, start, end, discover_desc_cb, ch);
}
}