aboutsummaryrefslogtreecommitdiffstats
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
bluez-95620eae34074fe1309d9823ea67ab7b2eb0287c.tar.xz
bluez-95620eae34074fe1309d9823ea67ab7b2eb0287c.zip
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 4ca2ea35..7a6b23b9 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);
}