aboutsummaryrefslogtreecommitdiffstats
path: root/attrib/client.c
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2010-08-24 14:47:30 -0300
committerJohan Hedberg <johan.hedberg@nokia.com>2010-09-22 22:34:26 +0300
commit37e3aa41e8604a67acd03746fbacaeccfb9a8aa3 (patch)
treebbab031e477ff7384ae69002fde4fa1395f0fb7f /attrib/client.c
parent7bf4b08d0bd35aaef50926e14c5be277df3550e2 (diff)
downloadbluez-37e3aa41e8604a67acd03746fbacaeccfb9a8aa3.tar.gz
bluez-37e3aa41e8604a67acd03746fbacaeccfb9a8aa3.tar.xz
bluez-37e3aa41e8604a67acd03746fbacaeccfb9a8aa3.zip
Update characteristic value when a notification is received
Changes the internal characteristic value in attribute client side. Messages to notify the watchers are not being sent yet.
Diffstat (limited to 'attrib/client.c')
-rw-r--r--attrib/client.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/attrib/client.c b/attrib/client.c
index 061e2762..320f8b44 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -27,6 +27,7 @@
#include <config.h>
#endif
+#include <errno.h>
#include <stdlib.h>
#include <glib.h>
@@ -169,6 +170,14 @@ static int gatt_path_cmp(gconstpointer a, gconstpointer b)
return strcmp(gatt->path, path);
}
+static int characteristic_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct characteristic *chr = a;
+ uint16_t handle = GPOINTER_TO_UINT(b);
+
+ return chr->handle - handle;
+}
+
static void append_char_dict(DBusMessageIter *iter, struct characteristic *chr)
{
DBusMessageIter dict;
@@ -210,15 +219,54 @@ static void watcher_exit(DBusConnection *conn, void *user_data)
prim->watchers = g_slist_remove(prim->watchers, watcher);
}
+static int characteristic_set_value(struct characteristic *chr,
+ const uint8_t *value, uint16_t len)
+{
+ uint8_t *newvalue;
+
+ newvalue = g_try_malloc0(len);
+ if (newvalue == NULL)
+ return -ENOMEM;
+
+ memcpy(newvalue, value, len);
+ g_free(chr->value);
+ chr->vlen = len;
+ chr->value = newvalue;
+
+ return 0;
+}
+
static void events_handler(const uint8_t *pdu, uint16_t len,
gpointer user_data)
{
+ struct gatt_service *gatt = user_data;
+ struct characteristic *chr;
+ struct primary *prim;
+ GSList *lprim, *lchr;
+ guint handle = att_get_u16((uint16_t *) &pdu[1]);
+
+ for (lprim = gatt->primary, prim = NULL, chr = NULL; lprim;
+ lprim = lprim->next) {
+ prim = lprim->data;
+
+ lchr = g_slist_find_custom(prim->chars,
+ GUINT_TO_POINTER(handle), characteristic_cmp);
+ if (lchr) {
+ chr = lchr->data;
+ break;
+ }
+ }
+
+ if (chr == NULL) {
+ DBG("Attribute handle 0x%02x not found", handle);
+ return;
+ }
+
switch (pdu[0]) {
case ATT_OP_HANDLE_NOTIFY:
- DBG("Notification");
- break;
case ATT_OP_HANDLE_IND:
- DBG("Indication");
+ if (characteristic_set_value(chr, pdu + 2, len - 2) < 0)
+ DBG("Can't change Characteristic %0x02x", handle);
break;
}
}