* [PATCH BlueZ v7 6/9] core: Disable unnecessary auto connections
From: João Paulo Rechi Vita @ 2012-09-25 17:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Paulo Alcantara
In-Reply-To: <1348594686-26221-1-git-send-email-jprvita@openbossa.org>
From: Paulo Alcantara <paulo.alcantara@openbossa.org>
BlueZ host disconnects the link when encryption fails. ECONNABORTED
error is returned by the kernel when the connection is terminated by the
local host. This scenario commonly happens when authentication fails due
PIN or Key Missing.
---
src/device.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/device.c b/src/device.c
index 5d92ff5..96d8b72 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1989,6 +1989,9 @@ static void att_error_cb(const GError *gerr, gpointer user_data)
struct att_callbacks *attcb = user_data;
struct btd_device *device = attcb->user_data;
+ if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
+ return;
+
if (device->auto_connect == FALSE)
return;
--
1.7.11.4
^ permalink raw reply related
* [PATCH BlueZ v7 5/9] core: Queue discovery if scanning is active
From: João Paulo Rechi Vita @ 2012-09-25 17:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348594686-26221-1-git-send-email-jprvita@openbossa.org>
From: Claudio Takahasi <claudio.takahasi@openbossa.org>
This patch manages BR/EDR inquiry and BLE scanning discovery sessions.
A scanning session is added in the discovery session list when there is
a bonded device which requires re-connection.
bluetoothd decides if interleaved or scanning needs to be executed based
on the queued discovery sessions. Interleaved discovery has higher
priority, scanning only is executed when there is only a scanning
session active.
---
src/adapter.c | 65 ++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 46 insertions(+), 19 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 201e6a0..0a0ac8f 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -132,6 +132,7 @@ struct btd_adapter {
GSList *devices; /* Devices structure pointers */
GSList *mode_sessions; /* Request Mode sessions */
GSList *disc_sessions; /* Discovery sessions */
+ struct session_req *scanning_session;
GSList *connect_list; /* Devices to connect when found */
guint discov_id; /* Discovery timer */
gboolean discovering; /* Discovery active */
@@ -221,17 +222,18 @@ static struct session_req *create_session(struct btd_adapter *adapter,
DBusMessage *msg, uint8_t mode,
GDBusWatchFunction cb)
{
- const char *sender = dbus_message_get_sender(msg);
+ const char *sender;
struct session_req *req;
req = g_new0(struct session_req, 1);
req->adapter = adapter;
- req->msg = dbus_message_ref(msg);
req->mode = mode;
- if (cb == NULL)
+ if (cb == NULL || msg == NULL)
return session_ref(req);
+ sender = dbus_message_get_sender(msg);
+ req->msg = dbus_message_ref(msg);
req->owner = g_strdup(sender);
req->id = g_dbus_add_disconnect_watch(btd_get_dbus_connection(),
sender, cb, req, NULL);
@@ -442,7 +444,9 @@ static struct session_req *find_session(GSList *list, const char *sender)
for (; list; list = list->next) {
struct session_req *req = list->data;
- if (g_str_equal(req->owner, sender))
+ /* req->owner may be NULL if the session has been added by the
+ * daemon itself, so we use g_strcmp0 instead of g_str_equal */
+ if (g_strcmp0(req->owner, sender) == 0)
return req;
}
@@ -517,7 +521,7 @@ static void session_remove(struct session_req *req)
struct btd_adapter *adapter = req->adapter;
/* Ignore set_mode session */
- if (req->owner == NULL)
+ if (req->owner == NULL && adapter->pending_mode)
return;
DBG("%s session %p with %s deactivated",
@@ -997,7 +1001,12 @@ static gboolean discovery_cb(gpointer user_data)
struct btd_adapter *adapter = user_data;
adapter->discov_id = 0;
- mgmt_start_discovery(adapter->dev_id);
+
+ if (adapter->scanning_session &&
+ (g_slist_length(adapter->disc_sessions) == 1))
+ mgmt_start_scanning(adapter->dev_id);
+ else
+ mgmt_start_discovery(adapter->dev_id);
return FALSE;
}
@@ -2190,6 +2199,8 @@ const char *btd_adapter_get_name(struct btd_adapter *adapter)
void adapter_connect_list_add(struct btd_adapter *adapter,
struct btd_device *device)
{
+ struct session_req *req;
+
if (g_slist_find(adapter->connect_list, device)) {
DBG("ignoring already added device %s",
device_get_path(device));
@@ -2201,10 +2212,21 @@ void adapter_connect_list_add(struct btd_adapter *adapter,
DBG("%s added to %s's connect_list", device_get_path(device),
adapter->name);
- if (adapter->disc_sessions)
+ if (!adapter->up)
+ return;
+
+ if (adapter->off_requested)
+ return;
+
+ if (adapter->scanning_session)
return;
- mgmt_start_scanning(adapter->dev_id);
+ if (adapter->disc_sessions == NULL)
+ adapter->discov_id = g_idle_add(discovery_cb, adapter);
+
+ req = create_session(adapter, NULL, 0, NULL);
+ adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
+ adapter->scanning_session = req;
}
void adapter_connect_list_remove(struct btd_adapter *adapter,
@@ -2224,6 +2246,7 @@ void adapter_connect_list_remove(struct btd_adapter *adapter,
void btd_adapter_start(struct btd_adapter *adapter)
{
+ struct session_req *req;
char address[18];
gboolean powered;
@@ -2250,8 +2273,15 @@ void btd_adapter_start(struct btd_adapter *adapter)
info("Adapter %s has been enabled", adapter->path);
- if (g_slist_length(adapter->connect_list) > 0)
- mgmt_start_scanning(adapter->dev_id);
+ if (g_slist_length(adapter->connect_list) == 0 ||
+ adapter->disc_sessions != NULL)
+ return;
+
+ req = create_session(adapter, NULL, 0, NULL);
+ adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
+ adapter->scanning_session = req;
+
+ adapter->discov_id = g_idle_add(discovery_cb, adapter);
}
static void reply_pending_requests(struct btd_adapter *adapter)
@@ -2595,6 +2625,11 @@ void adapter_set_discovering(struct btd_adapter *adapter,
connect_list_len = g_slist_length(adapter->connect_list);
+ if (connect_list_len == 0 && adapter->scanning_session) {
+ session_unref(adapter->scanning_session);
+ adapter->scanning_session = NULL;
+ }
+
if (adapter_has_discov_sessions(adapter)) {
adapter->discov_id = g_idle_add(discovery_cb, adapter);
@@ -2603,14 +2638,6 @@ void adapter_set_discovering(struct btd_adapter *adapter,
g_slist_length(adapter->disc_sessions));
return;
}
-
- if (connect_list_len > 0) {
- mgmt_start_scanning(adapter->dev_id);
-
- DBG("hci%u restarting scanning connect_list_len %u",
- adapter->dev_id, connect_list_len);
- return;
- }
}
static void suspend_discovery(struct btd_adapter *adapter)
@@ -2925,7 +2952,7 @@ static gboolean clean_connecting_state(GIOChannel *io, GIOCondition cond,
if (adapter->waiting_to_connect == 0 &&
g_slist_length(adapter->connect_list) > 0)
- mgmt_start_scanning(adapter->dev_id);
+ adapter->discov_id = g_idle_add(discovery_cb, adapter);
btd_device_unref(device);
--
1.7.11.4
^ permalink raw reply related
* [PATCH BlueZ v7 4/9] core: Start LE scanning when a device requests
From: João Paulo Rechi Vita @ 2012-09-25 17:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348594686-26221-1-git-send-email-jprvita@openbossa.org>
From: Claudio Takahasi <claudio.takahasi@openbossa.org>
This patch enables the LE scanning when a device requires connection and
there isn't discovery sessions, triggering the General Connection
Establishment Procedure.
---
src/adapter.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 49dee85..201e6a0 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2200,6 +2200,11 @@ void adapter_connect_list_add(struct btd_adapter *adapter,
btd_device_ref(device));
DBG("%s added to %s's connect_list", device_get_path(device),
adapter->name);
+
+ if (adapter->disc_sessions)
+ return;
+
+ mgmt_start_scanning(adapter->dev_id);
}
void adapter_connect_list_remove(struct btd_adapter *adapter,
--
1.7.11.4
^ permalink raw reply related
* [PATCH BlueZ v7 3/9] core: Replace interleaved by LE scanning
From: João Paulo Rechi Vita @ 2012-09-25 17:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348594686-26221-1-git-send-email-jprvita@openbossa.org>
From: Claudio Takahasi <claudio.takahasi@openbossa.org>
This patches replaces the interleaved discovery by LE scanning when LE
re-connection is required.
---
src/adapter.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 47f82c0..49dee85 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2246,7 +2246,7 @@ void btd_adapter_start(struct btd_adapter *adapter)
info("Adapter %s has been enabled", adapter->path);
if (g_slist_length(adapter->connect_list) > 0)
- mgmt_start_discovery(adapter->dev_id);
+ mgmt_start_scanning(adapter->dev_id);
}
static void reply_pending_requests(struct btd_adapter *adapter)
@@ -2590,14 +2590,22 @@ void adapter_set_discovering(struct btd_adapter *adapter,
connect_list_len = g_slist_length(adapter->connect_list);
- if (!adapter_has_discov_sessions(adapter) && connect_list_len == 0)
+ if (adapter_has_discov_sessions(adapter)) {
+ adapter->discov_id = g_idle_add(discovery_cb, adapter);
+
+ DBG("hci%u restarting discovery: disc_sessions %u",
+ adapter->dev_id,
+ g_slist_length(adapter->disc_sessions));
return;
+ }
- DBG("hci%u restarting discovery: disc_sessions %u connect_list_len %u",
- adapter->dev_id, g_slist_length(adapter->disc_sessions),
- connect_list_len);
+ if (connect_list_len > 0) {
+ mgmt_start_scanning(adapter->dev_id);
- adapter->discov_id = g_idle_add(discovery_cb, adapter);
+ DBG("hci%u restarting scanning connect_list_len %u",
+ adapter->dev_id, connect_list_len);
+ return;
+ }
}
static void suspend_discovery(struct btd_adapter *adapter)
@@ -2912,7 +2920,7 @@ static gboolean clean_connecting_state(GIOChannel *io, GIOCondition cond,
if (adapter->waiting_to_connect == 0 &&
g_slist_length(adapter->connect_list) > 0)
- mgmt_start_discovery(adapter->dev_id);
+ mgmt_start_scanning(adapter->dev_id);
btd_device_unref(device);
--
1.7.11.4
^ permalink raw reply related
* [PATCH BlueZ v7 2/9] mgmt: Add LE scanning callback
From: João Paulo Rechi Vita @ 2012-09-25 17:37 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348594686-26221-1-git-send-email-jprvita@openbossa.org>
From: Claudio Takahasi <claudio.takahasi@openbossa.org>
This patch adds a new callback to allow the adapter to control LE
scanning. The current approach uses the active scanning with default
windows and intervals defined by the core spec without any filtering.
---
src/mgmt.c | 34 ++++++++++++++++++++++++++++++++++
src/mgmt.h | 1 +
2 files changed, 35 insertions(+)
diff --git a/src/mgmt.c b/src/mgmt.c
index dbd9786..405a683 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -2055,6 +2055,40 @@ int mgmt_start_discovery(int index)
return 0;
}
+int mgmt_start_scanning(int index)
+{
+ char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
+ struct mgmt_hdr *hdr = (void *) buf;
+ struct mgmt_cp_start_discovery *cp = (void *) &buf[sizeof(*hdr)];
+ struct controller_info *info = &controllers[index];
+
+ DBG("index %d", index);
+
+ if (!mgmt_low_energy(info->current_settings)) {
+ error("scanning failed: Low Energy not enabled/supported");
+ return -ENOTSUP;
+ }
+
+ info->discov_type = 0;
+ hci_set_bit(BDADDR_LE_PUBLIC, &info->discov_type);
+ hci_set_bit(BDADDR_LE_RANDOM, &info->discov_type);
+
+ memset(buf, 0, sizeof(buf));
+ hdr->opcode = htobs(MGMT_OP_START_DISCOVERY);
+ hdr->len = htobs(sizeof(*cp));
+ hdr->index = htobs(index);
+
+ cp->type = info->discov_type;
+
+ if (write(mgmt_sock, buf, sizeof(buf)) < 0) {
+ int err = -errno;
+ error("failed to write to MGMT socket: %s", strerror(-err));
+ return err;
+ }
+
+ return 0;
+}
+
int mgmt_stop_discovery(int index)
{
char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
diff --git a/src/mgmt.h b/src/mgmt.h
index 95245d2..eb7434a 100644
--- a/src/mgmt.h
+++ b/src/mgmt.h
@@ -33,6 +33,7 @@ int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor);
int mgmt_set_fast_connectable(int index, gboolean enable);
int mgmt_start_discovery(int index);
+int mgmt_start_scanning(int index);
int mgmt_stop_discovery(int index);
int mgmt_read_clock(int index, bdaddr_t *bdaddr, int which, int timeout,
--
1.7.11.4
^ permalink raw reply related
* Re: [PATCH BlueZ v6 03/11] core: Mutually exclude concurrent connections
From: Joao Paulo Rechi Vita @ 2012-09-25 17:37 UTC (permalink / raw)
To: Johan Hedberg, linux-bluetooth
In-Reply-To: <20120920114323.GA11861@x220>
On Thu, Sep 20, 2012 at 8:43 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
(...)
>
> As a general note (not relating specifically to this patch) I'd like to
> see a clearer split and naming of LE/GATT-specific functionality and
> variables (function names, struct btd_adapter/device member naming &
> grouping, etc.). Right now these seem to be sprinkled all over the place
> which can be confusing for someone looking at the code from a
> BR/EDR-only or LE-only perspective.
>
Any suggestions on how to improve that? I've tried to improve naming
for quite a while before sending these for the first time to the list,
and neither I nor anyone else from INdT could come up with better
naming.
I'm sending an updated version now, than you can comment about other
improvements on top of that.
--
João Paulo Rechi Vita
Openbossa Labs - INdT
^ permalink raw reply
* [PATCH BlueZ v7 1/9] core: Mutually exclude concurrent connections
From: João Paulo Rechi Vita @ 2012-09-25 17:37 UTC (permalink / raw)
To: linux-bluetooth; +Cc: João Paulo Rechi Vita
Since controllers don't support more than one ongoing connection
procedure at the same time, new connection attempts needs to yield if
there is an ongoing connection procedure already.
---
src/adapter.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
src/device.c | 6 +++---
src/device.h | 2 +-
3 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index e154c69..47f82c0 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -135,6 +135,8 @@ struct btd_adapter {
GSList *connect_list; /* Devices to connect when found */
guint discov_id; /* Discovery timer */
gboolean discovering; /* Discovery active */
+ gboolean connecting; /* Connect active */
+ guint waiting_to_connect; /* # of devices waiting to connect */
gboolean discov_suspended; /* Discovery suspended */
guint auto_timeout_id; /* Automatic connections timeout */
sdp_list_t *services; /* Services associated to adapter */
@@ -2242,6 +2244,9 @@ void btd_adapter_start(struct btd_adapter *adapter)
call_adapter_powered_callbacks(adapter, TRUE);
info("Adapter %s has been enabled", adapter->path);
+
+ if (g_slist_length(adapter->connect_list) > 0)
+ mgmt_start_discovery(adapter->dev_id);
}
static void reply_pending_requests(struct btd_adapter *adapter)
@@ -2565,6 +2570,7 @@ void adapter_set_discovering(struct btd_adapter *adapter,
gboolean discovering)
{
const char *path = adapter->path;
+ guint connect_list_len;
adapter->discovering = discovering;
@@ -2579,11 +2585,17 @@ void adapter_set_discovering(struct btd_adapter *adapter,
g_slist_free_full(adapter->oor_devices, dev_info_free);
adapter->oor_devices = g_slist_copy(adapter->found_devices);
- if (!adapter_has_discov_sessions(adapter) || adapter->discov_suspended)
+ if (adapter->discov_suspended)
+ return;
+
+ connect_list_len = g_slist_length(adapter->connect_list);
+
+ if (!adapter_has_discov_sessions(adapter) && connect_list_len == 0)
return;
- DBG("hci%u restarting discovery, disc_sessions %u", adapter->dev_id,
- g_slist_length(adapter->disc_sessions));
+ DBG("hci%u restarting discovery: disc_sessions %u connect_list_len %u",
+ adapter->dev_id, g_slist_length(adapter->disc_sessions),
+ connect_list_len);
adapter->discov_id = g_idle_add(discovery_cb, adapter);
}
@@ -2890,17 +2902,46 @@ static char *read_stored_data(bdaddr_t *local, bdaddr_t *peer,
return textfile_get(filename, key);
}
+static gboolean clean_connecting_state(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ struct btd_device *device = user_data;
+ struct btd_adapter *adapter = device_get_adapter(device);
+
+ adapter->connecting = FALSE;
+
+ if (adapter->waiting_to_connect == 0 &&
+ g_slist_length(adapter->connect_list) > 0)
+ mgmt_start_discovery(adapter->dev_id);
+
+ btd_device_unref(device);
+
+ return FALSE;
+}
+
static gboolean connect_pending_cb(gpointer user_data)
{
struct btd_device *device = user_data;
struct btd_adapter *adapter = device_get_adapter(device);
+ GIOChannel *io;
/* in the future we may want to check here if the controller supports
* scanning and connecting at the same time */
if (adapter->discovering)
return TRUE;
- device_att_connect(device);
+ if (adapter->connecting)
+ return TRUE;
+
+ adapter->connecting = TRUE;
+ adapter->waiting_to_connect--;
+
+ io = device_att_connect(device);
+ g_io_add_watch(io, G_IO_OUT | G_IO_ERR, clean_connecting_state,
+ btd_device_ref(device));
+ g_io_channel_unref(io);
+
+ btd_device_unref(device);
return FALSE;
}
@@ -2993,12 +3034,19 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
if (bdaddr_type == BDADDR_LE_PUBLIC ||
bdaddr_type == BDADDR_LE_RANDOM) {
+ struct btd_device *device;
+
l = g_slist_find_custom(adapter->connect_list, bdaddr,
(GCompareFunc) device_bdaddr_cmp);
- if (l) {
- g_idle_add(connect_pending_cb, l->data);
- stop_discovery(adapter);
- }
+ if (!l)
+ goto done;
+
+ device = l->data;
+ adapter_connect_list_remove(adapter, device);
+
+ g_idle_add(connect_pending_cb, btd_device_ref(device));
+ stop_discovery(adapter);
+ adapter->waiting_to_connect++;
}
done:
diff --git a/src/device.c b/src/device.c
index 57fdf00..5d92ff5 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2007,7 +2007,7 @@ static void att_success_cb(gpointer user_data)
g_slist_foreach(device->attios, attio_connected, device->attrib);
}
-gboolean device_att_connect(gpointer user_data)
+GIOChannel *device_att_connect(gpointer user_data)
{
struct btd_device *device = user_data;
struct btd_adapter *adapter = device->adapter;
@@ -2050,12 +2050,12 @@ gboolean device_att_connect(gpointer user_data)
error("ATT bt_io_connect(%s): %s", addr, gerr->message);
g_error_free(gerr);
g_free(attcb);
- return FALSE;
+ return NULL;
}
device->att_io = io;
- return FALSE;
+ return g_io_channel_ref(io);
}
static void att_browse_error_cb(const GError *gerr, gpointer user_data)
diff --git a/src/device.h b/src/device.h
index aee6d13..d9aa6f5 100644
--- a/src/device.h
+++ b/src/device.h
@@ -124,4 +124,4 @@ int device_unblock(struct btd_device *device, gboolean silent,
void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
uint16_t vendor_id, uint16_t product_id,
uint16_t product_ver);
-gboolean device_att_connect(gpointer user_data);
+GIOChannel *device_att_connect(gpointer user_data);
--
1.7.11.4
^ permalink raw reply related
* Re: [PATCHv2 0/4] Remove unsafe batostr
From: Marcel Holtmann @ 2012-09-25 16:27 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth, gustavo
In-Reply-To: <1348566586-28572-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
> Since the patch "vsprintf: add %pMR for Bluetooth MAC address" in in bluetooth-next resend the patch series.
>
> Changes:
> * v2: Rebase against recent bluetooth-next.
>
> Andrei Emeltchenko (4):
> Bluetooth: Use %pMR in debug instead of batostr
> Bluetooth: Use %pMR in sprintf/seq_printf instead of batostr
> Bluetooth: Use %pMR instead of baswap in seq_show
> bluetooth: Remove unneeded batostr function
>
> include/net/bluetooth/bluetooth.h | 1 -
> net/bluetooth/af_bluetooth.c | 10 ++++------
> net/bluetooth/bnep/core.c | 3 +--
> net/bluetooth/cmtp/core.c | 2 +-
> net/bluetooth/hci_conn.c | 6 +++---
> net/bluetooth/hci_core.c | 22 +++++++++++-----------
> net/bluetooth/hci_event.c | 15 +++++++--------
> net/bluetooth/hci_sysfs.c | 10 +++++-----
> net/bluetooth/hidp/core.c | 8 ++++++--
> net/bluetooth/l2cap_core.c | 17 ++++++++---------
> net/bluetooth/lib.c | 14 --------------
> net/bluetooth/rfcomm/core.c | 15 +++++++--------
> net/bluetooth/rfcomm/sock.c | 9 ++++-----
> net/bluetooth/rfcomm/tty.c | 6 +++---
> net/bluetooth/sco.c | 12 ++++++------
> 15 files changed, 66 insertions(+), 84 deletions(-)
>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* [PATCH BlueZ v3 6/6] hog: Add writting Control Point
From: Claudio Takahasi @ 2012-09-25 15:34 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348587260-431-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 4b43d67..a558110 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 3888c2b..2d72444 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
@@ -43,14 +43,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_profile *p, struct btd_device *device,
--
1.7.12
^ permalink raw reply related
* [PATCH BlueZ v3 5/6] hog: Move HoG device list to manager
From: Claudio Takahasi @ 2012-09-25 15:34 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348587260-431-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 03af931..4b43d67 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 6d173cc..3888c2b 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
@@ -41,6 +41,7 @@
#include "hog_device.h"
static gboolean suspend_supported = FALSE;
+static GSList *devices = NULL;
static void suspend_callback(void)
{
@@ -56,19 +57,36 @@ static int hog_device_probe(struct btd_profile *p, 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_profile *p, 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 v3 4/6] hog: Create a FIFO for dummy suspend
From: Claudio Takahasi @ 2012-09-25 15:34 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348587260-431-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 v3 3/6] hog: Add suspend/resume callbacks declaration
From: Claudio Takahasi @ 2012-09-25 15:34 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348587260-431-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 8ddaf2f..6d173cc 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
@@ -42,6 +42,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_profile *p, struct btd_device *device,
GSList *uuids)
{
@@ -72,7 +82,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 v3 2/6] hog: Add suspend back-end selection
From: Claudio Takahasi @ 2012-09-25 15:34 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348587260-431-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 93558b2..444c341 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 v3 1/6] hog: Add initial files for suspend support
From: Claudio Takahasi @ 2012-09-25 15:34 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348587260-431-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 372111a..93558b2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -183,7 +183,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 612c12a..8ddaf2f 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
@@ -37,8 +37,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_profile *p, struct btd_device *device,
GSList *uuids)
{
@@ -67,11 +70,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 v3 0/6] HoG Suspend/Resume
From: Claudio Takahasi @ 2012-09-25 15:34 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 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 can 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.
*** v3 changes:
Code rebased: conflicts with profile parameter in device probe.
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 8/8] scan: Avoid discover if scan handle is known
From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348586802-32613-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
* [PATCH BlueZ v2 7/8] scan: Write parameters when requested
From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348586802-32613-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 v2 6/8] scan: Register notification handler
From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348586802-32613-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 v2 5/8] scan: Enable Scan Refresh notification
From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348586802-32613-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 v2 4/8] scan: Add write scan interval window
From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348586802-32613-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 v2 3/8] scan: Add ATTIO callbacks registration
From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348586802-32613-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 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
* [PATCH BlueZ v2 2/8] scan: Register profile
From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348586802-32613-1-git-send-email-claudio.takahasi@openbossa.org>
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
* [PATCH BlueZ v2 1/8] scan: Add plugin skeleton
From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1348586802-32613-1-git-send-email-claudio.takahasi@openbossa.org>
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
* [PATCH BlueZ v2 0/8] Scan Parameters Plugin
From: Claudio Takahasi @ 2012-09-25 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346695965-25422-1-git-send-email-claudio.takahasi@openbossa.org>
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
* Re: [PATCH 00/14] Thermometer watchers API change + fixes
From: Anderson Lizardo @ 2012-09-25 15:21 UTC (permalink / raw)
To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1348584763-22824-1-git-send-email-andrzej.kaczmarek@tieto.com>
Hi Andrzej,
On Tue, Sep 25, 2012 at 10:52 AM, Andrzej Kaczmarek
<andrzej.kaczmarek@tieto.com> wrote:
> Hi,
>
> Here's series of patches to move watchers from per-device to per-adapter
> interface (basically the same as done for HRP, see other series of patches).
> This applies to both final and intermediate temperature watchers - once
> watcher is registered, all connected devices are setup to send measurement
> notifications and the opposite when last watcher is unregistered.
>
> This major change is done in patches 1-6.
>
> Patches 7-11 contain some code and documentation refactoring, i.e. to
> remove duplicated code.
>
> Patches 12-14 are trival coding style fixes.
>
> Unfortunately, I wasn't able to fully test this code due to lack of proper
> thermometer device and sample device from CC2540 devkit does not quite
> work as expected (e.g. I can see CCC is written properly when watcher is
> registered but remote does not send any indications for unknown reason).
Unfortunately, the thermometer demo app (at least on TI's BLE stack
v1.1 installation) has several bugs. I haven't tested yet the latest
release (1.2.1), which version are you using?
Do you have access to PTS? You could test with it as well.
Maybe we should consider implementing a simple Thermometer role in
BlueZ for testing purposes. It is a relatively simple profile.
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
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