* [PATCH BlueZ v0 0/8] Scan Parameters Plugin
@ 2012-08-22 19:45 Claudio Takahasi
2012-08-22 19:45 ` [PATCH BlueZ v0 1/8] scan: Add plugin skeleton Claudio Takahasi
` (8 more replies)
0 siblings, 9 replies; 28+ messages in thread
From: Claudio Takahasi @ 2012-08-22 19:45 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
This patch series implements a new GATT based service/plugin for Scan
Parameters: Optional service for HID devices.
This service enables a GATT Client to store the LE scan parameters on
a GATT Server device, allowing the GATT Server to utilize the information
to adjust behavior to optimize power consumption and/or reconnection
latency.
Claudio Takahasi (8):
scan: Add plugin skeleton
scan: Register device driver
scan: Add ATTIO callbacks registration
scan: Add write scan interval window
scan: Enable Scan Refresh notification
scan: Register notification handler
scan: Write parameters when requested
scan: Avoid discover if scan handle is known
Makefile.am | 8 +-
profiles/scanparam/main.c | 55 +++++++++
profiles/scanparam/manager.c | 89 ++++++++++++++
profiles/scanparam/manager.h | 26 +++++
profiles/scanparam/scan.c | 272 +++++++++++++++++++++++++++++++++++++++++++
profiles/scanparam/scan.h | 26 +++++
6 files changed, 474 insertions(+), 2 deletions(-)
create mode 100644 profiles/scanparam/main.c
create mode 100644 profiles/scanparam/manager.c
create mode 100644 profiles/scanparam/manager.h
create mode 100644 profiles/scanparam/scan.c
create mode 100644 profiles/scanparam/scan.h
--
1.7.12
^ permalink raw reply [flat|nested] 28+ messages in thread* [PATCH BlueZ v0 1/8] scan: Add plugin skeleton 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi @ 2012-08-22 19:45 ` Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 2/8] scan: Register device driver Claudio Takahasi ` (7 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-08-22 19:45 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch adds the Makefile changes and plugin declaration to support Scan Parameters service. BlueZ will act as Scan Client writting to a Scan Server the scanning parameters. --- Makefile.am | 5 +++-- profiles/scanparam/main.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/main.c diff --git a/Makefile.am b/Makefile.am index 4977a05..161586e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -212,7 +212,7 @@ endif if GATTMODULES builtin_modules += thermometer alert time gatt_example proximity deviceinfo \ - gatt + gatt scanparam builtin_sources += profiles/thermometer/main.c \ profiles/thermometer/manager.h \ profiles/thermometer/manager.c \ @@ -241,7 +241,8 @@ builtin_sources += profiles/thermometer/main.c \ profiles/deviceinfo/deviceinfo.c \ profiles/gatt/main.c profiles/gatt/manager.h \ profiles/gatt/manager.c profiles/gatt/gas.h \ - profiles/gatt/gas.c + profiles/gatt/gas.c \ + profiles/scanparam/main.c endif builtin_modules += formfactor diff --git a/profiles/scanparam/main.c b/profiles/scanparam/main.c new file mode 100644 index 0000000..6e90929 --- /dev/null +++ b/profiles/scanparam/main.c @@ -0,0 +1,53 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdint.h> +#include <glib.h> + +#include "log.h" +#include "plugin.h" +#include "hcid.h" + +static int scan_param_init(void) +{ + if (!main_opts.gatt_enabled) { + DBG("Scan Parameters: GATT is disabled"); + return -ENOTSUP; + } + + return 0; +} + +static void scan_param_exit(void) +{ +} + +BLUETOOTH_PLUGIN_DEFINE(scanparam, VERSION, + BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, + scan_param_init, scan_param_exit) -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v0 2/8] scan: Register device driver 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 1/8] scan: Add plugin skeleton Claudio Takahasi @ 2012-08-22 19:45 ` Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 3/8] scan: Add ATTIO callbacks registration Claudio Takahasi ` (6 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-08-22 19:45 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch add the probe and remove callbacks for the GATT Scan Parameters service. --- Makefile.am | 4 ++- profiles/scanparam/main.c | 4 ++- profiles/scanparam/manager.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ profiles/scanparam/manager.h | 26 ++++++++++++++++++ 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/manager.c create mode 100644 profiles/scanparam/manager.h diff --git a/Makefile.am b/Makefile.am index 161586e..0bc97ae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -242,7 +242,9 @@ builtin_sources += profiles/thermometer/main.c \ profiles/gatt/main.c profiles/gatt/manager.h \ profiles/gatt/manager.c profiles/gatt/gas.h \ profiles/gatt/gas.c \ - profiles/scanparam/main.c + profiles/scanparam/main.c \ + profiles/scanparam/manager.h \ + profiles/scanparam/manager.c endif builtin_modules += formfactor diff --git a/profiles/scanparam/main.c b/profiles/scanparam/main.c index 6e90929..ba4b2c0 100644 --- a/profiles/scanparam/main.c +++ b/profiles/scanparam/main.c @@ -33,6 +33,7 @@ #include "log.h" #include "plugin.h" #include "hcid.h" +#include "manager.h" static int scan_param_init(void) { @@ -41,11 +42,12 @@ static int scan_param_init(void) return -ENOTSUP; } - return 0; + return scan_param_manager_init(); } static void scan_param_exit(void) { + scan_param_manager_exit(); } BLUETOOTH_PLUGIN_DEFINE(scanparam, VERSION, diff --git a/profiles/scanparam/manager.c b/profiles/scanparam/manager.c new file mode 100644 index 0000000..365320a --- /dev/null +++ b/profiles/scanparam/manager.c @@ -0,0 +1,65 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> + +#include "log.h" +#include "adapter.h" +#include "device.h" +#include "manager.h" + +#define SCAN_PARAMETERS_UUID "00001813-0000-1000-8000-00805f9b34fb" + +static int scan_param_probe(struct btd_device *device, GSList *uuids) +{ + DBG("Probing Scan Parameters"); + + return 0; +} + +static void scan_param_remove(struct btd_device *device) +{ +} + +static struct btd_device_driver scan_driver = { + .name = "Scan Parameters Client Driver", + .uuids = BTD_UUIDS(SCAN_PARAMETERS_UUID), + .probe = scan_param_probe, + .remove = scan_param_remove, +}; + +int scan_param_manager_init(void) +{ + return btd_register_device_driver(&scan_driver); + +} + +void scan_param_manager_exit(void) +{ + btd_unregister_device_driver(&scan_driver); +} diff --git a/profiles/scanparam/manager.h b/profiles/scanparam/manager.h new file mode 100644 index 0000000..1cf2e5e --- /dev/null +++ b/profiles/scanparam/manager.h @@ -0,0 +1,26 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int scan_param_manager_init(void); +void scan_param_manager_exit(void); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v0 3/8] scan: Add ATTIO callbacks registration 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 1/8] scan: Add plugin skeleton Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 2/8] scan: Register device driver Claudio Takahasi @ 2012-08-22 19:45 ` Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 4/8] scan: Add write scan interval window Claudio Takahasi ` (5 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-08-22 19:45 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch add the functions to manage ATTIO callbacks. The current registration mechanism is not suitable for this service since it needs to be passive. Scan Parameters should not actively request connections, it needs to be notified if the connections has been established requested by other services. --- Makefile.am | 3 +- profiles/scanparam/manager.c | 26 ++++++++++- profiles/scanparam/scan.c | 103 +++++++++++++++++++++++++++++++++++++++++++ profiles/scanparam/scan.h | 26 +++++++++++ 4 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/scan.c create mode 100644 profiles/scanparam/scan.h diff --git a/Makefile.am b/Makefile.am index 0bc97ae..955c78f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -244,7 +244,8 @@ builtin_sources += profiles/thermometer/main.c \ profiles/gatt/gas.c \ profiles/scanparam/main.c \ profiles/scanparam/manager.h \ - profiles/scanparam/manager.c + profiles/scanparam/manager.c \ + profiles/scanparam/scan.h profiles/scanparam/scan.c endif builtin_modules += formfactor diff --git a/profiles/scanparam/manager.c b/profiles/scanparam/manager.c index 365320a..2d33f4b 100644 --- a/profiles/scanparam/manager.c +++ b/profiles/scanparam/manager.c @@ -26,24 +26,48 @@ #include <config.h> #endif +#include <errno.h> #include <glib.h> +#include <bluetooth/uuid.h> #include "log.h" #include "adapter.h" #include "device.h" +#include "att.h" +#include "gattrib.h" +#include "gatt.h" #include "manager.h" +#include "scan.h" #define SCAN_PARAMETERS_UUID "00001813-0000-1000-8000-00805f9b34fb" +static gint primary_uuid_cmp(gconstpointer a, gconstpointer b) +{ + const struct gatt_primary *prim = a; + const char *uuid = b; + + return g_strcmp0(prim->uuid, uuid); +} + static int scan_param_probe(struct btd_device *device, GSList *uuids) { + GSList *primaries, *l; + DBG("Probing Scan Parameters"); - return 0; + primaries = btd_device_get_primaries(device); + + l = g_slist_find_custom(primaries, SCAN_PARAMETERS_UUID, + primary_uuid_cmp); + if (!l) + return -EINVAL; + + return scan_register(device, l->data); } static void scan_param_remove(struct btd_device *device) { + scan_unregister(device); } static struct btd_device_driver scan_driver = { diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c new file mode 100644 index 0000000..5af1e57 --- /dev/null +++ b/profiles/scanparam/scan.c @@ -0,0 +1,103 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <bluetooth/bluetooth.h> +#include <bluetooth/uuid.h> + +#include "adapter.h" +#include "device.h" +#include "att.h" +#include "gattrib.h" +#include "gatt.h" +#include "attio.h" +#include "scan.h" + +struct scan { + struct btd_device *device; + GAttrib *attrib; + guint attioid; +}; + +GSList *servers = NULL; + +static gint scan_device_cmp(gconstpointer a, gconstpointer b) +{ + const struct scan *scan = a; + const struct btd_device *device = b; + + return (device == scan->device ? 0 : -1); +} + +static void attio_connected_cb(GAttrib *attrib, gpointer user_data) +{ + struct scan *scan = user_data; + + scan->attrib = g_attrib_ref(attrib); +} + +static void attio_disconnected_cb(gpointer user_data) +{ + struct scan *scan = user_data; + + g_attrib_unref(scan->attrib); + scan->attrib = NULL; +} + +int scan_register(struct btd_device *device, struct gatt_primary *prim) +{ + struct scan *scan; + + scan = g_new0(struct scan, 1); + scan->device = btd_device_ref(device); + scan->attioid = btd_device_add_attio_callback(device, + attio_connected_cb, + attio_disconnected_cb, + scan); + + servers = g_slist_prepend(servers, scan); + + return 0; +} + +void scan_unregister(struct btd_device *device) +{ + struct scan *scan; + GSList *l; + + l = g_slist_find_custom(servers, device, scan_device_cmp); + if (l == NULL) + return; + + scan = l->data; + servers = g_slist_remove(servers, scan); + + btd_device_remove_attio_callback(scan->device, scan->attioid); + btd_device_unref(scan->device); + g_attrib_unref(scan->attrib); + g_free(scan); +} diff --git a/profiles/scanparam/scan.h b/profiles/scanparam/scan.h new file mode 100644 index 0000000..93f7edd --- /dev/null +++ b/profiles/scanparam/scan.h @@ -0,0 +1,26 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int scan_register(struct btd_device *device, struct gatt_primary *prim); +void scan_unregister(struct btd_device *device); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v0 4/8] scan: Add write scan interval window 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi ` (2 preceding siblings ...) 2012-08-22 19:45 ` [PATCH BlueZ v0 3/8] scan: Add ATTIO callbacks registration Claudio Takahasi @ 2012-08-22 19:45 ` Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 5/8] scan: Enable Scan Refresh notification Claudio Takahasi ` (4 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-08-22 19:45 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch adds the handle discovery of the Scan Interval Window Characteristic and writes the default value (hard-coded in the kernel) of the scan interval, and scan window in the remote's characteristic. --- profiles/scanparam/scan.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 5af1e57..86bdcb7 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -29,6 +29,7 @@ #include <bluetooth/bluetooth.h> #include <bluetooth/uuid.h> +#include "log.h" #include "adapter.h" #include "device.h" #include "att.h" @@ -37,10 +38,18 @@ #include "attio.h" #include "scan.h" +#define SCAN_INTERVAL_WIN_UUID 0x2A4F + +#define SCAN_INTERVAL 0x0060 +#define SCAN_WINDOW 0x0030 + struct scan { struct btd_device *device; GAttrib *attrib; + struct att_range range; guint attioid; + uint16_t interval; + uint16_t window; }; GSList *servers = NULL; @@ -53,11 +62,42 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -1); } +static void iwin_discovered_cb(GSList *chars, guint8 status, + gpointer user_data) +{ + struct scan *scan = user_data; + struct gatt_char *chr; + uint8_t value[4]; + + if (status) { + error("Discover Scan Interval Window: %s", + att_ecode2str(status)); + return; + } + + chr = chars->data; + + DBG("Scan Interval Window handle: 0x%04x", + chr->value_handle); + + att_put_u16(SCAN_INTERVAL, &value[0]); + att_put_u16(SCAN_WINDOW, &value[2]); + + gatt_write_char(scan->attrib, chr->value_handle, value, + sizeof(value), NULL, NULL); +} + static void attio_connected_cb(GAttrib *attrib, gpointer user_data) { struct scan *scan = user_data; + bt_uuid_t iwin_uuid; + + bt_uuid16_create(&iwin_uuid, SCAN_INTERVAL_WIN_UUID); scan->attrib = g_attrib_ref(attrib); + + gatt_discover_char(scan->attrib, scan->range.start, scan->range.end, + &iwin_uuid, iwin_discovered_cb, scan); } static void attio_disconnected_cb(gpointer user_data) @@ -74,6 +114,7 @@ int scan_register(struct btd_device *device, struct gatt_primary *prim) scan = g_new0(struct scan, 1); scan->device = btd_device_ref(device); + scan->range = prim->range; scan->attioid = btd_device_add_attio_callback(device, attio_connected_cb, attio_disconnected_cb, -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v0 5/8] scan: Enable Scan Refresh notification 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi ` (3 preceding siblings ...) 2012-08-22 19:45 ` [PATCH BlueZ v0 4/8] scan: Add write scan interval window Claudio Takahasi @ 2012-08-22 19:45 ` Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 6/8] scan: Register notification handler Claudio Takahasi ` (3 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-08-22 19:45 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch discovers the Scan Refresh Characteristic handle and sets it's Client Characteristic Configuration bit to enable notifications. --- profiles/scanparam/scan.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 86bdcb7..59ff336 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/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 @@ -62,6 +63,80 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -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[2]; + uint8_t format; + + list = dec_find_info_resp(pdu, len, &format); + if (list == NULL) + return; + + if (format != ATT_FIND_INFO_RESP_FMT_16BIT) + 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; + + att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value); + 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) { @@ -90,14 +165,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) -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v0 6/8] scan: Register notification handler 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi ` (4 preceding siblings ...) 2012-08-22 19:45 ` [PATCH BlueZ v0 5/8] scan: Enable Scan Refresh notification Claudio Takahasi @ 2012-08-22 19:45 ` Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 7/8] scan: Write parameters when requested Claudio Takahasi ` (2 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-08-22 19:45 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch registers the GAttrib notification handler for Refresh Characteristic notification. --- profiles/scanparam/scan.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 59ff336..36e21f3 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -51,6 +51,8 @@ struct scan { guint attioid; uint16_t interval; uint16_t window; + uint16_t refresh_handle; + uint16_t refresh_cb_id; }; GSList *servers = NULL; @@ -63,9 +65,30 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -1); } +static void refresh_value_cb(const uint8_t *pdu, uint16_t len, + gpointer user_data) +{ + struct scan *scan = user_data; + uint16_t handle; + + if (len < 4) { /* 1-byte opcode + 2-byte handle + refresh */ + error("Malformed ATT notification"); + return; + } + + handle = att_get_u16(&pdu[1]); + + if (handle != scan->refresh_handle) + return; + + DBG("Server requires refresh: %d", pdu[3]); +} + static void ccc_written_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { + struct scan *scan = user_data; + if (status != 0) { error("Write Scan Refresh CCC failed: %s", att_ecode2str(status)); @@ -73,6 +96,10 @@ static void ccc_written_cb(guint8 status, const guint8 *pdu, } DBG("Scan Refresh: notification enabled"); + + scan->refresh_cb_id = g_attrib_register(scan->attrib, + ATT_OP_HANDLE_NOTIFY, refresh_value_cb, + user_data, NULL); } static void discover_descriptor_cb(guint8 status, const guint8 *pdu, @@ -101,7 +128,7 @@ static void discover_descriptor_cb(guint8 status, const guint8 *pdu, att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value); gatt_write_char(scan->attrib, handle, value, sizeof(value), - ccc_written_cb, NULL); + ccc_written_cb, user_data); done: att_data_list_free(list); } @@ -133,6 +160,8 @@ static void refresh_discovered_cb(GSList *chars, guint8 status, if (start >= end) return; + scan->refresh_handle = chr->value_handle; + gatt_find_info(scan->attrib, start, end, discover_descriptor_cb, user_data); } @@ -216,6 +245,11 @@ void scan_unregister(struct btd_device *device) scan = l->data; servers = g_slist_remove(servers, scan); + if (scan->refresh_cb_id) { + g_attrib_unregister(scan->attrib, scan->refresh_cb_id); + scan->refresh_cb_id = 0; + } + btd_device_remove_attio_callback(scan->device, scan->attioid); btd_device_unref(scan->device); g_attrib_unref(scan->attrib); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v0 7/8] scan: Write parameters when requested 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi ` (5 preceding siblings ...) 2012-08-22 19:45 ` [PATCH BlueZ v0 6/8] scan: Register notification handler Claudio Takahasi @ 2012-08-22 19:45 ` Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 8/8] scan: Avoid discover if scan handle is known Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-08-22 19:45 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch implements the update procedure of the scan parameters when the Scan Server requests. The Scan Refresh characteristic is used to inform the Scan Client(BlueZ) that the Scan Server requires the most recent scan settings. --- profiles/scanparam/scan.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 36e21f3..f292eb1 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -43,6 +43,7 @@ #define SCAN_INTERVAL 0x0060 #define SCAN_WINDOW 0x0030 +#define SERVER_REQUIRES_REFRESH 0x00 struct scan { struct btd_device *device; @@ -51,6 +52,7 @@ struct scan { guint attioid; uint16_t interval; uint16_t window; + uint16_t iwhandle; uint16_t refresh_handle; uint16_t refresh_cb_id; }; @@ -65,6 +67,16 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -1); } +static void write_scan_params(GAttrib *attrib, uint16_t handle) +{ + uint8_t value[4]; + + att_put_u16(SCAN_INTERVAL, &value[0]); + att_put_u16(SCAN_WINDOW, &value[2]); + + gatt_write_char(attrib, handle, value, sizeof(value), NULL, NULL); +} + static void refresh_value_cb(const uint8_t *pdu, uint16_t len, gpointer user_data) { @@ -82,6 +94,9 @@ static void refresh_value_cb(const uint8_t *pdu, uint16_t len, return; DBG("Server requires refresh: %d", pdu[3]); + + if (pdu[3] == SERVER_REQUIRES_REFRESH) + write_scan_params(scan->attrib, scan->iwhandle); } static void ccc_written_cb(guint8 status, const guint8 *pdu, @@ -171,7 +186,6 @@ static void iwin_discovered_cb(GSList *chars, guint8 status, { struct scan *scan = user_data; struct gatt_char *chr; - uint8_t value[4]; if (status) { error("Discover Scan Interval Window: %s", @@ -180,15 +194,11 @@ static void iwin_discovered_cb(GSList *chars, guint8 status, } chr = chars->data; + scan->iwhandle = chr->value_handle; - DBG("Scan Interval Window handle: 0x%04x", - chr->value_handle); - - att_put_u16(SCAN_INTERVAL, &value[0]); - att_put_u16(SCAN_WINDOW, &value[2]); + DBG("Scan Interval Window handle: 0x%04x", scan->iwhandle); - gatt_write_char(scan->attrib, chr->value_handle, value, - sizeof(value), NULL, NULL); + write_scan_params(scan->attrib, scan->iwhandle); } static void attio_connected_cb(GAttrib *attrib, gpointer user_data) -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v0 8/8] scan: Avoid discover if scan handle is known 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi ` (6 preceding siblings ...) 2012-08-22 19:45 ` [PATCH BlueZ v0 7/8] scan: Write parameters when requested Claudio Takahasi @ 2012-08-22 19:45 ` Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-08-22 19:45 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch avoids the characteristic discovery for Scan Interval Window if the attribute value handle was discovered on a previous interaction. --- profiles/scanparam/scan.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index f292eb1..788f183 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -206,11 +206,16 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data) struct scan *scan = user_data; bt_uuid_t iwin_uuid, refresh_uuid; + scan->attrib = g_attrib_ref(attrib); + + if (scan->iwhandle) { + write_scan_params(scan->attrib, scan->iwhandle); + return; + } + 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); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v1 0/8] Scan Parameters Plugin 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi ` (7 preceding siblings ...) 2012-08-22 19:45 ` [PATCH BlueZ v0 8/8] scan: Avoid discover if scan handle is known Claudio Takahasi @ 2012-09-03 18:12 ` Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 1/8] scan: Add plugin skeleton Claudio Takahasi ` (8 more replies) 8 siblings, 9 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch series implements a new GATT based service/plugin for Scan Parameters: Optional service for HID devices. This service enables a GATT Client to store the LE scan parameters on a GATT Server device, allowing the GATT Server to use this information to adjust the scanning settings to optimize power consumption and/or reconnection latency. Changes from previous version: Using new profile abstraction (replaces btd_device drivers) Claudio Takahasi (8): scan: Add plugin skeleton scan: Register profile scan: Add ATTIO callbacks registration scan: Add write scan interval window scan: Enable Scan Refresh notification scan: Register notification handler scan: Write parameters when requested scan: Avoid discover if scan handle is known Makefile.am | 8 +- profiles/scanparam/main.c | 55 +++++++++ profiles/scanparam/manager.c | 90 ++++++++++++++ profiles/scanparam/manager.h | 26 ++++ profiles/scanparam/scan.c | 274 +++++++++++++++++++++++++++++++++++++++++++ profiles/scanparam/scan.h | 26 ++++ 6 files changed, 477 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/main.c create mode 100644 profiles/scanparam/manager.c create mode 100644 profiles/scanparam/manager.h create mode 100644 profiles/scanparam/scan.c create mode 100644 profiles/scanparam/scan.h -- 1.7.12 ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH BlueZ v1 1/8] scan: Add plugin skeleton 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi @ 2012-09-03 18:12 ` Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 2/8] scan: Register profile Claudio Takahasi ` (7 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch adds the Makefile changes and plugin declaration to support Scan Parameters service. BlueZ will act as Scan Client writting to a Scan Server the scanning parameters. --- Makefile.am | 5 +++-- profiles/scanparam/main.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/main.c diff --git a/Makefile.am b/Makefile.am index 4977a05..161586e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -212,7 +212,7 @@ endif if GATTMODULES builtin_modules += thermometer alert time gatt_example proximity deviceinfo \ - gatt + gatt scanparam builtin_sources += profiles/thermometer/main.c \ profiles/thermometer/manager.h \ profiles/thermometer/manager.c \ @@ -241,7 +241,8 @@ builtin_sources += profiles/thermometer/main.c \ profiles/deviceinfo/deviceinfo.c \ profiles/gatt/main.c profiles/gatt/manager.h \ profiles/gatt/manager.c profiles/gatt/gas.h \ - profiles/gatt/gas.c + profiles/gatt/gas.c \ + profiles/scanparam/main.c endif builtin_modules += formfactor diff --git a/profiles/scanparam/main.c b/profiles/scanparam/main.c new file mode 100644 index 0000000..6e90929 --- /dev/null +++ b/profiles/scanparam/main.c @@ -0,0 +1,53 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdint.h> +#include <glib.h> + +#include "log.h" +#include "plugin.h" +#include "hcid.h" + +static int scan_param_init(void) +{ + if (!main_opts.gatt_enabled) { + DBG("Scan Parameters: GATT is disabled"); + return -ENOTSUP; + } + + return 0; +} + +static void scan_param_exit(void) +{ +} + +BLUETOOTH_PLUGIN_DEFINE(scanparam, VERSION, + BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, + scan_param_init, scan_param_exit) -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v1 2/8] scan: Register profile 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 1/8] scan: Add plugin skeleton Claudio Takahasi @ 2012-09-03 18:12 ` Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 3/8] scan: Add ATTIO callbacks registration Claudio Takahasi ` (6 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch add the probe and remove callbacks for the GATT Scan Parameters service. --- Makefile.am | 4 ++- profiles/scanparam/main.c | 4 ++- profiles/scanparam/manager.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ profiles/scanparam/manager.h | 26 +++++++++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/manager.c create mode 100644 profiles/scanparam/manager.h diff --git a/Makefile.am b/Makefile.am index 161586e..0bc97ae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -242,7 +242,9 @@ builtin_sources += profiles/thermometer/main.c \ profiles/gatt/main.c profiles/gatt/manager.h \ profiles/gatt/manager.c profiles/gatt/gas.h \ profiles/gatt/gas.c \ - profiles/scanparam/main.c + profiles/scanparam/main.c \ + profiles/scanparam/manager.h \ + profiles/scanparam/manager.c endif builtin_modules += formfactor diff --git a/profiles/scanparam/main.c b/profiles/scanparam/main.c index 6e90929..ba4b2c0 100644 --- a/profiles/scanparam/main.c +++ b/profiles/scanparam/main.c @@ -33,6 +33,7 @@ #include "log.h" #include "plugin.h" #include "hcid.h" +#include "manager.h" static int scan_param_init(void) { @@ -41,11 +42,12 @@ static int scan_param_init(void) return -ENOTSUP; } - return 0; + return scan_param_manager_init(); } static void scan_param_exit(void) { + scan_param_manager_exit(); } BLUETOOTH_PLUGIN_DEFINE(scanparam, VERSION, diff --git a/profiles/scanparam/manager.c b/profiles/scanparam/manager.c new file mode 100644 index 0000000..94625f5 --- /dev/null +++ b/profiles/scanparam/manager.c @@ -0,0 +1,66 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdbool.h> +#include <glib.h> + +#include "log.h" +#include "adapter.h" +#include "device.h" +#include "manager.h" + +#define SCAN_PARAMETERS_UUID "00001813-0000-1000-8000-00805f9b34fb" + +static int scan_param_probe(struct btd_device *device, GSList *uuids) +{ + DBG("Probing Scan Parameters"); + + return 0; +} + +static void scan_param_remove(struct btd_device *device) +{ +} + +static struct btd_profile scan_profile = { + .name = "Scan Parameters Client Driver", + .remote_uuids = BTD_UUIDS(SCAN_PARAMETERS_UUID), + .device_probe = scan_param_probe, + .device_remove = scan_param_remove, +}; + +int scan_param_manager_init(void) +{ + return btd_profile_register(&scan_profile); + +} + +void scan_param_manager_exit(void) +{ + btd_profile_unregister(&scan_profile); +} diff --git a/profiles/scanparam/manager.h b/profiles/scanparam/manager.h new file mode 100644 index 0000000..1cf2e5e --- /dev/null +++ b/profiles/scanparam/manager.h @@ -0,0 +1,26 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int scan_param_manager_init(void); +void scan_param_manager_exit(void); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v1 3/8] scan: Add ATTIO callbacks registration 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 1/8] scan: Add plugin skeleton Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 2/8] scan: Register profile Claudio Takahasi @ 2012-09-03 18:12 ` Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 4/8] scan: Add write scan interval window Claudio Takahasi ` (5 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch add the functions to manage ATTIO callbacks. The current registration mechanism is not suitable for this service since it needs to be passive. Scan Parameters should not actively request connections, it needs to be notified if the connections has been established requested by other services. --- Makefile.am | 3 +- profiles/scanparam/manager.c | 26 ++++++++++- profiles/scanparam/scan.c | 105 +++++++++++++++++++++++++++++++++++++++++++ profiles/scanparam/scan.h | 26 +++++++++++ 4 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/scan.c create mode 100644 profiles/scanparam/scan.h diff --git a/Makefile.am b/Makefile.am index 0bc97ae..955c78f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -244,7 +244,8 @@ builtin_sources += profiles/thermometer/main.c \ profiles/gatt/gas.c \ profiles/scanparam/main.c \ profiles/scanparam/manager.h \ - profiles/scanparam/manager.c + profiles/scanparam/manager.c \ + profiles/scanparam/scan.h profiles/scanparam/scan.c endif builtin_modules += formfactor diff --git a/profiles/scanparam/manager.c b/profiles/scanparam/manager.c index 94625f5..b413f41 100644 --- a/profiles/scanparam/manager.c +++ b/profiles/scanparam/manager.c @@ -27,24 +27,48 @@ #endif #include <stdbool.h> +#include <errno.h> #include <glib.h> +#include <bluetooth/uuid.h> #include "log.h" #include "adapter.h" #include "device.h" +#include "att.h" +#include "gattrib.h" +#include "gatt.h" #include "manager.h" +#include "scan.h" #define SCAN_PARAMETERS_UUID "00001813-0000-1000-8000-00805f9b34fb" +static gint primary_uuid_cmp(gconstpointer a, gconstpointer b) +{ + const struct gatt_primary *prim = a; + const char *uuid = b; + + return g_strcmp0(prim->uuid, uuid); +} + static int scan_param_probe(struct btd_device *device, GSList *uuids) { + GSList *primaries, *l; + DBG("Probing Scan Parameters"); - return 0; + primaries = btd_device_get_primaries(device); + + l = g_slist_find_custom(primaries, SCAN_PARAMETERS_UUID, + primary_uuid_cmp); + if (!l) + return -EINVAL; + + return scan_register(device, l->data); } static void scan_param_remove(struct btd_device *device) { + scan_unregister(device); } static struct btd_profile scan_profile = { diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c new file mode 100644 index 0000000..c6aaf97 --- /dev/null +++ b/profiles/scanparam/scan.c @@ -0,0 +1,105 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdbool.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/uuid.h> + +#include "adapter.h" +#include "device.h" +#include "att.h" +#include "gattrib.h" +#include "gatt.h" +#include "attio.h" +#include "scan.h" + +struct scan { + struct btd_device *device; + GAttrib *attrib; + guint attioid; +}; + +GSList *servers = NULL; + +static gint scan_device_cmp(gconstpointer a, gconstpointer b) +{ + const struct scan *scan = a; + const struct btd_device *device = b; + + return (device == scan->device ? 0 : -1); +} + +static void attio_connected_cb(GAttrib *attrib, gpointer user_data) +{ + struct scan *scan = user_data; + + scan->attrib = g_attrib_ref(attrib); +} + +static void attio_disconnected_cb(gpointer user_data) +{ + struct scan *scan = user_data; + + g_attrib_unref(scan->attrib); + scan->attrib = NULL; +} + +int scan_register(struct btd_device *device, struct gatt_primary *prim) +{ + struct scan *scan; + + scan = g_new0(struct scan, 1); + scan->device = btd_device_ref(device); + scan->attioid = btd_device_add_attio_callback(device, + attio_connected_cb, + attio_disconnected_cb, + scan); + + servers = g_slist_prepend(servers, scan); + + return 0; +} + +void scan_unregister(struct btd_device *device) +{ + struct scan *scan; + GSList *l; + + l = g_slist_find_custom(servers, device, scan_device_cmp); + if (l == NULL) + return; + + scan = l->data; + servers = g_slist_remove(servers, scan); + + btd_device_remove_attio_callback(scan->device, scan->attioid); + btd_device_unref(scan->device); + g_attrib_unref(scan->attrib); + g_free(scan); +} diff --git a/profiles/scanparam/scan.h b/profiles/scanparam/scan.h new file mode 100644 index 0000000..93f7edd --- /dev/null +++ b/profiles/scanparam/scan.h @@ -0,0 +1,26 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int scan_register(struct btd_device *device, struct gatt_primary *prim); +void scan_unregister(struct btd_device *device); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v1 4/8] scan: Add write scan interval window 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi ` (2 preceding siblings ...) 2012-09-03 18:12 ` [PATCH BlueZ v1 3/8] scan: Add ATTIO callbacks registration Claudio Takahasi @ 2012-09-03 18:12 ` Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 5/8] scan: Enable Scan Refresh notification Claudio Takahasi ` (4 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch adds the handle discovery of the Scan Interval Window Characteristic and writes the default value (hard-coded in the kernel) of the scan interval, and scan window in the remote's characteristic. --- profiles/scanparam/scan.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index c6aaf97..03934b0 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -31,6 +31,7 @@ #include <bluetooth/bluetooth.h> #include <bluetooth/uuid.h> +#include "log.h" #include "adapter.h" #include "device.h" #include "att.h" @@ -39,10 +40,18 @@ #include "attio.h" #include "scan.h" +#define SCAN_INTERVAL_WIN_UUID 0x2A4F + +#define SCAN_INTERVAL 0x0060 +#define SCAN_WINDOW 0x0030 + struct scan { struct btd_device *device; GAttrib *attrib; + struct att_range range; guint attioid; + uint16_t interval; + uint16_t window; }; GSList *servers = NULL; @@ -55,11 +64,42 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -1); } +static void iwin_discovered_cb(GSList *chars, guint8 status, + gpointer user_data) +{ + struct scan *scan = user_data; + struct gatt_char *chr; + uint8_t value[4]; + + if (status) { + error("Discover Scan Interval Window: %s", + att_ecode2str(status)); + return; + } + + chr = chars->data; + + DBG("Scan Interval Window handle: 0x%04x", + chr->value_handle); + + att_put_u16(SCAN_INTERVAL, &value[0]); + att_put_u16(SCAN_WINDOW, &value[2]); + + gatt_write_char(scan->attrib, chr->value_handle, value, + sizeof(value), NULL, NULL); +} + static void attio_connected_cb(GAttrib *attrib, gpointer user_data) { struct scan *scan = user_data; + bt_uuid_t iwin_uuid; + + bt_uuid16_create(&iwin_uuid, SCAN_INTERVAL_WIN_UUID); scan->attrib = g_attrib_ref(attrib); + + gatt_discover_char(scan->attrib, scan->range.start, scan->range.end, + &iwin_uuid, iwin_discovered_cb, scan); } static void attio_disconnected_cb(gpointer user_data) @@ -76,6 +116,7 @@ int scan_register(struct btd_device *device, struct gatt_primary *prim) scan = g_new0(struct scan, 1); scan->device = btd_device_ref(device); + scan->range = prim->range; scan->attioid = btd_device_add_attio_callback(device, attio_connected_cb, attio_disconnected_cb, -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v1 5/8] scan: Enable Scan Refresh notification 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi ` (3 preceding siblings ...) 2012-09-03 18:12 ` [PATCH BlueZ v1 4/8] scan: Add write scan interval window Claudio Takahasi @ 2012-09-03 18:12 ` Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 6/8] scan: Register notification handler Claudio Takahasi ` (3 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch discovers the Scan Refresh Characteristic handle and sets it's Client Characteristic Configuration bit to enable notifications. --- profiles/scanparam/scan.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 03934b0..7285774 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -41,6 +41,7 @@ #include "scan.h" #define SCAN_INTERVAL_WIN_UUID 0x2A4F +#define SCAN_REFRESH_UUID 0x2A31 #define SCAN_INTERVAL 0x0060 #define SCAN_WINDOW 0x0030 @@ -64,6 +65,80 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -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[2]; + uint8_t format; + + list = dec_find_info_resp(pdu, len, &format); + if (list == NULL) + return; + + if (format != ATT_FIND_INFO_RESP_FMT_16BIT) + 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; + + att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value); + 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) { @@ -92,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) -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v1 6/8] scan: Register notification handler 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi ` (4 preceding siblings ...) 2012-09-03 18:12 ` [PATCH BlueZ v1 5/8] scan: Enable Scan Refresh notification Claudio Takahasi @ 2012-09-03 18:12 ` Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 7/8] scan: Write parameters when requested Claudio Takahasi ` (2 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch registers the GAttrib notification handler for Refresh Characteristic notification. --- profiles/scanparam/scan.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 7285774..08d04a7 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -53,6 +53,8 @@ struct scan { guint attioid; uint16_t interval; uint16_t window; + uint16_t refresh_handle; + uint16_t refresh_cb_id; }; GSList *servers = NULL; @@ -65,9 +67,30 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -1); } +static void refresh_value_cb(const uint8_t *pdu, uint16_t len, + gpointer user_data) +{ + struct scan *scan = user_data; + uint16_t handle; + + if (len < 4) { /* 1-byte opcode + 2-byte handle + refresh */ + error("Malformed ATT notification"); + return; + } + + handle = att_get_u16(&pdu[1]); + + if (handle != scan->refresh_handle) + return; + + DBG("Server requires refresh: %d", pdu[3]); +} + static void ccc_written_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { + struct scan *scan = user_data; + if (status != 0) { error("Write Scan Refresh CCC failed: %s", att_ecode2str(status)); @@ -75,6 +98,10 @@ static void ccc_written_cb(guint8 status, const guint8 *pdu, } DBG("Scan Refresh: notification enabled"); + + scan->refresh_cb_id = g_attrib_register(scan->attrib, + ATT_OP_HANDLE_NOTIFY, refresh_value_cb, + user_data, NULL); } static void discover_descriptor_cb(guint8 status, const guint8 *pdu, @@ -103,7 +130,7 @@ static void discover_descriptor_cb(guint8 status, const guint8 *pdu, att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value); gatt_write_char(scan->attrib, handle, value, sizeof(value), - ccc_written_cb, NULL); + ccc_written_cb, user_data); done: att_data_list_free(list); } @@ -135,6 +162,8 @@ static void refresh_discovered_cb(GSList *chars, guint8 status, if (start >= end) return; + scan->refresh_handle = chr->value_handle; + gatt_find_info(scan->attrib, start, end, discover_descriptor_cb, user_data); } @@ -218,6 +247,11 @@ void scan_unregister(struct btd_device *device) scan = l->data; servers = g_slist_remove(servers, scan); + if (scan->refresh_cb_id) { + g_attrib_unregister(scan->attrib, scan->refresh_cb_id); + scan->refresh_cb_id = 0; + } + btd_device_remove_attio_callback(scan->device, scan->attioid); btd_device_unref(scan->device); g_attrib_unref(scan->attrib); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v1 7/8] scan: Write parameters when requested 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi ` (5 preceding siblings ...) 2012-09-03 18:12 ` [PATCH BlueZ v1 6/8] scan: Register notification handler Claudio Takahasi @ 2012-09-03 18:12 ` Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 8/8] scan: Avoid discover if scan handle is known Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch implements the update procedure of the scan parameters when the Scan Server requests. The Scan Refresh characteristic is used to inform the Scan Client(BlueZ) that the Scan Server requires the most recent scan settings. --- profiles/scanparam/scan.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 08d04a7..50fef43 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -45,6 +45,7 @@ #define SCAN_INTERVAL 0x0060 #define SCAN_WINDOW 0x0030 +#define SERVER_REQUIRES_REFRESH 0x00 struct scan { struct btd_device *device; @@ -53,6 +54,7 @@ struct scan { guint attioid; uint16_t interval; uint16_t window; + uint16_t iwhandle; uint16_t refresh_handle; uint16_t refresh_cb_id; }; @@ -67,6 +69,16 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -1); } +static void write_scan_params(GAttrib *attrib, uint16_t handle) +{ + uint8_t value[4]; + + att_put_u16(SCAN_INTERVAL, &value[0]); + att_put_u16(SCAN_WINDOW, &value[2]); + + gatt_write_char(attrib, handle, value, sizeof(value), NULL, NULL); +} + static void refresh_value_cb(const uint8_t *pdu, uint16_t len, gpointer user_data) { @@ -84,6 +96,9 @@ static void refresh_value_cb(const uint8_t *pdu, uint16_t len, return; DBG("Server requires refresh: %d", pdu[3]); + + if (pdu[3] == SERVER_REQUIRES_REFRESH) + write_scan_params(scan->attrib, scan->iwhandle); } static void ccc_written_cb(guint8 status, const guint8 *pdu, @@ -173,7 +188,6 @@ static void iwin_discovered_cb(GSList *chars, guint8 status, { struct scan *scan = user_data; struct gatt_char *chr; - uint8_t value[4]; if (status) { error("Discover Scan Interval Window: %s", @@ -182,15 +196,11 @@ static void iwin_discovered_cb(GSList *chars, guint8 status, } chr = chars->data; + scan->iwhandle = chr->value_handle; - DBG("Scan Interval Window handle: 0x%04x", - chr->value_handle); - - att_put_u16(SCAN_INTERVAL, &value[0]); - att_put_u16(SCAN_WINDOW, &value[2]); + DBG("Scan Interval Window handle: 0x%04x", scan->iwhandle); - gatt_write_char(scan->attrib, chr->value_handle, value, - sizeof(value), NULL, NULL); + write_scan_params(scan->attrib, scan->iwhandle); } static void attio_connected_cb(GAttrib *attrib, gpointer user_data) -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v1 8/8] scan: Avoid discover if scan handle is known 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi ` (6 preceding siblings ...) 2012-09-03 18:12 ` [PATCH BlueZ v1 7/8] scan: Write parameters when requested Claudio Takahasi @ 2012-09-03 18:12 ` Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch avoids the characteristic discovery for Scan Interval Window if the attribute value handle was discovered on a previous interaction. --- profiles/scanparam/scan.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 50fef43..491b50d 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -208,11 +208,16 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data) struct scan *scan = user_data; bt_uuid_t iwin_uuid, refresh_uuid; + scan->attrib = g_attrib_ref(attrib); + + if (scan->iwhandle) { + write_scan_params(scan->attrib, scan->iwhandle); + return; + } + 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); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v2 0/8] Scan Parameters Plugin 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi ` (7 preceding siblings ...) 2012-09-03 18:12 ` [PATCH BlueZ v1 8/8] scan: Avoid discover if scan handle is known Claudio Takahasi @ 2012-09-25 15:26 ` Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 1/8] scan: Add plugin skeleton Claudio Takahasi ` (8 more replies) 8 siblings, 9 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch series implements a new GATT based service/plugin for Scan Parameters: Optional service for HID devices. This service enables a GATT Client to store the LE scan parameters on a GATT Server device, allowing the GATT Server to use this information to adjust the scanning settings to optimize power consumption and/or reconnection latency. v1 changes: Using new profile abstraction (replaces btd_device drivers) v2 changes: Add profile parameter to device probe function Claudio Takahasi (8): scan: Add plugin skeleton scan: Register profile scan: Add ATTIO callbacks registration scan: Add write scan interval window scan: Enable Scan Refresh notification scan: Register notification handler scan: Write parameters when requested scan: Avoid discover if scan handle is known Makefile.am | 8 +- profiles/scanparam/main.c | 55 +++++++++ profiles/scanparam/manager.c | 92 +++++++++++++++ profiles/scanparam/manager.h | 26 ++++ profiles/scanparam/scan.c | 274 +++++++++++++++++++++++++++++++++++++++++++ profiles/scanparam/scan.h | 26 ++++ 6 files changed, 479 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/main.c create mode 100644 profiles/scanparam/manager.c create mode 100644 profiles/scanparam/manager.h create mode 100644 profiles/scanparam/scan.c create mode 100644 profiles/scanparam/scan.h -- 1.7.12 ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH BlueZ v2 1/8] scan: Add plugin skeleton 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi @ 2012-09-25 15:26 ` Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 2/8] scan: Register profile Claudio Takahasi ` (7 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch adds the Makefile changes and plugin declaration to support Scan Parameters service. BlueZ will act as Scan Client writting to a Scan Server the scanning parameters. --- Makefile.am | 5 +++-- profiles/scanparam/main.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/main.c diff --git a/Makefile.am b/Makefile.am index 315077f..bf86453 100644 --- a/Makefile.am +++ b/Makefile.am @@ -211,7 +211,7 @@ endif if GATTMODULES builtin_modules += thermometer alert time gatt_example proximity deviceinfo \ - gatt + gatt scanparam builtin_sources += profiles/thermometer/main.c \ profiles/thermometer/manager.h \ profiles/thermometer/manager.c \ @@ -240,7 +240,8 @@ builtin_sources += profiles/thermometer/main.c \ profiles/deviceinfo/deviceinfo.c \ profiles/gatt/main.c profiles/gatt/manager.h \ profiles/gatt/manager.c profiles/gatt/gas.h \ - profiles/gatt/gas.c + profiles/gatt/gas.c \ + profiles/scanparam/main.c endif builtin_modules += formfactor diff --git a/profiles/scanparam/main.c b/profiles/scanparam/main.c new file mode 100644 index 0000000..6e90929 --- /dev/null +++ b/profiles/scanparam/main.c @@ -0,0 +1,53 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdint.h> +#include <glib.h> + +#include "log.h" +#include "plugin.h" +#include "hcid.h" + +static int scan_param_init(void) +{ + if (!main_opts.gatt_enabled) { + DBG("Scan Parameters: GATT is disabled"); + return -ENOTSUP; + } + + return 0; +} + +static void scan_param_exit(void) +{ +} + +BLUETOOTH_PLUGIN_DEFINE(scanparam, VERSION, + BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, + scan_param_init, scan_param_exit) -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v2 2/8] scan: Register profile 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 1/8] scan: Add plugin skeleton Claudio Takahasi @ 2012-09-25 15:26 ` Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 3/8] scan: Add ATTIO callbacks registration Claudio Takahasi ` (6 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch add the probe and remove callbacks for the GATT Scan Parameters service. --- Makefile.am | 4 ++- profiles/scanparam/main.c | 4 ++- profiles/scanparam/manager.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ profiles/scanparam/manager.h | 26 +++++++++++++++++ 4 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/manager.c create mode 100644 profiles/scanparam/manager.h diff --git a/Makefile.am b/Makefile.am index bf86453..50f780e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -241,7 +241,9 @@ builtin_sources += profiles/thermometer/main.c \ profiles/gatt/main.c profiles/gatt/manager.h \ profiles/gatt/manager.c profiles/gatt/gas.h \ profiles/gatt/gas.c \ - profiles/scanparam/main.c + profiles/scanparam/main.c \ + profiles/scanparam/manager.h \ + profiles/scanparam/manager.c endif builtin_modules += formfactor diff --git a/profiles/scanparam/main.c b/profiles/scanparam/main.c index 6e90929..ba4b2c0 100644 --- a/profiles/scanparam/main.c +++ b/profiles/scanparam/main.c @@ -33,6 +33,7 @@ #include "log.h" #include "plugin.h" #include "hcid.h" +#include "manager.h" static int scan_param_init(void) { @@ -41,11 +42,12 @@ static int scan_param_init(void) return -ENOTSUP; } - return 0; + return scan_param_manager_init(); } static void scan_param_exit(void) { + scan_param_manager_exit(); } BLUETOOTH_PLUGIN_DEFINE(scanparam, VERSION, diff --git a/profiles/scanparam/manager.c b/profiles/scanparam/manager.c new file mode 100644 index 0000000..c1ac0bb --- /dev/null +++ b/profiles/scanparam/manager.c @@ -0,0 +1,68 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdbool.h> +#include <glib.h> + +#include "log.h" +#include "adapter.h" +#include "device.h" +#include "profile.h" +#include "manager.h" + +#define SCAN_PARAMETERS_UUID "00001813-0000-1000-8000-00805f9b34fb" + +static int scan_param_probe(struct btd_profile *p, struct btd_device *device, + GSList *uuids) +{ + DBG("Probing Scan Parameters"); + + return 0; +} + +static void scan_param_remove(struct btd_profile *p, struct btd_device *device) +{ +} + +static struct btd_profile scan_profile = { + .name = "Scan Parameters Client Driver", + .remote_uuids = BTD_UUIDS(SCAN_PARAMETERS_UUID), + .device_probe = scan_param_probe, + .device_remove = scan_param_remove, +}; + +int scan_param_manager_init(void) +{ + return btd_profile_register(&scan_profile); + +} + +void scan_param_manager_exit(void) +{ + btd_profile_unregister(&scan_profile); +} diff --git a/profiles/scanparam/manager.h b/profiles/scanparam/manager.h new file mode 100644 index 0000000..1cf2e5e --- /dev/null +++ b/profiles/scanparam/manager.h @@ -0,0 +1,26 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int scan_param_manager_init(void); +void scan_param_manager_exit(void); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v2 3/8] scan: Add ATTIO callbacks registration 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 1/8] scan: Add plugin skeleton Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 2/8] scan: Register profile Claudio Takahasi @ 2012-09-25 15:26 ` Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 4/8] scan: Add write scan interval window Claudio Takahasi ` (5 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch add the functions to manage ATTIO callbacks. The current registration mechanism is not suitable for this service since it needs to be passive. Scan Parameters should not actively request connections, it needs to be notified if the connections has been established requested by other services. --- Makefile.am | 3 +- profiles/scanparam/manager.c | 26 ++++++++++- profiles/scanparam/scan.c | 105 +++++++++++++++++++++++++++++++++++++++++++ profiles/scanparam/scan.h | 26 +++++++++++ 4 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 profiles/scanparam/scan.c create mode 100644 profiles/scanparam/scan.h diff --git a/Makefile.am b/Makefile.am index 50f780e..bdfa1cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -243,7 +243,8 @@ builtin_sources += profiles/thermometer/main.c \ profiles/gatt/gas.c \ profiles/scanparam/main.c \ profiles/scanparam/manager.h \ - profiles/scanparam/manager.c + profiles/scanparam/manager.c \ + profiles/scanparam/scan.h profiles/scanparam/scan.c endif builtin_modules += formfactor diff --git a/profiles/scanparam/manager.c b/profiles/scanparam/manager.c index c1ac0bb..24d1e78 100644 --- a/profiles/scanparam/manager.c +++ b/profiles/scanparam/manager.c @@ -27,26 +27,50 @@ #endif #include <stdbool.h> +#include <errno.h> #include <glib.h> +#include <bluetooth/uuid.h> #include "log.h" #include "adapter.h" #include "device.h" #include "profile.h" +#include "att.h" +#include "gattrib.h" +#include "gatt.h" #include "manager.h" +#include "scan.h" #define SCAN_PARAMETERS_UUID "00001813-0000-1000-8000-00805f9b34fb" +static gint primary_uuid_cmp(gconstpointer a, gconstpointer b) +{ + const struct gatt_primary *prim = a; + const char *uuid = b; + + return g_strcmp0(prim->uuid, uuid); +} + static int scan_param_probe(struct btd_profile *p, struct btd_device *device, GSList *uuids) { + GSList *primaries, *l; + DBG("Probing Scan Parameters"); - return 0; + primaries = btd_device_get_primaries(device); + + l = g_slist_find_custom(primaries, SCAN_PARAMETERS_UUID, + primary_uuid_cmp); + if (!l) + return -EINVAL; + + return scan_register(device, l->data); } static void scan_param_remove(struct btd_profile *p, struct btd_device *device) { + scan_unregister(device); } static struct btd_profile scan_profile = { diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c new file mode 100644 index 0000000..c6aaf97 --- /dev/null +++ b/profiles/scanparam/scan.c @@ -0,0 +1,105 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdbool.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/uuid.h> + +#include "adapter.h" +#include "device.h" +#include "att.h" +#include "gattrib.h" +#include "gatt.h" +#include "attio.h" +#include "scan.h" + +struct scan { + struct btd_device *device; + GAttrib *attrib; + guint attioid; +}; + +GSList *servers = NULL; + +static gint scan_device_cmp(gconstpointer a, gconstpointer b) +{ + const struct scan *scan = a; + const struct btd_device *device = b; + + return (device == scan->device ? 0 : -1); +} + +static void attio_connected_cb(GAttrib *attrib, gpointer user_data) +{ + struct scan *scan = user_data; + + scan->attrib = g_attrib_ref(attrib); +} + +static void attio_disconnected_cb(gpointer user_data) +{ + struct scan *scan = user_data; + + g_attrib_unref(scan->attrib); + scan->attrib = NULL; +} + +int scan_register(struct btd_device *device, struct gatt_primary *prim) +{ + struct scan *scan; + + scan = g_new0(struct scan, 1); + scan->device = btd_device_ref(device); + scan->attioid = btd_device_add_attio_callback(device, + attio_connected_cb, + attio_disconnected_cb, + scan); + + servers = g_slist_prepend(servers, scan); + + return 0; +} + +void scan_unregister(struct btd_device *device) +{ + struct scan *scan; + GSList *l; + + l = g_slist_find_custom(servers, device, scan_device_cmp); + if (l == NULL) + return; + + scan = l->data; + servers = g_slist_remove(servers, scan); + + btd_device_remove_attio_callback(scan->device, scan->attioid); + btd_device_unref(scan->device); + g_attrib_unref(scan->attrib); + g_free(scan); +} diff --git a/profiles/scanparam/scan.h b/profiles/scanparam/scan.h new file mode 100644 index 0000000..93f7edd --- /dev/null +++ b/profiles/scanparam/scan.h @@ -0,0 +1,26 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Nordic Semiconductor Inc. + * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int scan_register(struct btd_device *device, struct gatt_primary *prim); +void scan_unregister(struct btd_device *device); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v2 4/8] scan: Add write scan interval window 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi ` (2 preceding siblings ...) 2012-09-25 15:26 ` [PATCH BlueZ v2 3/8] scan: Add ATTIO callbacks registration Claudio Takahasi @ 2012-09-25 15:26 ` Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 5/8] scan: Enable Scan Refresh notification Claudio Takahasi ` (4 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch adds the handle discovery of the Scan Interval Window Characteristic and writes the default value (hard-coded in the kernel) of the scan interval, and scan window in the remote's characteristic. --- profiles/scanparam/scan.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index c6aaf97..03934b0 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -31,6 +31,7 @@ #include <bluetooth/bluetooth.h> #include <bluetooth/uuid.h> +#include "log.h" #include "adapter.h" #include "device.h" #include "att.h" @@ -39,10 +40,18 @@ #include "attio.h" #include "scan.h" +#define SCAN_INTERVAL_WIN_UUID 0x2A4F + +#define SCAN_INTERVAL 0x0060 +#define SCAN_WINDOW 0x0030 + struct scan { struct btd_device *device; GAttrib *attrib; + struct att_range range; guint attioid; + uint16_t interval; + uint16_t window; }; GSList *servers = NULL; @@ -55,11 +64,42 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -1); } +static void iwin_discovered_cb(GSList *chars, guint8 status, + gpointer user_data) +{ + struct scan *scan = user_data; + struct gatt_char *chr; + uint8_t value[4]; + + if (status) { + error("Discover Scan Interval Window: %s", + att_ecode2str(status)); + return; + } + + chr = chars->data; + + DBG("Scan Interval Window handle: 0x%04x", + chr->value_handle); + + att_put_u16(SCAN_INTERVAL, &value[0]); + att_put_u16(SCAN_WINDOW, &value[2]); + + gatt_write_char(scan->attrib, chr->value_handle, value, + sizeof(value), NULL, NULL); +} + static void attio_connected_cb(GAttrib *attrib, gpointer user_data) { struct scan *scan = user_data; + bt_uuid_t iwin_uuid; + + bt_uuid16_create(&iwin_uuid, SCAN_INTERVAL_WIN_UUID); scan->attrib = g_attrib_ref(attrib); + + gatt_discover_char(scan->attrib, scan->range.start, scan->range.end, + &iwin_uuid, iwin_discovered_cb, scan); } static void attio_disconnected_cb(gpointer user_data) @@ -76,6 +116,7 @@ int scan_register(struct btd_device *device, struct gatt_primary *prim) scan = g_new0(struct scan, 1); scan->device = btd_device_ref(device); + scan->range = prim->range; scan->attioid = btd_device_add_attio_callback(device, attio_connected_cb, attio_disconnected_cb, -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v2 5/8] scan: Enable Scan Refresh notification 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi ` (3 preceding siblings ...) 2012-09-25 15:26 ` [PATCH BlueZ v2 4/8] scan: Add write scan interval window Claudio Takahasi @ 2012-09-25 15:26 ` Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 6/8] scan: Register notification handler Claudio Takahasi ` (3 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch discovers the Scan Refresh Characteristic handle and sets it's Client Characteristic Configuration bit to enable notifications. --- profiles/scanparam/scan.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 03934b0..7285774 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -41,6 +41,7 @@ #include "scan.h" #define SCAN_INTERVAL_WIN_UUID 0x2A4F +#define SCAN_REFRESH_UUID 0x2A31 #define SCAN_INTERVAL 0x0060 #define SCAN_WINDOW 0x0030 @@ -64,6 +65,80 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -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[2]; + uint8_t format; + + list = dec_find_info_resp(pdu, len, &format); + if (list == NULL) + return; + + if (format != ATT_FIND_INFO_RESP_FMT_16BIT) + 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; + + att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value); + 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) { @@ -92,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) -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v2 6/8] scan: Register notification handler 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi ` (4 preceding siblings ...) 2012-09-25 15:26 ` [PATCH BlueZ v2 5/8] scan: Enable Scan Refresh notification Claudio Takahasi @ 2012-09-25 15:26 ` Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 7/8] scan: Write parameters when requested Claudio Takahasi ` (2 subsequent siblings) 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch registers the GAttrib notification handler for Refresh Characteristic notification. --- profiles/scanparam/scan.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 7285774..08d04a7 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -53,6 +53,8 @@ struct scan { guint attioid; uint16_t interval; uint16_t window; + uint16_t refresh_handle; + uint16_t refresh_cb_id; }; GSList *servers = NULL; @@ -65,9 +67,30 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -1); } +static void refresh_value_cb(const uint8_t *pdu, uint16_t len, + gpointer user_data) +{ + struct scan *scan = user_data; + uint16_t handle; + + if (len < 4) { /* 1-byte opcode + 2-byte handle + refresh */ + error("Malformed ATT notification"); + return; + } + + handle = att_get_u16(&pdu[1]); + + if (handle != scan->refresh_handle) + return; + + DBG("Server requires refresh: %d", pdu[3]); +} + static void ccc_written_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { + struct scan *scan = user_data; + if (status != 0) { error("Write Scan Refresh CCC failed: %s", att_ecode2str(status)); @@ -75,6 +98,10 @@ static void ccc_written_cb(guint8 status, const guint8 *pdu, } DBG("Scan Refresh: notification enabled"); + + scan->refresh_cb_id = g_attrib_register(scan->attrib, + ATT_OP_HANDLE_NOTIFY, refresh_value_cb, + user_data, NULL); } static void discover_descriptor_cb(guint8 status, const guint8 *pdu, @@ -103,7 +130,7 @@ static void discover_descriptor_cb(guint8 status, const guint8 *pdu, att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value); gatt_write_char(scan->attrib, handle, value, sizeof(value), - ccc_written_cb, NULL); + ccc_written_cb, user_data); done: att_data_list_free(list); } @@ -135,6 +162,8 @@ static void refresh_discovered_cb(GSList *chars, guint8 status, if (start >= end) return; + scan->refresh_handle = chr->value_handle; + gatt_find_info(scan->attrib, start, end, discover_descriptor_cb, user_data); } @@ -218,6 +247,11 @@ void scan_unregister(struct btd_device *device) scan = l->data; servers = g_slist_remove(servers, scan); + if (scan->refresh_cb_id) { + g_attrib_unregister(scan->attrib, scan->refresh_cb_id); + scan->refresh_cb_id = 0; + } + btd_device_remove_attio_callback(scan->device, scan->attioid); btd_device_unref(scan->device); g_attrib_unref(scan->attrib); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v2 7/8] scan: Write parameters when requested 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi ` (5 preceding siblings ...) 2012-09-25 15:26 ` [PATCH BlueZ v2 6/8] scan: Register notification handler Claudio Takahasi @ 2012-09-25 15:26 ` Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 8/8] scan: Avoid discover if scan handle is known Claudio Takahasi 2012-09-28 10:05 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Johan Hedberg 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch implements the update procedure of the scan parameters when the Scan Server requests. The Scan Refresh characteristic is used to inform the Scan Client(BlueZ) that the Scan Server requires the most recent scan settings. --- profiles/scanparam/scan.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 08d04a7..50fef43 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -45,6 +45,7 @@ #define SCAN_INTERVAL 0x0060 #define SCAN_WINDOW 0x0030 +#define SERVER_REQUIRES_REFRESH 0x00 struct scan { struct btd_device *device; @@ -53,6 +54,7 @@ struct scan { guint attioid; uint16_t interval; uint16_t window; + uint16_t iwhandle; uint16_t refresh_handle; uint16_t refresh_cb_id; }; @@ -67,6 +69,16 @@ static gint scan_device_cmp(gconstpointer a, gconstpointer b) return (device == scan->device ? 0 : -1); } +static void write_scan_params(GAttrib *attrib, uint16_t handle) +{ + uint8_t value[4]; + + att_put_u16(SCAN_INTERVAL, &value[0]); + att_put_u16(SCAN_WINDOW, &value[2]); + + gatt_write_char(attrib, handle, value, sizeof(value), NULL, NULL); +} + static void refresh_value_cb(const uint8_t *pdu, uint16_t len, gpointer user_data) { @@ -84,6 +96,9 @@ static void refresh_value_cb(const uint8_t *pdu, uint16_t len, return; DBG("Server requires refresh: %d", pdu[3]); + + if (pdu[3] == SERVER_REQUIRES_REFRESH) + write_scan_params(scan->attrib, scan->iwhandle); } static void ccc_written_cb(guint8 status, const guint8 *pdu, @@ -173,7 +188,6 @@ static void iwin_discovered_cb(GSList *chars, guint8 status, { struct scan *scan = user_data; struct gatt_char *chr; - uint8_t value[4]; if (status) { error("Discover Scan Interval Window: %s", @@ -182,15 +196,11 @@ static void iwin_discovered_cb(GSList *chars, guint8 status, } chr = chars->data; + scan->iwhandle = chr->value_handle; - DBG("Scan Interval Window handle: 0x%04x", - chr->value_handle); - - att_put_u16(SCAN_INTERVAL, &value[0]); - att_put_u16(SCAN_WINDOW, &value[2]); + DBG("Scan Interval Window handle: 0x%04x", scan->iwhandle); - gatt_write_char(scan->attrib, chr->value_handle, value, - sizeof(value), NULL, NULL); + write_scan_params(scan->attrib, scan->iwhandle); } static void attio_connected_cb(GAttrib *attrib, gpointer user_data) -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH BlueZ v2 8/8] scan: Avoid discover if scan handle is known 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi ` (6 preceding siblings ...) 2012-09-25 15:26 ` [PATCH BlueZ v2 7/8] scan: Write parameters when requested Claudio Takahasi @ 2012-09-25 15:26 ` Claudio Takahasi 2012-09-28 10:05 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Johan Hedberg 8 siblings, 0 replies; 28+ messages in thread From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: Claudio Takahasi This patch avoids the characteristic discovery for Scan Interval Window if the attribute value handle was discovered on a previous interaction. --- profiles/scanparam/scan.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c index 50fef43..491b50d 100644 --- a/profiles/scanparam/scan.c +++ b/profiles/scanparam/scan.c @@ -208,11 +208,16 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data) struct scan *scan = user_data; bt_uuid_t iwin_uuid, refresh_uuid; + scan->attrib = g_attrib_ref(attrib); + + if (scan->iwhandle) { + write_scan_params(scan->attrib, scan->iwhandle); + return; + } + 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); -- 1.7.12 ^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH BlueZ v2 0/8] Scan Parameters Plugin 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi ` (7 preceding siblings ...) 2012-09-25 15:26 ` [PATCH BlueZ v2 8/8] scan: Avoid discover if scan handle is known Claudio Takahasi @ 2012-09-28 10:05 ` Johan Hedberg 8 siblings, 0 replies; 28+ messages in thread From: Johan Hedberg @ 2012-09-28 10:05 UTC (permalink / raw) To: Claudio Takahasi; +Cc: linux-bluetooth Hi Claudio, On Tue, Sep 25, 2012, Claudio Takahasi wrote: > This patch series implements a new GATT based service/plugin for Scan > Parameters: Optional service for HID devices. > > This service enables a GATT Client to store the LE scan parameters on > a GATT Server device, allowing the GATT Server to use this information > to adjust the scanning settings to optimize power consumption and/or > reconnection latency. > > v1 changes: Using new profile abstraction (replaces btd_device drivers) > v2 changes: Add profile parameter to device probe function > > Claudio Takahasi (8): > scan: Add plugin skeleton > scan: Register profile > scan: Add ATTIO callbacks registration > scan: Add write scan interval window > scan: Enable Scan Refresh notification > scan: Register notification handler > scan: Write parameters when requested > scan: Avoid discover if scan handle is known > > Makefile.am | 8 +- > profiles/scanparam/main.c | 55 +++++++++ > profiles/scanparam/manager.c | 92 +++++++++++++++ > profiles/scanparam/manager.h | 26 ++++ > profiles/scanparam/scan.c | 274 +++++++++++++++++++++++++++++++++++++++++++ > profiles/scanparam/scan.h | 26 ++++ > 6 files changed, 479 insertions(+), 2 deletions(-) > create mode 100644 profiles/scanparam/main.c > create mode 100644 profiles/scanparam/manager.c > create mode 100644 profiles/scanparam/manager.h > create mode 100644 profiles/scanparam/scan.c > create mode 100644 profiles/scanparam/scan.h All patches in this set have been applied. Thanks. Johan ^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2012-09-28 10:05 UTC | newest] Thread overview: 28+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-08-22 19:45 [PATCH BlueZ v0 0/8] Scan Parameters Plugin Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 1/8] scan: Add plugin skeleton Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 2/8] scan: Register device driver Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 3/8] scan: Add ATTIO callbacks registration Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 4/8] scan: Add write scan interval window Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 5/8] scan: Enable Scan Refresh notification Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 6/8] scan: Register notification handler Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 7/8] scan: Write parameters when requested Claudio Takahasi 2012-08-22 19:45 ` [PATCH BlueZ v0 8/8] scan: Avoid discover if scan handle is known Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 0/8] Scan Parameters Plugin Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 1/8] scan: Add plugin skeleton Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 2/8] scan: Register profile Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 3/8] scan: Add ATTIO callbacks registration Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 4/8] scan: Add write scan interval window Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 5/8] scan: Enable Scan Refresh notification Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 6/8] scan: Register notification handler Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 7/8] scan: Write parameters when requested Claudio Takahasi 2012-09-03 18:12 ` [PATCH BlueZ v1 8/8] scan: Avoid discover if scan handle is known Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 1/8] scan: Add plugin skeleton Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 2/8] scan: Register profile Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 3/8] scan: Add ATTIO callbacks registration Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 4/8] scan: Add write scan interval window Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 5/8] scan: Enable Scan Refresh notification Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 6/8] scan: Register notification handler Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 7/8] scan: Write parameters when requested Claudio Takahasi 2012-09-25 15:26 ` [PATCH BlueZ v2 8/8] scan: Avoid discover if scan handle is known Claudio Takahasi 2012-09-28 10:05 ` [PATCH BlueZ v2 0/8] Scan Parameters Plugin Johan Hedberg
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).