* [PATCH BlueZ v1 3/8] scan: Add ATTIO callbacks registration
From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346695965-25422-1-git-send-email-claudio.takahasi@openbossa.org>
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
* [PATCH BlueZ v1 4/8] scan: Add write scan interval window
From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346695965-25422-1-git-send-email-claudio.takahasi@openbossa.org>
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
* [PATCH BlueZ v1 5/8] scan: Enable Scan Refresh notification
From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346695965-25422-1-git-send-email-claudio.takahasi@openbossa.org>
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
* [PATCH BlueZ v1 6/8] scan: Register notification handler
From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346695965-25422-1-git-send-email-claudio.takahasi@openbossa.org>
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
* [PATCH BlueZ v1 7/8] scan: Write parameters when requested
From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346695965-25422-1-git-send-email-claudio.takahasi@openbossa.org>
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
* [PATCH BlueZ v1 8/8] scan: Avoid discover if scan handle is known
From: Claudio Takahasi @ 2012-09-03 18:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346695965-25422-1-git-send-email-claudio.takahasi@openbossa.org>
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
* Re: [PATCH BlueZ v4 01/15] core: Fix missing g_io_channel_ref
From: Joao Paulo Rechi Vita @ 2012-09-03 18:16 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20120830233451.GA972@x220.sheraton.com>
On Thu, Aug 30, 2012 at 8:34 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi João Paulo,
>
> On Thu, Aug 30, 2012, João Paulo Rechi Vita wrote:
>> ---
>> src/device.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/src/device.c b/src/device.c
>> index 3b44d9b..2c40ec2 100644
>> --- a/src/device.c
>> +++ b/src/device.c
>> @@ -2027,7 +2027,7 @@ static gboolean att_connect(gpointer user_data)
>> return FALSE;
>> }
>>
>> - device->att_io = io;
>> + device->att_io = g_io_channel_ref(io);
>>
>> return FALSE;
>> }
>
> This doesn't look right to me. bt_io_connect returns a reference for the
> caller and you shouldn't need to re-increment the ref count again unless
> you store a pointer in multiple places (which you don't). If this patch
> fixes some behavior the real bug must be somewhere else.
>
Yes, this became wrong due to spliting this code out of "core:
Mutually exclude concurrent connections". I'll fix that and re-send
the series one more time.
--
João Paulo Rechi Vita
Openbossa Labs - INdT
^ permalink raw reply
* [PATCH BlueZ v2 0/6] HoG Suspend/Resume
From: Claudio Takahasi @ 2012-09-03 18:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346273590-16693-1-git-send-email-claudio.takahasi@openbossa.org>
This patch series adds HID Control Point support. This control point
allows the report host(BlueZ) to notify the report device(HoG device)
when the host is entering or leaving the Suspend Mode.
The low power Suspend Mode concept is implementation specific. This
proposal adds a selectable back-end for HoG Suspend/Resume control.
Each platform is free to write it's own HoG suspend back-end.
A dummy back-end based on a FIFO (/tmp/hogsuspend) is proposed for
reference and testing purpose only. Writting "suspend" or "resume"
in this FIFO will trigger the update of the HID Control Point.
Notify the HoG device is useful to save power. Devices can implement
different actions (diff than disconnect) when commands are written
on the HID control point. The HoG capable device cab reduce the key
press detection frequency or disable LEDs.
*** v1 changes:
Replaces UPower by a dummy selectable back-end. As discussed in IRC
tracking UPower "suspending" or "resuming" signals are not suitable
for desktops since the connection is dropped right after detecting
suspend.
*** v2 changes:
Code rebased and fixed conflicts with the recent changes. Due the
new profile abstraction (btd_device drivers replaces) v1 doesn't apply.
Claudio Takahasi (6):
hog: Add initial files for suspend support
hog: Add suspend back-end selection
hog: Add suspend/resume callbacks declaration
hog: Create a FIFO for dummy suspend
hog: Move HoG device list to manager
hog: Add writting Control Point
Makefile.am | 6 +-
acinclude.m4 | 7 ++
profiles/input/hog_device.c | 73 ++++++++++++++-------
profiles/input/hog_device.h | 9 ++-
profiles/input/hog_manager.c | 62 ++++++++++++++++-
profiles/input/suspend-dummy.c | 146 +++++++++++++++++++++++++++++++++++++++++
profiles/input/suspend.h | 29 ++++++++
7 files changed, 302 insertions(+), 30 deletions(-)
create mode 100644 profiles/input/suspend-dummy.c
create mode 100644 profiles/input/suspend.h
--
1.7.12
^ permalink raw reply
* [PATCH BlueZ v2 1/6] hog: Add initial files for suspend support
From: Claudio Takahasi @ 2012-09-03 18:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346696594-1062-1-git-send-email-claudio.takahasi@openbossa.org>
This patch adds the initial files to support HoG suspend. The suspend
concept for HoG is implementation specific. The proposal is allowing
back-end selection at build time. Each Linux distribution/platform is
responsible for defining and writting their own policy to manage suspend
on HoG capable devices.
When setting the Control Point, the report device can execute actions to
save power. eg: Reduce the cycle of the key press detection or disable
LEDs.
---
Makefile.am | 3 ++-
profiles/input/hog_manager.c | 14 ++++++++++++++
profiles/input/suspend-dummy.c | 38 ++++++++++++++++++++++++++++++++++++++
profiles/input/suspend.h | 26 ++++++++++++++++++++++++++
4 files changed, 80 insertions(+), 1 deletion(-)
create mode 100644 profiles/input/suspend-dummy.c
create mode 100644 profiles/input/suspend.h
diff --git a/Makefile.am b/Makefile.am
index 4977a05..f6eb96b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -184,7 +184,8 @@ endif
if HOGPLUGIN
builtin_modules += hog
builtin_sources += profiles/input/hog_manager.c profiles/input/hog_device.h \
- profiles/input/hog_device.c profiles/input/uhid_copy.h
+ profiles/input/hog_device.c profiles/input/uhid_copy.h \
+ profiles/input/suspend-dummy.c profiles/input/suspend.h
endif
if NETWORKPLUGIN
diff --git a/profiles/input/hog_manager.c b/profiles/input/hog_manager.c
index 6d971fa..79cd712 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
@@ -36,8 +36,11 @@
#include "plugin.h"
#include "hcid.h"
#include "device.h"
+#include "suspend.h"
#include "hog_device.h"
+static gboolean suspend_supported = FALSE;
+
static int hog_device_probe(struct btd_device *device, GSList *uuids)
{
const char *path = device_get_path(device);
@@ -65,11 +68,22 @@ static struct btd_profile hog_profile = {
static int hog_manager_init(void)
{
+ int err;
+
+ err = suspend_init();
+ if (err < 0)
+ DBG("Suspend: %s(%d)", strerror(-err), -err);
+ else
+ suspend_supported = TRUE;
+
return btd_profile_register(&hog_profile);
}
static void hog_manager_exit(void)
{
+ if (suspend_supported)
+ suspend_exit();
+
btd_profile_register(&hog_profile);
}
diff --git a/profiles/input/suspend-dummy.c b/profiles/input/suspend-dummy.c
new file mode 100644
index 0000000..0a97158
--- /dev/null
+++ b/profiles/input/suspend-dummy.c
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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 "suspend.h"
+
+int suspend_init(void)
+{
+ return 0;
+}
+
+void suspend_exit(void)
+{
+}
diff --git a/profiles/input/suspend.h b/profiles/input/suspend.h
new file mode 100644
index 0000000..3f37a29
--- /dev/null
+++ b/profiles/input/suspend.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 suspend_init(void);
+void suspend_exit(void);
--
1.7.12
^ permalink raw reply related
* [PATCH BlueZ v2 2/6] hog: Add suspend back-end selection
From: Claudio Takahasi @ 2012-09-03 18:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346696594-1062-1-git-send-email-claudio.takahasi@openbossa.org>
This patch series introduces back-end selection for HoG suspend drivers.
The default back-end is called "dummy", added for testing purpose only.
---
Makefile.am | 3 +++
acinclude.m4 | 7 +++++++
2 files changed, 10 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index f6eb96b..198515b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -439,6 +439,9 @@ audio/telephony.c: audio/@TELEPHONY_DRIVER@
profiles/sap/sap.c: profiles/sap/@SAP_DRIVER@
$(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@
+profiles/input/suspend.c: profiles/input/@HOG_SUSPEND_DRIVER@
+ $(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@
+
scripts/%.rules:
$(AM_V_GEN)cp $(subst 97-,,$@) $@
diff --git a/acinclude.m4 b/acinclude.m4
index 39b0a18..ed2d011 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -185,6 +185,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
datafiles_enable=yes
telephony_driver=dummy
sap_driver=dummy
+ hog_suspend_driver=dummy
dbusoob_enable=no
wiimote_enable=no
gatt_enable=no
@@ -288,6 +289,12 @@ AC_DEFUN([AC_ARG_BLUEZ], [
wiimote_enable=${enableval}
])
+ AC_ARG_WITH(gatt, AC_HELP_STRING([--with-hog-suspend=DRIVER], [select HoG suspend driver]), [
+ hog_suspend_driver=${withval}
+ ])
+
+ AC_SUBST([HOG_SUSPEND_DRIVER], [suspend-${hog_suspend_driver}.c])
+
AC_ARG_ENABLE(gatt, AC_HELP_STRING([--enable-gatt], [enable gatt module]), [
gatt_enable=${enableval}
])
--
1.7.12
^ permalink raw reply related
* [PATCH BlueZ v2 3/6] hog: Add suspend/resume callbacks declaration
From: Claudio Takahasi @ 2012-09-03 18:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346696594-1062-1-git-send-email-claudio.takahasi@openbossa.org>
This patch declares the callbacks functions that intend to be used
by the suspend back-ends.
---
profiles/input/hog_manager.c | 12 +++++++++++-
profiles/input/suspend-dummy.c | 10 +++++++++-
profiles/input/suspend.h | 5 ++++-
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/profiles/input/hog_manager.c b/profiles/input/hog_manager.c
index 79cd712..98f8158 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
@@ -41,6 +41,16 @@
static gboolean suspend_supported = FALSE;
+static void suspend_callback(void)
+{
+ DBG("Suspending ...");
+}
+
+static void resume_callback(void)
+{
+ DBG("Resuming ...");
+}
+
static int hog_device_probe(struct btd_device *device, GSList *uuids)
{
const char *path = device_get_path(device);
@@ -70,7 +80,7 @@ static int hog_manager_init(void)
{
int err;
- err = suspend_init();
+ err = suspend_init(suspend_callback, resume_callback);
if (err < 0)
DBG("Suspend: %s(%d)", strerror(-err), -err);
else
diff --git a/profiles/input/suspend-dummy.c b/profiles/input/suspend-dummy.c
index 0a97158..282d3fb 100644
--- a/profiles/input/suspend-dummy.c
+++ b/profiles/input/suspend-dummy.c
@@ -26,10 +26,18 @@
#include <config.h>
#endif
+#include <stdlib.h>
+
#include "suspend.h"
-int suspend_init(void)
+static suspend_event suspend_cb = NULL;
+static resume_event resume_cb = NULL;
+
+int suspend_init(suspend_event suspend, resume_event resume)
{
+ suspend_cb = suspend;
+ resume_cb = resume;
+
return 0;
}
diff --git a/profiles/input/suspend.h b/profiles/input/suspend.h
index 3f37a29..bfee3cf 100644
--- a/profiles/input/suspend.h
+++ b/profiles/input/suspend.h
@@ -22,5 +22,8 @@
*
*/
-int suspend_init(void);
+typedef void (*suspend_event) (void);
+typedef void (*resume_event) (void);
+
+int suspend_init(suspend_event suspend, resume_event resume);
void suspend_exit(void);
--
1.7.12
^ permalink raw reply related
* [PATCH BlueZ v2 4/6] hog: Create a FIFO for dummy suspend
From: Claudio Takahasi @ 2012-09-03 18:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346696594-1062-1-git-send-email-claudio.takahasi@openbossa.org>
This patch creates a FIFO on "/tmp/hogsuspend" to allow the users to
test the HoG suspend(HID Control Point) when the dummy back-end is
enabled.
---
profiles/input/suspend-dummy.c | 102 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 101 insertions(+), 1 deletion(-)
diff --git a/profiles/input/suspend-dummy.c b/profiles/input/suspend-dummy.c
index 282d3fb..f2941fe 100644
--- a/profiles/input/suspend-dummy.c
+++ b/profiles/input/suspend-dummy.c
@@ -26,21 +26,121 @@
#include <config.h>
#endif
+#include <errno.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include "log.h"
#include "suspend.h"
+#define HOG_SUSPEND_FIFO "/tmp/hogsuspend"
+
static suspend_event suspend_cb = NULL;
static resume_event resume_cb = NULL;
+static GIOChannel *fifoio = NULL;
+
+static int fifo_open(void);
+
+static gboolean read_fifo(GIOChannel *io, GIOCondition cond, gpointer user_data)
+{
+ gchar buffer[12];
+ gsize offset, left, bread;
+ GIOStatus iostatus;
+
+ if (cond & (G_IO_ERR | G_IO_HUP))
+ goto failed;
+
+ offset = 0;
+ left = sizeof(buffer) - 1;
+ memset(buffer, 0, sizeof(buffer));
+
+ do {
+ iostatus = g_io_channel_read_chars(io, &buffer[offset], left,
+ &bread, NULL);
+
+ offset += bread;
+ left -= bread;
+ if (left == 0)
+ break;
+ } while (iostatus == G_IO_STATUS_NORMAL);
+
+ if (g_ascii_strncasecmp("suspend", buffer, 7) == 0)
+ suspend_cb();
+ else if (g_ascii_strncasecmp("resume", buffer, 6) == 0)
+ resume_cb();
+
+ return TRUE;
+
+failed:
+ /*
+ * Both ends needs to be open simultaneously before proceeding any input
+ * or output operation. When the remote closes the channel, hup signal is
+ * received on this end.
+ */
+
+ g_io_channel_unref(fifoio);
+ fifoio = NULL;
+
+ fifo_open();
+
+ return FALSE;
+}
+
+static int fifo_open(void)
+{
+ GIOCondition condition = G_IO_IN | G_IO_ERR | G_IO_HUP;
+ int fd;
+
+ fd = open(HOG_SUSPEND_FIFO, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ int err = -errno;
+ error("Can't open FIFO (%s): %s(%d)", HOG_SUSPEND_FIFO,
+ strerror(-err), -err);
+ return err;
+ }
+
+ fifoio = g_io_channel_unix_new(fd);
+ g_io_channel_set_close_on_unref(fifoio, TRUE);
+
+ g_io_add_watch(fifoio, condition, read_fifo, NULL);
+
+ return 0;
+}
int suspend_init(suspend_event suspend, resume_event resume)
{
+ int ret;
+
suspend_cb = suspend;
resume_cb = resume;
- return 0;
+ if (mkfifo(HOG_SUSPEND_FIFO, S_IRWXU) < 0) {
+ int err = -errno;
+ error("Can't create FIFO (%s) : %s(%d)", HOG_SUSPEND_FIFO,
+ strerror(-err), -err);
+ return err;
+ }
+
+ ret = fifo_open();
+ if (ret < 0)
+ remove(HOG_SUSPEND_FIFO);
+
+ return ret;
}
void suspend_exit(void)
{
+ if (fifoio) {
+ g_io_channel_shutdown(fifoio, FALSE, NULL);
+ g_io_channel_unref(fifoio);
+ }
+
+ remove(HOG_SUSPEND_FIFO);
}
--
1.7.12
^ permalink raw reply related
* [PATCH BlueZ v2 5/6] hog: Move HoG device list to manager
From: Claudio Takahasi @ 2012-09-03 18:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346696594-1062-1-git-send-email-claudio.takahasi@openbossa.org>
This patch moves the HoG device list from hog_device.c to hog_manager.c
in order to be possible to easily notify suspend/resume events to each
created device.
---
profiles/input/hog_device.c | 46 +++++++++++++++++++++-----------------------
profiles/input/hog_device.h | 8 ++++++--
profiles/input/hog_manager.c | 22 +++++++++++++++++++--
3 files changed, 48 insertions(+), 28 deletions(-)
diff --git a/profiles/input/hog_device.c b/profiles/input/hog_device.c
index 664c52b..6f73ede 100644
--- a/profiles/input/hog_device.c
+++ b/profiles/input/hog_device.c
@@ -94,8 +94,6 @@ struct report {
struct hog_device *hogdev;
};
-static GSList *devices = NULL;
-
static gint report_handle_cmp(gconstpointer a, gconstpointer b)
{
const struct report *report = a;
@@ -629,7 +627,7 @@ static void attio_disconnected_cb(gpointer user_data)
hogdev->attrib = NULL;
}
-static struct hog_device *find_device_by_path(GSList *list, const char *path)
+struct hog_device *hog_device_find(GSList *list, const char *path)
{
for (; list; list = list->next) {
struct hog_device *hogdev = list->data;
@@ -691,31 +689,33 @@ static void hog_device_free(struct hog_device *hogdev)
g_free(hogdev);
}
-int hog_device_register(struct btd_device *device, const char *path)
+struct hog_device *hog_device_register(struct btd_device *device,
+ const char *path, int *perr)
{
- struct hog_device *hogdev;
struct gatt_primary *prim;
+ struct hog_device *hogdev;
GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
GIOChannel *io;
-
- hogdev = find_device_by_path(devices, path);
- if (hogdev)
- return -EALREADY;
+ int err;
prim = load_hog_primary(device);
- if (!prim)
- return -EINVAL;
+ if (!prim) {
+ err = -EINVAL;
+ goto failed;
+ }
hogdev = hog_device_new(device, path);
- if (!hogdev)
- return -ENOMEM;
+ if (!hogdev) {
+ err = -ENOMEM;
+ goto failed;
+ }
hogdev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
if (hogdev->uhid_fd < 0) {
- int err = -errno;
+ err = -errno;
error("Failed to open uHID device: %s", strerror(-err));
hog_device_free(hogdev);
- return err;
+ goto failed;
}
io = g_io_channel_unix_new(hogdev->uhid_fd);
@@ -733,20 +733,19 @@ int hog_device_register(struct btd_device *device, const char *path)
device_set_auto_connect(device, TRUE);
- devices = g_slist_append(devices, hogdev);
+ return hogdev;
- return 0;
+failed:
+ if (perr)
+ *perr = err;
+
+ return NULL;
}
-int hog_device_unregister(const char *path)
+int hog_device_unregister(struct hog_device *hogdev)
{
- struct hog_device *hogdev;
struct uhid_event ev;
- hogdev = find_device_by_path(devices, path);
- if (hogdev == NULL)
- return -EINVAL;
-
btd_device_remove_attio_callback(hogdev->device, hogdev->attioid);
if (hogdev->uhid_watch_id) {
@@ -762,7 +761,6 @@ int hog_device_unregister(const char *path)
close(hogdev->uhid_fd);
hogdev->uhid_fd = -1;
- devices = g_slist_remove(devices, hogdev);
hog_device_free(hogdev);
return 0;
diff --git a/profiles/input/hog_device.h b/profiles/input/hog_device.h
index 597dc7c..efb7b4f 100644
--- a/profiles/input/hog_device.h
+++ b/profiles/input/hog_device.h
@@ -25,5 +25,9 @@
#define HOG_UUID "00001812-0000-1000-8000-00805f9b34fb"
-int hog_device_register(struct btd_device *device, const char *path);
-int hog_device_unregister(const char *path);
+struct hog_device;
+
+struct hog_device *hog_device_register(struct btd_device *device,
+ const char *path, int *perr);
+int hog_device_unregister(struct hog_device *hogdev);
+struct hog_device *hog_device_find(GSList *list, const char *path);
diff --git a/profiles/input/hog_manager.c b/profiles/input/hog_manager.c
index 98f8158..25974c4 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
@@ -40,6 +40,7 @@
#include "hog_device.h"
static gboolean suspend_supported = FALSE;
+static GSList *devices = NULL;
static void suspend_callback(void)
{
@@ -54,19 +55,36 @@ static void resume_callback(void)
static int hog_device_probe(struct btd_device *device, GSList *uuids)
{
const char *path = device_get_path(device);
+ struct hog_device *hogdev;
+ int err;
DBG("path %s", path);
- return hog_device_register(device, path);
+ hogdev = hog_device_find(devices, path);
+ if (hogdev)
+ return -EALREADY;
+
+ hogdev = hog_device_register(device, path, &err);
+ if (hogdev == NULL)
+ return err;
+
+ devices = g_slist_append(devices, hogdev);
+
+ return 0;
}
static void hog_device_remove(struct btd_device *device)
{
const gchar *path = device_get_path(device);
+ struct hog_device *hogdev;
DBG("path %s", path);
- hog_device_unregister(path);
+ hogdev = hog_device_find(devices, path);
+ if (hogdev) {
+ devices = g_slist_remove(devices, hogdev);
+ hog_device_unregister(hogdev);
+ }
}
static struct btd_profile hog_profile = {
--
1.7.12
^ permalink raw reply related
* [PATCH BlueZ v2 6/6] hog: Add writting Control Point
From: Claudio Takahasi @ 2012-09-03 18:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346696594-1062-1-git-send-email-claudio.takahasi@openbossa.org>
This patch adds GATT write without response operation when suspending
or resuming.
---
profiles/input/hog_device.c | 27 ++++++++++++++++++++++++++-
profiles/input/hog_device.h | 1 +
profiles/input/hog_manager.c | 16 ++++++++++++++++
3 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/profiles/input/hog_device.c b/profiles/input/hog_device.c
index 6f73ede..e68134c 100644
--- a/profiles/input/hog_device.c
+++ b/profiles/input/hog_device.c
@@ -57,6 +57,7 @@
#define HOG_REPORT_MAP_UUID 0x2A4B
#define HOG_REPORT_UUID 0x2A4D
#define HOG_PROTO_MODE_UUID 0x2A4E
+#define HOG_CONTROL_POINT_UUID 0x2A4C
#define HOG_REPORT_TYPE_INPUT 1
#define HOG_REPORT_TYPE_OUTPUT 2
@@ -84,6 +85,7 @@ struct hog_device {
uint16_t bcdhid;
uint8_t bcountrycode;
uint16_t proto_mode_handle;
+ uint16_t ctrlpt_handle;
uint8_t flags;
};
@@ -439,7 +441,8 @@ static void proto_mode_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
static void char_discovered_cb(GSList *chars, guint8 status, gpointer user_data)
{
struct hog_device *hogdev = user_data;
- bt_uuid_t report_uuid, report_map_uuid, info_uuid, proto_mode_uuid;
+ bt_uuid_t report_uuid, report_map_uuid, info_uuid, proto_mode_uuid,
+ ctrlpt_uuid;
struct report *report;
GSList *l;
uint16_t info_handle = 0, proto_mode_handle = 0;
@@ -454,6 +457,7 @@ static void char_discovered_cb(GSList *chars, guint8 status, gpointer user_data)
bt_uuid16_create(&report_map_uuid, HOG_REPORT_MAP_UUID);
bt_uuid16_create(&info_uuid, HOG_INFO_UUID);
bt_uuid16_create(&proto_mode_uuid, HOG_PROTO_MODE_UUID);
+ bt_uuid16_create(&ctrlpt_uuid, HOG_CONTROL_POINT_UUID);
for (l = chars; l; l = g_slist_next(l)) {
struct gatt_char *chr, *next;
@@ -482,6 +486,8 @@ static void char_discovered_cb(GSList *chars, guint8 status, gpointer user_data)
info_handle = chr->value_handle;
else if (bt_uuid_cmp(&uuid, &proto_mode_uuid) == 0)
proto_mode_handle = chr->value_handle;
+ else if (bt_uuid_cmp(&uuid, &ctrlpt_uuid) == 0)
+ hogdev->ctrlpt_handle = chr->value_handle;
}
if (proto_mode_handle) {
@@ -765,3 +771,22 @@ int hog_device_unregister(struct hog_device *hogdev)
return 0;
}
+
+int hog_device_set_control_point(struct hog_device *hogdev, gboolean suspend)
+{
+ uint8_t value = suspend ? 0x00 : 0x01;
+
+ if (hogdev->attrib == NULL)
+ return -ENOTCONN;
+
+ DBG("%s HID Control Point: %s", hogdev->path, suspend ?
+ "Suspend" : "Exit Suspend");
+
+ if (hogdev->ctrlpt_handle == 0)
+ return -ENOTSUP;
+
+ gatt_write_char(hogdev->attrib, hogdev->ctrlpt_handle, &value,
+ sizeof(value), NULL, NULL);
+
+ return 0;
+}
diff --git a/profiles/input/hog_device.h b/profiles/input/hog_device.h
index efb7b4f..03f1c90 100644
--- a/profiles/input/hog_device.h
+++ b/profiles/input/hog_device.h
@@ -31,3 +31,4 @@ struct hog_device *hog_device_register(struct btd_device *device,
const char *path, int *perr);
int hog_device_unregister(struct hog_device *hogdev);
struct hog_device *hog_device_find(GSList *list, const char *path);
+int hog_device_set_control_point(struct hog_device *hogdev, gboolean suspend);
diff --git a/profiles/input/hog_manager.c b/profiles/input/hog_manager.c
index 25974c4..d770b2a 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
@@ -42,14 +42,30 @@
static gboolean suspend_supported = FALSE;
static GSList *devices = NULL;
+static void set_suspend(gpointer data, gpointer user_data)
+{
+ struct hog_device *hogdev = data;
+ gboolean suspend = GPOINTER_TO_INT(user_data);
+
+ hog_device_set_control_point(hogdev, suspend);
+}
+
static void suspend_callback(void)
{
+ gboolean suspend = TRUE;
+
DBG("Suspending ...");
+
+ g_slist_foreach(devices, set_suspend, GINT_TO_POINTER(suspend));
}
static void resume_callback(void)
{
+ gboolean suspend = FALSE;
+
DBG("Resuming ...");
+
+ g_slist_foreach(devices, set_suspend, GINT_TO_POINTER(suspend));
}
static int hog_device_probe(struct btd_device *device, GSList *uuids)
--
1.7.12
^ permalink raw reply related
* [PATCH v7] gatt: Translate Characteristic names
From: chen.ganir @ 2012-09-04 4:46 UTC (permalink / raw)
To: linux-bluetooth; +Cc: chen.ganir
From: Chen Ganir <chen.ganir@ti.com>
Translate Characteristic UUID's to name. This list was taken from
the Bluetooth SIG developer site.
---
attrib/client.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 73 insertions(+), 3 deletions(-)
diff --git a/attrib/client.c b/attrib/client.c
index 906d345..d51e558 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -106,8 +106,77 @@ struct watcher {
struct gatt_service *gatt;
};
+static const struct {
+ const char *uuid;
+ const char *name;
+} char_names[] = {
+ { "00002a43-0000-1000-8000-00805f9b34fb", "Alert Category ID" },
+ { "00002a42-0000-1000-8000-00805f9b34fb", "Alert Category ID Bit Mask" },
+ { "00002a06-0000-1000-8000-00805f9b34fb", "Alert Level" },
+ { "00002a44-0000-1000-8000-00805f9b34fb", "Alert Notification Control Point" },
+ { "00002a3f-0000-1000-8000-00805f9b34fb", "Alert Status" },
+ { "00002a01-0000-1000-8000-00805f9b34fb", "Appearance" },
+ { "00002a49-0000-1000-8000-00805f9b34fb", "Blood Pressure Feature" },
+ { "00002a35-0000-1000-8000-00805f9b34fb", "Blood Pressure Measurement" },
+ { "00002a38-0000-1000-8000-00805f9b34fb", "Body Sensor Location" },
+ { "00002a2b-0000-1000-8000-00805f9b34fb", "Current Time" },
+ { "00002a08-0000-1000-8000-00805f9b34fb", "Date Time" },
+ { "00002a0a-0000-1000-8000-00805f9b34fb", "Day Date Time" },
+ { "00002a09-0000-1000-8000-00805f9b34fb", "Day of Week" },
+ { "00002a00-0000-1000-8000-00805f9b34fb", "Device Name" },
+ { "00002a0d-0000-1000-8000-00805f9b34fb", "DST Offset" },
+ { "00002a0c-0000-1000-8000-00805f9b34fb", "Exact Time 256" },
+ { "00002a26-0000-1000-8000-00805f9b34fb", "Firmware Revision String" },
+ { "00002a27-0000-1000-8000-00805f9b34fb", "Hardware Revision String" },
+ { "00002a39-0000-1000-8000-00805f9b34fb", "Heart Rate Control Point" },
+ { "00002a37-0000-1000-8000-00805f9b34fb", "Heart Rate Measurement" },
+ { "00002a2a-0000-1000-8000-00805f9b34fb", "IEEE 11073-20601 Regulatory" },
+ { "00002a36-0000-1000-8000-00805f9b34fb", "Intermediate Cuff Pressure" },
+ { "00002a1e-0000-1000-8000-00805f9b34fb", "Intermediate Temperature" },
+ { "00002a0f-0000-1000-8000-00805f9b34fb", "Local Time Information" },
+ { "00002a29-0000-1000-8000-00805f9b34fb", "Manufacturer Name String" },
+ { "00002a21-0000-1000-8000-00805f9b34fb", "Measurement Interval" },
+ { "00002a24-0000-1000-8000-00805f9b34fb", "Model Number String" },
+ { "00002a46-0000-1000-8000-00805f9b34fb", "New Alert" },
+ { "00002a04-0000-1000-8000-00805f9b34fb", "Peripheral Preferred Connection Parameters" },
+ { "00002a02-0000-1000-8000-00805f9b34fb", "Peripheral Privacy Flag" },
+ { "00002a03-0000-1000-8000-00805f9b34fb", "Reconnection Address" },
+ { "00002a14-0000-1000-8000-00805f9b34fb", "Reference Time Information" },
+ { "00002a40-0000-1000-8000-00805f9b34fb", "Ringer Control Point" },
+ { "00002a41-0000-1000-8000-00805f9b34fb", "Ringer Setting" },
+ { "00002a25-0000-1000-8000-00805f9b34fb", "Serial Number String" },
+ { "00002a05-0000-1000-8000-00805f9b34fb", "Service Changed" },
+ { "00002a28-0000-1000-8000-00805f9b34fb", "Software Revision String" },
+ { "00002a47-0000-1000-8000-00805f9b34fb", "Supported New Alert Category" },
+ { "00002a48-0000-1000-8000-00805f9b34fb", "Supported Unread Alert Category" },
+ { "00002a23-0000-1000-8000-00805f9b34fb", "System ID" },
+ { "00002a1c-0000-1000-8000-00805f9b34fb", "Temperature Measurement" },
+ { "00002a1d-0000-1000-8000-00805f9b34fb", "Temperature Type" },
+ { "00002a12-0000-1000-8000-00805f9b34fb", "Time Accuracy" },
+ { "00002a13-0000-1000-8000-00805f9b34fb", "Time Source" },
+ { "00002a16-0000-1000-8000-00805f9b34fb", "Time Update Control Point" },
+ { "00002a17-0000-1000-8000-00805f9b34fb", "Time Update State" },
+ { "00002a11-0000-1000-8000-00805f9b34fb", "Time with DST" },
+ { "00002a0e-0000-1000-8000-00805f9b34fb", "Time Zone" },
+ { "00002a07-0000-1000-8000-00805f9b34fb", "Tx Power Level" },
+ { "00002a45-0000-1000-8000-00805f9b34fb", "Unread Alert Status" },
+ { }
+};
+
static GSList *gatt_services = NULL;
+static const char *get_char_name(const char *uuid)
+{
+ unsigned int i;
+
+ for (i = 0; i < G_N_ELEMENTS(char_names); i++) {
+ if (bt_uuid_strcmp(char_names[i].uuid, uuid) == 0)
+ return char_names[i].name;
+ }
+
+ return NULL;
+}
+
static void characteristic_free(void *user_data)
{
struct characteristic *chr = user_data;
@@ -191,7 +260,7 @@ static int watcher_cmp(gconstpointer a, gconstpointer b)
static void append_char_dict(DBusMessageIter *iter, struct characteristic *chr)
{
DBusMessageIter dict;
- const char *name = "";
+ const char *name;
char *uuid;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
@@ -203,8 +272,9 @@ static void append_char_dict(DBusMessageIter *iter, struct characteristic *chr)
dict_append_entry(&dict, "UUID", DBUS_TYPE_STRING, &uuid);
g_free(uuid);
- /* FIXME: Translate UUID to name. */
- dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &name);
+ name = get_char_name(chr->type);
+ if (name)
+ dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &name);
if (chr->desc)
dict_append_entry(&dict, "Description", DBUS_TYPE_STRING,
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v7] gatt: Translate Characteristic names
From: Johan Hedberg @ 2012-09-04 7:47 UTC (permalink / raw)
To: chen.ganir; +Cc: linux-bluetooth
In-Reply-To: <1346733990-23351-1-git-send-email-chen.ganir@ti.com>
Hi Chen,
On Tue, Sep 04, 2012, chen.ganir@ti.com wrote:
> From: Chen Ganir <chen.ganir@ti.com>
>
> Translate Characteristic UUID's to name. This list was taken from
> the Bluetooth SIG developer site.
> ---
> attrib/client.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 73 insertions(+), 3 deletions(-)
Applied after removing one last issue with the empty element at the end
of the list. Thanks.
Johan
^ permalink raw reply
* [PATCH] audio: Fix gateway probe always failing
From: Mikel Astiz @ 2012-09-04 9:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
Commit 813b674bce1aab009e7f2d14d1825f603330563d introduced this trivial
bug which causes the failure of the gateway profile probe.
---
audio/manager.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/audio/manager.c b/audio/manager.c
index 9ca8593..5c81957 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -706,7 +706,7 @@ static int ag_probe(struct btd_device *device, GSList *uuids)
return -1;
}
- if (!audio_dev->gateway)
+ if (audio_dev->gateway)
return -EALREADY;
audio_dev->gateway = gateway_init(audio_dev);
--
1.7.7.6
^ permalink raw reply related
* Re: [PATCH] audio: Fix gateway probe always failing
From: Johan Hedberg @ 2012-09-04 10:30 UTC (permalink / raw)
To: Mikel Astiz; +Cc: linux-bluetooth, Mikel Astiz
In-Reply-To: <1346752527-8761-1-git-send-email-mikel.astiz.oss@gmail.com>
Hi Mikel,
On Tue, Sep 04, 2012, Mikel Astiz wrote:
> From: Mikel Astiz <mikel.astiz@bmw-carit.de>
>
> Commit 813b674bce1aab009e7f2d14d1825f603330563d introduced this trivial
> bug which causes the failure of the gateway profile probe.
> ---
> audio/manager.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
Good catch. The patch has now been applied. Thanks!
Johan
^ permalink raw reply
* [PATCH v0 1/3] audio: Remove unused function
From: Mikel Astiz @ 2012-09-04 11:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
gateway_config_stream() is now unnecessary after the removal of the unix
socket support in commit 1d9d0527cfb6d96a976ede56bd43a2bc16bb5f21.
---
audio/gateway.c | 16 ----------------
audio/gateway.h | 2 --
2 files changed, 0 insertions(+), 18 deletions(-)
diff --git a/audio/gateway.c b/audio/gateway.c
index c0159a4..77a8cb0 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -858,22 +858,6 @@ unsigned int gateway_request_stream(struct audio_device *dev,
return connect_cb_new(gw, cb, user_data);
}
-int gateway_config_stream(struct audio_device *dev, gateway_stream_cb_t cb,
- void *user_data)
-{
- struct gateway *gw = dev->gateway;
- unsigned int id;
-
- id = connect_cb_new(gw, cb, user_data);
-
- if (!gw->rfcomm)
- get_records(dev);
- else if (cb)
- g_idle_add(request_stream_cb, dev);
-
- return id;
-}
-
gboolean gateway_cancel_stream(struct audio_device *dev, unsigned int id)
{
struct gateway *gw = dev->gateway;
diff --git a/audio/gateway.h b/audio/gateway.h
index 6fde445..0893962 100644
--- a/audio/gateway.h
+++ b/audio/gateway.h
@@ -64,8 +64,6 @@ int gateway_connect_sco(struct audio_device *dev, GIOChannel *chan);
void gateway_start_service(struct audio_device *device);
unsigned int gateway_request_stream(struct audio_device *dev,
gateway_stream_cb_t cb, void *user_data);
-int gateway_config_stream(struct audio_device *dev, gateway_stream_cb_t cb,
- void *user_data);
gboolean gateway_cancel_stream(struct audio_device *dev, unsigned int id);
int gateway_get_sco_fd(struct audio_device *dev);
void gateway_suspend_stream(struct audio_device *dev);
--
1.7.7.6
^ permalink raw reply related
* [PATCH v0 2/3] audio: Fix gateway in connecting state forever
From: Mikel Astiz @ 2012-09-04 11:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
In-Reply-To: <1346757356-20341-1-git-send-email-mikel.astiz.oss@gmail.com>
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
If bt_search_service() fails the state should be left unchanged.
Otherwise the gateway state is set forever to GATEWAY_STATE_CONNECTING.
This issue can be easily reproduced if a connection attempt is done
very soon after startup.
---
audio/gateway.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/audio/gateway.c b/audio/gateway.c
index 77a8cb0..8603038 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -526,11 +526,18 @@ fail:
static int get_records(struct audio_device *device)
{
uuid_t uuid;
+ int err;
- change_state(device, GATEWAY_STATE_CONNECTING);
sdp_uuid16_create(&uuid, HANDSFREE_AGW_SVCLASS_ID);
- return bt_search_service(&device->src, &device->dst, &uuid,
- get_record_cb, device, NULL);
+
+ err = bt_search_service(&device->src, &device->dst, &uuid,
+ get_record_cb, device, NULL);
+ if (err < 0)
+ return err;
+
+ change_state(device, GATEWAY_STATE_CONNECTING);
+
+ return 0;
}
static DBusMessage *ag_connect(DBusConnection *conn, DBusMessage *msg,
--
1.7.7.6
^ permalink raw reply related
* [PATCH v0 3/3] audio: Handle error in gateway_request_stream()
From: Mikel Astiz @ 2012-09-04 11:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
In-Reply-To: <1346757356-20341-1-git-send-email-mikel.astiz.oss@gmail.com>
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
gateway_request_stream() should check if the call to get_records() has
succeeded, and fail otherwise.
---
audio/gateway.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/audio/gateway.c b/audio/gateway.c
index 8603038..0603f12 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -846,9 +846,10 @@ unsigned int gateway_request_stream(struct audio_device *dev,
GError *err = NULL;
GIOChannel *io;
- if (!gw->rfcomm)
- get_records(dev);
- else if (!gw->sco) {
+ if (!gw->rfcomm) {
+ if (get_records(dev) < 0)
+ return 0;
+ } else if (!gw->sco) {
io = bt_io_connect(sco_connect_cb, dev, NULL, &err,
BT_IO_OPT_SOURCE_BDADDR, &dev->src,
BT_IO_OPT_DEST_BDADDR, &dev->dst,
--
1.7.7.6
^ permalink raw reply related
* [PATCH] Bluetooth: Fix freeing uninitialized delayed works
From: Andrei Emeltchenko @ 2012-09-04 12:00 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
When releasing L2CAP socket which is in BT_CONFIG state l2cap_chan_close
invokes l2cap_send_disconn_req which cancel delayed works which are only
set in BT_CONNECTED state with l2cap_ertm_init. Add state check before
cancelling those works.
...
[ 9668.574372] [21085] l2cap_sock_release: sock cd065200, sk f073e800
[ 9668.574399] [21085] l2cap_sock_shutdown: sock cd065200, sk f073e800
[ 9668.574411] [21085] l2cap_chan_close: chan f073ec00 state BT_CONFIG sk f073e800
[ 9668.574421] [21085] l2cap_send_disconn_req: chan f073ec00 conn ecc16600
[ 9668.574441] INFO: trying to register non-static key.
[ 9668.574443] the code is fine but needs lockdep annotation.
[ 9668.574446] turning off the locking correctness validator.
[ 9668.574450] Pid: 21085, comm: obex-client Tainted: G O 3.5.0+ #57
[ 9668.574452] Call Trace:
[ 9668.574463] [<c10a64b3>] __lock_acquire+0x12e3/0x1700
[ 9668.574468] [<c10a44fb>] ? trace_hardirqs_on+0xb/0x10
[ 9668.574476] [<c15e4f60>] ? printk+0x4d/0x4f
[ 9668.574479] [<c10a6e38>] lock_acquire+0x88/0x130
[ 9668.574487] [<c1059740>] ? try_to_del_timer_sync+0x60/0x60
[ 9668.574491] [<c1059790>] del_timer_sync+0x50/0xc0
[ 9668.574495] [<c1059740>] ? try_to_del_timer_sync+0x60/0x60
[ 9668.574515] [<f8aa1c23>] l2cap_send_disconn_req+0xe3/0x160 [bluetooth]
...
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 4d7f6ea..5661d85 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1152,7 +1152,7 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c
BT_DBG("chan %p conn %p", chan, conn);
- if (chan->mode == L2CAP_MODE_ERTM) {
+ if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
__clear_retrans_timer(chan);
__clear_monitor_timer(chan);
__clear_ack_timer(chan);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v0 1/3] audio: Remove unused function
From: Johan Hedberg @ 2012-09-04 12:51 UTC (permalink / raw)
To: Mikel Astiz; +Cc: linux-bluetooth, Mikel Astiz
In-Reply-To: <1346757356-20341-1-git-send-email-mikel.astiz.oss@gmail.com>
Hi Mikel,
On Tue, Sep 04, 2012, Mikel Astiz wrote:
> From: Mikel Astiz <mikel.astiz@bmw-carit.de>
>
> gateway_config_stream() is now unnecessary after the removal of the unix
> socket support in commit 1d9d0527cfb6d96a976ede56bd43a2bc16bb5f21.
> ---
> audio/gateway.c | 16 ----------------
> audio/gateway.h | 2 --
> 2 files changed, 0 insertions(+), 18 deletions(-)
All three patches have been applied. Thanks.
Johan
^ permalink raw reply
* [RFCv1 00/15] AMP Logical Link setup
From: Andrei Emeltchenko @ 2012-09-04 13:44 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
RFC for setting up AMP logical link over AMP physical
link (previously sent).
Andrei Emeltchenko (13):
Bluetooth: Set Exended Flowspec flag for HS chan
Bluetooth: Add logical link create function
Bluetooth: AMP: Process Logical Link Complete event
Bluetooth: AMP: Add handle to hci_chan structure
Bluetooth: AMP: Process Disc Logical Link
Bluetooth: AMP: Process Disc Physical Link
Bluetooth: L2CAP: Create Conf Response function
Bluetooth: AMP: Send EFS Conf Rsp when loglink cmpl
Bluetooth: AMP: Add hs_hchan and hs_hcon to l2cap_chan
Bluetooth: AMP: Handle AMP_LINK connection
Bluetooth: AMP: Send data over AMP channel
Bluetooth: Factor out hci_queue_acl
Bluetooth: AMP: Use Loglink handle in ACL Handle field
Mat Martineau (2):
Bluetooth: Process create response and connect response identically
Bluetooth: Factor out common L2CAP connection code
include/net/bluetooth/amp.h | 2 +
include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/hci_core.h | 19 ++++++-
include/net/bluetooth/l2cap.h | 5 ++
net/bluetooth/amp.c | 50 ++++++++++++++++++
net/bluetooth/hci_conn.c | 35 +++++++++++++
net/bluetooth/hci_core.c | 43 +++++++++++++---
net/bluetooth/hci_event.c | 103 ++++++++++++++++++++++++++++++++++++++
net/bluetooth/l2cap_core.c | 98 ++++++++++++++++++++++++++----------
9 files changed, 320 insertions(+), 36 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [RFCv1 01/15] Bluetooth: Set Exended Flowspec flag for HS chan
From: Andrei Emeltchenko @ 2012-09-04 13:44 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1346766274-21612-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
For AMP we always assume EFS L2CAP option.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
include/net/bluetooth/l2cap.h | 2 ++
net/bluetooth/l2cap_core.c | 7 ++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 161be83..3ec8679 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -508,6 +508,8 @@ struct l2cap_chan {
__u32 remote_acc_lat;
__u32 remote_flush_to;
+ __u8 ctrl_id;
+
struct delayed_work chan_timer;
struct delayed_work retrans_timer;
struct delayed_work monitor_timer;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index de6f52c..aea2b50 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5439,8 +5439,13 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
void l2cap_chan_create_cfm(struct hci_conn *hcon, u8 remote_id)
{
struct amp_mgr *mgr = hcon->amp_mgr;
+ struct l2cap_chan *chan = mgr->bredr_chan;
- l2cap_send_chan_create_req(mgr->bredr_chan, remote_id);
+ /* Set Extended Flow Spec for AMP */
+ set_bit(FLAG_EFS_ENABLE, &chan->flags);
+ chan->ctrl_id = remote_id;
+
+ l2cap_send_chan_create_req(chan, remote_id);
}
int l2cap_disconn_ind(struct hci_conn *hcon)
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox