* [PATCH 4/4] Remove unnecessary disconnect callback from source.c
From: Radoslaw Jablonski @ 2010-09-22 13:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1285162521-21997-1-git-send-email-ext-jablonski.radoslaw@nokia.com>
Headsets for proper disconnecting need to disconnect profiles in specified
order(by ex. disconnect a2dp, then sink and hfp at the end). Instead of
adding separate callbacks for disconnecting each profile, now adding only
one callback in audio/device.c for calling audio disconnect functions in
correct order.
---
audio/source.c | 33 ---------------------------------
1 files changed, 0 insertions(+), 33 deletions(-)
diff --git a/audio/source.c b/audio/source.c
index 01173f5..e8671ed 100644
--- a/audio/source.c
+++ b/audio/source.c
@@ -62,7 +62,6 @@ struct source {
struct avdtp *session;
struct avdtp_stream *stream;
unsigned int cb_id;
- guint dc_id;
guint retry_id;
avdtp_session_state_t session_state;
avdtp_state_t stream_state;
@@ -133,12 +132,6 @@ static void avdtp_state_callback(struct audio_device *dev,
switch (new_state) {
case AVDTP_SESSION_STATE_DISCONNECTED:
- if (source->state != SOURCE_STATE_CONNECTING &&
- source->dc_id) {
- device_remove_disconnect_watch(dev->btd_dev,
- source->dc_id);
- source->dc_id = 0;
- }
source_set_state(dev, SOURCE_STATE_DISCONNECTED);
break;
case AVDTP_SESSION_STATE_CONNECTING:
@@ -164,17 +157,6 @@ static void pending_request_free(struct audio_device *dev,
g_free(pending);
}
-static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
- void *user_data)
-{
- struct audio_device *device = user_data;
- struct source *source = device->source;
-
- DBG("Source: disconnect %s", device->path);
-
- avdtp_close(source->session, source->stream, TRUE);
-}
-
static void stream_state_changed(struct avdtp_stream *stream,
avdtp_state_t old_state,
avdtp_state_t new_state,
@@ -201,12 +183,6 @@ static void stream_state_changed(struct avdtp_stream *stream,
pending_request_free(dev, p);
}
- if (source->dc_id) {
- device_remove_disconnect_watch(dev->btd_dev,
- source->dc_id);
- source->dc_id = 0;
- }
-
if (source->session) {
avdtp_unref(source->session);
source->session = NULL;
@@ -215,12 +191,6 @@ static void stream_state_changed(struct avdtp_stream *stream,
source->cb_id = 0;
break;
case AVDTP_STATE_OPEN:
- if (old_state == AVDTP_STATE_CONFIGURED &&
- source->state == SOURCE_STATE_CONNECTING) {
- source->dc_id = device_add_disconnect_watch(dev->btd_dev,
- disconnect_cb,
- dev, NULL);
- }
source_set_state(dev, SOURCE_STATE_CONNECTED);
break;
case AVDTP_STATE_STREAMING:
@@ -536,9 +506,6 @@ static void source_free(struct audio_device *dev)
avdtp_stream_remove_cb(source->session, source->stream,
source->cb_id);
- if (source->dc_id)
- device_remove_disconnect_watch(dev->btd_dev, source->dc_id);
-
if (source->session)
avdtp_unref(source->session);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/4] Remove unnecessary disconnect callback from sink.c
From: Radoslaw Jablonski @ 2010-09-22 13:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1285162521-21997-1-git-send-email-ext-jablonski.radoslaw@nokia.com>
Headsets for proper disconnecting need to disconnect profiles in specified
order(by ex. disconnect a2dp, then sink and hfp at the end). Instead of
adding separate callbacks for disconnecting each profile, now adding only
one callback in audio/device.c for calling audio disconnect functions in
correct order.
---
audio/sink.c | 29 -----------------------------
1 files changed, 0 insertions(+), 29 deletions(-)
diff --git a/audio/sink.c b/audio/sink.c
index 67cffee..eb90c21 100644
--- a/audio/sink.c
+++ b/audio/sink.c
@@ -61,7 +61,6 @@ struct sink {
struct avdtp *session;
struct avdtp_stream *stream;
unsigned int cb_id;
- guint dc_id;
guint retry_id;
avdtp_session_state_t session_state;
avdtp_state_t stream_state;
@@ -140,11 +139,6 @@ static void avdtp_state_callback(struct audio_device *dev,
emit_property_changed(dev->conn, dev->path,
AUDIO_SINK_INTERFACE, "Connected",
DBUS_TYPE_BOOLEAN, &value);
- if (sink->dc_id) {
- device_remove_disconnect_watch(dev->btd_dev,
- sink->dc_id);
- sink->dc_id = 0;
- }
}
sink_set_state(dev, SINK_STATE_DISCONNECTED);
break;
@@ -171,17 +165,6 @@ static void pending_request_free(struct audio_device *dev,
g_free(pending);
}
-static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
- void *user_data)
-{
- struct audio_device *device = user_data;
- struct sink *sink = device->sink;
-
- DBG("Sink: disconnect %s", device->path);
-
- avdtp_close(sink->session, sink->stream, TRUE);
-}
-
static void stream_state_changed(struct avdtp_stream *stream,
avdtp_state_t old_state,
avdtp_state_t new_state,
@@ -209,12 +192,6 @@ static void stream_state_changed(struct avdtp_stream *stream,
pending_request_free(dev, p);
}
- if (sink->dc_id) {
- device_remove_disconnect_watch(dev->btd_dev,
- sink->dc_id);
- sink->dc_id = 0;
- }
-
if (sink->session) {
avdtp_unref(sink->session);
sink->session = NULL;
@@ -234,9 +211,6 @@ static void stream_state_changed(struct avdtp_stream *stream,
AUDIO_SINK_INTERFACE,
"Connected",
DBUS_TYPE_BOOLEAN, &value);
- sink->dc_id = device_add_disconnect_watch(dev->btd_dev,
- disconnect_cb,
- dev, NULL);
} else if (old_state == AVDTP_STATE_STREAMING) {
value = FALSE;
g_dbus_emit_signal(dev->conn, dev->path,
@@ -601,9 +575,6 @@ static void sink_free(struct audio_device *dev)
avdtp_stream_remove_cb(sink->session, sink->stream,
sink->cb_id);
- if (sink->dc_id)
- device_remove_disconnect_watch(dev->btd_dev, sink->dc_id);
-
if (sink->session)
avdtp_unref(sink->session);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/4] Remove unnecessary disconnect callback from headset.c
From: Radoslaw Jablonski @ 2010-09-22 13:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1285162521-21997-1-git-send-email-ext-jablonski.radoslaw@nokia.com>
Headsets for proper disconnecting need to disconnect profiles in specified
order(by ex. disconnect a2dp, then sink and hfp at the end). Instead of
adding separate callbacks for disconnecting each profile, now adding only
one callback in audio/device.c for calling audio disconnect functions in
correct order.
---
audio/headset.c | 19 -------------------
1 files changed, 0 insertions(+), 19 deletions(-)
diff --git a/audio/headset.c b/audio/headset.c
index dad0716..9955d4b 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -158,7 +158,6 @@ struct headset {
GIOChannel *tmp_rfcomm;
GIOChannel *sco;
guint sco_id;
- guint dc_id;
gboolean auto_dc;
@@ -2162,9 +2161,6 @@ static void headset_free(struct audio_device *dev)
hs->dc_timer = 0;
}
- if (hs->dc_id)
- device_remove_disconnect_watch(dev->btd_dev, hs->dc_id);
-
close_sco(dev);
headset_close_rfcomm(dev);
@@ -2477,16 +2473,6 @@ int headset_connect_sco(struct audio_device *dev, GIOChannel *io)
return 0;
}
-static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
- void *user_data)
-{
- struct audio_device *device = user_data;
-
- info("Headset: disconnect %s", device->path);
-
- headset_shutdown(device);
-}
-
void headset_set_state(struct audio_device *dev, headset_state_t state)
{
struct headset *hs = dev->headset;
@@ -2520,8 +2506,6 @@ void headset_set_state(struct audio_device *dev, headset_state_t state)
telephony_device_disconnected(dev);
}
active_devices = g_slist_remove(active_devices, dev);
- device_remove_disconnect_watch(dev->btd_dev, hs->dc_id);
- hs->dc_id = 0;
break;
case HEADSET_STATE_CONNECTING:
emit_property_changed(dev->conn, dev->path,
@@ -2550,9 +2534,6 @@ void headset_set_state(struct audio_device *dev, headset_state_t state)
DBUS_TYPE_BOOLEAN, &value);
active_devices = g_slist_append(active_devices, dev);
telephony_device_connected(dev);
- hs->dc_id = device_add_disconnect_watch(dev->btd_dev,
- disconnect_cb,
- dev, NULL);
} else if (hs->state == HEADSET_STATE_PLAYING) {
value = FALSE;
g_dbus_emit_signal(dev->conn, dev->path,
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/4] Fix headset disconnecting via device disconnect
From: Radoslaw Jablonski @ 2010-09-22 13:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Radoslaw Jablonski
Headsets for proper disconnecting need to disconnect profiles in specified
order(by ex. disconnect a2dp, then sink and hfp at the end). Instead of
adding separate callbacks for disconnecting each profile, now adding only
one callback in audio/device.c for calling audio disconnect functions in
correct order.
Added disconnect_cb callback to audio/device.c
---
audio/device.c | 119 ++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 82 insertions(+), 37 deletions(-)
diff --git a/audio/device.c b/audio/device.c
index b30590e..8fe79d3 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -91,7 +91,9 @@ struct dev_priv {
guint control_timer;
guint avdtp_timer;
guint headset_timer;
+ guint dc_id;
+ gboolean disconnecting;
gboolean authorized;
guint auth_idle_id;
};
@@ -123,6 +125,9 @@ static void device_free(struct audio_device *dev)
dbus_message_unref(priv->dc_req);
if (priv->conn_req)
dbus_message_unref(priv->conn_req);
+ if (priv->dc_id)
+ device_remove_disconnect_watch(dev->btd_dev,
+ priv->dc_id);
g_free(priv);
}
@@ -145,6 +150,70 @@ static const char *state2str(audio_state_t state)
}
}
+static gboolean control_connect_timeout(gpointer user_data)
+{
+ struct audio_device *dev = user_data;
+
+ dev->priv->control_timer = 0;
+
+ if (dev->control)
+ avrcp_connect(dev);
+
+ return FALSE;
+}
+
+static gboolean device_set_control_timer(struct audio_device *dev)
+{
+ struct dev_priv *priv = dev->priv;
+
+ if (!dev->control)
+ return FALSE;
+
+ if (priv->control_timer)
+ return FALSE;
+
+ priv->control_timer = g_timeout_add_seconds(CONTROL_CONNECT_TIMEOUT,
+ control_connect_timeout,
+ dev);
+
+ return TRUE;
+}
+
+static void device_remove_control_timer(struct audio_device *dev)
+{
+ if (dev->priv->control_timer)
+ g_source_remove(dev->priv->control_timer);
+ dev->priv->control_timer = 0;
+}
+
+static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
+ void *user_data)
+{
+ struct audio_device *dev = user_data;
+ struct dev_priv *priv = dev->priv;
+
+ if (priv->state == AUDIO_STATE_DISCONNECTED)
+ return;
+
+ if (priv->disconnecting)
+ return;
+
+ priv->disconnecting = TRUE;
+
+ if (dev->control) {
+ device_remove_control_timer(dev);
+ avrcp_disconnect(dev);
+ }
+
+ if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED)
+ sink_shutdown(dev->sink);
+
+ if (priv->hs_state != HEADSET_STATE_DISCONNECTED)
+ headset_shutdown(dev);
+
+ priv->disconnecting = FALSE;
+}
+
static void device_set_state(struct audio_device *dev, audio_state_t new_state)
{
struct dev_priv *priv = dev->priv;
@@ -155,9 +224,21 @@ static void device_set_state(struct audio_device *dev, audio_state_t new_state)
if (!state_str)
return;
- if (new_state == AUDIO_STATE_DISCONNECTED)
+ if (new_state == AUDIO_STATE_DISCONNECTED) {
priv->authorized = FALSE;
+ if (priv->dc_id) {
+ device_remove_disconnect_watch(dev->btd_dev,
+ priv->dc_id);
+ priv->dc_id = 0;
+ }
+ }
+ else if (new_state == AUDIO_STATE_CONNECTED) {
+ priv->disconnecting = FALSE;
+ priv->dc_id = device_add_disconnect_watch(dev->btd_dev,
+ disconnect_cb, dev, NULL);
+ }
+
if (dev->priv->state == new_state) {
DBG("state change attempted from %s to %s",
state_str, state_str);
@@ -191,42 +272,6 @@ static void device_set_state(struct audio_device *dev, audio_state_t new_state)
DBUS_TYPE_STRING, &state_str);
}
-static gboolean control_connect_timeout(gpointer user_data)
-{
- struct audio_device *dev = user_data;
-
- dev->priv->control_timer = 0;
-
- if (dev->control)
- avrcp_connect(dev);
-
- return FALSE;
-}
-
-static gboolean device_set_control_timer(struct audio_device *dev)
-{
- struct dev_priv *priv = dev->priv;
-
- if (!dev->control)
- return FALSE;
-
- if (priv->control_timer)
- return FALSE;
-
- priv->control_timer = g_timeout_add_seconds(CONTROL_CONNECT_TIMEOUT,
- control_connect_timeout,
- dev);
-
- return TRUE;
-}
-
-static void device_remove_control_timer(struct audio_device *dev)
-{
- if (dev->priv->control_timer)
- g_source_remove(dev->priv->control_timer);
- dev->priv->control_timer = 0;
-}
-
static gboolean avdtp_connect_timeout(gpointer user_data)
{
struct audio_device *dev = user_data;
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH v4 0/2] Get and Set Feature Reports on HIDRAW (USB and Bluetooth)
From: Jiri Kosina @ 2010-09-22 12:09 UTC (permalink / raw)
To: Alan Ott, Marcel Holtmann, David S. Miller
Cc: Stefan Achatz, Antonio Ospite, Alexey Dobriyan, Tejun Heo,
Alan Stern, Greg Kroah-Hartman, Stephane Chatty, Michael Poole,
Bastien Nocera, Eric Dumazet, linux-input, linux-kernel,
linux-usb, linux-bluetooth, netdev
In-Reply-To: <alpine.LNX.2.00.1009021724480.26813@pobox.suse.cz>
On Thu, 2 Sep 2010, Jiri Kosina wrote:
> > > This is version 4. Built against 2.6.35+ revision 320b2b8de12698 .
> > >
> > > Alan Ott (2):
> > > HID: Add Support for Setting and Getting Feature Reports from hidraw
> > > Bluetooth: hidp: Add support for hidraw HIDIOCGFEATURE and
> > > HIDIOCSFEATURE
> > >
> > > drivers/hid/hidraw.c | 105 ++++++++++++++++++++++++++++++++++++--
> > > drivers/hid/usbhid/hid-core.c | 37 +++++++++++++-
> > > include/linux/hid.h | 3 +
> > > include/linux/hidraw.h | 3 +
> > > net/bluetooth/hidp/core.c | 114 +++++++++++++++++++++++++++++++++++++++--
> > > net/bluetooth/hidp/hidp.h | 8 +++
> > > 6 files changed, 260 insertions(+), 10 deletions(-)
> >
> > Marcel, as per our previous discussion -- what is your word on this? I'd
> > be glad taking it once you Ack the bluetooth bits (which, as far as I
> > understood from your last mail, don't have strong objections against any
> > more).
>
> ... Marcel?
>
> I'd really like not to miss 2.6.37 merge window with this.
Seemingly I have not enought powers to get statement from Marcel here
these days/weeks.
Davem, would you perhaps be able to step in here?
Thanks,
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* Fix bluetoothd not starting on cold boot
From: Bastien Nocera @ 2010-09-22 11:38 UTC (permalink / raw)
To: BlueZ development
[-- Attachment #1: Type: text/plain, Size: 24 bytes --]
Patch attached.
Cheers
[-- Attachment #2: 0001-Also-run-bluetoothd-on-udev-change-events.patch --]
[-- Type: text/x-patch, Size: 896 bytes --]
>From 156877874776d3caec3641f09a34a42e4102ef71 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Wed, 22 Sep 2010 12:35:54 +0100
Subject: [PATCH] Also run bluetoothd on udev change events
Fixes bluetoothd not starting on cold boot with newer versions
of udev. See:
https://bugzilla.redhat.com/show_bug.cgi?id=634205
---
scripts/bluetooth.rules.in | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/scripts/bluetooth.rules.in b/scripts/bluetooth.rules.in
index 6809e9d..64df69d 100644
--- a/scripts/bluetooth.rules.in
+++ b/scripts/bluetooth.rules.in
@@ -1,3 +1,4 @@
# Run helper every time a Bluetooth device appears
# On remove actions, bluetoothd should go away by itself
ACTION=="add", SUBSYSTEM=="bluetooth", RUN+="@prefix@/sbin/bluetoothd --udev"
+ACTION=="change", SUBSYSTEM=="bluetooth", RUN+="@prefix@/sbin/bluetoothd --udev"
--
1.7.2.3
^ permalink raw reply related
* Re: Running "putkey" for keyboards and mice
From: Bastien Nocera @ 2010-09-22 11:33 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: BlueZ development
In-Reply-To: <1283791359.7529.28.camel@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 814 bytes --]
On Mon, 2010-09-06 at 17:42 +0100, Bastien Nocera wrote:
> On Mon, 2010-09-06 at 13:19 +0100, Bastien Nocera wrote:
> <snip>
> > Johan mentioned that we could implement this using a boolean property
> > for whether to store the linkkey on the device or not. When TRUE, should
> > we store the linkkey on both the device and on the local filesystem, or
> > just on the device?
> >
> > hci_read_stored_link_key() is not currently used in the code at all, so
> > it's possible that a device will be paired, but not marked as such in
> > the interface.
>
> I was wrongly reading the code, and it already does that.
>
> Patch attached to add the "KeyOnAdapter" property to devices.
>
> Note that I did not test this thoroughly yet. I'm more looking for
> comments right now.
Updated for latest git master.
Cheers
[-- Attachment #2: 0001-Add-KeyOnAdapter-property-to-devices.patch --]
[-- Type: text/x-patch, Size: 9661 bytes --]
>From ae889732f66e1814622b546f167963cda2fa5de5 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Mon, 6 Sep 2010 17:21:30 +0100
Subject: [PATCH] Add KeyOnAdapter property to devices
The KeyOnAdapter property will be true if the linkkey comes from
the adapter storage, rather than the local filesystem storage.
This makes it possible for front-ends to add linkkeys to the
adapter itself for keyboard and mice to automatically work
when dual-booting under other OSes.
---
doc/device-api.txt | 16 ++++++++
plugins/hciops.c | 32 ++++++++++++++++
src/adapter.c | 22 +++++++++++
src/adapter.h | 7 +++
src/dbus-hci.c | 1 +
src/device.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/device.h | 1 +
7 files changed, 185 insertions(+), 0 deletions(-)
diff --git a/doc/device-api.txt b/doc/device-api.txt
index b818299..c4f633b 100644
--- a/doc/device-api.txt
+++ b/doc/device-api.txt
@@ -161,6 +161,22 @@ Properties string Address [readonly]
drivers will also be removed and no new ones will
be probed as long as the device is blocked.
+ boolean KeyOnAdapter [readwrite]
+
+ Whether the linkkey for the device is available
+ on the adapter. This will be FALSE if the device
+ is not paired, or the key is not available on
+ the adapter (and just on the filesystem).
+
+ Setting this to TRUE, will write the key to the
+ adapter, returning an error if the adapter
+ does not support this.
+
+ Note that the key is not removed from the local
+ filesystem storage, as, once on the adapter, it
+ will lack linkkey type information, which is
+ required for Bluetooth 2.1 devices.
+
string Alias [readwrite]
The name alias for the remote device. The alias can
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 626cba2..e935eb0 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -786,6 +786,36 @@ fail:
return err;
}
+static int hciops_put_key (int index, bdaddr_t bdaddr, uint8_t *key)
+{
+ int dd, err;
+
+ dd = hci_open_dev(index);
+ if (dd < 0)
+ return -EIO;
+
+ err = hci_write_stored_link_key(dd, &bdaddr, key, HCI_REQ_TIMEOUT);
+
+ hci_close_dev(dd);
+
+ return -err;
+}
+
+static int hciops_del_key (int index, bdaddr_t bdaddr)
+{
+ int dd, err;
+
+ dd = hci_open_dev(index);
+ if (dd < 0)
+ return -EIO;
+
+ err = hci_delete_stored_link_key(dd, &bdaddr, 0, HCI_REQ_TIMEOUT);
+
+ hci_close_dev(dd);
+
+ return -err;
+}
+
static struct btd_adapter_ops hci_ops = {
.setup = hciops_setup,
.cleanup = hciops_cleanup,
@@ -805,6 +835,8 @@ static struct btd_adapter_ops hci_ops = {
.set_fast_connectable = hciops_fast_connectable,
.read_clock = hciops_read_clock,
.get_conn_handle = hciops_conn_handle,
+ .put_key = hciops_put_key,
+ .del_key = hciops_del_key,
};
static int hciops_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 9121c20..675787c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3544,3 +3544,25 @@ int btd_adapter_get_conn_handle(struct btd_adapter *adapter,
return adapter_ops->get_conn_handle(adapter->dev_id, bdaddr, handle);
}
+
+int btd_adapter_put_key (struct btd_adapter *adapter, bdaddr_t bdaddr, uint8_t *key)
+{
+ if (!adapter_ops)
+ return -EINVAL;
+
+ if (!adapter->up)
+ return -EINVAL;
+
+ return adapter_ops->put_key(adapter->dev_id, bdaddr, key);
+}
+
+int btd_adapter_del_key (struct btd_adapter *adapter, bdaddr_t bdaddr)
+{
+ if (!adapter_ops)
+ return -EINVAL;
+
+ if (!adapter->up)
+ return -EINVAL;
+
+ return adapter_ops->del_key(adapter->dev_id, bdaddr);
+}
diff --git a/src/adapter.h b/src/adapter.h
index 5eceaee..ec9981f 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -190,6 +190,8 @@ struct btd_adapter_ops {
int (*read_clock) (int index, int handle, int which, int timeout,
uint32_t *clock, uint16_t *accuracy);
int (*get_conn_handle) (int index, const bdaddr_t *bdaddr, int *handle);
+ int (*put_key) (int index, bdaddr_t bdaddr, uint8_t *key);
+ int (*del_key) (int index, bdaddr_t bdaddr);
};
int btd_register_adapter_ops(struct btd_adapter_ops *btd_adapter_ops);
@@ -214,3 +216,8 @@ int btd_adapter_read_clock(struct btd_adapter *adapter, int handle, int which,
uint16_t *accuracy);
int btd_adapter_get_conn_handle(struct btd_adapter *adapter,
const bdaddr_t *bdaddr, int *handle);
+
+int btd_adapter_put_key (struct btd_adapter *adapter,
+ bdaddr_t bdaddr,
+ uint8_t *key);
+int btd_adapter_del_key (struct btd_adapter *adapter, bdaddr_t bdaddr);
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index 9055ffe..f266409 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -903,6 +903,7 @@ void hcid_dbus_returned_link_key(bdaddr_t *local, bdaddr_t *peer)
return;
device_set_paired(device, TRUE);
+ device_set_key_on_adapter(device, TRUE);
}
int hcid_dbus_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
diff --git a/src/device.c b/src/device.c
index 9055eca..df89656 100644
--- a/src/device.c
+++ b/src/device.c
@@ -139,6 +139,7 @@ struct btd_device {
gboolean paired;
gboolean blocked;
gboolean renewed_key;
+ gboolean key_on_adapter;
gboolean authorizing;
gint ref;
@@ -256,6 +257,11 @@ gboolean device_is_paired(struct btd_device *device)
return device->paired;
}
+gboolean device_linkkey_is_on_adapter(struct btd_device *device)
+{
+ return device->key_on_adapter;
+}
+
gboolean device_is_trusted(struct btd_device *device)
{
return device->trusted;
@@ -329,6 +335,10 @@ static DBusMessage *get_properties(DBusConnection *conn,
boolean = device_is_paired(device);
dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean);
+ /* KeyOnAdapter */
+ boolean = device_linkkey_is_on_adapter(device);
+ dict_append_entry(&dict, "KeyOnAdapter", DBUS_TYPE_BOOLEAN, &boolean);
+
/* Trusted */
boolean = device_is_trusted(device);
dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean);
@@ -570,6 +580,80 @@ static DBusMessage *set_blocked(DBusConnection *conn, DBusMessage *msg,
}
}
+static int device_put_key_on_adapter(DBusConnection *conn, struct btd_device *device)
+{
+ int err;
+ bdaddr_t src;
+ unsigned char linkkey[16];
+
+ if (device->key_on_adapter)
+ return 0;
+ if (!device->paired)
+ return 0;
+
+ adapter_get_address(device->adapter, &src);
+ if (read_link_key(&src, &device->bdaddr, linkkey, NULL) < 0)
+ return -ENOKEY;
+
+ err = btd_adapter_put_key(device->adapter, device->bdaddr, linkkey);
+ if (err < 0)
+ return -err;
+
+ device->key_on_adapter = TRUE;
+
+ emit_property_changed(conn, device->path, DEVICE_INTERFACE, "KeyOnAdapter",
+ DBUS_TYPE_BOOLEAN, &device->key_on_adapter);
+
+ return 0;
+}
+
+static int device_del_key_on_adapter(DBusConnection *conn, struct btd_device *device)
+{
+ int err;
+
+ if (!device->key_on_adapter)
+ return 0;
+
+ err = btd_adapter_del_key(device->adapter, device->bdaddr);
+ if (err < 0)
+ return err;
+
+ device->key_on_adapter = FALSE;
+
+ emit_property_changed(conn, device->path, DEVICE_INTERFACE, "KeyOnAdapter",
+ DBUS_TYPE_BOOLEAN, &device->key_on_adapter);
+
+ return 0;
+}
+
+static DBusMessage *set_key_on_adapter(DBusConnection *conn, DBusMessage *msg,
+ gboolean value, void *data)
+{
+ struct btd_device *device = data;
+ int err;
+
+ if (value)
+ err = device_put_key_on_adapter(conn, device);
+ else
+ err = device_del_key_on_adapter(conn, device);
+
+ switch (-err) {
+ case 0:
+ return dbus_message_new_method_return(msg);
+ case EINVAL:
+ return g_dbus_create_error(msg,
+ ERROR_INTERFACE ".NotSupported",
+ "Adapter lacks storage support");
+ case ENOKEY:
+ return g_dbus_create_error(msg,
+ ERROR_INTERFACE ".Failed",
+ "Device is paired but link key is not available");
+ default:
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
+ "%s", strerror(-err));
+ }
+}
+
static inline DBusMessage *invalid_args(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
@@ -620,6 +704,15 @@ static DBusMessage *set_property(DBusConnection *conn,
dbus_message_iter_get_basic(&sub, &value);
return set_blocked(conn, msg, value, data);
+ } else if (g_str_equal("KeyOnAdapter", property)) {
+ dbus_bool_t value;
+
+ if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
+ return invalid_args(msg);
+
+ dbus_message_iter_get_basic(&sub, &value);
+
+ return set_key_on_adapter(conn, msg, value, data);
}
return invalid_args(msg);
@@ -1836,6 +1929,19 @@ void device_set_paired(struct btd_device *device, gboolean value)
DBUS_TYPE_BOOLEAN, &value);
}
+void device_set_key_on_adapter(struct btd_device *device, gboolean value)
+{
+ DBusConnection *conn = get_dbus_connection();
+
+ if (device->key_on_adapter == value)
+ return;
+
+ device->key_on_adapter = value;
+
+ emit_property_changed(conn, device->path, DEVICE_INTERFACE, "KeyOnAdapter",
+ DBUS_TYPE_BOOLEAN, &value);
+}
+
static void device_agent_removed(struct agent *agent, void *user_data)
{
struct btd_device *device = user_data;
diff --git a/src/device.h b/src/device.h
index 21f67d0..6f57b37 100644
--- a/src/device.h
+++ b/src/device.h
@@ -55,6 +55,7 @@ gboolean device_is_temporary(struct btd_device *device);
gboolean device_is_paired(struct btd_device *device);
gboolean device_is_trusted(struct btd_device *device);
void device_set_paired(struct btd_device *device, gboolean paired);
+void device_set_key_on_adapter(struct btd_device *device, gboolean key_on_adapter);
void device_set_temporary(struct btd_device *device, gboolean temporary);
void device_set_cap(struct btd_device *device, uint8_t cap);
uint8_t device_get_cap(struct btd_device *device);
--
1.7.2.3
^ permalink raw reply related
* Re: [PATCH 2/2] Remove magic numbers in MCAP CSP
From: Johan Hedberg @ 2010-09-22 7:59 UTC (permalink / raw)
To: Santiago Carot-Nemesio; +Cc: linux-bluetooth
In-Reply-To: <1285139031-1570-2-git-send-email-sancane@gmail.com>
Hi,
On Wed, Sep 22, 2010, Santiago Carot-Nemesio wrote:
> ---
> health/mcap_sync.c | 18 ++++++++++--------
> 1 files changed, 10 insertions(+), 8 deletions(-)
Thanks. This patch is now also in the upstream tree.
Johan
^ permalink raw reply
* Re: [PATCH 1/2] Simplify logic to calculate the BT/system clock latency
From: Johan Hedberg @ 2010-09-22 7:59 UTC (permalink / raw)
To: Santiago Carot-Nemesio; +Cc: linux-bluetooth
In-Reply-To: <1285139031-1570-1-git-send-email-sancane@gmail.com>
Hi,
On Wed, Sep 22, 2010, Santiago Carot-Nemesio wrote:
> This is only a cosmetic change. Using a while loop
> we avoid direct manipulation of counter loop variable
> when error happens reading the BT clock.
> ---
> health/mcap_sync.c | 7 ++++---
> 1 files changed, 4 insertions(+), 3 deletions(-)
Thanks. The patch has been pushed upstream.
> + while ((i < 20) && (retries > 0)) {
The extra parentheses around the comparisons are unnecessary. I fixed
that in a subsequent cleanup commit. Usually we only add these extra
parentheses for binary bitwise operations such as & and | for clarity.
Johan
^ permalink raw reply
* Re: [PATCH 2/2] Use hciops functions instead of HCI raw sockets
From: Johan Hedberg @ 2010-09-22 7:48 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <1285118546-29558-2-git-send-email-epx@signove.com>
Hi Elvis,
On Tue, Sep 21, 2010, Elvis Pfützenreuter wrote:
> ---
> health/mcap_sync.c | 84 +++++++++++++++------------------------------------
> 1 files changed, 25 insertions(+), 59 deletions(-)
Thanks. This one has also been pushed upstream.
Johan
^ permalink raw reply
* Re: [PATCH 1/2] Add BT read clock and get conn handle to hciops
From: Johan Hedberg @ 2010-09-22 7:47 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <1285118546-29558-1-git-send-email-epx@signove.com>
Hi Elvis,
On Tue, Sep 21, 2010, Elvis Pfützenreuter wrote:
> ---
> plugins/hciops.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
> src/adapter.c | 25 +++++++++++++++++++++++++
> src/adapter.h | 9 +++++++++
> 3 files changed, 78 insertions(+), 0 deletions(-)
Thanks. the patch has been pushed upstream. I also pushed another patch
to cleanup error variable usage in hciops.
Johan
^ permalink raw reply
* Re: [PATCH] Fix Headset Audio gateway SDP record.
From: Johan Hedberg @ 2010-09-22 7:22 UTC (permalink / raw)
To: Jaikumar Ganesh; +Cc: linux-bluetooth
In-Reply-To: <1285113932-16299-1-git-send-email-jaikumar@google.com>
Hi Jaikumar,
On Tue, Sep 21, 2010, Jaikumar Ganesh wrote:
> Headset Audio Gateway does not have the Supported Features
> in the SDP records according to the HSP specification.
> ---
> tools/sdptool.c | 6 +-----
> 1 files changed, 1 insertions(+), 5 deletions(-)
Thanks. The patch has been pushed upstream.
Johan
^ permalink raw reply
* [PATCH 2/2] Remove magic numbers in MCAP CSP
From: Santiago Carot-Nemesio @ 2010-09-22 7:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Santiago Carot-Nemesio
In-Reply-To: <1285139031-1570-1-git-send-email-sancane@gmail.com>
---
health/mcap_sync.c | 18 ++++++++++--------
1 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/health/mcap_sync.c b/health/mcap_sync.c
index 3d54936..b9f2a65 100644
--- a/health/mcap_sync.c
+++ b/health/mcap_sync.c
@@ -48,6 +48,8 @@
#define CLK CLOCK_MONOTONIC
#define MCAP_CSP_ERROR g_quark_from_static_string("mcap-csp-error-quark")
+#define MAX_RETRIES 10
+#define SAMPLE_COUNT 20
struct mcap_csp {
uint64_t base_tmstamp; /* CSP base timestamp */
@@ -363,7 +365,7 @@ uint32_t mcap_get_btclock(struct mcap_mcl *mcl)
static gboolean initialize_caps(struct mcap_mcl *mcl)
{
struct timespec t1, t2;
- int latencies[20];
+ int latencies[SAMPLE_COUNT];
int latency, avg, dev;
uint32_t btclock;
uint16_t btaccuracy;
@@ -385,8 +387,8 @@ static gboolean initialize_caps(struct mcap_mcl *mcl)
/* Do clock read a number of times and measure latency */
avg = 0;
i = 0;
- retries = 10;
- while ((i < 20) && (retries > 0)) {
+ retries = MAX_RETRIES;
+ while ((i < SAMPLE_COUNT) && (retries > 0)) {
clock_gettime(CLK, &t1);
if (!read_btclock(mcl, &btclock, &btaccuracy)) {
retries--;
@@ -404,21 +406,21 @@ static gboolean initialize_caps(struct mcap_mcl *mcl)
return FALSE;
/* Calculate average and deviation */
- avg /= 20;
+ avg /= SAMPLE_COUNT;
dev = 0;
- for (i = 0; i < 20; ++i)
+ for (i = 0; i < SAMPLE_COUNT; ++i)
dev += abs(latencies[i] - avg);
- dev /= 20;
+ dev /= SAMPLE_COUNT;
/* Calculate corrected average, without 'freak' latencies */
latency = 0;
- for (i = 0; i < 20; ++i) {
+ for (i = 0; i < SAMPLE_COUNT; ++i) {
if (latencies[i] > (avg + dev * 6))
latency += avg;
else
latency += latencies[i];
}
- latency /= 20;
+ latency /= SAMPLE_COUNT;
_caps.latency = latency;
_caps.preempt_thresh = latency * 4;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/2] Simplify logic to calculate the BT/system clock latency
From: Santiago Carot-Nemesio @ 2010-09-22 7:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Santiago Carot-Nemesio
This is only a cosmetic change. Using a while loop
we avoid direct manipulation of counter loop variable
when error happens reading the BT clock.
---
health/mcap_sync.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/health/mcap_sync.c b/health/mcap_sync.c
index 670260b..3d54936 100644
--- a/health/mcap_sync.c
+++ b/health/mcap_sync.c
@@ -384,12 +384,12 @@ static gboolean initialize_caps(struct mcap_mcl *mcl)
/* Do clock read a number of times and measure latency */
avg = 0;
+ i = 0;
retries = 10;
- for (i = 0; i < 20 && retries > 0; ++i) {
+ while ((i < 20) && (retries > 0)) {
clock_gettime(CLK, &t1);
if (!read_btclock(mcl, &btclock, &btaccuracy)) {
- --i;
- --retries;
+ retries--;
continue;
}
clock_gettime(CLK, &t2);
@@ -397,6 +397,7 @@ static gboolean initialize_caps(struct mcap_mcl *mcl)
latency = time_us(&t2) - time_us(&t1);
latencies[i] = latency;
avg += latency;
+ i++;
}
if (retries <= 0)
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 2/2] Bluetooth: support to send power management enable during hci open
From: Suraj Sumangala @ 2010-09-22 4:01 UTC (permalink / raw)
To: Pavan Savoy
Cc: Suraj Sumangala, linux-bluetooth@vger.kernel.org,
Jothikumar Mothilal
In-Reply-To: <AANLkTinS9YnKBUnv-RhV8ZZ185FtN_VDOWTQa3gTr6FC@mail.gmail.com>
Hi Pavan,
On 9/22/2010 1:22 AM, Pavan Savoy wrote:
> On Tue, Sep 21, 2010 at 8:33 AM, Suraj Sumangala<suraj@atheros.com> wrote:
>> This patch enables HCI_UART_ATH3K transport driver to support
>> sending Vendor specific hci commands during hci open
>> to enable or disable power management feature.
>
> Why? shouldn't this be done from the hciattach? like for the other
> manufacturers?
> If you want it to be sent before hci0 interface is exposed, send it
> over ttyXX, you have your _init function and if you require it to be
> sent after the hci0 is exposed - do it in the _post function.
>
We are already using the _init and _post of hciattach.
The mentioned feature will get disabled in the controller on receiving a
HCI RESET command.
If the user does an HCI close, this feature will be disabled and we need
to enable it again when the user opens the HCI device again.
I guess the "hdev->driver_init" queue is provided for that reason.
An hciattach is called only once but hci open/close can be done multiple
times.
Regards
Suraj
^ permalink raw reply
* [PATCH 2/2] Use hciops functions instead of HCI raw sockets
From: Elvis Pfützenreuter @ 2010-09-22 1:22 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
In-Reply-To: <1285118546-29558-1-git-send-email-epx@signove.com>
---
health/mcap_sync.c | 84 +++++++++++++++------------------------------------
1 files changed, 25 insertions(+), 59 deletions(-)
diff --git a/health/mcap_sync.c b/health/mcap_sync.c
index 670260b..954a9b8 100644
--- a/health/mcap_sync.c
+++ b/health/mcap_sync.c
@@ -32,8 +32,9 @@
#include <time.h>
#include <stdlib.h>
#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
+#include <bluetooth/l2cap.h>
+#include "../src/adapter.h"
+#include "../src/manager.h"
#include <sys/ioctl.h>
#include "config.h"
@@ -60,8 +61,6 @@ struct mcap_csp {
guint ind_timer; /* CSP-Slave: indication timer */
guint set_timer; /* CSP-Slave: delayed set timer */
void *set_data; /* CSP-Slave: delayed set data */
- gint dev_id; /* CSP-Slave: device ID */
- gint dev_hci_fd; /* CSP-Slave fd to read BT clock */
void *csp_priv_data; /* CSP-Master: In-flight request data */
};
@@ -173,8 +172,6 @@ void mcap_sync_init(struct mcap_mcl *mcl)
mcl->csp->rem_req_acc = 10000; /* safe divisor */
mcl->csp->set_data = NULL;
- mcl->csp->dev_id = -1;
- mcl->csp->dev_hci_fd = -1;
mcl->csp->csp_priv_data = NULL;
reset_tmstamp(mcl->csp, NULL, 0);
@@ -185,9 +182,6 @@ void mcap_sync_stop(struct mcap_mcl *mcl)
if (!mcl->csp)
return;
- if (mcl->csp->dev_hci_fd > -1)
- hci_close_dev(mcl->csp->dev_hci_fd);
-
if (mcl->csp->ind_timer)
g_source_remove(mcl->csp->ind_timer);
@@ -200,7 +194,6 @@ void mcap_sync_stop(struct mcap_mcl *mcl)
if (mcl->csp->csp_priv_data)
g_free(mcl->csp->csp_priv_data);
- mcl->csp->dev_hci_fd = -1;
mcl->csp->ind_timer = 0;
mcl->csp->set_timer = 0;
mcl->csp->set_data = NULL;
@@ -247,54 +240,23 @@ static gboolean valid_btclock(uint32_t btclk)
return btclk <= MCAP_BTCLOCK_MAX;
}
-static int mcl_hci_fd(struct mcap_mcl *mcl)
-{
- if (mcl->csp->dev_hci_fd < 0) {
- if (mcl->csp->dev_id < 0)
- mcl->csp->dev_id = hci_get_route(&mcl->addr);
- mcl->csp->dev_hci_fd = hci_open_dev(mcl->csp->dev_id);
- }
- return mcl->csp->dev_hci_fd;
-}
-
-static void mcl_hci_fd_close(struct mcap_mcl *mcl)
-{
- hci_close_dev(mcl->csp->dev_hci_fd);
- mcl->csp->dev_hci_fd = -1;
-}
-
/* This call may fail; either deal with retry or use read_btclock_retry */
static gboolean read_btclock(struct mcap_mcl *mcl, uint32_t *btclock,
uint16_t *btaccuracy)
{
- int fd, ret, handle, which;
- struct hci_conn_info_req *cr;
-
- if (mcl) {
- which = 1;
- fd = mcl_hci_fd(mcl);
-
- cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
- bacpy(&cr->bdaddr, &mcl->addr);
- cr->type = ACL_LINK;
+ int ret, handle, which = 1;
+ struct btd_adapter *adapter;
- ret = ioctl(fd, HCIGETCONNINFO, (unsigned long) cr);
- g_free(cr);
+ adapter = manager_find_adapter(&mcl->ms->src);
- if (ret < 0)
- return FALSE;
- else
- handle = htobs(cr->conn_info->handle);
- } else {
- fd = hci_open_dev(hci_get_route(NULL));
- which = 0;
- handle = 0;
- }
+ if (!adapter)
+ return FALSE;
- ret = hci_read_clock(fd, handle, which, btclock, btaccuracy, 1000);
+ if (btd_adapter_get_conn_handle(adapter, &mcl->addr, &handle))
+ return FALSE;
- if (!mcl)
- hci_close_dev(fd);
+ ret = btd_adapter_read_clock(adapter, handle, which, 1000, btclock,
+ btaccuracy);
return ret < 0 ? FALSE : TRUE;
}
@@ -315,15 +277,19 @@ static gboolean read_btclock_retry(struct mcap_mcl *mcl, uint32_t *btclock,
static gboolean get_btrole(struct mcap_mcl *mcl)
{
- int fd = mcl_hci_fd(mcl);
- struct hci_dev_info di = { dev_id: mcl->csp->dev_id };
+ int sock, flags;
+ socklen_t len;
- if (ioctl(fd, HCIGETDEVINFO, (void *) &di)) {
- mcl_hci_fd_close(mcl);
- return FALSE;
- }
+ if (mcl->cc == NULL)
+ return -1;
+
+ sock = g_io_channel_unix_get_fd(mcl->cc);
+ len = sizeof(flags);
+
+ if (getsockopt(sock, SOL_L2CAP, L2CAP_LM, &flags, &len))
+ DBG("CSP: could not read role");
- return di.link_mode == HCI_LM_MASTER;
+ return flags & L2CAP_LM_MASTER;
}
uint64_t mcap_get_timestamp(struct mcap_mcl *mcl,
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/2] Add BT read clock and get conn handle to hciops
From: Elvis Pfützenreuter @ 2010-09-22 1:22 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
---
plugins/hciops.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
src/adapter.c | 25 +++++++++++++++++++++++++
src/adapter.h | 9 +++++++++
3 files changed, 78 insertions(+), 0 deletions(-)
diff --git a/plugins/hciops.c b/plugins/hciops.c
index f1e9f69..faac4ce 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -748,6 +748,48 @@ static int hciops_fast_connectable(int index, gboolean enable)
return err;
}
+static int hciops_read_clock(int index, int handle, int which, int timeout,
+ uint32_t *clock, uint16_t *accuracy)
+{
+ int dd, err = 0;
+
+ dd = hci_open_dev(index);
+ if (dd < 0)
+ return -EIO;
+
+ if (hci_read_clock(dd, handle, which, clock, accuracy, timeout))
+ err = errno;
+
+ hci_close_dev(dd);
+
+ return err;
+}
+
+static int hciops_conn_handle(int index, const bdaddr_t *bdaddr, int *handle)
+{
+ struct hci_conn_info_req *cr;
+ int dd, err = 0;
+
+ dd = hci_open_dev(index);
+ if (dd < 0)
+ return -EIO;
+
+ cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
+ bacpy(&cr->bdaddr, bdaddr);
+ cr->type = ACL_LINK;
+
+ if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr))
+ err = errno;
+
+ if (!err)
+ *handle = htobs(cr->conn_info->handle);
+
+ hci_close_dev(dd);
+ g_free(cr);
+
+ return err;
+}
+
static struct btd_adapter_ops hci_ops = {
.setup = hciops_setup,
.cleanup = hciops_cleanup,
@@ -765,6 +807,8 @@ static struct btd_adapter_ops hci_ops = {
.read_name = hciops_read_name,
.set_class = hciops_set_class,
.set_fast_connectable = hciops_fast_connectable,
+ .read_clock = hciops_read_clock,
+ .get_conn_handle = hciops_conn_handle,
};
static int hciops_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 670b8bd..9121c20 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3519,3 +3519,28 @@ int btd_adapter_set_fast_connectable(struct btd_adapter *adapter,
return adapter_ops->set_fast_connectable(adapter->dev_id, enable);
}
+
+int btd_adapter_read_clock(struct btd_adapter *adapter, int handle, int which,
+ int timeout, uint32_t *clock, uint16_t *accuracy)
+{
+ if (!adapter_ops)
+ return -EINVAL;
+
+ if (!adapter->up)
+ return -EINVAL;
+
+ return adapter_ops->read_clock(adapter->dev_id, handle, which,
+ timeout, clock, accuracy);
+}
+
+int btd_adapter_get_conn_handle(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr, int *handle)
+{
+ if (!adapter_ops)
+ return -EINVAL;
+
+ if (!adapter->up)
+ return -EINVAL;
+
+ return adapter_ops->get_conn_handle(adapter->dev_id, bdaddr, handle);
+}
diff --git a/src/adapter.h b/src/adapter.h
index fb52b34..5eceaee 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -187,6 +187,9 @@ struct btd_adapter_ops {
int (*read_name) (int index);
int (*set_class) (int index, uint32_t class);
int (*set_fast_connectable) (int index, gboolean enable);
+ int (*read_clock) (int index, int handle, int which, int timeout,
+ uint32_t *clock, uint16_t *accuracy);
+ int (*get_conn_handle) (int index, const bdaddr_t *bdaddr, int *handle);
};
int btd_register_adapter_ops(struct btd_adapter_ops *btd_adapter_ops);
@@ -205,3 +208,9 @@ void btd_adapter_unregister_powered_callback(struct btd_adapter *adapter,
* type to default values. Valid for both connectable and discoverable modes. */
int btd_adapter_set_fast_connectable(struct btd_adapter *adapter,
gboolean enable);
+
+int btd_adapter_read_clock(struct btd_adapter *adapter, int handle, int which,
+ int timeout, uint32_t *clock,
+ uint16_t *accuracy);
+int btd_adapter_get_conn_handle(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr, int *handle);
--
1.7.0.4
^ permalink raw reply related
* [PATCH] Fix Headset Audio gateway SDP record.
From: Jaikumar Ganesh @ 2010-09-22 0:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jaikumar Ganesh
Headset Audio Gateway does not have the Supported Features
in the SDP records according to the HSP specification.
---
tools/sdptool.c | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/tools/sdptool.c b/tools/sdptool.c
index d06b159..140a46a 100644
--- a/tools/sdptool.c
+++ b/tools/sdptool.c
@@ -1477,8 +1477,7 @@ static int add_headset_ag(sdp_session_t *session, svc_info_t *si)
sdp_list_t *aproto, *proto[2];
sdp_record_t record;
uint8_t u8 = si->channel ? si->channel : 7;
- uint16_t u16 = 0x17;
- sdp_data_t *channel, *features;
+ sdp_data_t *channel;
uint8_t netid = si->network ? si->network : 0x01; // ???? profile document
sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
int ret = 0;
@@ -1511,9 +1510,6 @@ static int add_headset_ag(sdp_session_t *session, svc_info_t *si)
proto[1] = sdp_list_append(proto[1], channel);
apseq = sdp_list_append(apseq, proto[1]);
- features = sdp_data_alloc(SDP_UINT16, &u16);
- sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
-
aproto = sdp_list_append(0, apseq);
sdp_set_access_protos(&record, aproto);
--
1.6.5.7
^ permalink raw reply related
* Re: [PATCH] Fix Headset Audio gateway SDP record.
From: jaikumar Ganesh @ 2010-09-22 0:05 UTC (permalink / raw)
To: y; +Cc: linux-bluetooth, Jaikumar Ganesh
In-Reply-To: <4447611680690660620@unknownmsgid>
Please ignore. Sending again with a valid "to address".
On Tue, Sep 21, 2010 at 4:50 PM, <y@google.com> wrote:
> From: Jaikumar Ganesh <jaikumar@google.com>
>
> Headset Audio Gateway does not have the Supported Features
> in the SDP records according to the HSP specification.
> ---
> tools/sdptool.c | 6 +-----
> 1 files changed, 1 insertions(+), 5 deletions(-)
>
> diff --git a/tools/sdptool.c b/tools/sdptool.c
> index d06b159..140a46a 100644
> --- a/tools/sdptool.c
> +++ b/tools/sdptool.c
> @@ -1477,8 +1477,7 @@ static int add_headset_ag(sdp_session_t *session, svc_info_t *si)
> sdp_list_t *aproto, *proto[2];
> sdp_record_t record;
> uint8_t u8 = si->channel ? si->channel : 7;
> - uint16_t u16 = 0x17;
> - sdp_data_t *channel, *features;
> + sdp_data_t *channel;
> uint8_t netid = si->network ? si->network : 0x01; // ???? profile document
> sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
> int ret = 0;
> @@ -1511,9 +1510,6 @@ static int add_headset_ag(sdp_session_t *session, svc_info_t *si)
> proto[1] = sdp_list_append(proto[1], channel);
> apseq = sdp_list_append(apseq, proto[1]);
>
> - features = sdp_data_alloc(SDP_UINT16, &u16);
> - sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
> -
> aproto = sdp_list_append(0, apseq);
> sdp_set_access_protos(&record, aproto);
>
> --
> 1.6.5.7
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Fw: 2.6.35.4 + rfcomm -> segfault
From: Andrew Morton @ 2010-09-21 23:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Martin Pirker
Begin forwarded message:
Date: Mon, 30 Aug 2010 10:00:37 +0200
From: Martin Pirker <lkml.collector@gmail.com>
To: LKML <linux-kernel@vger.kernel.org>
Subject: 2.6.35.4 + rfcomm -> segfault
Hi...
given a Notebook with Bluetooth connection to mobile phone for GPRS Internet:
Aug 28 11:43:16 h kernel: [ 1520.976793] general protection fault:
0000 [#1] SMP
Aug 28 11:43:16 h kernel: [ 1520.976802] last sysfs file:
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:09/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/curre
nt_now
Aug 28 11:43:16 h kernel: [ 1520.976808] CPU 1
Aug 28 11:43:16 h kernel: [ 1520.976811] Modules linked in:
ppp_deflate zlib_deflate bsd_comp ppp_async crc_ccitt sco bridge stp
bnep rfcomm l2cap joydev arc4 iw
lagn i915 iwlcore snd_hda_codec_intelhdmi snd_hda_codec_conexant
mac80211 drm_kms_helper snd_hda_intel snd_hda_codec drm btusb
snd_hwdep bluetooth cfg80211 snd_pcm p
smouse pcspkr snd_timer serio_raw thinkpad_acpi tpm_tis i2c_i801 snd
iTCO_wdt led_class tpm tpm_bios nvram e1000e soundcore
iTCO_vendor_support snd_page_alloc i2c_al
go_bit cfbcopyarea intel_agp cfbimgblt cfbfillrect video
Aug 28 11:43:16 h kernel: [ 1520.976897]
Aug 28 11:43:16 h kernel: [ 1520.976902] Pid: 4223, comm: wvdial Not
tainted 2.6.35.4 #1 5413A13/5413A13
Aug 28 11:43:16 h kernel: [ 1520.976907] RIP:
0010:[<ffffffff8147b0fd>] [<ffffffff8147b0fd>]
sock_sendmsg+0xed/0x120
Aug 28 11:43:16 h kernel: [ 1520.976921] RSP: 0018:ffff880130ea78a8
EFLAGS: 00010246
Aug 28 11:43:16 h kernel: [ 1520.976925] RAX: dead4ead00002020 RBX:
ffff8801379c9140 RCX: 0000000000000004
Aug 28 11:43:16 h kernel: [ 1520.976929] RDX: ffff880130ea7a48 RSI:
ffff8801379c9140 RDI: ffff880130ea78a8
Aug 28 11:43:16 h kernel: [ 1520.976934] RBP: ffff880130ea7a18 R08:
0000000000000004 R09: ffff8801379c9140
Aug 28 11:43:16 h kernel: [ 1520.976938] R10: 0000000000000001 R11:
2222222222222222 R12: ffff880130ea7a48
Aug 28 11:43:16 h kernel: [ 1520.976942] R13: 0000000000000004 R14:
ffff880132695000 R15: ffff88012e0bc870
Aug 28 11:43:16 h kernel: [ 1520.976947] FS: 00007ff03bb66720(0000)
GS:ffff880002680000(0000) knlGS:0000000000000000
Aug 28 11:43:16 h kernel: [ 1520.976952] CS: 0010 DS: 0000 ES: 0000
CR0: 0000000080050033
Aug 28 11:43:16 h kernel: [ 1520.976956] CR2: 00007f5edee18000 CR3:
000000012bdfb000 CR4: 00000000000006e0
Aug 28 11:43:16 h kernel: [ 1520.976961] DR0: 0000000000000000 DR1:
0000000000000000 DR2: 0000000000000000
Aug 28 11:43:16 h kernel: [ 1520.976965] DR3: 0000000000000000 DR6:
00000000ffff0ff0 DR7: 0000000000000400
Aug 28 11:43:16 h kernel: [ 1520.976970] Process wvdial (pid: 4223,
threadinfo ffff880130ea6000, task ffff88013060bfc0)
Aug 28 11:43:16 h kernel: [ 1520.976974] Stack:
Aug 28 11:43:16 h kernel: [ 1520.976976] 0000000000015cc0
0000000000015cc0 0000000000000000 ffffffff00000001
Aug 28 11:43:16 h kernel: [ 1520.976984] <0> 0000000000000000
0000000000000000 0000000000000000 0000000000000000
Aug 28 11:43:16 h kernel: [ 1520.976993] <0> 0000000000000000
ffff88013060bfc0 0000000000000000 0000000000000931
Aug 28 11:43:16 h kernel: [ 1520.977003] Call Trace:
Aug 28 11:43:16 h kernel: [ 1520.977013] [<ffffffff8147b171>]
kernel_sendmsg+0x41/0x60
Aug 28 11:43:16 h kernel: [ 1520.977022] [<ffffffffa014314b>]
rfcomm_send_frame+0x3b/0x40 [rfcomm]
Aug 28 11:43:16 h kernel: [ 1520.977030] [<ffffffffa01431b3>]
rfcomm_send_disc+0x63/0x70 [rfcomm]
Aug 28 11:43:16 h kernel: [ 1520.977038] [<ffffffffa014429c>]
__rfcomm_dlc_close+0x25c/0x2b0 [rfcomm]
Aug 28 11:43:16 h kernel: [ 1520.977048] [<ffffffff81583d05>] ?
mutex_lock_nested+0x35/0x40
Aug 28 11:43:16 h kernel: [ 1520.977055] [<ffffffffa0144555>]
rfcomm_dlc_close+0x35/0x50 [rfcomm]
Aug 28 11:43:16 h kernel: [ 1520.977064] [<ffffffffa0148a8e>]
rfcomm_tty_close+0x4e/0x100 [rfcomm]
Aug 28 11:43:16 h kernel: [ 1520.977071] [<ffffffff813530ee>]
tty_release+0x17e/0x720
Aug 28 11:43:16 h kernel: [ 1520.977080] [<ffffffff812be59e>] ?
do_raw_spin_unlock+0x5e/0xb0
Aug 28 11:43:16 h kernel: [ 1520.977088] [<ffffffff81585aab>] ?
_raw_spin_unlock+0x2b/0x40
Aug 28 11:43:16 h kernel: [ 1520.977096] [<ffffffffa0148d83>] ?
rfcomm_tty_open+0x243/0x330 [rfcomm]
Aug 28 11:43:16 h kernel: [ 1520.977105] [<ffffffff810502c0>] ?
default_wake_function+0x0/0x20
Aug 28 11:43:16 h kernel: [ 1520.977111] [<ffffffff813544be>]
tty_open+0x52e/0x600
Aug 28 11:43:16 h kernel: [ 1520.977121] [<ffffffff8114fd27>]
chrdev_open+0xf7/0x210
Aug 28 11:43:16 h kernel: [ 1520.977128] [<ffffffff81585aab>] ?
_raw_spin_unlock+0x2b/0x40
Aug 28 11:43:16 h kernel: [ 1520.977134] [<ffffffff8114fc30>] ?
chrdev_open+0x0/0x210
Aug 28 11:43:16 h kernel: [ 1520.977141] [<ffffffff8114a4f4>]
__dentry_open+0xe4/0x330
Aug 28 11:43:16 h kernel: [ 1520.977150] [<ffffffff81286708>] ?
devcgroup_inode_permission+0x48/0x190
Aug 28 11:43:16 h kernel: [ 1520.977160] [<ffffffff8125c34f>] ?
security_inode_permission+0x1f/0x30
Aug 28 11:43:16 h kernel: [ 1520.977167] [<ffffffff8114a854>]
nameidata_to_filp+0x54/0x70
Aug 28 11:43:16 h kernel: [ 1520.977173] [<ffffffff81158445>]
do_last+0x3e5/0x720
Aug 28 11:43:16 h kernel: [ 1520.977180] [<ffffffff8115a867>]
do_filp_open+0x207/0x680
Aug 28 11:43:16 h kernel: [ 1520.977186] [<ffffffff812be59e>] ?
do_raw_spin_unlock+0x5e/0xb0
Aug 28 11:43:16 h kernel: [ 1520.977193] [<ffffffff81585aab>] ?
_raw_spin_unlock+0x2b/0x40
Aug 28 11:43:16 h kernel: [ 1520.977201] [<ffffffff81165e6a>] ?
alloc_fd+0xfa/0x140
Aug 28 11:43:16 h kernel: [ 1520.977207] [<ffffffff8114a2c9>]
do_sys_open+0x69/0x140
Aug 28 11:43:16 h kernel: [ 1520.977214] [<ffffffff81585062>] ?
trace_hardirqs_on_thunk+0x3a/0x3f
Aug 28 11:43:16 h kernel: [ 1520.977220] [<ffffffff8114a3e0>]
sys_open+0x20/0x30
Aug 28 11:43:16 h kernel: [ 1520.977229] [<ffffffff8100b072>]
system_call_fastpath+0x16/0x1b
Aug 28 11:43:16 h kernel: [ 1520.977233] Code: ad 74 ff ff ff 44 89 ea
4c 89 e6 48 89 df e8 7b 0c de ff 85 c0 75 1a 48 8b 43 28 48 8d bd 90
fe ff ff 4c 89 e9 4c 89 e2 48 89 de <ff> 90 88 00 00 00 3d ef fd ff ff
74 16 48 8b 5d e8 4c 8b 65 f0
Aug 28 11:43:16 h kernel: [ 1520.977313] RIP [<ffffffff8147b0fd>]
sock_sendmsg+0xed/0x120
Aug 28 11:43:16 h kernel: [ 1520.977319] RSP <ffff880130ea78a8>
Aug 28 11:43:16 h kernel: [ 1520.977325] ---[ end trace b38fcf1132041c2a ]---
I remember this happened also on older kernels, but so far it happens
so rarely I didn't bother.
Maybe the stack trace is of help to you...
Martin
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* [PATCH] Fix Headset Audio gateway SDP record.
From: y @ 2010-09-21 23:50 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jaikumar Ganesh
From: Jaikumar Ganesh <jaikumar@google.com>
Headset Audio Gateway does not have the Supported Features
in the SDP records according to the HSP specification.
---
tools/sdptool.c | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/tools/sdptool.c b/tools/sdptool.c
index d06b159..140a46a 100644
--- a/tools/sdptool.c
+++ b/tools/sdptool.c
@@ -1477,8 +1477,7 @@ static int add_headset_ag(sdp_session_t *session, svc_info_t *si)
sdp_list_t *aproto, *proto[2];
sdp_record_t record;
uint8_t u8 = si->channel ? si->channel : 7;
- uint16_t u16 = 0x17;
- sdp_data_t *channel, *features;
+ sdp_data_t *channel;
uint8_t netid = si->network ? si->network : 0x01; // ???? profile document
sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
int ret = 0;
@@ -1511,9 +1510,6 @@ static int add_headset_ag(sdp_session_t *session, svc_info_t *si)
proto[1] = sdp_list_append(proto[1], channel);
apseq = sdp_list_append(apseq, proto[1]);
- features = sdp_data_alloc(SDP_UINT16, &u16);
- sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
-
aproto = sdp_list_append(0, apseq);
sdp_set_access_protos(&record, aproto);
--
1.6.5.7
^ permalink raw reply related
* [PATCH] Bluetooth: Fix deadlock in the ERTM logic
From: Gustavo F. Padovan @ 2010-09-21 21:20 UTC (permalink / raw)
To: netdev; +Cc: linux-bluetooth, linux-kernel, padovan, marcel, davem, mathewm
In-Reply-To: <1285104013-9946-1-git-send-email-padovan@profusion.mobi>
The Enhanced Retransmission Mode(ERTM) is a realiable mode of operation
of the Bluetooth L2CAP layer. Think on it like a simplified version of
TCP.
The problem we were facing here was a deadlock. ERTM uses a backlog
queue to queue incomimg packets while the user is helding the lock. The
problem is that at some moment the user doesn't have memory anymore to
do alloc new skbs and sleep with the lock to wait for memory, that
stalls the ERTM connection once we can't read the acknowledgements
packets in the backlog queue to free memory and make the allocation of
outcoming skb successful.
I'm thinking on this patch more like a proof of concept than a real fix
to the deadlock in ERTM.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 44a8fb0..dd406b5 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1633,7 +1633,9 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in
while (len) {
count = min_t(unsigned int, conn->mtu, len);
+ release_sock(sk);
*frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
+ lock_sock(sk);
if (!*frag)
return -EFAULT;
if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
@@ -1724,8 +1726,10 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *m
hlen += 2;
count = min_t(unsigned int, (conn->mtu - hlen), len);
+ release_sock(sk);
skb = bt_skb_send_alloc(sk, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
+ lock_sock(sk);
if (!skb)
return ERR_PTR(-ENOMEM);
--
1.7.3
^ permalink raw reply related
* Deadlock in Bluetooth code in 2.6.36
From: Gustavo F. Padovan @ 2010-09-21 21:20 UTC (permalink / raw)
To: netdev; +Cc: linux-bluetooth, linux-kernel, padovan, marcel, davem, mathewm
Hi,
I would like to discuss here a problem we are having in the Bluetooth Layer.
There we have the Enhanced Retransmission Mode(ERTM) which is a reliable mode
of operation of the Bluetooth L2CAP layer. Think on it like a simplified
version of TCP.
The problem we were facing was a deadlock. ERTM uses a backlog queue to
queue incoming packets while the user held the lock. The problem is that
at some moment the user doesn't have memory anymore to alloc new skbs and
sleeps to wait for memory with the lock held, that stalls the ERTM connection
because we can't read the acknowledgements packets in the backlog queue to
free memory and then make the allocation of outcoming skb successful.
Looks like the solution to this issue is release the lock before go to sleep
waiting for memory and then lock the sock lock again when we wake up and have
memory. That's the solution TCP does through sk_stream_alloc_skb() and
sk_stream_wait_memory(). The sock lock is released and locked again inside
sk_wait_event() macro.
For bluetooth we do that in different way, we alloc memory through
sock_alloc_send_skb() which differently from sk_stream_alloc_skb() sleeps
with the lock held when waiting for memory.
The following patch is more like a proof of concept that sleeping
without the lock fixes the problem for L2CAP. Mat Martineau also found out
that some time ago.
My questions here is on how to fix this properly. Maybe
sock_alloc_send_skb() should not be used with SOCK_STREAM and reliable
protocols and I'm not aware of that? And should I use something like
sk_stream_alloc_skb() instead?
Any comments are welcome. With lucky we can fix that for 2.6.36 and
together with others fixes we have queued deliver a fully functional
L2CAP layer on 2.6.36.
Thanks,
---
Gustavo F. Padovan (1):
Bluetooth: Fix deadlock in the ERTM logic
net/bluetooth/l2cap.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
^ permalink raw reply
* Re: [PATCH] Simplify linker script
From: Lucas De Marchi @ 2010-09-21 20:41 UTC (permalink / raw)
To: Lucas De Marchi, linux-bluetooth, barbieri
In-Reply-To: <20100921201402.GA29547@jh-x301>
On Tue, Sep 21, 2010 at 5:14 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Thanks for the patch. It has been pushed to the upstream tree. Could you
> provide one for obexd too?
It seems that obexd does not have a linker script like connman, ofono
and bluez. Which functions should I export in that case?
Regards
Lucas De Marchi
^ permalink raw reply
* Re: Need complete docs on PAN and DUN with bluez 4.66
From: Mumia W @ 2010-09-21 20:21 UTC (permalink / raw)
To: list-linux-bluetooth
>From: Arun Kumar <arunkat@gmail.com>
>
>[...] Alternatively if the use case is to simply set up the device in
>nap role with bluez, for instance,
>pand -s -r NAP -M -n could well be used. It would set up the device
>in NAP role after auto registering same with SDP.
>
>[...]
Thanks. I'm hoping that "pand" isn't the only way for an
end-user to do that.
--
^ 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