aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2012-05-03 17:01:11 -0300
committerJoão Paulo Rechi Vita <jprvita@openbossa.org>2012-06-21 18:00:18 -0300
commita27199b29b06babce2ede5fdf04cb6b52c537511 (patch)
tree069131efa4c972a495d3ee970cb959ac3cff054a
parent046bedecc1bb15c62722db4f452a902ca2998860 (diff)
downloadbluez-a27199b29b06babce2ede5fdf04cb6b52c537511.tar.gz
bluez-a27199b29b06babce2ede5fdf04cb6b52c537511.tar.xz
bluez-a27199b29b06babce2ede5fdf04cb6b52c537511.zip
scan: Enable Scan Refresh notification
This patch discovers the Scan Refresh Characteristic handle and sets it's Client Characteristic Configuration bit to enable notifications.
-rw-r--r--scanparam/scan.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/scanparam/scan.c b/scanparam/scan.c
index 84feb1bd..41c03e71 100644
--- a/scanparam/scan.c
+++ b/scanparam/scan.c
@@ -39,6 +39,7 @@
#include "scan.h"
#define SCAN_INTERVAL_WIN_UUID 0x2A4F
+#define SCAN_REFRESH_UUID 0x2A31
#define SCAN_INTERVAL 0x0060
#define SCAN_WINDOW 0x0030
@@ -65,6 +66,79 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b)
return -1;
}
+static void ccc_written_cb(guint8 status, const guint8 *pdu,
+ guint16 plen, gpointer user_data)
+{
+ if (status != 0) {
+ error("Write Scan Refresh CCC failed: %s",
+ att_ecode2str(status));
+ return;
+ }
+
+ DBG("Scan Refresh: notification enabled");
+}
+
+static void discover_descriptor_cb(guint8 status, const guint8 *pdu,
+ guint16 len, gpointer user_data)
+{
+ struct scan *scan = user_data;
+ struct att_data_list *list;
+ uint8_t *ptr;
+ uint16_t uuid16, handle;
+ uint8_t value[] = { 0x01, 0x00 };
+ uint8_t format;
+
+ list = dec_find_info_resp(pdu, len, &format);
+ if (list == NULL)
+ return;
+
+ if (format != 0x01)
+ goto done;
+
+ ptr = list->data[0];
+ handle = att_get_u16(ptr);
+ uuid16 = att_get_u16(&ptr[2]);
+
+ if (uuid16 != GATT_CLIENT_CHARAC_CFG_UUID)
+ goto done;
+
+ gatt_write_char(scan->attrib, handle, value, sizeof(value),
+ ccc_written_cb, NULL);
+done:
+ att_data_list_free(list);
+}
+
+static void refresh_discovered_cb(GSList *chars, guint8 status,
+ gpointer user_data)
+{
+ struct scan *scan = user_data;
+ struct gatt_char *chr;
+ uint16_t start, end;
+
+ if (status) {
+ error("Scan Refresh %s", att_ecode2str(status));
+ return;
+ }
+
+ if (!chars) {
+ DBG("Scan Refresh not supported");
+ return;
+ }
+
+ chr = chars->data;
+
+ DBG("Scan Refresh handle: 0x%04x", chr->value_handle);
+
+ start = chr->value_handle + 1;
+ end = scan->range.end;
+
+ if (start >= end)
+ return;
+
+ gatt_find_info(scan->attrib, start, end,
+ discover_descriptor_cb, user_data);
+}
+
static void iwin_discovered_cb(GSList *chars, guint8 status,
gpointer user_data)
{
@@ -93,14 +167,18 @@ static void iwin_discovered_cb(GSList *chars, guint8 status,
static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
struct scan *scan = user_data;
- bt_uuid_t iwin_uuid;
+ bt_uuid_t iwin_uuid, refresh_uuid;
bt_uuid16_create(&iwin_uuid, SCAN_INTERVAL_WIN_UUID);
+ bt_uuid16_create(&refresh_uuid, SCAN_REFRESH_UUID);
scan->attrib = g_attrib_ref(attrib);
gatt_discover_char(scan->attrib, scan->range.start, scan->range.end,
&iwin_uuid, iwin_discovered_cb, scan);
+
+ gatt_discover_char(scan->attrib, scan->range.start, scan->range.end,
+ &refresh_uuid, refresh_discovered_cb, scan);
}
static void attio_disconnected_cb(gpointer user_data)