Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ 4/6] AVRCP: Get player list if supported
From: Luiz Augusto von Dentz @ 2013-02-01  3:58 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359691117-13847-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

If addressed player changed is supported get the list of players
---
 profiles/audio/avrcp.c  | 147 ++++++++++++++++++++++++++++++++++++++++++++++++
 profiles/audio/player.c | 119 +++++++++++++++++++++++++++++++++++++++
 profiles/audio/player.h |   4 ++
 3 files changed, 270 insertions(+)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 8187ddf..793b5cf 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -99,6 +99,7 @@
 #define AVRCP_REQUEST_CONTINUING	0x40
 #define AVRCP_ABORT_CONTINUING		0x41
 #define AVRCP_SET_ABSOLUTE_VOLUME	0x50
+#define AVRCP_GET_FOLDER_ITEMS		0x71
 #define AVRCP_GENERAL_REJECT		0xA0
 
 /* Capabilities for AVRCP_GET_CAPABILITIES pdu */
@@ -1859,6 +1860,151 @@ static void avrcp_get_element_attributes(struct avrcp *session)
 					session);
 }
 
+static const char *type_to_string(uint8_t type)
+{
+	switch (type & 0x0F) {
+	case 0x01:
+		return "Audio";
+	case 0x02:
+		return "Video";
+	case 0x03:
+		return "Audio, Video";
+	case 0x04:
+		return "Audio Broadcasting";
+	case 0x05:
+		return "Audio, Audio Broadcasting";
+	case 0x06:
+		return "Video, Audio Broadcasting";
+	case 0x07:
+		return "Audio, Video, Audio Broadcasting";
+	case 0x08:
+		return "Video Broadcasting";
+	case 0x09:
+		return "Audio, Video Broadcasting";
+	case 0x0A:
+		return "Video, Video Broadcasting";
+	case 0x0B:
+		return "Audio, Video, Video Broadcasting";
+	case 0x0C:
+		return "Audio Broadcasting, Video Broadcasting";
+	case 0x0D:
+		return "Audio, Audio Broadcasting, Video Broadcasting";
+	case 0x0E:
+		return "Video, Audio Broadcasting, Video Broadcasting";
+	case 0x0F:
+		return "Audio, Video, Audio Broadcasting, Video Broadcasting";
+	}
+
+	return "None";
+}
+
+static const char *subtype_to_string(uint32_t subtype)
+{
+	switch (subtype & 0x03) {
+	case 0x01:
+		return "Audio Book";
+	case 0x02:
+		return "Podcast";
+	case 0x03:
+		return "Audio Book, Podcast";
+	}
+
+	return "None";
+}
+
+static void avrcp_parse_media_player_item(struct avrcp *session,
+					uint8_t *operands, uint16_t len)
+{
+	struct avrcp_player *player = session->player;
+	struct media_player *mp = player->user_data;
+	uint16_t id;
+	uint32_t subtype;
+	const char *curval, *strval;
+	uint64_t features[2];
+	char name[255];
+
+	if (len < 28)
+		return;
+
+	id = bt_get_be16(&operands[0]);
+
+	if (player->id != id)
+		return;
+
+	media_player_set_type(mp, type_to_string(operands[2]));
+
+	subtype = bt_get_be32(&operands[3]);
+
+	media_player_set_subtype(mp, subtype_to_string(subtype));
+
+	curval = media_player_get_status(mp);
+	strval = status_to_string(operands[7]);
+
+	if (g_strcmp0(curval, strval) != 0) {
+		media_player_set_status(mp, strval);
+		avrcp_get_play_status(session);
+	}
+
+	features[0] = bt_get_be64(&operands[8]);
+	features[1] = bt_get_be64(&operands[16]);
+
+	media_player_set_features(mp, features);
+
+	if (operands[26] == 0)
+		return;
+
+	memcpy(name, &operands[27], operands[26]);
+
+	media_player_set_name(mp, name);
+}
+
+static gboolean avrcp_get_media_player_list_rsp(struct avctp *conn,
+						uint8_t *operands,
+						size_t operand_count,
+						void *user_data)
+{
+	struct avrcp *session = user_data;
+	uint16_t count;
+	int i;
+
+	if (operands[3] != AVRCP_STATUS_SUCCESS || operand_count < 5)
+		return FALSE;
+
+	count = bt_get_be16(&operands[6]);
+
+	for (i = 8; count; count--) {
+		uint8_t type;
+		uint16_t len;
+
+		type = operands[i++];
+		len = bt_get_be16(&operands[i]);
+		i += 2;
+
+		if (type != 0x01) {
+			i += len;
+			continue;
+		}
+
+		avrcp_parse_media_player_item(session, &operands[i], len);
+	}
+
+	return FALSE;
+}
+
+static void avrcp_get_media_player_list(struct avrcp *session)
+{
+	uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 10];
+	struct avrcp_browsing_header *pdu = (void *) buf;
+
+	memset(buf, 0, sizeof(buf));
+
+	pdu->pdu_id = AVRCP_GET_FOLDER_ITEMS;
+	pdu->param_len = htons(10);
+
+	avctp_send_browsing_req(session->conn, buf, sizeof(buf),
+				avrcp_get_media_player_list_rsp, session);
+}
+
 static gboolean avrcp_handle_event(struct avctp *conn,
 					uint8_t code, uint8_t subunit,
 					uint8_t *operands, size_t operand_count,
@@ -1944,6 +2090,7 @@ static gboolean avrcp_handle_event(struct avctp *conn,
 
 		player->id = id;
 		player->uid_counter = bt_get_be16(&pdu->params[3]);
+		avrcp_get_media_player_list(session);
 		break;
 	}
 
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index fb750fd..b4efa70 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -57,6 +57,10 @@ struct pending_req {
 
 struct media_player {
 	char			*device;	/* Device path */
+	char			*name;		/* Player name */
+	char			*type;		/* Player type */
+	char			*subtype;	/* Player subtype */
+	uint64_t		features[2];	/* Player features */
 	char			*path;		/* Player object path */
 	GHashTable		*settings;	/* Player settings */
 	GHashTable		*track;		/* Player current track */
@@ -272,6 +276,72 @@ static gboolean get_device(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static gboolean name_exists(const GDBusPropertyTable *property, void *data)
+{
+	struct media_player *mp = data;
+
+	return mp->name != NULL;
+}
+
+static gboolean get_name(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_player *mp = data;
+
+	if (mp->name == NULL)
+		return FALSE;
+
+	DBG("%s", mp->name);
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &mp->name);
+
+	return TRUE;
+}
+
+static gboolean type_exists(const GDBusPropertyTable *property, void *data)
+{
+	struct media_player *mp = data;
+
+	return mp->type != NULL;
+}
+
+static gboolean get_type(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_player *mp = data;
+
+	if (mp->type == NULL)
+		return FALSE;
+
+	DBG("%s", mp->type);
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &mp->type);
+
+	return TRUE;
+}
+
+static gboolean subtype_exists(const GDBusPropertyTable *property, void *data)
+{
+	struct media_player *mp = data;
+
+	return mp->subtype != NULL;
+}
+
+static gboolean get_subtype(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_player *mp = data;
+
+	if (mp->subtype == NULL)
+		return FALSE;
+
+	DBG("%s", mp->subtype);
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &mp->subtype);
+
+	return TRUE;
+}
+
 static DBusMessage *media_player_play(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
@@ -410,6 +480,12 @@ static const GDBusSignalTable media_player_signals[] = {
 };
 
 static const GDBusPropertyTable media_player_properties[] = {
+	{ "Name", "s", get_name, NULL, name_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Type", "s", get_type, NULL, type_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Subtype", "s", get_subtype, NULL, subtype_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
 	{ "Position", "u", get_position, NULL, NULL,
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
 	{ "Status", "s", get_status, NULL, status_exists,
@@ -452,6 +528,9 @@ void media_player_destroy(struct media_player *mp)
 	g_free(mp->status);
 	g_free(mp->path);
 	g_free(mp->device);
+	g_free(mp->subtype);
+	g_free(mp->type);
+	g_free(mp->name);
 	g_free(mp);
 }
 
@@ -618,6 +697,46 @@ void media_player_set_metadata(struct media_player *mp, const char *key,
 	g_hash_table_replace(mp->track, g_strdup(key), value);
 }
 
+void media_player_set_type(struct media_player *mp, const char *type)
+{
+	DBG("%s", type);
+
+	mp->type = g_strdup(type);
+
+	g_dbus_emit_property_changed(btd_get_dbus_connection(),
+					mp->path, MEDIA_PLAYER_INTERFACE,
+					"Type");
+}
+
+void media_player_set_subtype(struct media_player *mp, const char *subtype)
+{
+	DBG("%s", subtype);
+
+	mp->subtype = g_strdup(subtype);
+
+	g_dbus_emit_property_changed(btd_get_dbus_connection(),
+					mp->path, MEDIA_PLAYER_INTERFACE,
+					"Subtype");
+}
+
+void media_player_set_name(struct media_player *mp, const char *name)
+{
+	DBG("%s", name);
+
+	mp->name = g_strdup(name);
+
+	g_dbus_emit_property_changed(btd_get_dbus_connection(),
+					mp->path, MEDIA_PLAYER_INTERFACE,
+					"Name");
+}
+
+void media_player_set_features(struct media_player *mp, uint64_t *features)
+{
+	DBG("0x%08zx %08zx", features[0], features[1]);
+
+	memcpy(features, mp->features, sizeof(mp->features));
+}
+
 void media_player_set_callbacks(struct media_player *mp,
 				const struct media_player_callback *cbs,
 				void *user_data)
diff --git a/profiles/audio/player.h b/profiles/audio/player.h
index fec1d06..b546ba7 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
@@ -47,6 +47,10 @@ const char *media_player_get_status(struct media_player *mp);
 void media_player_set_status(struct media_player *mp, const char *status);
 void media_player_set_metadata(struct media_player *mp, const char *key,
 						void *data, size_t len);
+void media_player_set_type(struct media_player *mp, const char *type);
+void media_player_set_subtype(struct media_player *mp, const char *subtype);
+void media_player_set_features(struct media_player *mp, uint64_t *features);
+void media_player_set_name(struct media_player *mp, const char *name);
 
 void media_player_set_callbacks(struct media_player *mp,
 				const struct media_player_callback *cbs,
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 3/6] AVRCP: Register to addressed player changed event if supported
From: Luiz Augusto von Dentz @ 2013-02-01  3:58 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359691117-13847-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This enables registering for addressed player changed event and handle
the interim response setting the player id and uid counter to the current
player.
---
 profiles/audio/avrcp.c | 14 ++++++++++++++
 profiles/audio/avrcp.h | 15 ++++++++-------
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 0a173bc..8187ddf 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -176,6 +176,8 @@ struct pending_pdu {
 struct avrcp_player {
 	struct avrcp_server *server;
 	GSList *sessions;
+	uint16_t id;
+	uint16_t uid_counter;
 
 	struct avrcp_player_cb *cb;
 	void *user_data;
@@ -1869,6 +1871,7 @@ static gboolean avrcp_handle_event(struct avctp *conn,
 	uint8_t event;
 	uint8_t value;
 	uint8_t count;
+	uint16_t id;
 	const char *curval, *strval;
 	int i;
 
@@ -1932,6 +1935,16 @@ static gboolean avrcp_handle_event(struct avctp *conn,
 		}
 
 		break;
+
+	case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
+		id = bt_get_be16(&pdu->params[1]);
+
+		if (player->id == id)
+			break;
+
+		player->id = id;
+		player->uid_counter = bt_get_be16(&pdu->params[3]);
+		break;
 	}
 
 	session->registered_events |= (1 << event);
@@ -2112,6 +2125,7 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn,
 		case AVRCP_EVENT_STATUS_CHANGED:
 		case AVRCP_EVENT_TRACK_CHANGED:
 		case AVRCP_EVENT_SETTINGS_CHANGED:
+		case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
 			avrcp_register_notification(session, event);
 			break;
 		}
diff --git a/profiles/audio/avrcp.h b/profiles/audio/avrcp.h
index b2c0d61..3799da1 100644
--- a/profiles/audio/avrcp.h
+++ b/profiles/audio/avrcp.h
@@ -69,13 +69,14 @@
 #define AVRCP_PLAY_STATUS_ERROR		0xFF
 
 /* Notification events */
-#define AVRCP_EVENT_STATUS_CHANGED	0x01
-#define AVRCP_EVENT_TRACK_CHANGED	0x02
-#define AVRCP_EVENT_TRACK_REACHED_END	0x03
-#define AVRCP_EVENT_TRACK_REACHED_START	0x04
-#define AVRCP_EVENT_SETTINGS_CHANGED	0x08
-#define AVRCP_EVENT_VOLUME_CHANGED	0x0d
-#define AVRCP_EVENT_LAST		AVRCP_EVENT_VOLUME_CHANGED
+#define AVRCP_EVENT_STATUS_CHANGED		0x01
+#define AVRCP_EVENT_TRACK_CHANGED		0x02
+#define AVRCP_EVENT_TRACK_REACHED_END		0x03
+#define AVRCP_EVENT_TRACK_REACHED_START		0x04
+#define AVRCP_EVENT_SETTINGS_CHANGED		0x08
+#define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED	0x0b
+#define AVRCP_EVENT_VOLUME_CHANGED		0x0d
+#define AVRCP_EVENT_LAST			AVRCP_EVENT_VOLUME_CHANGED
 
 struct avrcp_player_cb {
 	GList *(*list_settings) (void *user_data);
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 2/6] AVRCP: Avoid repeating command due to changed event
From: Luiz Augusto von Dentz @ 2013-02-01  3:58 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359691117-13847-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Currently we are repeating the same command twice for notification, first
for changed and then latter for interim response.

To avoid this the code now just do it for interim responses, changed
responses just trigger another registration.
---
 profiles/audio/avrcp.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 728ba91..0a173bc 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1877,6 +1877,12 @@ static gboolean avrcp_handle_event(struct avctp *conn,
 
 	event = pdu->params[0];
 
+	if (code == AVC_CTYPE_CHANGED) {
+		session->registered_events ^= (1 << event);
+		avrcp_register_notification(session, event);
+		return FALSE;
+	}
+
 	switch (event) {
 	case AVRCP_EVENT_VOLUME_CHANGED:
 		value = pdu->params[1] & 0x7F;
@@ -1900,12 +1906,8 @@ static gboolean avrcp_handle_event(struct avctp *conn,
 
 		break;
 	case AVRCP_EVENT_TRACK_CHANGED:
-		mp = player->user_data;
-
 		avrcp_get_element_attributes(session);
-
-		if (code == AVC_CTYPE_CHANGED)
-			avrcp_get_play_status(session);
+		avrcp_get_play_status(session);
 
 		break;
 
@@ -1932,12 +1934,6 @@ static gboolean avrcp_handle_event(struct avctp *conn,
 		break;
 	}
 
-	if (code == AVC_CTYPE_CHANGED) {
-		session->registered_events ^= (1 << event);
-		avrcp_register_notification(session, event);
-		return FALSE;
-	}
-
 	session->registered_events |= (1 << event);
 
 	return TRUE;
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 1/6] media-api: Add org.bluez.MediaFolder1
From: Luiz Augusto von Dentz @ 2013-02-01  3:58 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This interface adds support for browsing and searching in the player's
storage using AVRCP 1.4/1.5.

Some remarks about the design:

  - Exposing UIDCounter and UIDs was considered, but the spec seems to have
    missed to define the player's id persistency. There are also the fact that
    UIDCounter alone does not guarantee persistency across sessions and do not
    provide what exact items have changed, so in the end exposing these
    details will bring almost no value.
  - Indexing or caching the whole media library is not recommended, Bluetooth
    is too slow for that and even vendors such as Apple do not recommend doing
    it, so the only items keep in cache are the current listed ones.
  - Addressed vs Browsed player is done implicitly when accessed, this was done
    to simplify the API and avoid confusions between applications and players.
---
 doc/media-api.txt | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 183 insertions(+)

diff --git a/doc/media-api.txt b/doc/media-api.txt
index 972716e..54e53b9 100644
--- a/doc/media-api.txt
+++ b/doc/media-api.txt
@@ -226,6 +226,189 @@ Properties	string Equalizer [readwrite]
 
 			Device object path.
 
+		string Name [readonly]
+
+			Player name
+
+		boolean Browsable [readonly]
+
+			If present indicates the player can be browsed using
+			MediaLibrary interface.
+
+			Possible values:
+
+				True: Supported and active
+				False: Supported but inactive
+
+			Note: If supported but inactive clients can enable it
+			by using MediaLibrary interface but it might interfere
+			in the playback of other players.
+
+
+		boolean Searchable [readonly]
+
+			If present indicates the player can be searched using
+			MediaLibrary interface.
+
+			Possible values:
+
+				True: Supported and active
+				False: Supported but inactive
+
+			Note: If supported but inactive clients can enable it
+			by using MediaLibrary interface but it might interfere
+			in the playback of other players.
+
+		array{string} Buttons [readonly]
+
+			If available indicates the buttons supported by the
+			player.
+
+			Possible values:
+
+				"Play", "Pause", "Stop", "Next", "Previous",
+				"FastForward" and "Rewind"
+
+			Default value: All
+
+MediaFolder1 hierarchy
+======================
+
+Service		unique name (Target role)
+		org.bluez (Controller role)
+Interface	org.bluez.MediaFolder1 [Experimental]
+Object path	freely definable (Target role)
+		[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX
+		(Controller role)
+
+Methods		object Search(string value, dict filter)
+
+			Return a folder object containing the search result.
+
+			To list the items found use the folder object returned
+			and pass to ChangeFolder.
+
+		array{objects, properties} ListItems(dict filter)
+
+			Return a list of items found
+
+		void ChangeFolder(object folder)
+
+			Change current folder.
+
+			Note: By changing folder the items of previous folder
+			might be destroyed and have to be listed again, the
+			exception is NowPlaying folder which should be always
+			present while the player is active.
+
+Properties	uint32 NumberOfItems:
+
+			Number of items in the folder
+
+		string Name:
+
+			Folder name:
+
+			Possible values:
+				"/Filesystem/...": Filesystem scope
+				"/NowPlaying/...": NowPlaying scope
+
+			Note: /NowPlaying folder might not be listed if player
+			is stopped, folders created by Search are virtual so
+			once another Search is perform or the folder is
+			changed using ChangeFolder it will no longer be listed.
+
+Filters		uint32 Start:
+
+			Offset of the first item.
+
+			Default value: 0
+
+		uint32 End:
+
+			Offset of the last item.
+
+			Default value: NumbeOfItems
+
+		array{string} Attributes
+
+			Item properties that should be included in the list.
+
+			Possible Values:
+
+				"title", "artist", "album", "genre",
+				"number-of-tracks", "number", "duration"
+
+			Default Value: All
+
+MediaItem1 hierarchy
+====================
+
+Service		unique name (Target role)
+		org.bluez (Controller role)
+Interface	org.bluez.MediaItem1 [Experimental]
+Object path	freely definable (Target role)
+		[variable
+		prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX
+		(Controller role)
+
+Methods		void Play()
+
+			Play item
+
+		void AddtoNowPlaying()
+
+			Add item to now playing list
+
+Properties	string Name [readonly]
+
+			Item displayable name
+
+		boolean Folder [readonly]
+
+			Indicates whether the item is a folder
+
+		string Type [readonly]
+
+			Item type
+
+			Possible values:
+
+				Folder: "Mixed", "Titles", "Albums", "Artists"
+				Other Items: "Video", "Audio"
+
+		boolean Playable [readonly]
+
+			Indicates if the item can be played
+
+		string Title:
+
+			Item title name
+
+		string Artist:
+
+			Item artist name
+
+		string Album:
+
+			Item album name
+
+		string Genre:
+
+			Item genre name
+
+		uint32 NumberOfTracks:
+
+			Item album number of tracks in total
+
+		uint32 Number:
+
+			Item album number
+
+		uint32 Duration:
+
+			Item duration in milliseconds
+
 MediaEndpoint1 hierarchy
 ========================
 
-- 
1.8.1


^ permalink raw reply related

* [PATCH] Bluetooth: Remove unneeded locking
From: Andre Guedes @ 2013-01-31 23:12 UTC (permalink / raw)
  To: linux-bluetooth

This patch removes unneeded locking in hci_le_adv_report_evt. There
is no need to lock hdev before calling mgmt_device_found.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 net/bluetooth/hci_event.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d4fcba6..06e7657 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3988,8 +3988,6 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	void *ptr = &skb->data[1];
 	s8 rssi;
 
-	hci_dev_lock(hdev);
-
 	while (num_reports--) {
 		struct hci_ev_le_advertising_info *ev = ptr;
 
@@ -3999,8 +3997,6 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 		ptr += sizeof(*ev) + ev->length + 1;
 	}
-
-	hci_dev_unlock(hdev);
 }
 
 static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-- 
1.8.1.1


^ permalink raw reply related

* Re: [PATCH BlueZ 1/3] hcidump: Distinct Control and Browsing AVCTP channels
From: Luiz Augusto von Dentz @ 2013-01-31 23:03 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <20130131220726.GA3878@samus>

Hi Vinicius,

On Thu, Jan 31, 2013 at 4:07 PM, Vinicius Costa Gomes
<vinicius.gomes@openbossa.org> wrote:
> Hi Luiz,
>
> On 09:33 Thu 31 Jan, Luiz Augusto von Dentz wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> This prints the respective channel of the trafic
>
> These (three?) series got all mixed in the list.
>
> Could you send them again?
>
>
> Cheers,
> --
> Vinicius

They are applied already, sorry for the mess.

--
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH BlueZ 1/3] hcidump: Distinct Control and Browsing AVCTP channels
From: Vinicius Costa Gomes @ 2013-01-31 22:07 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1359646436-8113-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On 09:33 Thu 31 Jan, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> This prints the respective channel of the trafic

These (three?) series got all mixed in the list.

Could you send them again?


Cheers,
-- 
Vinicius

^ permalink raw reply

* Re: [PATCH v2 1/3] Bluetooth: Fix hci_conn timeout routine
From: Gustavo Padovan @ 2013-01-31 17:39 UTC (permalink / raw)
  To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1359557457-10199-1-git-send-email-andre.guedes@openbossa.org>

Hi Andre,

* Andre Guedes <andre.guedes@openbossa.org> [2013-01-30 11:50:55 -0300]:

> If occurs a LE or SCO hci_conn timeout and the connection is already
> established (BT_CONNECTED state), the connection is not terminated as
> expected. This bug can be reproduced using l2test or scotest tool.
> Once the connection is established, kill l2test/scotest and the
> connection won't be terminated.
> 
> This patch fixes hci_conn_disconnect helper so it is able to
> terminate LE and SCO connections, as well as ACL.
> 
> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> ---
>  net/bluetooth/hci_conn.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

I just pushed this patch to bluetooth.git, this also means I'm not applying
the hci_acl_disconn() rename patch until the next release cycle. A rename
patch is not suitable for 3.8 anymore.  Thanks.

	Gustavo

^ permalink raw reply

* Re: [PATCH v2] Bluetooth: Fix handling of unexpected SMP PDUs
From: Gustavo Padovan @ 2013-01-31 17:36 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1359477863-24645-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

* Johan Hedberg <johan.hedberg@gmail.com> [2013-01-29 10:44:23 -0600]:

> From: Johan Hedberg <johan.hedberg@intel.com>
> 
> The conn->smp_chan pointer can be NULL if SMP PDUs arrive at unexpected
> moments. To avoid NULL pointer dereferences the code should be checking
> for this and disconnect if an unexpected SMP PDU arrives. This patch
> fixes the issue by adding a check for conn->smp_chan for all other PDUs
> except pairing request and security request (which are are the first
> PDUs to come to initialize the SMP context).
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> CC: stable@vger.kernel.org
> ---
> v2: Move the checks to a single place in smp_sig_channel() and instead
> of ignoring the PDUs return failure from smp_sig_channel() to trigger a
> disconnection.
> 
>  net/bluetooth/smp.c |   13 +++++++++++++
>  1 file changed, 13 insertions(+)

Patch has been applied to bluetooth.git. Thanks.

	Gustavo

^ permalink raw reply

* [PATCH BlueZ 4/4] AVRCP: Get track duration using GetPlayStatus command
From: Luiz Augusto von Dentz @ 2013-01-31 17:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359652363-25602-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Some stacks, notably broadcom, don't send track duration together with
other metadata so it has to be set using GetPlayStatus.
---
 profiles/audio/avrcp.c  |  6 ++++--
 profiles/audio/player.c | 21 +++++++++++++++++++++
 profiles/audio/player.h |  1 +
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index f83c3db..728ba91 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1632,6 +1632,7 @@ static gboolean avrcp_get_play_status_rsp(struct avctp *conn,
 
 	memcpy(&duration, pdu->params, sizeof(uint32_t));
 	duration = ntohl(duration);
+	media_player_set_duration(mp, duration);
 
 	memcpy(&position, pdu->params + 4, sizeof(uint32_t));
 	position = ntohl(position);
@@ -1900,11 +1901,12 @@ static gboolean avrcp_handle_event(struct avctp *conn,
 		break;
 	case AVRCP_EVENT_TRACK_CHANGED:
 		mp = player->user_data;
-		if (code == AVC_CTYPE_CHANGED)
-			media_player_set_position(mp, 0);
 
 		avrcp_get_element_attributes(session);
 
+		if (code == AVC_CTYPE_CHANGED)
+			avrcp_get_play_status(session);
+
 		break;
 
 	case AVRCP_EVENT_SETTINGS_CHANGED:
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index 841a577..fb750fd 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -483,6 +483,27 @@ struct media_player *media_player_controller_create(const char *path)
 	return mp;
 }
 
+void media_player_set_duration(struct media_player *mp, uint32_t duration)
+{
+	char *value, *curval;
+
+	DBG("%u", duration);
+
+	value = g_strdup_printf("%u", duration);
+
+	curval = g_hash_table_lookup(mp->track, "Duration");
+	if (g_strcmp0(curval, value) == 0) {
+		g_free(value);
+		return;
+	}
+
+	g_hash_table_replace(mp->track, g_strdup("Duration"), value);
+
+	g_dbus_emit_property_changed(btd_get_dbus_connection(),
+					mp->path, MEDIA_PLAYER_INTERFACE,
+					"Track");
+}
+
 void media_player_set_position(struct media_player *mp, uint32_t position)
 {
 	DBG("%u", position);
diff --git a/profiles/audio/player.h b/profiles/audio/player.h
index 212a5a6..fec1d06 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
@@ -39,6 +39,7 @@ struct media_player_callback {
 
 struct media_player *media_player_controller_create(const char *path);
 void media_player_destroy(struct media_player *mp);
+void media_player_set_duration(struct media_player *mp, uint32_t duration);
 void media_player_set_position(struct media_player *mp, uint32_t position);
 void media_player_set_setting(struct media_player *mp, const char *key,
 							const char *value);
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 3/4] A2DP: Fix not setting setup error to NULL
From: Luiz Augusto von Dentz @ 2013-01-31 17:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359652363-25602-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Once the error is informed to the callback it should be properly freed and
set to NULL otherwise a subsequent operation may end up reusing the same
error which might lead to crashes.
---
 profiles/audio/a2dp.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index efb4178..4b28465 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -366,16 +366,13 @@ static void stream_state_changed(struct avdtp_stream *stream,
 static gboolean auto_config(gpointer data)
 {
 	struct a2dp_setup *setup = data;
-	struct avdtp_error *err = NULL;
 
 	/* Check if configuration was aborted */
 	if (setup->sep->stream == NULL)
 		return FALSE;
 
-	if (setup->err != NULL) {
-		err = setup->err;
+	if (setup->err != NULL)
 		goto done;
-	}
 
 	avdtp_stream_add_cb(setup->session, setup->stream,
 				stream_state_changed, setup->sep);
@@ -391,8 +388,10 @@ done:
 
 	finalize_config(setup);
 
-	if (err)
-		g_free(err);
+	if (setup->err) {
+		g_free(setup->err);
+		setup->err = NULL;
+	}
 
 	setup_unref(setup);
 
@@ -565,6 +564,7 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 		if (setup) {
 			setup->err = err;
 			finalize_config(setup);
+			setup->err = NULL;
 		}
 		return;
 	}
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 2/4] AVCTP: Fix memory leak
From: Luiz Augusto von Dentz @ 2013-01-31 17:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359652363-25602-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

651 (280 direct, 371 indirect) bytes in 7 blocks are definitely lost in loss record 306 of 332
   at 0x4A06B2F: calloc (vg_replace_malloc.c:593)
   by 0x319724D706: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.3400.2)
   by 0x418A54: avctp_send_browsing_req (avctp.c:1457)
   by 0x41A330: avrcp_handle_event (avrcp.c:1998)
   by 0x417810: session_cb (avctp.c:702)
   by 0x3197247A74: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
   by 0x3197247DA7: ??? (in /usr/lib64/libglib-2.0.so.0.3400.2)
   by 0x31972481A1: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3400.2)
   by 0x409D6E: main (main.c:583)
---
 profiles/audio/avctp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index 303427e..13dd4c3 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
@@ -749,6 +749,7 @@ static void browsing_response(struct avctp_channel *browsing,
 			return;
 
 		browsing->processed = g_slist_remove(browsing->processed, p);
+		pending_destroy(p, NULL);
 
 		return;
 	}
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 1/4] AVCTP: Fix allways destroying browsing channel
From: Luiz Augusto von Dentz @ 2013-01-31 17:12 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This reverts commit 53d3fc3fad5152167458625ad2acf19070cdf26a that leads
to always destroy the browsing channel because the callback changes the
state.

To fix session_browsing_cb naw takes care of destroying the channel if it
disconnects.
---
 profiles/audio/avctp.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index 41e2f46..303427e 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
@@ -490,10 +490,6 @@ static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
 		break;
 	case AVCTP_STATE_CONNECTED:
 		DBG("AVCTP Connected");
-		if (session->browsing) {
-			avctp_channel_destroy(session->browsing);
-			session->browsing = NULL;
-		}
 		break;
 	case AVCTP_STATE_BROWSING_CONNECTING:
 		DBG("AVCTP Browsing Connecting");
@@ -817,6 +813,13 @@ send:
 
 failed:
 	DBG("AVCTP Browsing: disconnected");
+	avctp_set_state(session, AVCTP_STATE_CONNECTED);
+
+	if (session->browsing) {
+		avctp_channel_destroy(session->browsing);
+		session->browsing = NULL;
+	}
+
 	return FALSE;
 }
 
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 3/3] hcidump: Fix parsing of SetBrowsedPlayer
From: Luiz Augusto von Dentz @ 2013-01-31 15:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359646436-8113-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 tools/parser/avrcp.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/parser/avrcp.c b/tools/parser/avrcp.c
index 1029287..4d88b41 100644
--- a/tools/parser/avrcp.c
+++ b/tools/parser/avrcp.c
@@ -1294,7 +1294,7 @@ static void avrcp_set_browsed_player_dump(int level, struct frame *frm,
 	}
 
 	id = get_u16(frm);
-	printf("PlayerID: 0x%04x (%u)", id, id);
+	printf("PlayerID: 0x%04x (%u)\n", id, id);
 	return;
 
 response:
@@ -1313,12 +1313,12 @@ response:
 	p_indent(level, frm);
 
 	uids = get_u16(frm);
-	printf("UIDCounter: 0x%04x (%u)", uids, uids);
+	printf("UIDCounter: 0x%04x (%u)\n", uids, uids);
 
 	p_indent(level, frm);
 
 	items = get_u32(frm);
-	printf("Number of Items: 0x%04x (%u)", items, items);
+	printf("Number of Items: 0x%04x (%u)\n", items, items);
 
 	p_indent(level, frm);
 
@@ -1328,7 +1328,7 @@ response:
 	p_indent(level, frm);
 
 	folders = get_u8(frm);
-	printf("Folder Depth: 0x%02x (%u)", folders, folders);
+	printf("Folder Depth: 0x%02x (%u)\n", folders, folders);
 
 	for (; folders > 0; folders--) {
 		uint16_t len;
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 2/2] tools: Fix mpris-player creating busname starting with digit
From: Luiz Augusto von Dentz @ 2013-01-31 15:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359646436-8113-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

D-Bus does not allow a bus name starting with digits after . so the code
now prefix with bt_ if the device name starts with a digit.
---
 tools/mpris-player.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/mpris-player.c b/tools/mpris-player.c
index b82b5df..4dbde90 100644
--- a/tools/mpris-player.c
+++ b/tools/mpris-player.c
@@ -1381,7 +1381,11 @@ static const GDBusPropertyTable mpris_properties[] = {
 
 static char *mpris_busname(char *name)
 {
-	return g_strconcat(MPRIS_BUS_NAME,
+	if (g_ascii_isdigit(name[0]))
+		return g_strconcat(MPRIS_BUS_NAME, "bt_",
+				g_strcanon(name, A_Z a_z _0_9, '_'), NULL);
+	else
+		return g_strconcat(MPRIS_BUS_NAME,
 				g_strcanon(name, A_Z a_z _0_9, '_'), NULL);
 }
 
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 2/3] hcidump: Fix parsing of GetCurrentPlayerApplicationSettingValue
From: Luiz Augusto von Dentz @ 2013-01-31 15:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359646436-8113-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 tools/parser/avrcp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/parser/avrcp.c b/tools/parser/avrcp.c
index 1d4a319..1029287 100644
--- a/tools/parser/avrcp.c
+++ b/tools/parser/avrcp.c
@@ -618,7 +618,7 @@ static void avrcp_get_current_player_value_dump(int level, struct frame *frm,
 
 	p_indent(level, frm);
 
-	if (len < 2) {
+	if (len < 1) {
 		printf("PDU Malformed\n");
 		raw_dump(level, frm);
 		return;
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 2/2 v2] attrib: Don't attempt to unregister event id 0
From: Luiz Augusto von Dentz @ 2013-01-31 15:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359646436-8113-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Id 0 is considered invalid so the code should not even try to lookup for
it in the event list instead print a warning and return FALSE
immediatelly.
---
 attrib/gattrib.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index 58f19d0..01c19f9 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -719,6 +719,11 @@ gboolean g_attrib_unregister(GAttrib *attrib, guint id)
 	struct event *evt;
 	GSList *l;
 
+	if (id == 0) {
+		warn("%s: invalid id", __FUNCTION__);
+		return FALSE;
+	}
+
 	l = g_slist_find_custom(attrib->events, GUINT_TO_POINTER(id),
 							event_cmp_by_id);
 	if (l == NULL)
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 1/2] tools: Use device Alias instead of Name
From: Luiz Augusto von Dentz @ 2013-01-31 15:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359646436-8113-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

User may have set a different Name using Alias, Alias should always
be set.
---
 tools/mpris-player.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/mpris-player.c b/tools/mpris-player.c
index aafa142..b82b5df 100644
--- a/tools/mpris-player.c
+++ b/tools/mpris-player.c
@@ -1422,7 +1422,7 @@ static void register_player(GDBusProxy *proxy)
 	if (device == NULL)
 		return;
 
-	if (!g_dbus_proxy_get_property(device, "Name", &iter))
+	if (!g_dbus_proxy_get_property(device, "Alias", &iter))
 		return;
 
 	dbus_message_iter_get_basic(&iter, &name);
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 1/2 v2] thermometer: Fix crash while unregistering adapter
From: Luiz Augusto von Dentz @ 2013-01-31 15:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1359646436-8113-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Invalid read of size 8
   at 0x448200: g_attrib_unregister (gattrib.c:722)
   by 0x440476: destroy_thermometer (thermometer.c:167)
   by 0x40D849: remove_interface (object.c:656)
   by 0x40DAA9: g_dbus_unregister_interface (object.c:1413)
   by 0x3DF7A63C9C: g_slist_foreach (gslist.c:894)
   by 0x469656: device_remove (device.c:2200)
   by 0x45CDC1: adapter_remove (adapter.c:3884)
   by 0x45F146: index_removed (adapter.c:5442)
   by 0x46BC17: received_data (mgmt.c:252)
   by 0x3DF7A47A74: g_main_context_dispatch (gmain.c:2715)
   by 0x3DF7A47DA7: g_main_context_iterate.isra.24 (gmain.c:3290)
   by 0x3DF7A481A1: g_main_loop_run (gmain.c:3484)
 Address 0x40 is not stack'd, malloc'd or (recently) free'd
---
v2: Print a warning if invalid id is passed to g_attrib_unregister

 profiles/thermometer/thermometer.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 0cf14e6..1b299e7 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -164,12 +164,12 @@ static void destroy_thermometer(gpointer user_data)
 	if (t->attioid > 0)
 		btd_device_remove_attio_callback(t->dev, t->attioid);
 
-	g_attrib_unregister(t->attrib, t->attio_measurement_id);
-	g_attrib_unregister(t->attrib, t->attio_intermediate_id);
-	g_attrib_unregister(t->attrib, t->attio_interval_id);
-
-	if (t->attrib != NULL)
+	if (t->attrib != NULL) {
+		g_attrib_unregister(t->attrib, t->attio_measurement_id);
+		g_attrib_unregister(t->attrib, t->attio_intermediate_id);
+		g_attrib_unregister(t->attrib, t->attio_interval_id);
 		g_attrib_unref(t->attrib);
+	}
 
 	btd_device_unref(t->dev);
 	g_free(t->svc_range);
-- 
1.8.1


^ permalink raw reply related

* [PATCH BlueZ 1/3] hcidump: Distinct Control and Browsing AVCTP channels
From: Luiz Augusto von Dentz @ 2013-01-31 15:33 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This prints the respective channel of the trafic
---
 tools/parser/avctp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/parser/avctp.c b/tools/parser/avctp.c
index 60a5f69..58b181d 100644
--- a/tools/parser/avctp.c
+++ b/tools/parser/avctp.c
@@ -60,7 +60,8 @@ void avctp_dump(int level, struct frame *frm, uint16_t psm)
 	hdr = get_u8(frm);
 	pid = get_u16(frm);
 
-	printf("AVCTP: %s %s: pt 0x%02x transaction %d pid 0x%04x \n",
+	printf("AVCTP %s: %s %s: pt 0x%02x transaction %d pid 0x%04x\n",
+				psm == 23 ? "Control" : "Browsing",
 				hdr & 0x02 ? "Response" : "Command",
 				pt2str(hdr), hdr & 0x0c, hdr >> 4, pid);
 
-- 
1.8.1


^ permalink raw reply related

* Re: [PATCH] avctp: Move state change callbacks
From: Luiz Augusto von Dentz @ 2013-01-31 14:36 UTC (permalink / raw)
  To: Alexandros Antonopoulos; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1359640112-10920-1-git-send-email-alexandros.antonopoulos@oss.bmw-carit.de>

Hi Alex,

On Thu, Jan 31, 2013 at 7:48 AM, Alexandros Antonopoulos
<alexandros.antonopoulos@oss.bmw-carit.de> wrote:
> In avctp_set_change the callbacks are happening before the switch.
> The callbacks can change the state so they should happen at the end
> of the function and not before the switch.
> For example when the state is AVCTP_STATE_CONNECTED the
> avrcp.c:state_changed callback creates a browsing channel which in
> turn is destroyed immediately a few lines below in the
> AVCTP_STATE_CONNECTED case.
>
> ---
>  profiles/audio/avctp.c | 15 ++++++++-------
>  1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
> index 41e2f46..2515505 100644
> --- a/profiles/audio/avctp.c
> +++ b/profiles/audio/avctp.c
> @@ -473,13 +473,6 @@ static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
>                 return;
>         }
>
> -       session->state = new_state;
> -
> -       for (l = callbacks; l != NULL; l = l->next) {
> -               struct avctp_state_callback *cb = l->data;
> -               cb->cb(dev, old_state, new_state, cb->user_data);
> -       }
> -
>         switch (new_state) {
>         case AVCTP_STATE_DISCONNECTED:
>                 DBG("AVCTP Disconnected");
> @@ -505,6 +498,14 @@ static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
>                 error("Invalid AVCTP state %d", new_state);
>                 return;
>         }
> +
> +       session->state = new_state;
> +
> +       for (l = callbacks; l != NULL; l = l->next) {
> +               struct avctp_state_callback *cb = l->data;
> +               cb->cb(dev, old_state, new_state, cb->user_data);
> +       }
> +
>  }
>
>  static int avctp_send(struct avctp_channel *control, uint8_t transaction,
> --
> 1.8.1.2

I would like to avoid calling the callback after the session is
destroyed, in fact I will revert
53d3fc3fad5152167458625ad2acf19070cdf26a and move the check to
session_browsing_cb that should fix the problem for good.


--
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH] avctp: Move state change callbacks
From: Alexandros Antonopoulos @ 2013-01-31 13:48 UTC (permalink / raw)
  To: linux-bluetooth

In avctp_set_change the callbacks are happening before the switch.
The callbacks can change the state so they should happen at the end
of the function and not before the switch.
For example when the state is AVCTP_STATE_CONNECTED the
avrcp.c:state_changed callback creates a browsing channel which in
turn is destroyed immediately a few lines below in the
AVCTP_STATE_CONNECTED case.

---
 profiles/audio/avctp.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index 41e2f46..2515505 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
@@ -473,13 +473,6 @@ static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
 		return;
 	}
 
-	session->state = new_state;
-
-	for (l = callbacks; l != NULL; l = l->next) {
-		struct avctp_state_callback *cb = l->data;
-		cb->cb(dev, old_state, new_state, cb->user_data);
-	}
-
 	switch (new_state) {
 	case AVCTP_STATE_DISCONNECTED:
 		DBG("AVCTP Disconnected");
@@ -505,6 +498,14 @@ static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
 		error("Invalid AVCTP state %d", new_state);
 		return;
 	}
+
+	session->state = new_state;
+
+	for (l = callbacks; l != NULL; l = l->next) {
+		struct avctp_state_callback *cb = l->data;
+		cb->cb(dev, old_state, new_state, cb->user_data);
+	}
+
 }
 
 static int avctp_send(struct avctp_channel *control, uint8_t transaction,
-- 
1.8.1.2


^ permalink raw reply related

* Re: Cannot get bluetooth audio (A2DP or SCO) with an LG tone+ HBS-730 headset
From: Ben Klopfenstein @ 2013-01-31  7:24 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <CAJzW9NCoE7xO=dMJEYkAVKk8QtQaopNkZb2JC51PbL3+-asPUQ@mail.gmail.com>

> My suspicion is that this headset, which supports some unusual
> features like the APT-X proprietary codec and multiple simultaneous
> A2DP connections from different devices may be sending some unexpected
> response. I'm not sure where to look next for this. Any suggestions
> what might be going on, or how to troubleshoot this further?

I took my own suggestion and determined how to put bluetoothd in debug
mode. The output is pretty interesting, but I still don't know enough
to really draw any serious conclusions from where it is having issues.
here is that log:

bluetoothd[9664]: plugins/mgmtops.c:mgmt_cod_changed() index 0
bluetoothd[9664]: audio/headset.c:headset_set_state() State changed
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC: HEADSET_STATE_DISCONNECTED
-> HEADSET_STATE_CONNECTING
bluetoothd[9664]: audio/media.c:headset_state_changed()
bluetoothd[9664]: audio/media.c:media_endpoint_async_call() Calling
SetConfiguration: name = :1.55 path = /MediaEndpoint/HFPAG
bluetoothd[9664]: plugins/mgmtops.c:mgmt_event() cond 1
bluetoothd[9664]: plugins/mgmtops.c:mgmt_event() Received 30 bytes
from management socket
bluetoothd[9664]: plugins/mgmtops.c:mgmt_device_connected() hci0
device 00:18:6B:15:AC:DC connected eir_len 11
bluetoothd[9664]: src/adapter.c:adapter_get_device() 00:18:6B:15:AC:DC
bluetoothd[9664]: audio/headset.c:headset_set_channel() Discovered
Handsfree service on channel 3
bluetoothd[9664]: audio/headset.c:rfcomm_connect()
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC: Connecting to
00:18:6B:15:AC:DC channel 3
bluetoothd[9664]: audio/headset.c:headset_connect_cb()
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC: Connected to
00:18:6B:15:AC:DC
bluetoothd[9664]: audio/headset.c:handle_event() Received AT+BRSF=155
bluetoothd[9664]: audio/headset.c:print_hf_features() HFP HF features:
"EC and/or NR function" "Call waiting and 3-way calling" "Voice
recognition activation" "Remote volume control"
bluetoothd[9664]: audio/headset.c:handle_event() Received AT+CIND=?
bluetoothd[9664]: audio/headset.c:handle_event() Received AT+CIND?
bluetoothd[9664]: audio/headset.c:handle_event() Received AT+CMER=3, 0, 0, 1
bluetoothd[9664]: audio/headset.c:event_reporting() Event reporting
(CMER): mode=3, ind=1
bluetoothd[9664]: audio/headset.c:hfp_slc_complete() HFP Service Level
Connection established
bluetoothd[9664]: audio/telephony.c:telephony_device_connected()
telephony-dummy: device 0x7fd3ac51a2d0 connected
bluetoothd[9664]: audio/headset.c:headset_set_state() State changed
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC: HEADSET_STATE_CONNECTING
-> HEADSET_STATE_CONNECTED
bluetoothd[9664]: audio/media.c:headset_state_changed()
bluetoothd[9664]: audio/headset.c:handle_event() Received AT+VGS=12
bluetoothd[9664]: audio/avdtp.c:avdtp_confirm_cb() AVDTP: incoming
connect from 00:18:6B:15:AC:DC
bluetoothd[9664]: audio/sink.c:sink_set_state() State changed
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC: SINK_STATE_DISCONNECTED ->
SINK_STATE_CONNECTING
bluetoothd[9664]: audio/headset.c:handle_event() Received AT+BTRH?
bluetoothd[9664]: audio/avdtp.c:avdtp_connect_cb() AVDTP: connected
signaling channel to 00:18:6B:15:AC:DC
bluetoothd[9664]: audio/avdtp.c:avdtp_connect_cb() AVDTP imtu=672, omtu=895
bluetoothd[9664]: audio/headset.c:handle_event() Received
AT+XAPL=0000-0000-0100,7
bluetoothd[9664]: audio/headset.c:apple_command() Got Apple command:
AT+XAPL=0000-0000-0100,7
bluetoothd[9664]: audio/headset.c:handle_event() Received
AT+IPHONEACCEV=2,1,7,2,0
bluetoothd[9664]: audio/headset.c:apple_command() Got Apple command:
AT+IPHONEACCEV=2,1,7,2,0
bluetoothd[9664]: audio/headset.c:handle_event() Received AT+BIA=0,0,0,1,1,1,0
bluetoothd[9664]: Badly formated or unrecognized command: AT+BIA=0,0,0,1,1,1,0
bluetoothd[9664]: audio/avdtp.c:avdtp_ref() 0x7fd3ac52ad00: ref=2
bluetoothd[9664]: audio/avdtp.c:session_cb()
bluetoothd[9664]: audio/avdtp.c:avdtp_parse_resp() DISCOVER request succeeded
bluetoothd[9664]: audio/avdtp.c:avdtp_discover_resp() seid 5 type 1
media 0 in use 0
bluetoothd[9664]: audio/avdtp.c:avdtp_discover_resp() seid 3 type 1
media 0 in use 0
bluetoothd[9664]: audio/avdtp.c:avdtp_discover_resp() seid 2 type 1
media 0 in use 0
bluetoothd[9664]: audio/avdtp.c:avdtp_discover_resp() seid 1 type 1
media 0 in use 0
bluetoothd[9664]: audio/avdtp.c:session_cb()
bluetoothd[9664]: audio/avdtp.c:avdtp_parse_resp() GET_CAPABILITIES
request succeeded
bluetoothd[9664]: audio/avdtp.c:avdtp_get_capabilities_resp() seid 5
type 1 media 0
bluetoothd[9664]: audio/avdtp.c:session_cb()
bluetoothd[9664]: audio/avdtp.c:avdtp_parse_resp() GET_CAPABILITIES
request succeeded
bluetoothd[9664]: audio/avdtp.c:avdtp_get_capabilities_resp() seid 3
type 1 media 0
bluetoothd[9664]: audio/avdtp.c:session_cb()
bluetoothd[9664]: audio/avdtp.c:avdtp_parse_resp() GET_CAPABILITIES
request succeeded
bluetoothd[9664]: audio/avdtp.c:avdtp_get_capabilities_resp() seid 2
type 1 media 0
bluetoothd[9664]: audio/avdtp.c:session_cb()
bluetoothd[9664]: audio/avdtp.c:avdtp_parse_resp() GET_CAPABILITIES
request succeeded
bluetoothd[9664]: audio/avdtp.c:avdtp_get_capabilities_resp() seid 1
type 1 media 0
bluetoothd[9664]: audio/sink.c:discovery_complete() Discovery complete
bluetoothd[9664]: audio/avdtp.c:avdtp_ref() 0x7fd3ac52ad00: ref=3
bluetoothd[9664]: audio/a2dp.c:setup_ref() 0x7fd3ac529a60: ref=1
bluetoothd[9664]: audio/a2dp.c:a2dp_config() a2dp_config: selected SEP
0x7fd3ac5115a0
bluetoothd[9664]: audio/a2dp.c:setup_ref() 0x7fd3ac529a60: ref=2
bluetoothd[9664]: audio/avdtp.c:avdtp_set_configuration()
0x7fd3ac52ad00: int_seid=1, acp_seid=1
bluetoothd[9664]: audio/a2dp.c:setup_unref() 0x7fd3ac529a60: ref=1
bluetoothd[9664]: audio/avdtp.c:session_cb()
bluetoothd[9664]: audio/avdtp.c:avdtp_parse_resp() SET_CONFIGURATION
request succeeded
bluetoothd[9664]: audio/a2dp.c:setconf_cfm() Source 0x7fd3ac5115a0:
Set_Configuration_Cfm
bluetoothd[9664]: audio/avdtp.c:avdtp_sep_set_state() stream state
changed: IDLE -> CONFIGURED
bluetoothd[9664]: audio/avdtp.c:session_cb()
bluetoothd[9664]: audio/avdtp.c:avdtp_parse_resp() OPEN request succeeded
bluetoothd[9664]: audio/avdtp.c:avdtp_connect_cb() AVDTP: connected
transport channel to 00:18:6B:15:AC:DC
bluetoothd[9664]: audio/avdtp.c:handle_transport_connect() Flushable
packets enabled
bluetoothd[9664]: audio/avdtp.c:handle_transport_connect() sk 27, omtu
895, send buffer size 106496
bluetoothd[9664]: audio/a2dp.c:open_cfm() Source 0x7fd3ac5115a0: Open_Cfm
bluetoothd[9664]: audio/sink.c:stream_setup_complete() Stream
successfully created
bluetoothd[9664]: audio/a2dp.c:setup_unref() 0x7fd3ac529a60: ref=0
bluetoothd[9664]: audio/a2dp.c:setup_free() 0x7fd3ac529a60
bluetoothd[9664]: audio/avdtp.c:avdtp_unref() 0x7fd3ac52ad00: ref=2
bluetoothd[9664]: audio/avdtp.c:avdtp_sep_set_state() stream state
changed: CONFIGURED -> OPEN
bluetoothd[9664]: audio/sink.c:sink_set_state() State changed
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC: SINK_STATE_CONNECTING ->
SINK_STATE_CONNECTED
bluetoothd[9664]: audio/unix.c:server_cb() Accepted new client
connection on unix socket (fd=30)
bluetoothd[9664]: audio/transport.c:media_transport_acquire()
Transport /org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC/fd0: read lock
acquired
bluetoothd[9664]: audio/transport.c:media_transport_acquire()
Transport /org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC/fd0: write lock
acquired
bluetoothd[9664]: audio/transport.c:media_owner_create() Owner
created: sender=:1.55 accesstype=rw
bluetoothd[9664]: audio/headset.c:headset_set_state() State changed
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC: HEADSET_STATE_CONNECTED ->
HEADSET_STATE_PLAY_IN_PROGRESS
bluetoothd[9664]: audio/media.c:headset_state_changed()
bluetoothd[9664]: audio/transport.c:media_request_create() Request
created: method=Acquire id=1
bluetoothd[9664]: audio/transport.c:media_owner_add() Owner :1.55
Request Acquire
bluetoothd[9664]: audio/transport.c:media_transport_add() Transport
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC/fd0 Owner :1.55
bluetoothd[9664]: Operation not supported (95)
bluetoothd[9664]: audio/transport.c:media_transport_remove() Transport
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC/fd0 Owner :1.55
bluetoothd[9664]: audio/transport.c:media_transport_release()
Transport /org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC/fd0: read lock
released
bluetoothd[9664]: audio/transport.c:media_transport_release()
Transport /org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC/fd0: write lock
released
bluetoothd[9664]: audio/transport.c:media_request_reply() Request
Acquire Reply Input/output error
bluetoothd[9664]: audio/transport.c:media_owner_free() Owner :1.55
bluetoothd[9664]: audio/transport.c:media_owner_remove() Owner :1.55
Request Acquire
bluetoothd[9664]: audio/headset.c:headset_set_state() State changed
/org/bluez/9664/hci0/dev_00_18_6B_15_AC_DC:
HEADSET_STATE_PLAY_IN_PROGRESS -> HEADSET_STATE_CONNECTED
bluetoothd[9664]: audio/media.c:headset_state_changed()
bluetoothd[9664]: audio/unix.c:client_cb() Unix client disconnected (fd=30)
bluetoothd[9664]: audio/unix.c:client_free() client_free(0x7fd3ac529a60)
bluetoothd[9664]: audio/avctp.c:avctp_confirm_cb() AVCTP: incoming
connect from 00:18:6B:15:AC:DC
bluetoothd[9664]: audio/avctp.c:avctp_set_state() AVCTP Connecting
bluetoothd[9664]: audio/avctp.c:avctp_connect_cb() AVCTP: connected to
00:18:6B:15:AC:DC
bluetoothd[9664]: audio/avctp.c:init_uinput() AVRCP: uinput
initialized for 00:18:6B:15:AC:DC
bluetoothd[9664]: audio/avctp.c:avctp_set_state() AVCTP Connected
bluetoothd[9664]: audio/avctp.c:session_cb() Got 14 bytes of data for
AVCTP session 0x7fd3ac52b320
bluetoothd[9664]: audio/avctp.c:session_cb() AVCTP transaction 1,
packet type 0, C/R 0, IPID 0, PID 0x110E
bluetoothd[9664]: audio/avctp.c:session_cb() AV/C command 0x1,
subunit_type 0x09, subunit_id 0x0, opcode 0x00, 8 operands
bluetoothd[9664]: audio/avctp.c:session_cb() handler not found for 0x00
bluetoothd[9664]: audio/avrcp.c:avrcp_handle_vendor_reject() rejecting
AVRCP PDU 0x10, company 0x001958 len 0x0100
bluetoothd[9664]: audio/avctp.c:session_cb() Got 18 bytes of data for
AVCTP session 0x7fd3ac52b320
bluetoothd[9664]: audio/avctp.c:session_cb() AVCTP transaction 2,
packet type 0, C/R 0, IPID 0, PID 0x110E
bluetoothd[9664]: audio/avctp.c:session_cb() AV/C command 0x3,
subunit_type 0x09, subunit_id 0x0, opcode 0x00, 12 operands
bluetoothd[9664]: audio/avctp.c:session_cb() handler not found for 0x00
bluetoothd[9664]: audio/avrcp.c:avrcp_handle_vendor_reject() rejecting
AVRCP PDU 0x31, company 0x001958 len 0x0100

Thanks!

Ben

^ permalink raw reply

* Cannot get bluetooth audio (A2DP or SCO) with an LG tone+ HBS-730 headset
From: Ben Klopfenstein @ 2013-01-31  4:51 UTC (permalink / raw)
  To: linux-bluetooth

Hello,

I have been trying for  while now to get a new headset I purchased to
work with bluez and pulseaudio. I can get other A2DP devices to work,
so I know my setup is sane, and I have this issue with multiple
laptops running the most recent bluez/kernel.

When attempting to connect to the headset, I get the following in the logs:

Jan 30 20:37:36 ben-HP-Pavilion-dm4-Notebook-PC bluetoothd[983]:
Endpoint registered: sender=:1.55 path=/MediaEndpoint/HFPAG
Jan 30 20:37:36 ben-HP-Pavilion-dm4-Notebook-PC bluetoothd[983]:
Endpoint registered: sender=:1.55 path=/MediaEndpoint/HFPHS
Jan 30 20:37:36 ben-HP-Pavilion-dm4-Notebook-PC bluetoothd[983]:
Endpoint registered: sender=:1.55 path=/MediaEndpoint/A2DPSource
Jan 30 20:37:36 ben-HP-Pavilion-dm4-Notebook-PC bluetoothd[983]:
Endpoint registered: sender=:1.55 path=/MediaEndpoint/A2DPSink
Jan 30 20:37:53 ben-HP-Pavilion-dm4-Notebook-PC ntpdate[3446]: step
time server 91.189.94.4 offset 11.616705 sec
Jan 30 20:37:53 ben-HP-Pavilion-dm4-Notebook-PC kernel: [  187.053807]
userif-2: sent link up event.<7>[  196.133807] /dev/vmmon[0]:
HostIFReadUptimeWork: detected settimeofday: fixed uptimeBase old
18445384470424071485 new 18445384470412454752 attempts 1
Jan 30 21:12:50 ben-HP-Pavilion-dm4-Notebook-PC bluetoothd[983]:
Unable to get service record: Host is down (112)
Jan 30 21:13:10 ben-HP-Pavilion-dm4-Notebook-PC bluetoothd[983]: Badly
formated or unrecognized command: AT+BIA=0,0,0,1,1,1,0
Jan 30 21:13:12 ben-HP-Pavilion-dm4-Notebook-PC bluetoothd[983]:
Operation not supported (95)
Jan 30 21:13:12 ben-HP-Pavilion-dm4-Notebook-PC pulseaudio[3486]:
[pulseaudio] bluetooth-util.c: Failed to acquire transport fd:
Input/output error
Jan 30 21:13:12 ben-HP-Pavilion-dm4-Notebook-PC pulseaudio[3486]:
[pulseaudio] module.c: Failed to load module "module-bluetooth-device"
(argument: "address="00:18:6B:15:AC:DC"
path="/org/bluez/983/hci0/dev_00_18_6B_15_AC_DC""): initialization
failed.
Jan 30 21:13:12 ben-HP-Pavilion-dm4-Notebook-PC kernel: [ 2311.875574]
input: 00:18:6B:15:AC:DC as /devices/virtual/input/input12


My suspicion is that this headset, which supports some unusual
features like the APT-X proprietary codec and multiple simultaneous
A2DP connections from different devices may be sending some unexpected
response. I'm not sure where to look next for this. Any suggestions
what might be going on, or how to troubleshoot this further?

^ permalink raw reply

* Re: [PATCH 5/5] Bluetooth: Reduce critical section in sco_conn_ready
From: Gustavo Padovan @ 2013-01-30 19:31 UTC (permalink / raw)
  To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1359500396-8184-5-git-send-email-andre.guedes@openbossa.org>

Hi Andre,

* Andre Guedes <andre.guedes@openbossa.org> [2013-01-29 19:59:56 -0300]:

> This patch reduces the critical section protected by sco_conn_lock in
> sco_conn_ready function. The lock is acquired only when it is really
> needed.
> 
> This patch fixes the following lockdep warning which is generated
> when the host terminates a SCO connection.
> 
> Today, this warning is a false positive. There is no way those
> two threads reported by lockdep are running at the same time since
> hdev->workqueue (where rx_work is queued) is single-thread. However,
> if somehow this behavior is changed in future, we will have a
> potential deadlock.
> 
> ======================================================
> [ INFO: possible circular locking dependency detected ]
> 3.8.0-rc1+ #7 Not tainted
> -------------------------------------------------------
> kworker/u:1H/1018 is trying to acquire lock:
>  (&(&conn->lock)->rlock){+.+...}, at: [<ffffffffa0033ba6>] sco_chan_del+0x66/0x190 [bluetooth]
> 
> but task is already holding lock:
>  (slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}, at: [<ffffffffa0033d5a>] sco_conn_del+0x8a/0xe0 [bluetooth]
> 
> which lock already depends on the new lock.
> 
> the existing dependency chain (in reverse order) is:
> 
> -> #1 (slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}:
>        [<ffffffff81083011>] lock_acquire+0xb1/0xe0
>        [<ffffffff813efd01>] _raw_spin_lock+0x41/0x80
>        [<ffffffffa003436e>] sco_connect_cfm+0xbe/0x350 [bluetooth]
>        [<ffffffffa0015d6c>] hci_event_packet+0xd3c/0x29b0 [bluetooth]
>        [<ffffffffa0004583>] hci_rx_work+0x133/0x870 [bluetooth]
>        [<ffffffff8104d65f>] process_one_work+0x2bf/0x4f0
>        [<ffffffff81050022>] worker_thread+0x2b2/0x3e0
>        [<ffffffff81056021>] kthread+0xd1/0xe0
>        [<ffffffff813f14bc>] ret_from_fork+0x7c/0xb0
> 
> -> #0 (&(&conn->lock)->rlock){+.+...}:
>        [<ffffffff81082215>] __lock_acquire+0x1465/0x1c70
>        [<ffffffff81083011>] lock_acquire+0xb1/0xe0
>        [<ffffffff813efd01>] _raw_spin_lock+0x41/0x80
>        [<ffffffffa0033ba6>] sco_chan_del+0x66/0x190 [bluetooth]
>        [<ffffffffa0033d6d>] sco_conn_del+0x9d/0xe0 [bluetooth]
>        [<ffffffffa0034653>] sco_disconn_cfm+0x53/0x60 [bluetooth]
>        [<ffffffffa000fef3>] hci_disconn_complete_evt.isra.54+0x363/0x3c0 [bluetooth]
>        [<ffffffffa00150f7>] hci_event_packet+0xc7/0x29b0 [bluetooth]
>        [<ffffffffa0004583>] hci_rx_work+0x133/0x870 [bluetooth]
>        [<ffffffff8104d65f>] process_one_work+0x2bf/0x4f0
>        [<ffffffff81050022>] worker_thread+0x2b2/0x3e0
>        [<ffffffff81056021>] kthread+0xd1/0xe0
>        [<ffffffff813f14bc>] ret_from_fork+0x7c/0xb0
> 
> other info that might help us debug this:
> 
>  Possible unsafe locking scenario:
> 
>        CPU0                    CPU1
>        ----                    ----
>   lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
>                                lock(&(&conn->lock)->rlock);
>                                lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
>   lock(&(&conn->lock)->rlock);
> 
>  *** DEADLOCK ***
> 
> 4 locks held by kworker/u:1H/1018:
>  #0:  (hdev->name#2){.+.+.+}, at: [<ffffffff8104d5f8>] process_one_work+0x258/0x4f0
>  #1:  ((&hdev->rx_work)){+.+.+.}, at: [<ffffffff8104d5f8>] process_one_work+0x258/0x4f0
>  #2:  (&hdev->lock){+.+.+.}, at: [<ffffffffa000fbe9>] hci_disconn_complete_evt.isra.54+0x59/0x3c0 [bluetooth]
>  #3:  (slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}, at: [<ffffffffa0033d5a>] sco_conn_del+0x8a/0xe0 [bluetooth]
> 
> stack backtrace:
> Pid: 1018, comm: kworker/u:1H Not tainted 3.8.0-rc1+ #7
> Call Trace:
>  [<ffffffff813e92f9>] print_circular_bug+0x1fb/0x20c
>  [<ffffffff81082215>] __lock_acquire+0x1465/0x1c70
>  [<ffffffff81083011>] lock_acquire+0xb1/0xe0
>  [<ffffffffa0033ba6>] ? sco_chan_del+0x66/0x190 [bluetooth]
>  [<ffffffff813efd01>] _raw_spin_lock+0x41/0x80
>  [<ffffffffa0033ba6>] ? sco_chan_del+0x66/0x190 [bluetooth]
>  [<ffffffffa0033ba6>] sco_chan_del+0x66/0x190 [bluetooth]
>  [<ffffffffa0033d6d>] sco_conn_del+0x9d/0xe0 [bluetooth]
>  [<ffffffffa0034653>] sco_disconn_cfm+0x53/0x60 [bluetooth]
>  [<ffffffffa000fef3>] hci_disconn_complete_evt.isra.54+0x363/0x3c0 [bluetooth]
>  [<ffffffffa000fbd0>] ? hci_disconn_complete_evt.isra.54+0x40/0x3c0 [bluetooth]
>  [<ffffffffa00150f7>] hci_event_packet+0xc7/0x29b0 [bluetooth]
>  [<ffffffff81202e90>] ? __dynamic_pr_debug+0x80/0x90
>  [<ffffffff8133ff7d>] ? kfree_skb+0x2d/0x40
>  [<ffffffffa0021644>] ? hci_send_to_monitor+0x1a4/0x1c0 [bluetooth]
>  [<ffffffffa0004583>] hci_rx_work+0x133/0x870 [bluetooth]
>  [<ffffffff8104d5f8>] ? process_one_work+0x258/0x4f0
>  [<ffffffff8104d65f>] process_one_work+0x2bf/0x4f0
>  [<ffffffff8104d5f8>] ? process_one_work+0x258/0x4f0
>  [<ffffffff8104fdc1>] ? worker_thread+0x51/0x3e0
>  [<ffffffffa0004450>] ? hci_tx_work+0x800/0x800 [bluetooth]
>  [<ffffffff81050022>] worker_thread+0x2b2/0x3e0
>  [<ffffffff8104fd70>] ? busy_worker_rebind_fn+0x100/0x100
>  [<ffffffff81056021>] kthread+0xd1/0xe0
>  [<ffffffff81055f50>] ? flush_kthread_worker+0xc0/0xc0
>  [<ffffffff813f14bc>] ret_from_fork+0x7c/0xb0
>  [<ffffffff81055f50>] ? flush_kthread_worker+0xc0/0xc0
> 
> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> ---
> 
> This lockdep warning has been around for a long time. I could test
> until Linux 3.4, but it seems it is older than that. However, in
> current bluetooth-next, this warning has been masked by commit
> 53502d69be49e3dd5bc95ab0f2deeaea260bd617 which introduced a bug in
> SCO socket shutdown routine.
> 
> The bug in SCO socket shutdown routine has been fixed by patch 02/05
> from this patchset.
> 
>  net/bluetooth/sco.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)

Patch has been applied to bluetooth-next. Thanks.

	Gustavo

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox