* [PATCH BlueZ 4/6] media-api: Update documentation of MediaPlayer interface
From: Luiz Augusto von Dentz @ 2012-11-27 12:51 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354020685-17028-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
doc/media-api.txt | 21 ++-------------------
1 file changed, 2 insertions(+), 19 deletions(-)
diff --git a/doc/media-api.txt b/doc/media-api.txt
index b4f2fc6..a814b60 100644
--- a/doc/media-api.txt
+++ b/doc/media-api.txt
@@ -133,24 +133,12 @@ Object path freely definable (Target role)
[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX
(Controller role)
-Methods dict GetProperties()
-
- Returns all properties for the interface. See the
- properties section for available properties.
-
- dict GetTrack()
+Methods dict GetTrack()
Returns known metadata of the current track.
See TrackChanged for possible values.
- void SetProperty(string property, variant value)
-
- Changes the value of the specified property. Only
- properties that are listed as read-write can be changed.
-
- On success this will emit a PropertyChanged signal.
-
void Release()
This method gets called when the service daemon
@@ -159,12 +147,7 @@ Methods dict GetProperties()
player, because when this method gets called it has
already been unregistered.
-Signals PropertyChanged(string setting, variant value)
-
- This signal indicates a changed value of the given
- property.
-
- TrackChanged(dict metadata)
+Signals TrackChanged(dict metadata)
This signal indicates that current track has changed.
All available metadata for the new track shall be set
--
1.7.11.7
^ permalink raw reply related
* [PATCH BlueZ 5/6] test: Convert mpris-player to use DBus properties interface
From: Luiz Augusto von Dentz @ 2012-11-27 12:51 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354020685-17028-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
test/mpris-player.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/test/mpris-player.c b/test/mpris-player.c
index 13f5c85..7985cdd 100644
--- a/test/mpris-player.c
+++ b/test/mpris-player.c
@@ -114,17 +114,18 @@ static void dict_append_entry(DBusMessageIter *dict, const char *key, int type,
dbus_message_iter_close_container(dict, &entry);
}
-static dbus_bool_t emit_property_changed(DBusConnection *conn,
+static dbus_bool_t emit_properties_changed(DBusConnection *conn,
const char *path,
const char *interface,
const char *name,
int type, void *value)
{
DBusMessage *signal;
- DBusMessageIter iter;
+ DBusMessageIter iter, dict, entry, array;
dbus_bool_t result;
- signal = dbus_message_new_signal(path, interface, "PropertyChanged");
+ signal = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES,
+ "PropertiesChanged");
if (!signal) {
fprintf(stderr, "Unable to allocate new %s.PropertyChanged"
@@ -133,10 +134,23 @@ static dbus_bool_t emit_property_changed(DBusConnection *conn,
}
dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL,
+ &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &name);
+ append_variant(&entry, type, value);
+ dbus_message_iter_close_container(&dict, &entry);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
+ dbus_message_iter_close_container(&iter, &dict);
- append_variant(&iter, type, value);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &array);
+ dbus_message_iter_close_container(&iter, &array);
result = dbus_connection_send(conn, signal, NULL);
dbus_message_unref(signal);
@@ -171,7 +185,7 @@ static int parse_property(DBusConnection *conn, const char *path,
dict_append_entry(properties, "Status",
DBUS_TYPE_STRING, &value);
else
- emit_property_changed(sys, path,
+ emit_properties_changed(sys, path,
"org.bluez.MediaPlayer", "Status",
DBUS_TYPE_STRING, &value);
} else if (strcasecmp(key, "Position") == 0) {
@@ -188,7 +202,7 @@ static int parse_property(DBusConnection *conn, const char *path,
dict_append_entry(properties, "Position",
DBUS_TYPE_UINT32, &msec);
else
- emit_property_changed(sys, path,
+ emit_properties_changed(sys, path,
"org.bluez.MediaPlayer", "Position",
DBUS_TYPE_UINT32, &msec);
} else if (strcasecmp(key, "Shuffle") == 0) {
@@ -206,9 +220,9 @@ static int parse_property(DBusConnection *conn, const char *path,
dict_append_entry(properties, "Shuffle",
DBUS_TYPE_STRING, &str);
else
- emit_property_changed(sys, path,
+ emit_properties_changed(sys, path,
"org.bluez.MediaPlayer", "Shuffle",
- DBUS_TYPE_UINT32, &str);
+ DBUS_TYPE_STRING, &str);
}
return 0;
--
1.7.11.7
^ permalink raw reply related
* [PATCH BlueZ 6/6] test: Convert simple-player to use DBus properties interface
From: Luiz Augusto von Dentz @ 2012-11-27 12:51 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354020685-17028-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
test/simple-player | 40 ++++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/test/simple-player b/test/simple-player
index 9e72f3e..0037f3a 100755
--- a/test/simple-player
+++ b/test/simple-player
@@ -17,14 +17,16 @@ class Player(dbus.service.Object):
bus = dbus.SystemBus()
mp = dbus.Interface(bus.get_object("org.bluez", obj),
"org.bluez.MediaPlayer")
+ prop = dbus.Interface(bus.get_object("org.bluez", obj),
+ "org.freedesktop.DBus.Properties")
- self.properties = mp.GetProperties()
+ self.properties = prop.GetAll("org.bluez.MediaPlayer")
self.metadata = mp.GetTrack()
- bus.add_signal_receiver(self.property_changed,
+ bus.add_signal_receiver(self.properties_changed,
path = obj,
- dbus_interface = "org.bluez.MediaPlayer",
- signal_name = "PropertyChanged")
+ dbus_interface = "org.freedesktop.DBus.Properties",
+ signal_name = "PropertiesChanged")
bus.add_signal_receiver(self.track_changed,
path = obj,
@@ -59,18 +61,20 @@ class Player(dbus.service.Object):
print("Release")
mainloop.quit()
- @dbus.service.method("org.bluez.MediaPlayer",
- in_signature="sv", out_signature="")
- def SetProperty(self, key, value):
- print("SetProperty (%s, %s)" % (key, value), file=sys.stderr)
+ @dbus.service.method("org.freedesktop.DBus.Properties",
+ in_signature="ssv", out_signature="")
+ def Set(self, interface, key, value):
+ print("Set (%s, %s)" % (key, value), file=sys.stderr)
return
- @dbus.service.signal("org.bluez.MediaPlayer", signature="sv")
- def PropertyChanged(self, setting, value):
- """PropertyChanged(setting, value)
+ @dbus.service.signal("org.freedesktop.DBus.Properties",
+ signature="sa{sv}as")
+ def PropertiesChanged(self, interface, properties,
+ invalidated = dbus.Array()):
+ """PropertiesChanged(interface, properties, invalidated)
- Send a PropertyChanged signal. 'setting' and 'value' are
- string parameters as specified in doc/media-api.txt.
+ Send a PropertiesChanged signal. 'properties' is a dictionary
+ containing string parameters as specified in doc/media-api.txt.
"""
pass
@@ -86,10 +90,10 @@ class Player(dbus.service.Object):
def help(self, func):
help(self.__class__.__dict__[func])
- def property_changed(self, setting, value):
- print("property_changed(%s, %s)" % (setting, value))
+ def properties_changed(self, interface, properties, invalidated):
+ print("properties_changed(%s, %s)" % (properties, invalidated))
- self.PropertyChanged(setting, value)
+ self.PropertiesChanged(interface, properties, invalidated)
def track_changed(self, metadata):
print("track_changed(%s)" % (metadata))
@@ -98,8 +102,8 @@ class Player(dbus.service.Object):
class InputHandler:
commands = { 'TrackChanged': '(metadata)',
- 'PropertyChanged': '(key, value)',
- 'help': '(cmd)' }
+ 'PropertiesChanged': '(interface, properties)',
+ 'help': '(cmd)' }
def __init__(self, player):
self.player = player
print('\n\nAvailable commands:')
--
1.7.11.7
^ permalink raw reply related
* Re: eSCO latency configuration
From: Arnaud Mouiche @ 2012-11-28 9:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20121127111241.GA24125@x220>
Hi Johan,
On 11/27/2012 12:12 PM, Johan Hedberg wrote:
> Hi Arnaud,
>
> On Mon, Sep 05, 2011, Arnaud Mouiche wrote:
>> What could be a way to add the feature without breaking any API
>> 1) use the MTU of the socket or hdev ?
>> 2) add hdev entry for sco latency (which can be configured with
>> hciconfig like voice settings)
>> 3) something else ...
>> or
>> 4) no one cares about latency...
>>
>> PS: the same way, the retransmit effort is not configurable today.
> I'm assuming this is for HFP or HSP? At least I'm not aware of other
> significant profiles using (e)SCO. Since the HFP specification defines a
> set of recommended parameter combinations I don't think we necessarily
> need any user-space facing interface for this (with the exception of the
> mSBC/CVSD codec selection which is needed for HFP 1.6).
>
> Instead, the kernel could simply start with the S3 settings and fall
> back to S2 and finally S1 if failures are encountered during the
> connection setup. For mSBC the starting point would be T2 with a
> fallback to T1 in case of failure. Do you agree that this would be an
> acceptable solution?
> Johan
yes, I'm concerned by the HFP with mSBC/CVSD case, with multiple
concurrent HFP sessions. So there is a need to avoid race conditions of
the configuration (ie no configuration at the adapter level).
I found the BT_DEFER_SETUP feature from Frédéric to be a nice solution,
since it gives more flexibility to the userland for this kind of
configuration.
(up to now for my tests, I'm doing ugly things like forcing the kernel
to not respond the eSCO setup, and do the response from userland.... )
I'm pretty busy at this time, but my goal may be to propose a way to
configure the eSCO response on top of the BT_DEFER_SETUP.
With BT_DEFER_SETUP, accepting is done on the first 'recvmsg'. May be we
can configure the socket (setsockopt, ioctl...) just before this first
'recvmsg' to tell the kernel the real purpose of the socket.
For example, userland can provide the expected set of configuration
(latency, bandwith, retransmissions, packets, voice settings). But I
don't have a clear of how handling fallback indeed.
I'll be also interested to be able to reject the connection_request for
"Limited Resources" reasons. The scenario using this feature is when
multiple active calls are already managed by the device, and
routing a new voice stream is simply not possible (for the hardware
and/or for the user).
(note: one limitation of the HFP specs is that the routing is not really
agreed before opening the link. only the codec selection is negociated,
but specifications are clear that we can't reject the CVSD codec, so a
real rejection of the route is not possible)
just a [raw] idea I just have:
Module --------------- Kernel --------------------------------- Userland
setsockopt( DEFER )
listen()
<-- socket in listen mode with DEFER option ---
-- Connection_request -->
--- socket accept available ----------------->
A) [ accept case ]
.............................................................
accept()
send() or
ioctl() or
setsockopt() or
better
<-------- provide the set of configuration
items
recv()
<-- Accept_synchronous_connection
-- Synchronous Connection Complete (OK or rjected) -->
-------------------------------> in case of failure
need to know the reason
for selecting a fallback
on next connection_request
attempt.
B) [ userland reject case ]
.............................................................
accept()
close()
<-- Reject_synchronous_connection (Limited Resources)
Note: Michael Knudsen seems to want to push also things concerning CSA2
for codec configuration. I'm not really aware of what it imply and why
it should be managed by the kernel. So I don't know how to put those
things in the picture.
Arnaud
^ permalink raw reply
* Re: [PATCH BlueZ] gdbus: Fix crash error when calling g_dbus_remove_all_watches
From: Johan Hedberg @ 2012-11-28 12:23 UTC (permalink / raw)
To: Tomasz Bursztyka; +Cc: linux-bluetooth
In-Reply-To: <1345802959-11774-1-git-send-email-tomasz.bursztyka@linux.intel.com>
Hi Thomasz,
On Fri, Aug 24, 2012, Tomasz Bursztyka wrote:
> ---
> Hi,
>
> While using gdbus on some other code, I found out that bug around g_dbus_remove_all_watches() usage.
>
> Tomasz
>
> gdbus/watch.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/gdbus/watch.c b/gdbus/watch.c
> index d749176..968a38a 100644
> --- a/gdbus/watch.c
> +++ b/gdbus/watch.c
> @@ -298,6 +298,9 @@ static void filter_data_call_and_free(struct filter_data *data)
> g_free(cb);
> }
>
> + g_slist_free(data->callbacks);
> + data->callbacks = NULL;
> +
> filter_data_free(data);
> }
It seems this patch never got applied. Is it so that no-one else has
seen the issue. Could someone (through basic static analysis) confirm if
the patch is correct? It'd be nice if we could also have a back trace of
the crash in the commit message.
Johan
^ permalink raw reply
* Re: [PATCH bluez] wiimote: add Wii-Remote-Plus ID and name detection
From: Johan Hedberg @ 2012-11-28 12:50 UTC (permalink / raw)
To: David Herrmann; +Cc: linux-bluetooth, Peter Olson
In-Reply-To: <1350894680-3947-1-git-send-email-dh.herrmann@googlemail.com>
Hi David,
On Mon, Oct 22, 2012, David Herrmann wrote:
> The Nintendo Wii Remote Plus uses a new product ID and name. To detect
> them properly, we need to add them to the wiimote-module.
>
> To avoid an overlong "if" statement, this converts the match-function to
> walk over an array and check all VID/PID pairs and device-names. This
> makes adding new devices much easier.
> ---
> Hi Johan
>
> I am actually not sure why Nintendo changed the VID/PID for the new revisions of
> the WiimotePlus. I have a WiimotePlus which still uses the old numbers and works
> here quite well. However, I have now got multiple requests from people with the
> new device name and IDs. Unfortunately, I cannot test these so I'd like to have
> a "Tested-by" by Peter (CC'ed) before this is applied.
>
> Thanks
> David
>
> plugins/wiimote.c | 35 ++++++++++++++++++++++++++++-------
> 1 file changed, 28 insertions(+), 7 deletions(-)
Well, the Tested-by never came, but since the patch looks ok to me I
went ahead and applied it anyway (with a minor fix to use G_N_ELEMENTS()
instead of your custom array length calculation).
Johan
^ permalink raw reply
* Re: [PATCH bluez] wiimote: add Wii-Remote-Plus ID and name detection
From: David Herrmann @ 2012-11-28 13:00 UTC (permalink / raw)
To: David Herrmann, linux-bluetooth@vger.kernel.org, Peter Olson
In-Reply-To: <20121128125041.GA995@x220.ger.corp.intel.com>
Hi Johan
On Wed, Nov 28, 2012 at 1:50 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi David,
>
> On Mon, Oct 22, 2012, David Herrmann wrote:
>> The Nintendo Wii Remote Plus uses a new product ID and name. To detect
>> them properly, we need to add them to the wiimote-module.
>>
>> To avoid an overlong "if" statement, this converts the match-function to
>> walk over an array and check all VID/PID pairs and device-names. This
>> makes adding new devices much easier.
>> ---
>> Hi Johan
>>
>> I am actually not sure why Nintendo changed the VID/PID for the new revisions of
>> the WiimotePlus. I have a WiimotePlus which still uses the old numbers and works
>> here quite well. However, I have now got multiple requests from people with the
>> new device name and IDs. Unfortunately, I cannot test these so I'd like to have
>> a "Tested-by" by Peter (CC'ed) before this is applied.
>>
>> Thanks
>> David
>>
>> plugins/wiimote.c | 35 ++++++++++++++++++++++++++++-------
>> 1 file changed, 28 insertions(+), 7 deletions(-)
>
> Well, the Tested-by never came, but since the patch looks ok to me I
> went ahead and applied it anyway (with a minor fix to use G_N_ELEMENTS()
> instead of your custom array length calculation).
Sorry for the long delay. But I don't have the device so it sometimes
takes a bit longer. Anyway, it doesn't do any harm if we apply it so
yes, thanks for not forgetting about it.
Cheers
David
^ permalink raw reply
* [PATCH v2 1/8] doc: Update settings-storage.txt
From: Frédéric Danis @ 2012-11-28 13:39 UTC (permalink / raw)
To: linux-bluetooth
Class should also be saved in device file of cache directory.
Link key and Long term key for a device should be saved in
keys file under storage device directory
---
doc/settings-storage.txt | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt
index 3fdcb03..db271a6 100644
--- a/doc/settings-storage.txt
+++ b/doc/settings-storage.txt
@@ -30,6 +30,7 @@ contains:
- one directory per remote device, named by remote device address, which
contains:
- an info file
+ - a keys file
- an attributes file containing attributes of remote LE services
So the directory structure is:
@@ -42,9 +43,11 @@ So the directory structure is:
...
./<remote device address>/
./info
+ ./keys
./attributes
./<remote device address>/
./info
+ ./keys
./attributes
...
@@ -124,11 +127,13 @@ This general group contains:
ShortName String Remote device shortened name
+ Class String Device class in hexadecimal, i.e. 0x000000
+
Info file format
================
-Info file may includes multiple groups (General, Device ID, Link key and
-Long term key) related to a remote device.
+Info file may includes multiple groups (General and Device ID) related to
+a remote device.
[General] group contains:
@@ -165,6 +170,12 @@ Long term key) related to a remote device.
Version Integer Device version
+Keys file format
+================
+
+Keys file may includes multiple groups (Link key and Long term key) related
+to a remote device.
+
[LinkKey] group contains:
Key String Key in hexadecimal format
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 2/8] adapter: Convert class to cached file
From: Frédéric Danis @ 2012-11-28 13:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354109967-6238-1-git-send-email-frederic.danis@linux.intel.com>
Instead of converting remote device's class directly in
<device storage dir>/info we should saved it in storage
cache directory.
Use 'converted Yes' instead of 'converted yes' to be able
to do conversion even if classes file was already converted
to device directory.
Class should be also saved in cache directory on device
discovery.
When a device is created it should try to retrieve class
from device info file.
If that fails fall back to the cache and save it to device
info file.
---
src/adapter.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------
src/device.c | 18 +++++++++++++-----
2 files changed, 61 insertions(+), 11 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 163360f..01cf22b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -253,8 +253,8 @@ static void store_adapter_info(struct btd_adapter *adapter)
g_key_file_free(key_file);
}
-static void store_cached_name(const bdaddr_t *local, const bdaddr_t *peer,
- char *name)
+static void store_cached_string(const bdaddr_t *local, const bdaddr_t *peer,
+ const char *key, const char *string)
{
char filename[PATH_MAX + 1];
char s_addr[18], d_addr[18];
@@ -270,7 +270,7 @@ static void store_cached_name(const bdaddr_t *local, const bdaddr_t *peer,
key_file = g_key_file_new();
g_key_file_load_from_file(key_file, filename, 0, NULL);
- g_key_file_set_string(key_file, "General", "Name", name);
+ g_key_file_set_string(key_file, "General", key, string);
data = g_key_file_to_data(key_file, &length, NULL);
g_file_set_contents(filename, data, length, NULL);
@@ -279,6 +279,18 @@ static void store_cached_name(const bdaddr_t *local, const bdaddr_t *peer,
g_key_file_free(key_file);
}
+static void store_cached_name(const bdaddr_t *local, const bdaddr_t *peer,
+ char *name)
+{
+ store_cached_string(local, peer, "Name", name);
+}
+
+static void store_cached_class(const bdaddr_t *local, const bdaddr_t *peer,
+ char *class)
+{
+ store_cached_string(local, peer, "Class", class);
+}
+
static struct session_req *session_ref(struct session_req *req)
{
req->refcount++;
@@ -2538,9 +2550,21 @@ static void convert_trusts_entry(GKeyFile *key_file, void *value)
g_key_file_set_boolean(key_file, "General", "Trusted", TRUE);
}
-static void convert_classes_entry(GKeyFile *key_file, void *value)
+static void convert_classes_entry(char *key, char *value, void *user_data)
{
- g_key_file_set_string(key_file, "General", "Class", value);
+ char *address = user_data;
+ char *str = key;
+ bdaddr_t local, peer;
+
+ if (strchr(key, '#'))
+ str[17] = '\0';
+
+ if (bachk(str) != 0)
+ return;
+
+ str2ba(address, &local);
+ str2ba(str, &peer);
+ store_cached_class(&local, &peer, value);
}
static void convert_blocked_entry(GKeyFile *key_file, void *value)
@@ -2668,7 +2692,18 @@ static void convert_device_storage(struct btd_adapter *adapter)
convert_file("trusts", address, convert_trusts_entry);
/* Convert classes */
- convert_file("classes", address, convert_classes_entry);
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/classes", address);
+ filename[PATH_MAX] = '\0';
+
+ str = textfile_get(filename, "converted");
+ if (str && strcmp(str, "Yes") == 0) {
+ DBG("Legacy classes file already converted");
+ } else {
+ textfile_foreach(filename, convert_classes_entry, address);
+ textfile_put(filename, "converted", "Yes");
+ }
+ free(str);
+
/* Convert blocked */
convert_file("blocked", address, convert_blocked_entry);
@@ -3120,6 +3155,13 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
if (eir_data.name != NULL && eir_data.name_complete)
store_cached_name(&adapter->bdaddr, bdaddr, eir_data.name);
+ if (eir_data.class != 0) {
+ char class[9];
+
+ sprintf(class, "0x%06X", eir_data.class);
+ store_cached_class(&adapter->bdaddr, bdaddr, class);
+ }
+
/* Avoid creating LE device if it's not discoverable */
if (bdaddr_type != BDADDR_BREDR &&
!(eir_data.flags & (EIR_LIM_DISC | EIR_GEN_DISC))) {
diff --git a/src/device.c b/src/device.c
index a99ca34..f9927da 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1753,8 +1753,8 @@ static void device_set_version(struct btd_device *device, uint16_t value)
DEVICE_INTERFACE, "Version");
}
-static char *load_cached_name(struct btd_device *device, const char *local,
- const gchar *peer)
+static char *load_cached_string(struct btd_device *device, const char *local,
+ const gchar *peer, const char *key)
{
char filename[PATH_MAX + 1];
GKeyFile *key_file;
@@ -1769,7 +1769,7 @@ static char *load_cached_name(struct btd_device *device, const char *local,
if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
goto failed;
- str = g_key_file_get_string(key_file, "General", "Name", NULL);
+ str = g_key_file_get_string(key_file, "General", key, NULL);
if (str) {
len = strlen(str);
if (len > HCI_MAX_NAME_LENGTH)
@@ -1803,7 +1803,7 @@ static void load_info(struct btd_device *device, const gchar *local,
*/
str = g_key_file_get_string(key_file, "General", "Name", NULL);
if (str == NULL) {
- str = load_cached_name(device, local, peer);
+ str = load_cached_string(device, local, peer, "Name");
if (str)
store_needed = TRUE;
}
@@ -1817,8 +1817,16 @@ static void load_info(struct btd_device *device, const gchar *local,
device->alias = g_key_file_get_string(key_file, "General", "Alias",
NULL);
- /* Load class */
+ /* Load device class from storage info file, if that fails fall back to
+ * the cache.
+ */
str = g_key_file_get_string(key_file, "General", "Class", NULL);
+ if (str == NULL) {
+ str = load_cached_string(device, local, peer, "Class");
+ if (str)
+ store_needed = TRUE;
+ }
+
if (str) {
uint32_t class;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 3/8] adapter: Load devices from new storage architecture
From: Frédéric Danis @ 2012-11-28 13:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354109967-6238-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 01cf22b..1d6aa08 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -34,6 +34,7 @@
#include <stdbool.h>
#include <sys/ioctl.h>
#include <sys/file.h>
+#include <dirent.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/uuid.h>
@@ -2008,6 +2009,8 @@ static void load_devices(struct btd_adapter *adapter)
char srcaddr[18];
struct adapter_keys keys = { adapter, NULL };
int err;
+ DIR *dir;
+ struct dirent *entry;
ba2str(&adapter->bdaddr, srcaddr);
@@ -2043,6 +2046,35 @@ static void load_devices(struct btd_adapter *adapter)
create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "blocked");
textfile_foreach(filename, create_stored_device_from_blocked, adapter);
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s", srcaddr);
+ filename[PATH_MAX] = '\0';
+
+ dir = opendir(filename);
+ if (!dir) {
+ error("Unable to open adapter storage directory: %s", filename);
+ return;
+ }
+
+ while ((entry = readdir(dir)) != NULL) {
+ struct btd_device *device;
+
+ if (entry->d_type != DT_DIR || bachk(entry->d_name) < 0)
+ continue;
+
+ if (g_slist_find_custom(adapter->devices, entry->d_name,
+ (GCompareFunc) device_address_cmp))
+ continue;
+
+ device = device_create(adapter, entry->d_name, BDADDR_BREDR);
+ if (!device)
+ continue;
+
+ device_set_temporary(device, FALSE);
+ adapter->devices = g_slist_append(adapter->devices, device);
+ }
+
+ closedir(dir);
}
int btd_adapter_block_address(struct btd_adapter *adapter,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 4/8] adapter: Add destination file to convert_file()
From: Frédéric Danis @ 2012-11-28 13:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354109967-6238-1-git-send-email-frederic.danis@linux.intel.com>
In order to convert keys and longtermkeys, we will need to use
different target file names.
---
src/adapter.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 1d6aa08..f9382fd 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2570,6 +2570,7 @@ static void convert_names_entry(char *key, char *value, void *user_data)
struct device_converter {
char *address;
void (*cb)(GKeyFile *key_file, void *value);
+ char *filename;
};
static void convert_aliases_entry(GKeyFile *key_file, void *value)
@@ -2657,8 +2658,8 @@ static void convert_entry(char *key, char *value, void *user_data)
if (bachk(key) != 0)
return;
- snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
- converter->address, key);
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/%s",
+ converter->address, key, converter->filename);
filename[PATH_MAX] = '\0';
create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
@@ -2673,7 +2674,7 @@ static void convert_entry(char *key, char *value, void *user_data)
g_key_file_free(key_file);
}
-static void convert_file(char *file, char *address,
+static void convert_file(char *file, char *address, char *dest_file,
void (*cb)(GKeyFile *key_file, void *value))
{
char filename[PATH_MAX + 1];
@@ -2689,6 +2690,7 @@ static void convert_file(char *file, char *address,
} else {
converter.address = address;
converter.cb = cb;
+ converter.filename = dest_file;
textfile_foreach(filename, convert_entry, &converter);
textfile_put(filename, "converted", "yes");
@@ -2718,10 +2720,10 @@ static void convert_device_storage(struct btd_adapter *adapter)
free(str);
/* Convert aliases */
- convert_file("aliases", address, convert_aliases_entry);
+ convert_file("aliases", address, "info", convert_aliases_entry);
/* Convert trusts */
- convert_file("trusts", address, convert_trusts_entry);
+ convert_file("trusts", address, "info", convert_trusts_entry);
/* Convert classes */
snprintf(filename, PATH_MAX, STORAGEDIR "/%s/classes", address);
@@ -2738,10 +2740,10 @@ static void convert_device_storage(struct btd_adapter *adapter)
/* Convert blocked */
- convert_file("blocked", address, convert_blocked_entry);
+ convert_file("blocked", address, "info", convert_blocked_entry);
/* Convert device ids */
- convert_file("did", address, convert_did_entry);
+ convert_file("did", address, "info", convert_did_entry);
}
static void convert_config(struct btd_adapter *adapter, const char *filename,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 5/8] adapter: Convert storage linkkeys file
From: Frédéric Danis @ 2012-11-28 13:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354109967-6238-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index f9382fd..5bad0f9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2644,6 +2644,34 @@ static void convert_did_entry(GKeyFile *key_file, void *value)
g_key_file_set_integer(key_file, "DeviceID", "Version", val);
}
+static void convert_linkkey_entry(GKeyFile *key_file, void *value)
+{
+ char *type_str, *length_str, *str;
+ gint val;
+
+ type_str = strchr(value, ' ');
+ if (!type_str)
+ return;
+
+ *(type_str++) = 0;
+
+ length_str = strchr(type_str, ' ');
+ if (!length_str)
+ return;
+
+ *(length_str++) = 0;
+
+ str = g_strconcat("0x", value, NULL);
+ g_key_file_set_string(key_file, "LinkKey", "Key", str);
+ g_free(str);
+
+ val = strtol(type_str, NULL, 16);
+ g_key_file_set_integer(key_file, "LinkKey", "Type", val);
+
+ val = strtol(length_str, NULL, 16);
+ g_key_file_set_integer(key_file, "LinkKey", "PINLength", val);
+}
+
static void convert_entry(char *key, char *value, void *user_data)
{
struct device_converter *converter = user_data;
@@ -2744,6 +2772,9 @@ static void convert_device_storage(struct btd_adapter *adapter)
/* Convert device ids */
convert_file("did", address, "info", convert_did_entry);
+
+ /* Convert linkkeys */
+ convert_file("linkkeys", address, "keys", convert_linkkey_entry);
}
static void convert_config(struct btd_adapter *adapter, const char *filename,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 6/8] device: Remove keys file in device_remove_stored()
From: Frédéric Danis @ 2012-11-28 13:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354109967-6238-1-git-send-email-frederic.danis@linux.intel.com>
---
src/device.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/device.c b/src/device.c
index f9927da..9f05c1b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2022,6 +2022,11 @@ static void device_remove_stored(struct btd_device *device)
filename[PATH_MAX] = '\0';
remove(filename);
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/keys", adapter_addr,
+ device_addr);
+ filename[PATH_MAX] = '\0';
+ remove(filename);
+
snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr,
device_addr);
filename[PATH_MAX] = '\0';
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 7/8] adapter: Upload link keys from new storage
From: Frédéric Danis @ 2012-11-28 13:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354109967-6238-1-git-send-email-frederic.danis@linux.intel.com>
Remove read_link_key() from device_create, this moves to load_devices.
---
src/adapter.c | 109 +++++++++++++++++++++++++--------------------------------
src/device.c | 6 ----
2 files changed, 48 insertions(+), 67 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 5bad0f9..a87eeda 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1777,31 +1777,35 @@ static int str2buf(const char *str, uint8_t *buf, size_t blen)
return 0;
}
-static struct link_key_info *get_key_info(const char *addr, const char *value)
+static struct link_key_info *get_key_info(const char *local,
+ const char *peer)
{
- struct link_key_info *info;
- char tmp[3];
- long int l;
+ struct link_key_info *info = NULL;
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+ char *str;
- if (strlen(value) < 36) {
- error("Unexpectedly short (%zu) link key line", strlen(value));
- return NULL;
- }
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/keys", local, peer);
- info = g_new0(struct link_key_info, 1);
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
- str2ba(addr, &info->bdaddr);
+ str = g_key_file_get_string(key_file, "LinkKey", "Key", NULL);
+ if (!str || strlen(str) != 34)
+ goto failed;
- str2buf(value, info->key, sizeof(info->key));
+ info = g_new0(struct link_key_info, 1);
+
+ str2ba(peer, &info->bdaddr);
+ str2buf(&str[2], info->key, sizeof(info->key));
- memcpy(tmp, value + 33, 2);
- info->type = (uint8_t) strtol(tmp, NULL, 10);
+ info->type = g_key_file_get_integer(key_file, "LinkKey", "Type", NULL);
+ info->pin_len = g_key_file_get_integer(key_file, "LinkKey", "PINLength",
+ NULL);
- memcpy(tmp, value + 35, 2);
- l = strtol(tmp, NULL, 10);
- if (l < 0)
- l = 0;
- info->pin_len = l;
+failed:
+ g_free(str);
+ g_key_file_free(key_file);
return info;
}
@@ -1842,34 +1846,6 @@ static struct smp_ltk_info *get_ltk_info(const char *addr, uint8_t bdaddr_type,
return ltk;
}
-static void create_stored_device_from_linkkeys(char *key, char *value,
- void *user_data)
-{
- char address[18];
- uint8_t bdaddr_type;
- struct adapter_keys *keys = user_data;
- struct btd_adapter *adapter = keys->adapter;
- struct btd_device *device;
- struct link_key_info *info;
-
- if (sscanf(key, "%17s#%hhu", address, &bdaddr_type) < 2)
- bdaddr_type = BDADDR_BREDR;
-
- info = get_key_info(address, value);
- if (info)
- keys->keys = g_slist_append(keys->keys, info);
-
- if (g_slist_find_custom(adapter->devices, address,
- (GCompareFunc) device_address_cmp))
- return;
-
- device = device_create(adapter, address, bdaddr_type);
- if (device) {
- device_set_temporary(device, FALSE);
- adapter->devices = g_slist_append(adapter->devices, device);
- }
-}
-
static void create_stored_device_from_ltks(char *key, char *value,
void *user_data)
{
@@ -2022,18 +1998,6 @@ static void load_devices(struct btd_adapter *adapter)
textfile_foreach(filename, create_stored_device_from_primaries,
adapter);
- create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "linkkeys");
- textfile_foreach(filename, create_stored_device_from_linkkeys, &keys);
-
- err = mgmt_load_link_keys(adapter->dev_id, keys.keys,
- main_opts.debug_keys);
- if (err < 0)
- error("Unable to load link keys: %s (%d)",
- strerror(-err), -err);
-
- g_slist_free_full(keys.keys, g_free);
- keys.keys = NULL;
-
create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "longtermkeys");
textfile_foreach(filename, create_stored_device_from_ltks, &keys);
@@ -2058,13 +2022,22 @@ static void load_devices(struct btd_adapter *adapter)
while ((entry = readdir(dir)) != NULL) {
struct btd_device *device;
+ struct link_key_info *key_info;
+ GSList *l;
if (entry->d_type != DT_DIR || bachk(entry->d_name) < 0)
continue;
- if (g_slist_find_custom(adapter->devices, entry->d_name,
- (GCompareFunc) device_address_cmp))
- continue;
+ key_info = get_key_info(srcaddr, entry->d_name);
+ if (key_info)
+ keys.keys = g_slist_append(keys.keys, key_info);
+
+ l = g_slist_find_custom(adapter->devices, entry->d_name,
+ (GCompareFunc) device_address_cmp);
+ if (l) {
+ device = l->data;
+ goto device_exist;
+ }
device = device_create(adapter, entry->d_name, BDADDR_BREDR);
if (!device)
@@ -2072,9 +2045,23 @@ static void load_devices(struct btd_adapter *adapter)
device_set_temporary(device, FALSE);
adapter->devices = g_slist_append(adapter->devices, device);
+
+device_exist:
+ if (key_info) {
+ device_set_paired(device, TRUE);
+ device_set_bonded(device, TRUE);
+ }
}
closedir(dir);
+
+ err = mgmt_load_link_keys(adapter->dev_id, keys.keys,
+ main_opts.debug_keys);
+ if (err < 0)
+ error("Unable to load link keys: %s (%d)",
+ strerror(-err), -err);
+
+ g_slist_free_full(keys.keys, g_free);
}
int btd_adapter_block_address(struct btd_adapter *adapter,
diff --git a/src/device.c b/src/device.c
index 9f05c1b..53d1220 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1905,12 +1905,6 @@ struct btd_device *device_create(struct btd_adapter *adapter,
load_info(device, srcaddr, address);
- if (read_link_key(src, &device->bdaddr, device->bdaddr_type, NULL,
- NULL) == 0) {
- device_set_paired(device, TRUE);
- device_set_bonded(device, TRUE);
- }
-
if (device_is_le(device) && has_longtermkeys(src, &device->bdaddr,
device->bdaddr_type)) {
device_set_paired(device, TRUE);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 8/8] event: Store link key infos in new keys file
From: Frédéric Danis @ 2012-11-28 13:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354109967-6238-1-git-send-email-frederic.danis@linux.intel.com>
---
src/event.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 47 insertions(+), 12 deletions(-)
diff --git a/src/event.c b/src/event.c
index 7fc8f02..59da740 100644
--- a/src/event.c
+++ b/src/event.c
@@ -354,33 +354,68 @@ static int store_longtermkey(bdaddr_t *local, bdaddr_t *peer,
return err;
}
+static void store_link_key(struct btd_adapter *adapter,
+ struct btd_device *device, uint8_t *key,
+ uint8_t type, uint8_t pin_length)
+{
+ char adapter_addr[18];
+ char device_addr[18];
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+ char key_str[35];
+ char *str;
+ int i;
+ gsize length = 0;
+
+ ba2str(adapter_get_address(adapter), adapter_addr);
+ ba2str(device_get_address(device), device_addr);
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/keys", adapter_addr,
+ device_addr);
+ filename[PATH_MAX] = '\0';
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+ key_str[0] = '0';
+ key_str[1] = 'x';
+ for (i = 0; i < 16; i++)
+ sprintf(key_str + 2 + (i * 2), "%2.2X", key[i]);
+
+ g_key_file_set_string(key_file, "LinkKey", "Key", key_str);
+
+ g_key_file_set_integer(key_file, "LinkKey", "Type", type);
+ g_key_file_set_integer(key_file, "LinkKey", "PINLength", pin_length);
+
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ str = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(filename, str, length, NULL);
+ g_free(str);
+
+ g_key_file_free(key_file);
+}
+
int btd_event_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
uint8_t *key, uint8_t key_type,
uint8_t pin_length)
{
struct btd_adapter *adapter;
struct btd_device *device;
- uint8_t peer_type;
- int ret;
if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
return -ENODEV;
DBG("storing link key of type 0x%02x", key_type);
- peer_type = device_get_addr_type(device);
+ store_link_key(adapter, device, key, key_type, pin_length);
- ret = write_link_key(local, peer, peer_type, key, key_type,
- pin_length);
+ device_set_bonded(device, TRUE);
- if (ret == 0) {
- device_set_bonded(device, TRUE);
-
- if (device_is_temporary(device))
- device_set_temporary(device, FALSE);
- }
+ if (device_is_temporary(device))
+ device_set_temporary(device, FALSE);
- return ret;
+ return 0;
}
int btd_event_ltk_notify(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] Bluetooth: Fix possible deadlock in SCO code
From: Chan-yeol Park @ 2012-11-28 14:35 UTC (permalink / raw)
To: Gustavo Padovan; +Cc: linux-bluetooth
In-Reply-To: <1339738863-6407-1-git-send-email-gustavo@padovan.org>
Hi Gustavo
If we use the below patch, we face crash or circular locking dependency
detected.
*It's very easily reproduced(about 100%)
I guess once sco_sock_shutdown() is called,"sk" would be destructed.
but due to response from remote side, sco_disconn_cfm(),sco_conn_del()
would be called in order.
and finally in sco_conn_del() crash or circular locking dependency is
happened.
because it access "sk" that is already destructed.
I think in sco_chan_del(), based on conn info, the relation between sk
and conn should be cleaned
like the original code before you commit.
[ 104.889622] Bluetooth: [sco_sock_shutdown] sock e8856000, sk eb695000
[ 104.894666] Bluetooth: [sco_sock_clear_timer] sock eb695000 state 1
[ 104.900869] Bluetooth: [__sco_sock_close] sk eb695000 state 1 socket
e8856000
[ 104.907976] Bluetooth: [sco_sock_set_timer] sock eb695000 state 8
timeout 400
[ 104.915106] Bluetooth: [sco_sock_release] sock e8856000, sk eb695000
[ 104.921439] Bluetooth: [sco_sock_clear_timer] sock eb695000 state 8
[ 104.927875] Bluetooth: [__sco_sock_close] sk eb695000 state 8 socket
e8856000
[ 104.938762] Bluetooth: [sco_chan_del] sk eb695000, conn ed38da60, err 104
[ 104.956861] Bluetooth: [sco_sock_kill] sk eb695000 state 9
[ 104.962321] Bluetooth: [sco_sock_destruct] sk eb695000
[ 105.071125] Bluetooth: [sco_disconn_cfm] hcon ed376000 reason 22
[ 105.075875] Bluetooth: [sco_conn_del] hcon ed376000 conn ed38da60,
err 103
[ 105.082848] Bluetooth: [sco_conn_del] before bh_lock_sock () sk eb695000
Could you give me your opinion?
regards
chanyeol
On 06/15/2012 02:41 PM, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>
> sco_chan_del() only has conn != NULL when called from sco_conn_del() so
> just move the code from it that deal with conn to sco_conn_del().
>
> [ 120.765529]
> [ 120.765529] ======================================================
> [ 120.766529] [ INFO: possible circular locking dependency detected ]
> [ 120.766529] 3.5.0-rc1-10292-g3701f94-dirty #70 Tainted: G W
> [ 120.766529] -------------------------------------------------------
> [ 120.766529] kworker/u:3/1497 is trying to acquire lock:
> [ 120.766529] (&(&conn->lock)->rlock#2){+.+...}, at:
> [<ffffffffa00b7ecc>] sco_chan_del+0x4c/0x170 [bluetooth]
> [ 120.766529]
> [ 120.766529] but task is already holding lock:
> [ 120.766529] (slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}, at:
> [<ffffffffa00b8401>] sco_conn_del+0x61/0xe0 [bluetooth]
> [ 120.766529]
> [ 120.766529] which lock already depends on the new lock.
> [ 120.766529]
> [ 120.766529]
> [ 120.766529] the existing dependency chain (in reverse order) is:
> [ 120.766529]
> [ 120.766529] -> #1 (slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}:
> [ 120.766529] [<ffffffff8107980e>] lock_acquire+0x8e/0xb0
> [ 120.766529] [<ffffffff813c19e0>] _raw_spin_lock+0x40/0x80
> [ 120.766529] [<ffffffffa00b85e9>] sco_connect_cfm+0x79/0x300
> [bluetooth]
> [ 120.766529] [<ffffffffa0094b13>]
> hci_sync_conn_complete_evt.isra.90+0x343/0x400 [bluetooth]
> [ 120.766529] [<ffffffffa009d447>] hci_event_packet+0x317/0xfb0
> [bluetooth]
> [ 120.766529] [<ffffffffa008aa68>] hci_rx_work+0x2c8/0x890
> [bluetooth]
> [ 120.766529] [<ffffffff81047db7>] process_one_work+0x197/0x460
> [ 120.766529] [<ffffffff810489d6>] worker_thread+0x126/0x2d0
> [ 120.766529] [<ffffffff8104ee4d>] kthread+0x9d/0xb0
> [ 120.766529] [<ffffffff813c4294>] kernel_thread_helper+0x4/0x10
> [ 120.766529]
> [ 120.766529] -> #0 (&(&conn->lock)->rlock#2){+.+...}:
> [ 120.766529] [<ffffffff81078a8a>] __lock_acquire+0x154a/0x1d30
> [ 120.766529] [<ffffffff8107980e>] lock_acquire+0x8e/0xb0
> [ 120.766529] [<ffffffff813c19e0>] _raw_spin_lock+0x40/0x80
> [ 120.766529] [<ffffffffa00b7ecc>] sco_chan_del+0x4c/0x170
> [bluetooth]
> [ 120.766529] [<ffffffffa00b8414>] sco_conn_del+0x74/0xe0
> [bluetooth]
> [ 120.766529] [<ffffffffa00b88a2>] sco_disconn_cfm+0x32/0x60
> [bluetooth]
> [ 120.766529] [<ffffffffa0093a82>]
> hci_disconn_complete_evt.isra.53+0x242/0x390 [bluetooth]
> [ 120.766529] [<ffffffffa009d747>] hci_event_packet+0x617/0xfb0
> [bluetooth]
> [ 120.766529] [<ffffffffa008aa68>] hci_rx_work+0x2c8/0x890
> [bluetooth]
> [ 120.766529] [<ffffffff81047db7>] process_one_work+0x197/0x460
> [ 120.766529] [<ffffffff810489d6>] worker_thread+0x126/0x2d0
> [ 120.766529] [<ffffffff8104ee4d>] kthread+0x9d/0xb0
> [ 120.766529] [<ffffffff813c4294>] kernel_thread_helper+0x4/0x10
> [ 120.766529]
> [ 120.766529] other info that might help us debug this:
> [ 120.766529]
> [ 120.766529] Possible unsafe locking scenario:
> [ 120.766529]
> [ 120.766529] CPU0 CPU1
> [ 120.766529] ---- ----
> [ 120.766529] lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
> [ 120.766529]
> lock(&(&conn->lock)->rlock#2);
> [ 120.766529]
> lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
> [ 120.766529] lock(&(&conn->lock)->rlock#2);
> [ 120.766529]
> [ 120.766529] *** DEADLOCK ***
>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> ---
> net/bluetooth/sco.c | 19 +++++++++----------
> 1 file changed, 9 insertions(+), 10 deletions(-)
>
> diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
> index cbdd313..596fdc8 100644
> --- a/net/bluetooth/sco.c
> +++ b/net/bluetooth/sco.c
> @@ -149,6 +149,15 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
> sco_sock_clear_timer(sk);
> sco_chan_del(sk, err);
> bh_unlock_sock(sk);
> +
> + sco_conn_lock(conn);
> + conn->sk = NULL;
> + sco_pi(sk)->conn = NULL;
> + sco_conn_unlock(conn);
> +
> + if (conn->hcon)
> + hci_conn_put(conn->hcon);
> +
> sco_sock_kill(sk);
> }
>
> @@ -838,16 +847,6 @@ static void sco_chan_del(struct sock *sk, int err)
>
> BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
>
> - if (conn) {
> - sco_conn_lock(conn);
> - conn->sk = NULL;
> - sco_pi(sk)->conn = NULL;
> - sco_conn_unlock(conn);
> -
> - if (conn->hcon)
> - hci_conn_put(conn->hcon);
> - }
> -
> sk->sk_state = BT_CLOSED;
> sk->sk_err = err;
> sk->sk_state_change(sk);
^ permalink raw reply
* [PATCH] adapter: Fix memory leak in convert_config
From: Szymon Janc @ 2012-11-28 14:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
'converted' was not freed if config file was already converted.
---
src/adapter.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/adapter.c b/src/adapter.c
index 163360f..b44eb36 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2698,6 +2698,7 @@ static void convert_config(struct btd_adapter *adapter, const char *filename,
if (converted) {
if (strcmp(converted, "yes") == 0) {
DBG("Legacy config file already converted");
+ g_free(converted);
return;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 1/2] adapter: Fix memory leak in convert_config
From: Szymon Janc @ 2012-11-28 15:17 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
'converted' was not freed if config file was already converted.
---
src/adapter.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/adapter.c b/src/adapter.c
index 163360f..d6f8a37 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2698,6 +2698,7 @@ static void convert_config(struct btd_adapter *adapter, const char *filename,
if (converted) {
if (strcmp(converted, "yes") == 0) {
DBG("Legacy config file already converted");
+ free(converted);
return;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 2/2] adapter: Fix improper freeing with g_free in convert_config
From: Szymon Janc @ 2012-11-28 15:17 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1354115856-29301-1-git-send-email-szymon.janc@tieto.com>
Memory in textfile_get is allocated with malloc and it should be freed
with free not g_free.
---
src/adapter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/adapter.c b/src/adapter.c
index d6f8a37..f134dfe 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2702,7 +2702,7 @@ static void convert_config(struct btd_adapter *adapter, const char *filename,
return;
}
- g_free(converted);
+ free(converted);
}
if (read_local_name(&adapter->bdaddr, str) == 0)
--
1.7.9.5
^ permalink raw reply related
* [RFC 1/5] Bluetooth: AMP: Check that AMP is present and active
From: Andrei Emeltchenko @ 2012-11-28 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Before starting quering remote AMP controllers make sure
that there is local active AMP controller.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
include/net/bluetooth/hci_core.h | 16 ++++++++++++++++
net/bluetooth/l2cap_core.c | 1 +
2 files changed, 17 insertions(+)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2f2b743..014a2ea 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -779,6 +779,22 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_host_le_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE)
#define lmp_host_le_br_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE_BREDR)
+/* returns true if at least one AMP active */
+static inline bool hci_amp_capable(void)
+{
+ struct hci_dev *hdev;
+ bool ret = false;
+
+ read_lock(&hci_dev_list_lock);
+ list_for_each_entry(hdev, &hci_dev_list, list)
+ if (hdev->amp_type == HCI_AMP &&
+ test_bit(HCI_UP, &hdev->flags))
+ ret = true;
+ read_unlock(&hci_dev_list_lock);
+
+ return ret;
+}
+
/* ----- HCI protocols ----- */
#define HCI_PROTO_DEFER 0x01
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b52f66d..39e144f 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1014,6 +1014,7 @@ static bool __amp_capable(struct l2cap_chan *chan)
struct l2cap_conn *conn = chan->conn;
if (enable_hs &&
+ hci_amp_capable() &&
chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
conn->fixed_chan_mask & L2CAP_FC_A2MP)
return true;
--
1.7.10.4
^ permalink raw reply related
* [RFC 2/5] Bluetooth: Refactor l2cap_send_disconn_req
From: Andrei Emeltchenko @ 2012-11-28 15:59 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354118382-25571-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
l2cap_send_disconn_req takes 3 parameters of which conn might be
derived from chan. Make this conversion inside l2cap_send_disconn_req.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 56 ++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 30 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 39e144f..d8cffdb 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -53,8 +53,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
void *data);
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
-static void l2cap_send_disconn_req(struct l2cap_conn *conn,
- struct l2cap_chan *chan, int err);
+static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
struct sk_buff_head *skbs, u8 event);
@@ -632,7 +631,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
conn->hcon->type == ACL_LINK) {
__set_chan_timer(chan, sk->sk_sndtimeo);
- l2cap_send_disconn_req(conn, chan, reason);
+ l2cap_send_disconn_req(chan, reason);
} else
l2cap_chan_del(chan, reason);
break;
@@ -1181,10 +1180,10 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
}
}
-static void l2cap_send_disconn_req(struct l2cap_conn *conn,
- struct l2cap_chan *chan, int err)
+static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
{
struct sock *sk = chan->sk;
+ struct l2cap_conn *conn = chan->conn;
struct l2cap_disconn_req req;
if (!conn)
@@ -1961,7 +1960,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan)
if (chan->max_tx != 0 &&
bt_cb(skb)->control.retries > chan->max_tx) {
BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
l2cap_seq_list_clear(&chan->retrans_list);
break;
}
@@ -2667,7 +2666,7 @@ static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
__set_monitor_timer(chan);
chan->retry_count++;
} else {
- l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
+ l2cap_send_disconn_req(chan, ECONNABORTED);
}
break;
default:
@@ -3878,7 +3877,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
/* Complete config. */
len = l2cap_parse_conf_req(chan, rsp);
if (len < 0) {
- l2cap_send_disconn_req(conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
goto unlock;
}
@@ -3900,7 +3899,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
err = l2cap_ertm_init(chan);
if (err < 0)
- l2cap_send_disconn_req(chan->conn, chan, -err);
+ l2cap_send_disconn_req(chan, -err);
else
l2cap_chan_ready(chan);
@@ -3968,7 +3967,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
len = l2cap_parse_conf_rsp(chan, rsp->data, len,
buf, &result);
if (len < 0) {
- l2cap_send_disconn_req(conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
goto done;
}
@@ -3989,7 +3988,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
char req[64];
if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
- l2cap_send_disconn_req(conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
goto done;
}
@@ -3998,7 +3997,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
len = l2cap_parse_conf_rsp(chan, rsp->data, len,
req, &result);
if (len < 0) {
- l2cap_send_disconn_req(conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
goto done;
}
@@ -4014,7 +4013,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
l2cap_chan_set_err(chan, ECONNRESET);
__set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
- l2cap_send_disconn_req(conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
goto done;
}
@@ -4031,7 +4030,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
err = l2cap_ertm_init(chan);
if (err < 0)
- l2cap_send_disconn_req(chan->conn, chan, -err);
+ l2cap_send_disconn_req(chan, -err);
else
l2cap_chan_ready(chan);
}
@@ -4393,7 +4392,7 @@ static void l2cap_logical_fail(struct l2cap_chan *chan)
/* Logical link setup failed */
if (chan->state != BT_CONNECTED) {
/* Create channel failure, disconnect */
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
return;
}
@@ -4436,7 +4435,7 @@ static void l2cap_logical_finish_create(struct l2cap_chan *chan,
err = l2cap_ertm_init(chan);
if (err < 0)
- l2cap_send_disconn_req(chan->conn, chan, -err);
+ l2cap_send_disconn_req(chan, -err);
else
l2cap_chan_ready(chan);
}
@@ -5401,7 +5400,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan,
if (control->reqseq == chan->next_tx_seq) {
BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
return;
}
@@ -5415,7 +5414,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan,
if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
return;
}
@@ -5459,7 +5458,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan,
if (control->reqseq == chan->next_tx_seq) {
BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
return;
}
@@ -5468,7 +5467,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan,
if (chan->max_tx && skb &&
bt_cb(skb)->control.retries >= chan->max_tx) {
BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
return;
}
@@ -5652,8 +5651,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
break;
case L2CAP_TXSEQ_INVALID:
default:
- l2cap_send_disconn_req(chan->conn, chan,
- ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
break;
}
break;
@@ -5786,8 +5784,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
break;
case L2CAP_TXSEQ_INVALID:
default:
- l2cap_send_disconn_req(chan->conn, chan,
- ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
break;
}
break;
@@ -5982,7 +5979,7 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
control->reqseq, chan->next_tx_seq,
chan->expected_ack_seq);
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
}
return err;
@@ -6051,7 +6048,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
len -= L2CAP_FCS_SIZE;
if (len > chan->mps) {
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
goto drop;
}
@@ -6076,8 +6073,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
}
if (err)
- l2cap_send_disconn_req(chan->conn, chan,
- ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
} else {
const u8 rx_func_to_event[4] = {
L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
@@ -6094,7 +6090,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
if (len != 0) {
BT_ERR("Trailing bytes: %d in sframe", len);
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
goto drop;
}
@@ -6105,7 +6101,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
event = rx_func_to_event[control->super];
if (l2cap_rx(chan, control, skb, event))
- l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ l2cap_send_disconn_req(chan, ECONNRESET);
}
return 0;
--
1.7.10.4
^ permalink raw reply related
* [RFC 3/5] Bluetooth: Fix missing L2CAP EWS Conf parameter
From: Andrei Emeltchenko @ 2012-11-28 15:59 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354118382-25571-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
If L2CAP_FEAT_FCS is not supported we sould miss EWS option
configuration because of break. Make code more readable by
combining FCS configuration in the single block.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d8cffdb..f10e4be 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3106,18 +3106,16 @@ done:
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
l2cap_add_opt_efs(&ptr, chan);
- if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
- break;
-
- if (chan->fcs == L2CAP_FCS_NONE ||
- test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
- chan->fcs = L2CAP_FCS_NONE;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
- }
-
if (test_bit(FLAG_EXT_CTRL, &chan->flags))
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
chan->tx_win);
+
+ if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
+ if (chan->fcs == L2CAP_FCS_NONE ||
+ test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
+ chan->fcs = L2CAP_FCS_NONE;
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
+ }
break;
case L2CAP_MODE_STREAMING:
@@ -3139,14 +3137,12 @@ done:
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
l2cap_add_opt_efs(&ptr, chan);
- if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
- break;
-
- if (chan->fcs == L2CAP_FCS_NONE ||
- test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
- chan->fcs = L2CAP_FCS_NONE;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
- }
+ if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
+ if (chan->fcs == L2CAP_FCS_NONE ||
+ test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
+ chan->fcs = L2CAP_FCS_NONE;
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
+ }
break;
}
--
1.7.10.4
^ permalink raw reply related
* [RFC 4/5] Bluetooth: Process receiving FCS_NONE in L2CAP Conf Rsp
From: Andrei Emeltchenko @ 2012-11-28 15:59 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354118382-25571-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Process L2CAP Config rsp Pending with FCS Option 0x00 (No FCS)
which is sent by Motorola Windows 7 Bluetooth stack. The trace
is shown below (all other options are skipped).
...
< ACL data: handle 1 flags 0x00 dlen 48
L2CAP(s): Config req: dcid 0x0043 flags 0x00 clen 36
...
FCS Option 0x00 (No FCS)
> ACL data: handle 1 flags 0x02 dlen 48
L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 36
...
FCS Option 0x01 (CRC16 Check)
< ACL data: handle 1 flags 0x00 dlen 47
L2CAP(s): Config rsp: scid 0x0043 flags 0x00 result 4 clen 33
Pending
...
> ACL data: handle 1 flags 0x02 dlen 50
L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 4 clen 36
Pending
...
FCS Option 0x00 (No FCS)
< ACL data: handle 1 flags 0x00 dlen 14
L2CAP(s): Config rsp: scid 0x0043 flags 0x00 result 0 clen 0
Success
> ACL data: handle 1 flags 0x02 dlen 14
L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 0
Success
...
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index f10e4be..d30978b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3429,6 +3429,12 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
(unsigned long) &efs);
break;
+
+ case L2CAP_CONF_FCS:
+ if (*result == L2CAP_CONF_PENDING)
+ if (val == L2CAP_FCS_NONE)
+ set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
+ break;
}
}
--
1.7.10.4
^ permalink raw reply related
* [RFC 5/5] Bluetooth: AMP: Mark controller radio powered down after HCIDEVDOWN
From: Andrei Emeltchenko @ 2012-11-28 15:59 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354118382-25571-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
After getting HCIDEVDOWN controller did not mark itself as 0x00 which
means: "The Controller radio is available but is currently physically
powered down". The result was even if the hdev was down we return
in controller list value 0x01 "status 0x01 (Bluetooth only)".
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/hci_core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 69eb644..ec7d3a7 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -861,6 +861,9 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Clear flags */
hdev->flags = 0;
+ /* Controller radio is available but is currently powered down */
+ hdev->amp_status = 0;
+
memset(hdev->eir, 0, sizeof(hdev->eir));
memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH v2 1/2] adapter: Fix memory leak in convert_config
From: Johan Hedberg @ 2012-11-28 17:08 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1354115856-29301-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Wed, Nov 28, 2012, Szymon Janc wrote:
> 'converted' was not freed if config file was already converted.
> ---
> src/adapter.c | 1 +
> 1 file changed, 1 insertion(+)
Both patches have been applied. Thanks.
Johan
^ 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