summaryrefslogtreecommitdiff
path: root/attrib/client.c
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2010-08-05 20:10:17 -0300
committerJohan Hedberg <johan.hedberg@nokia.com>2010-08-09 18:06:49 -0400
commit95620eae34074fe1309d9823ea67ab7b2eb0287c (patch)
tree8168009d432b327e62902421a26fee7b49430aec /attrib/client.c
parentd5e700051b1263b2028331d41d60de02a5a6f90e (diff)
downloadbluez-95620eae34074fe1309d9823ea67ab7b2eb0287c.tar.gz
Add support for reading Char values and descriptors
When the characteristic is read for the first time, we read and update its value and its descriptors.
Diffstat (limited to 'attrib/client.c')
-rw-r--r--attrib/client.c104
1 files changed, 98 insertions, 6 deletions
diff --git a/attrib/client.c b/attrib/client.c
index 4ca2ea352..7a6b23b98 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -58,6 +58,14 @@ struct gatt_service {
guint atid;
};
+struct format {
+ guint8 format;
+ guint8 exponent;
+ guint16 unit;
+ guint8 namespace;
+ guint16 desc;
+} __attribute__ ((packed));
+
struct characteristic {
char *path;
uint16_t handle;
@@ -66,6 +74,9 @@ struct characteristic {
uuid_t type;
char *name;
char *desc;
+ struct format *format;
+ uint8_t *value;
+ int vlen;
};
struct primary {
@@ -95,6 +106,10 @@ static void characteristic_free(void *user_data)
struct characteristic *chr = user_data;
g_free(chr->path);
+ g_free(chr->desc);
+ g_free(chr->format);
+ g_free(chr->value);
+ g_free(chr->name);
g_free(chr);
}
@@ -139,7 +154,14 @@ static void append_char_dict(DBusMessageIter *iter, struct characteristic *chr)
/* FIXME: Translate UUID to name. */
dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &name);
- dict_append_entry(&dict, "Description", DBUS_TYPE_STRING, &name);
+
+ if (chr->desc)
+ dict_append_entry(&dict, "Description", DBUS_TYPE_STRING,
+ &chr->desc);
+
+ if (chr->value)
+ dict_append_array(&dict, "Value", DBUS_TYPE_BYTE, &chr->value,
+ chr->vlen);
/* FIXME: Missing Format, Value and Representation */
@@ -373,16 +395,76 @@ static void load_characteristics(gpointer data, gpointer user_data)
return;
}
+static void update_char_desc(guint8 status, const guint8 *pdu,
+ guint16 len, gpointer user_data)
+{
+ struct characteristic *chr = user_data;
+
+ if (status != 0)
+ return;
+
+ g_free(chr->desc);
+
+ chr->desc = g_malloc(len);
+ memcpy(chr->desc, pdu + 1, len - 1);
+ chr->desc[len - 1] = '\0';
+}
+
+static void update_char_format(guint8 status, const guint8 *pdu,
+ guint16 len, gpointer user_data)
+{
+ struct characteristic *chr = user_data;
+
+ if (status != 0)
+ return;
+
+ if (len < 8)
+ return;
+
+ g_free(chr->format);
+
+ chr->format = g_new0(struct format, 1);
+ memcpy(chr->format, pdu + 1, 7);
+}
+
+static void update_char_value(guint8 status, const guint8 *pdu,
+ guint16 len, gpointer user_data)
+{
+ struct characteristic *chr = user_data;
+
+ if (status != 0)
+ return;
+
+ g_free(chr->value);
+
+ chr->vlen = len - 1;
+ chr->value = g_malloc(chr->vlen);
+ memcpy(chr->value, pdu + 1, chr->vlen);
+}
+
+static int uuid_desc16_cmp(uuid_t *uuid, guint16 desc)
+{
+ uuid_t u16;
+
+ sdp_uuid16_create(&u16, desc);
+
+ return sdp_uuid_cmp(uuid, &u16);
+}
+
static void descriptor_cb(guint8 status, const guint8 *pdu, guint16 plen,
gpointer user_data)
{
struct descriptor_data *current = user_data;
+ struct gatt_service *gatt = current->gatt;
+ struct characteristic *chr = current->chr;
struct att_data_list *list;
guint8 format;
int i;
- if (status != 0)
- goto fail;
+ if (status != 0) {
+ g_free(current);
+ return;
+ }
DBG("Find Information Response received");
@@ -404,12 +486,22 @@ static void descriptor_cb(guint8 status, const guint8 *pdu, guint16 plen,
if (format == 0x01) {
u16 = (void *) &info[2];
sdp_uuid16_create(&uuid, btohs(*u16));
- }
+ } else
+ continue;
+
+ if (uuid_desc16_cmp(&uuid, GATT_CHARAC_USER_DESC_UUID) == 0)
+ gatt_read_char(gatt->attrib, handle,
+ update_char_desc, chr);
- /* FIXME: do something useful here */
+ else if (uuid_desc16_cmp(&uuid, GATT_CHARAC_FMT_UUID) == 0)
+ gatt_read_char(gatt->attrib, handle,
+ update_char_format, chr);
+
+ gatt_read_char(gatt->attrib, chr->handle, update_char_value,
+ chr);
}
-fail:
+ att_data_list_free(list);
g_free(current);
}