Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2 BlueZ 00/13] Fix SDP DE Type Descriptor validation issues
From: Anderson Lizardo @ 2013-02-15 14:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1360531597-3506-1-git-send-email-anderson.lizardo@openbossa.org>

Hi,

Changes since v1:
* Fix license header to match BlueZ license (GPL v2 or later)
* Rename test source file and SDP tests to account for future addition of other
  libbluetooth tests

This series adds various missing DTD validations, specially for SEQ* types. The
lack of these validations allows for a remote device to crash BlueZ due to
invalid memory access.

I also added unit tests for all affected functions. They are in a separate C
file (unit/test-lib.c), which will in future contain tests for other
libbluetooth API functions.

The only pending related fixes from my part are some missing NULL pointer
checks when accessing empty sequences. These will take some time to fix as they
affect profile code as well.

Best Regards,

Anderson Lizardo (13):
  unit: Add initial SDP library unit tests
  lib: Add SDP_IS_ALT() macro
  lib: Reuse identical code in sdp_get_{add,}_access_protos()
  lib: Cleanup coding style in sdp_get_proto_descs()
  lib: Fix missing DTD validation while accessing SDP data elements
  unit: Add tests for sdp_get_lang_attr()
  lib: Add missing DTD validation in sdp_record_print()
  lib: Validate DTDs when parsing LanguageBaseAttributeIDList
  lib: Validate DTDs when parsing BluetoothProfileDescriptorList
  lib: Add comment to BluetoothProfileDescriptorList parsing workaround
  lib: Validate DTDs when parsing VersionNumberList
  unit: Add tests for sdp_get_profile_descs()
  unit: Add tests for sdp_get_server_ver()

 .gitignore      |    1 +
 Makefile.am     |    5 +
 lib/sdp.c       |  164 +++++++++++++------
 lib/sdp.h       |    1 +
 unit/test-lib.c |  471 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 596 insertions(+), 46 deletions(-)
 create mode 100644 unit/test-lib.c

-- 
1.7.9.5


^ permalink raw reply

* Re: [PATCH v2 BlueZ 00/13] Fix SDP DE Type Descriptor validation issues
From: Anderson Lizardo @ 2013-02-15 14:51 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1360940187-5202-1-git-send-email-anderson.lizardo@openbossa.org>

Hi,

Just noticed that "From:" field in my patches got mangled due to
importing from gmane archives. Will fix ASAP and resend.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH BlueZ 1/7] AVRCP: Prefix folder name with /Filesystem
From: Johan Hedberg @ 2013-02-15 14:45 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1360936972-12952-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Fri, Feb 15, 2013, Luiz Augusto von Dentz wrote:
> This separate the scopes of the folder as documented in doc/media-api.txt
> ---
>  profiles/audio/avrcp.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

All patches in this set have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH v2 1/6] neard: Use service name and not boolean to track if registered to neard
From: Johan Hedberg @ 2013-02-15 14:33 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1360930159-25658-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Fri, Feb 15, 2013, Szymon Janc wrote:
> ---
>  plugins/neard.c | 23 ++++++++++++++---------
>  1 file changed, 14 insertions(+), 9 deletions(-)

All patches in this set have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ 7/7] AVRCP: Fix parsing of SetBrowsedPlayer response
From: Luiz Augusto von Dentz @ 2013-02-15 14:02 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1360936972-12952-1-git-send-email-luiz.dentz@gmail.com>

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

Folder depth is actually the byte 13 not 14 of the response.
---
 profiles/audio/avrcp.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 9833a3a..9be977e 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1928,29 +1928,30 @@ static gboolean avrcp_set_browsed_player_rsp(struct avctp *conn,
 	struct avrcp *session = user_data;
 	struct avrcp_player *player = session->player;
 	struct media_player *mp = player->user_data;
+	struct avrcp_browsing_header *pdu = (void *) operands;
 	uint32_t items;
 	char **folders, *path;
 	uint8_t depth, count;
 	int i;
 
-	if (operands[3] != AVRCP_STATUS_SUCCESS || operand_count < 13)
+	if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 13)
 		return FALSE;
 
-	player->uid_counter = bt_get_be16(&operands[4]);
+	player->uid_counter = bt_get_be16(&pdu->params[1]);
 
-	items = bt_get_be32(&operands[6]);
+	items = bt_get_be32(&pdu->params[3]);
 
-	depth = operands[13];
+	depth = operands[9];
 
 	folders = g_new0(char *, depth + 2);
 	folders[0] = g_strdup("/Filesystem");
 
-	for (i = 14, count = 1; count - 1 < depth; count++) {
+	for (i = 10, count = 1; count - 1 < depth; count++) {
 		char *part;
 		uint8_t len;
 
-		len = operands[i++];
-		part = g_memdup(&operands[i], len);
+		len = pdu->params[i++];
+		part = g_memdup(&pdu->params[i], len);
 		i += len;
 		folders[count] = part;
 	}
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH BlueZ 6/7] AVRCP: Add support for GetItemAttributes
From: Luiz Augusto von Dentz @ 2013-02-15 14:02 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1360936972-12952-1-git-send-email-luiz.dentz@gmail.com>

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

GetItemAttributes should be used instead of GetElementAttributes if
browsing is supported.
---
 profiles/audio/avrcp.c | 112 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 83 insertions(+), 29 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 3b9aad6..9833a3a 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -100,6 +100,7 @@
 #define AVRCP_ABORT_CONTINUING		0x41
 #define AVRCP_SET_ABSOLUTE_VOLUME	0x50
 #define AVRCP_SET_BROWSED_PLAYER	0x70
+#define AVRCP_GET_ITEM_ATTRIBUTES	0x73
 #define AVRCP_GET_FOLDER_ITEMS		0x71
 #define AVRCP_GENERAL_REJECT		0xA0
 
@@ -1788,42 +1789,23 @@ static void avrcp_list_player_attributes(struct avrcp *session)
 					session);
 }
 
-static gboolean avrcp_get_attributes_rsp(struct avctp *conn,
-					uint8_t code, uint8_t subunit,
-					uint8_t *operands, size_t operand_count,
-					void *user_data)
+static void avrcp_parse_attribute_list(struct avrcp_player *player,
+					uint8_t *operands, uint8_t count)
 {
-	struct avrcp *session = user_data;
-	struct avrcp_player *player = session->player;
 	struct media_player *mp = player->user_data;
-	struct avrcp_header *pdu = (void *) operands;
-	uint8_t count;
 	int i;
 
-	if (code == AVC_CTYPE_REJECTED)
-		return FALSE;
-
-	count = pdu->params[0];
-
-	if (ntohs(pdu->params_len) - 1 < count * 8) {
-		error("Invalid parameters");
-		return FALSE;
-	}
-
-	for (i = 1; count > 0; count--) {
+	for (i = 0; count > 0; count--) {
 		uint32_t id;
 		uint16_t charset, len;
 
-		memcpy(&id, &pdu->params[i], sizeof(uint32_t));
-		id = ntohl(id);
+		id = bt_get_be32(&operands[i]);
 		i += sizeof(uint32_t);
 
-		memcpy(&charset, &pdu->params[i], sizeof(uint16_t));
-		charset = ntohs(charset);
+		charset = bt_get_be16(&operands[i]);
 		i += sizeof(uint16_t);
 
-		memcpy(&len, &pdu->params[i], sizeof(uint16_t));
-		len = ntohs(len);
+		len = bt_get_be16(&operands[i]);
 		i += sizeof(uint16_t);
 
 		if (charset == 106) {
@@ -1832,11 +1814,35 @@ static gboolean avrcp_get_attributes_rsp(struct avctp *conn,
 			if (key != NULL)
 				media_player_set_metadata(mp,
 							metadata_to_str(id),
-							&pdu->params[i], len);
+							&operands[i], len);
 		}
 
 		i += len;
 	}
+}
+
+static gboolean avrcp_get_element_attributes_rsp(struct avctp *conn,
+						uint8_t code, uint8_t subunit,
+						uint8_t *operands,
+						size_t operand_count,
+						void *user_data)
+{
+	struct avrcp *session = user_data;
+	struct avrcp_player *player = session->player;
+	struct avrcp_header *pdu = (void *) operands;
+	uint8_t count;
+
+	if (code == AVC_CTYPE_REJECTED)
+		return FALSE;
+
+	count = pdu->params[0];
+
+	if (ntohs(pdu->params_len) - 1 < count * 8) {
+		error("Invalid parameters");
+		return FALSE;
+	}
+
+	avrcp_parse_attribute_list(player, &pdu->params[1], count);
 
 	return FALSE;
 }
@@ -1858,7 +1864,7 @@ static void avrcp_get_element_attributes(struct avrcp *session)
 
 	avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
 					AVC_SUBUNIT_PANEL, buf, length,
-					avrcp_get_attributes_rsp,
+					avrcp_get_element_attributes_rsp,
 					session);
 }
 
@@ -1977,6 +1983,48 @@ static void avrcp_set_browsed_player(struct avrcp *session,
 				avrcp_set_browsed_player_rsp, session);
 }
 
+static gboolean avrcp_get_item_attributes_rsp(struct avctp *conn,
+						uint8_t *operands,
+						size_t operand_count,
+						void *user_data)
+{
+	struct avrcp *session = user_data;
+	struct avrcp_player *player = session->player;
+	struct avrcp_browsing_header *pdu = (void *) operands;
+	uint8_t count;
+
+	if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 4)
+		return FALSE;
+
+	count = pdu->params[1];
+
+	if (ntohs(pdu->param_len) - 1 < count * 8) {
+		error("Invalid parameters");
+		return FALSE;
+	}
+
+	avrcp_parse_attribute_list(player, &pdu->params[2], count);
+
+	return FALSE;
+}
+
+static void avrcp_get_item_attributes(struct avrcp *session, uint64_t uid)
+{
+	uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 12];
+	struct avrcp_browsing_header *pdu = (void *) buf;
+
+	memset(buf, 0, sizeof(buf));
+
+	pdu->pdu_id = AVRCP_GET_ITEM_ATTRIBUTES;
+	pdu->params[0] = 0x03;
+	bt_put_be64(uid, &pdu->params[1]);
+	bt_put_be16(session->player->uid_counter, &pdu->params[9]);
+	pdu->param_len = htons(12);
+
+	avctp_send_browsing_req(session->conn, buf, sizeof(buf),
+				avrcp_get_item_attributes_rsp, session);
+}
+
 static void avrcp_player_parse_features(struct avrcp_player *player,
 							uint8_t *features)
 {
@@ -2122,9 +2170,15 @@ static void avrcp_status_changed(struct avrcp *session,
 static void avrcp_track_changed(struct avrcp *session,
 						struct avrcp_header *pdu)
 {
-	avrcp_get_element_attributes(session);
-	avrcp_get_play_status(session);
+	uint64_t uid;
+
+	if (session->browsing_id) {
+		uid = bt_get_be64(&pdu->params[1]);
+		avrcp_get_item_attributes(session, uid);
+	} else
+		avrcp_get_element_attributes(session);
 
+	avrcp_get_play_status(session);
 }
 
 static void avrcp_setting_changed(struct avrcp *session,
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH BlueZ 5/7] AVRCP: Create folders for /Filesystem and /NowPlaying
From: Luiz Augusto von Dentz @ 2013-02-15 14:02 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1360936972-12952-1-git-send-email-luiz.dentz@gmail.com>

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

If browsing is supported create objects representing /Filesystem and
/NowPlaying, these object implement MediaItem interface and can be
passed to ChangeFolder to change the scope.
---
 profiles/audio/avrcp.c  |   7 +-
 profiles/audio/player.c | 233 ++++++++++++++++++++++++++++++++++++++++++------
 profiles/audio/player.h |   2 +
 3 files changed, 216 insertions(+), 26 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 55887bc..3b9aad6 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1984,11 +1984,16 @@ static void avrcp_player_parse_features(struct avrcp_player *player,
 
 	player->features = g_memdup(features, 16);
 
-	if (features[7] & 0x08)
+	if (features[7] & 0x08) {
 		media_player_set_browsable(mp, true);
+		media_player_create_folder(mp, "/Filesystem");
+	}
 
 	if (features[7] & 0x10)
 		media_player_set_searchable(mp, true);
+
+	if (features[8] & 0x02)
+		media_player_create_folder(mp, "/NowPlaying");
 }
 
 static void avrcp_parse_media_player_item(struct avrcp *session,
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index 07fd457..466b44a 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -45,6 +45,7 @@
 
 #define MEDIA_PLAYER_INTERFACE "org.bluez.MediaPlayer1"
 #define MEDIA_FOLDER_INTERFACE "org.bluez.MediaFolder1"
+#define MEDIA_ITEM_INTERFACE "org.bluez.MediaItem1"
 
 struct player_callback {
 	const struct media_player_callback *cbs;
@@ -57,9 +58,17 @@ struct pending_req {
 	const char *value;
 };
 
+struct media_item {
+	struct media_player	*player;
+	char			*path;		/* Item object path */
+	char			*name;		/* Item name */
+	bool			folder;		/* Item folder flag */
+	bool			playable;	/* Item playable flag */
+};
+
 struct media_folder {
-	char			*name;		/* Folder name */
-	uint32_t		items;		/* Number of items */
+	struct media_item	*item;		/* Folder item */
+	uint32_t		number_of_items;/* Number of items */
 };
 
 struct media_player {
@@ -79,6 +88,7 @@ struct media_player {
 	guint			process_id;
 	struct player_callback	*cb;
 	GSList			*pending;
+	GSList			*folders;
 };
 
 static void append_metadata(void *key, void *value, void *user_data)
@@ -592,25 +602,27 @@ static gboolean folder_name_exists(const GDBusPropertyTable *property,
 								void *data)
 {
 	struct media_player *mp = data;
+	struct media_folder *folder = mp->folder;
 
-	if (mp->folder == NULL)
+	if (folder == NULL || folder->item == NULL)
 		return FALSE;
 
-	return mp->folder->name != NULL;
+	return folder->item->name != NULL;
 }
 
 static gboolean get_folder_name(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
 {
 	struct media_player *mp = data;
+	struct media_folder *folder = mp->folder;
 
-	if (mp->folder == NULL || mp->folder->name == NULL)
+	if (folder == NULL || folder->item == NULL)
 		return FALSE;
 
-	DBG("%s", mp->folder->name);
+	DBG("%s", folder->item->name);
 
 	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
-							&mp->folder->name);
+							&folder->item->name);
 
 	return TRUE;
 }
@@ -626,14 +638,15 @@ static gboolean get_items(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
 {
 	struct media_player *mp = data;
+	struct media_folder *folder = mp->folder;
 
-	if (mp->folder == NULL)
+	if (folder == NULL)
 		return FALSE;
 
-	DBG("%u", mp->folder->items);
+	DBG("%u", folder->number_of_items);
 
 	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32,
-							&mp->folder->items);
+						&folder->number_of_items);
 
 	return TRUE;
 }
@@ -661,9 +674,22 @@ static const GDBusPropertyTable media_folder_properties[] = {
 	{ }
 };
 
+static void media_item_destroy(void *data)
+{
+	struct media_item *item = data;
+
+	DBG("%s", item->path);
+
+	g_dbus_unregister_interface(btd_get_dbus_connection(), item->path,
+						MEDIA_ITEM_INTERFACE);
+
+	g_free(item->path);
+	g_free(item->name);
+	g_free(item);
+}
+
 static void media_folder_destroy(struct media_folder *folder)
 {
-	g_free(folder->name);
 	g_free(folder);
 }
 
@@ -691,6 +717,7 @@ void media_player_destroy(struct media_player *mp)
 	}
 
 	g_slist_free_full(mp->pending, g_free);
+	g_slist_free_full(mp->folders, media_item_destroy);
 
 	g_timer_destroy(mp->progress);
 	g_free(mp->cb);
@@ -913,31 +940,187 @@ void media_player_set_searchable(struct media_player *mp, bool enabled)
 	mp->searchable = enabled;
 }
 
-void media_player_set_folder(struct media_player *mp, const char *path,
-								uint32_t items)
+static void media_player_set_folder_item(struct media_player *mp,
+						struct media_item *item,
+						uint32_t number_of_items)
 {
 	struct media_folder *folder;
 
-	DBG("%s items %u", path, items);
+	folder = mp->folder;
 
-	if (mp->folder != NULL)
-		media_folder_destroy(mp->folder);
+	if (folder == NULL) {
+		folder = g_new0(struct media_folder, 1);
+		mp->folder = folder;
 
-	folder = g_new0(struct media_folder, 1);
-	folder->name = g_strdup(path);
-	folder->items = items;
-	mp->folder = folder;
-
-	if (!g_dbus_register_interface(btd_get_dbus_connection(),
+		if (!g_dbus_register_interface(btd_get_dbus_connection(),
 					mp->path, MEDIA_FOLDER_INTERFACE,
 					media_folder_methods,
 					NULL,
 					media_folder_properties, mp, NULL)) {
-		error("D-Bus failed to register %s on %s path",
+			error("D-Bus failed to register %s on %s path",
 					MEDIA_FOLDER_INTERFACE, mp->path);
-		media_folder_destroy(mp->folder);
-		mp->folder = NULL;
+			media_folder_destroy(mp->folder);
+			mp->folder = NULL;
+			return;
+		}
+	}
+
+	folder->item = item;
+	folder->number_of_items = number_of_items;
+
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), mp->path,
+				MEDIA_FOLDER_INTERFACE, "Name");
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), mp->path,
+				MEDIA_FOLDER_INTERFACE, "NumberOfItems");
+}
+
+static struct media_item *media_player_find_folder(struct media_player *mp,
+							const char *name)
+{
+	GSList *l;
+
+	for (l = mp->folders; l; l = l->next) {
+		struct media_item *item = l->data;
+
+		if (!item->folder)
+			continue;
+
+		if (g_str_equal(item->name, name))
+			return item;
 	}
+
+	return NULL;
+}
+
+void media_player_set_folder(struct media_player *mp, const char *name,
+						uint32_t number_of_items)
+{
+	struct media_item *item;
+
+	DBG("%s number of items %u", name, number_of_items);
+
+	item = media_player_find_folder(mp, name);
+	if (item == NULL) {
+		error("Unknown folder: %s", name);
+		return;
+	}
+
+	media_player_set_folder_item(mp, item, number_of_items);
+}
+
+static DBusMessage *media_item_play(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	return btd_error_failed(msg, strerror(ENOTSUP));
+}
+
+static DBusMessage *media_item_add_to_nowplaying(DBusConnection *conn,
+						DBusMessage *msg, void *data)
+{
+	return btd_error_failed(msg, strerror(ENOTSUP));
+}
+
+static gboolean item_name_exists(const GDBusPropertyTable *property,
+								void *data)
+{
+	struct media_item *item = data;
+
+	return item->name != NULL;
+}
+
+static gboolean get_item_name(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_item *item = data;
+
+	if (item->name == NULL)
+		return FALSE;
+
+	DBG("%s", item->name);
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &item->name);
+
+	return TRUE;
+}
+
+static gboolean get_folder_flag(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_item *item = data;
+	dbus_bool_t value;
+
+	DBG("%s", item->folder ? "true" : "false");
+
+	value = item->folder;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+
+	return TRUE;
+}
+
+static gboolean get_playable(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_item *item = data;
+	dbus_bool_t value;
+
+	DBG("%s", item->playable ? "true" : "false");
+
+	value = item->playable;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+
+	return TRUE;
+}
+
+static const GDBusMethodTable media_item_methods[] = {
+	{ GDBUS_EXPERIMENTAL_METHOD("Play", NULL, NULL,
+					media_item_play) },
+	{ GDBUS_EXPERIMENTAL_METHOD("AddtoNowPlaying", NULL, NULL,
+					media_item_add_to_nowplaying) },
+	{ }
+};
+
+static const GDBusPropertyTable media_item_properties[] = {
+	{ "Name", "s", get_item_name, NULL, item_name_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Folder", "b", get_folder_flag, NULL, NULL,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Playable", "b", get_playable, NULL, NULL,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ }
+};
+
+int media_player_create_folder(struct media_player *mp, const char *name)
+{
+	struct media_item *item;
+
+	DBG("%s", name);
+
+	item = g_new0(struct media_item, 1);
+	item->player = mp;
+	item->path = g_strdup_printf("%s%s", mp->path, name);
+	item->name = g_strdup(name);
+	item->folder = true;
+	item->playable = false;
+
+	if (!g_dbus_register_interface(btd_get_dbus_connection(),
+					item->path, MEDIA_ITEM_INTERFACE,
+					media_item_methods,
+					NULL,
+					media_item_properties, item, NULL)) {
+		error("D-Bus failed to register %s on %s path",
+					MEDIA_ITEM_INTERFACE, item->path);
+		media_item_destroy(item);
+		return -EINVAL;
+	}
+
+	if (mp->folder == NULL)
+		media_player_set_folder_item(mp, item, 0);
+
+	mp->folders = g_slist_prepend(mp->folders, item);
+
+	return 0;
 }
 
 void media_player_set_callbacks(struct media_player *mp,
diff --git a/profiles/audio/player.h b/profiles/audio/player.h
index 9109b1f..a59cc66 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
@@ -55,6 +55,8 @@ void media_player_set_searchable(struct media_player *mp, bool enabled);
 void media_player_set_folder(struct media_player *mp, const char *path,
 								uint32_t items);
 
+int media_player_create_folder(struct media_player *mp, const char *path);
+
 void media_player_set_callbacks(struct media_player *mp,
 				const struct media_player_callback *cbs,
 				void *user_data);
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH BlueZ 4/7] AVRCP: Move features to avrcp.c
From: Luiz Augusto von Dentz @ 2013-02-15 14:02 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1360936972-12952-1-git-send-email-luiz.dentz@gmail.com>

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

avrcp.c should be responsible for specifics of AVRCP not player.c which
is more high level abstraction.
---
 profiles/audio/avrcp.c  | 4 ++++
 profiles/audio/player.c | 8 --------
 profiles/audio/player.h | 1 -
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index cabe2ee..55887bc 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -180,6 +180,7 @@ struct avrcp_player {
 	GSList *sessions;
 	uint16_t id;
 	uint16_t uid_counter;
+	uint8_t *features;
 
 	struct avrcp_player_cb *cb;
 	void *user_data;
@@ -1981,6 +1982,8 @@ static void avrcp_player_parse_features(struct avrcp_player *player,
 {
 	struct media_player *mp = player->user_data;
 
+	player->features = g_memdup(features, 16);
+
 	if (features[7] & 0x08)
 		media_player_set_browsable(mp, true);
 
@@ -2553,6 +2556,7 @@ static void player_destroy(gpointer data)
 		player->destroy(player->user_data);
 
 	g_slist_free(player->sessions);
+	g_free(player->features);
 	g_free(player);
 }
 
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index 7879193..07fd457 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -69,7 +69,6 @@ struct media_player {
 	char			*subtype;	/* Player subtype */
 	bool			browsable;	/* Player browsing feature */
 	bool			searchable;	/* Player searching feature */
-	uint8_t			*features;	/* Player features */
 	struct media_folder	*folder;	/* Player currenct folder */
 	char			*path;		/* Player object path */
 	GHashTable		*settings;	/* Player settings */
@@ -941,13 +940,6 @@ void media_player_set_folder(struct media_player *mp, const char *path,
 	}
 }
 
-void media_player_set_features(struct media_player *mp, uint64_t *features)
-{
-	DBG("0x%016" PRIx64 "%016" PRIx64, 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 e9a7d1c..9109b1f 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
@@ -49,7 +49,6 @@ 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_browsable(struct media_player *mp, bool enabled);
 void media_player_set_searchable(struct media_player *mp, bool enabled);
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH BlueZ 3/7] media-api: Fix referencing to MediaLibrary instead of MediaFolder
From: Luiz Augusto von Dentz @ 2013-02-15 14:02 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1360936972-12952-1-git-send-email-luiz.dentz@gmail.com>

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

MediaLibrary was replaced by MediaFolder so doesn't exist anymore.
---
 doc/media-api.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/media-api.txt b/doc/media-api.txt
index db1575f..2656a9e 100644
--- a/doc/media-api.txt
+++ b/doc/media-api.txt
@@ -233,7 +233,7 @@ Properties	string Equalizer [readwrite]
 		boolean Browsable [readonly]
 
 			If present indicates the player can be browsed using
-			MediaLibrary interface.
+			MediaFolder interface.
 
 			Possible values:
 
@@ -248,7 +248,7 @@ Properties	string Equalizer [readwrite]
 		boolean Searchable [readonly]
 
 			If present indicates the player can be searched using
-			MediaLibrary interface.
+			MediaFolder interface.
 
 			Possible values:
 
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH BlueZ 2/7] AVRCP: Parse browsing and searching features bits
From: Luiz Augusto von Dentz @ 2013-02-15 14:02 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1360936972-12952-1-git-send-email-luiz.dentz@gmail.com>

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

This parses browsing and searching features bits and set the respective
property.
---
 profiles/audio/avrcp.c  | 18 ++++++++----
 profiles/audio/player.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++-
 profiles/audio/player.h |  2 ++
 3 files changed, 87 insertions(+), 6 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 5967180..cabe2ee 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1976,6 +1976,18 @@ static void avrcp_set_browsed_player(struct avrcp *session,
 				avrcp_set_browsed_player_rsp, session);
 }
 
+static void avrcp_player_parse_features(struct avrcp_player *player,
+							uint8_t *features)
+{
+	struct media_player *mp = player->user_data;
+
+	if (features[7] & 0x08)
+		media_player_set_browsable(mp, true);
+
+	if (features[7] & 0x10)
+		media_player_set_searchable(mp, true);
+}
+
 static void avrcp_parse_media_player_item(struct avrcp *session,
 					uint8_t *operands, uint16_t len)
 {
@@ -1984,7 +1996,6 @@ static void avrcp_parse_media_player_item(struct avrcp *session,
 	uint16_t id;
 	uint32_t subtype;
 	const char *curval, *strval;
-	uint64_t features[2];
 	char name[255];
 
 	if (len < 28)
@@ -2009,10 +2020,7 @@ static void avrcp_parse_media_player_item(struct avrcp *session,
 		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);
+	avrcp_player_parse_features(player, &operands[8]);
 
 	if (operands[26] != 0) {
 		memcpy(name, &operands[27], operands[26]);
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index f875ee7..7879193 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -67,7 +67,9 @@ struct media_player {
 	char			*name;		/* Player name */
 	char			*type;		/* Player type */
 	char			*subtype;	/* Player subtype */
-	uint64_t		features[2];	/* Player features */
+	bool			browsable;	/* Player browsing feature */
+	bool			searchable;	/* Player searching feature */
+	uint8_t			*features;	/* Player features */
 	struct media_folder	*folder;	/* Player currenct folder */
 	char			*path;		/* Player object path */
 	GHashTable		*settings;	/* Player settings */
@@ -350,6 +352,57 @@ static gboolean get_subtype(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static gboolean browsable_exists(const GDBusPropertyTable *property, void *data)
+{
+	struct media_player *mp = data;
+
+	return mp->folder != NULL;
+}
+
+static gboolean get_browsable(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_player *mp = data;
+	dbus_bool_t value;
+
+	if (mp->folder == NULL)
+		return FALSE;
+
+	DBG("%s", mp->browsable ? "true" : "false");
+
+	value = mp->browsable;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+
+	return TRUE;
+}
+
+static gboolean searchable_exists(const GDBusPropertyTable *property,
+								void *data)
+{
+	struct media_player *mp = data;
+
+	return mp->folder != NULL;
+}
+
+static gboolean get_searchable(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_player *mp = data;
+	dbus_bool_t value;
+
+	if (mp->folder == NULL)
+		return FALSE;
+
+	DBG("%s", mp->searchable ? "true" : "false");
+
+	value = mp->searchable;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+
+	return TRUE;
+}
+
 static DBusMessage *media_player_play(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
@@ -510,6 +563,10 @@ static const GDBusPropertyTable media_player_properties[] = {
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
 	{ "Device", "s", get_device, NULL, NULL,
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Browsable", "b", get_browsable, NULL, browsable_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Searchable", "b", get_searchable, NULL, searchable_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
 	{ }
 };
 
@@ -843,6 +900,20 @@ void media_player_set_name(struct media_player *mp, const char *name)
 					"Name");
 }
 
+void media_player_set_browsable(struct media_player *mp, bool enabled)
+{
+	DBG("%s", enabled ? "true" : "false");
+
+	mp->browsable = enabled;
+}
+
+void media_player_set_searchable(struct media_player *mp, bool enabled)
+{
+	DBG("%s", enabled ? "true" : "false");
+
+	mp->searchable = enabled;
+}
+
 void media_player_set_folder(struct media_player *mp, const char *path,
 								uint32_t items)
 {
diff --git a/profiles/audio/player.h b/profiles/audio/player.h
index 1ac9800..e9a7d1c 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
@@ -51,6 +51,8 @@ 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_browsable(struct media_player *mp, bool enabled);
+void media_player_set_searchable(struct media_player *mp, bool enabled);
 void media_player_set_folder(struct media_player *mp, const char *path,
 								uint32_t items);
 
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH BlueZ 1/7] AVRCP: Prefix folder name with /Filesystem
From: Luiz Augusto von Dentz @ 2013-02-15 14:02 UTC (permalink / raw)
  To: linux-bluetooth

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

This separate the scopes of the folder as documented in doc/media-api.txt
---
 profiles/audio/avrcp.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 00eeea1..5967180 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1935,9 +1935,10 @@ static gboolean avrcp_set_browsed_player_rsp(struct avctp *conn,
 
 	depth = operands[13];
 
-	folders = g_new0(char *, depth + 1);
+	folders = g_new0(char *, depth + 2);
+	folders[0] = g_strdup("/Filesystem");
 
-	for (i = 14, count = 0; count < depth; count++) {
+	for (i = 14, count = 1; count - 1 < depth; count++) {
 		char *part;
 		uint8_t len;
 
-- 
1.8.1.2


^ permalink raw reply related

* Re: [PATCH] adapter: Fix registering adapter with no address
From: Johan Hedberg @ 2013-02-15 12:22 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1360317793-2015-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Fri, Feb 08, 2013, Szymon Janc wrote:
> adapter->bdaddr is set later in read_info_complete and current check
> always returns false. Check against bdaddr received in command response
> instead and fail if it is all zeros.
> ---
>  src/adapter.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH v2 6/6] neard: Add fallback to legacy register if register failed
From: Szymon Janc @ 2013-02-15 12:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1360930159-25658-1-git-send-email-szymon.janc@tieto.com>

This will allow to work with neard 0.9 which doesn't support handover
agent register with carrier type.
---
 plugins/neard.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/plugins/neard.c b/plugins/neard.c
index 697967a..4075f73 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -96,30 +96,48 @@ static DBusMessage *error_reply(DBusMessage *msg, int error)
 	return g_dbus_create_error(msg, name , "%s", strerror(error));
 }
 
+static void register_agent(bool append_carrier);
+
 static void register_agent_cb(DBusPendingCall *call, void *user_data)
 {
 	DBusMessage *reply;
 	DBusError err;
+	static bool try_fallback = true;
 
 	reply = dbus_pending_call_steal_reply(call);
 
 	dbus_error_init(&err);
 	if (dbus_set_error_from_message(&err, reply)) {
-		error("neard manager replied with an error: %s, %s",
-						err.name, err.message);
+		if (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) &&
+				try_fallback) {
+			info("Register to neard failed, trying legacy way");
+
+			register_agent(false);
+			try_fallback = false;
+		} else {
+			error("neard manager replied with an error: %s, %s",
+							err.name, err.message);
+
+			g_dbus_unregister_interface(btd_get_dbus_connection(),
+						AGENT_PATH, AGENT_INTERFACE);
+			try_fallback = true;
+		}
+
 		dbus_error_free(&err);
 		dbus_message_unref(reply);
 
-		g_dbus_unregister_interface(btd_get_dbus_connection(),
-						AGENT_PATH, AGENT_INTERFACE);
 		return;
 	}
 
 	dbus_message_unref(reply);
 	neard_service = g_strdup(dbus_message_get_sender(reply));
+
+	try_fallback = true;
+
+	info("Registered as neard handover agent");
 }
 
-static void register_agent(void)
+static void register_agent(bool append_carrier)
 {
 	DBusMessage *message;
 	DBusPendingCall *call;
@@ -136,7 +154,8 @@ static void register_agent(void)
 	dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &path,
 							DBUS_TYPE_INVALID);
 
-	dbus_message_append_args(message, DBUS_TYPE_STRING, &carrier,
+	if (append_carrier)
+		dbus_message_append_args(message, DBUS_TYPE_STRING, &carrier,
 							DBUS_TYPE_INVALID);
 
 	if (!dbus_connection_send_with_reply(btd_get_dbus_connection(),
@@ -252,7 +271,7 @@ static void read_local_complete(struct btd_adapter *adapter,
 
 		if (agent_register_postpone) {
 			agent_register_postpone = false;
-			register_agent();
+			register_agent(true);
 		}
 
 		return;
@@ -284,7 +303,7 @@ static void bonding_complete(struct btd_adapter *adapter,
 
 		if (agent_register_postpone) {
 			agent_register_postpone = false;
-			register_agent();
+			register_agent(true);
 		}
 
 		return;
@@ -840,7 +859,7 @@ static void neard_appeared(DBusConnection *conn, void *user_data)
 	if (adapter && btd_adapter_check_oob_handler(adapter))
 		agent_register_postpone = true;
 	else
-		register_agent();
+		register_agent(true);
 }
 
 static void neard_vanished(DBusConnection *conn, void *user_data)
-- 
1.8.1.1


^ permalink raw reply related

* [PATCH v2 5/6] neard: Updated neard handover registration agent api calls.
From: Szymon Janc @ 2013-02-15 12:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1360930159-25658-1-git-send-email-szymon.janc@tieto.com>

From: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>

neard RegisterHandoverAgent and UnregisterHandoverAgent apis
need an extra parameter of carrier type(e.g. bluetooth).
---
 plugins/neard.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/plugins/neard.c b/plugins/neard.c
index 2e583be..697967a 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -46,6 +46,7 @@
 #define NEARD_MANAGER_INTERFACE "org.neard.Manager"
 #define AGENT_INTERFACE "org.neard.HandoverAgent"
 #define AGENT_PATH "/org/bluez/neard_handover_agent"
+#define AGENT_CARRIER_TYPE "bluetooth"
 #define ERROR_INTERFACE "org.neard.HandoverAgent.Error"
 
 static guint watcher_id = 0;
@@ -123,6 +124,7 @@ static void register_agent(void)
 	DBusMessage *message;
 	DBusPendingCall *call;
 	const char *path = AGENT_PATH;
+	const char *carrier = AGENT_CARRIER_TYPE;
 
 	message = dbus_message_new_method_call(NEARD_NAME, NEARD_PATH,
 			NEARD_MANAGER_INTERFACE, "RegisterHandoverAgent");
@@ -134,6 +136,9 @@ static void register_agent(void)
 	dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &path,
 							DBUS_TYPE_INVALID);
 
+	dbus_message_append_args(message, DBUS_TYPE_STRING, &carrier,
+							DBUS_TYPE_INVALID);
+
 	if (!dbus_connection_send_with_reply(btd_get_dbus_connection(),
 							message, &call, -1)) {
 		dbus_message_unref(message);
@@ -151,6 +156,7 @@ static void unregister_agent(void)
 {
 	DBusMessage *message;
 	const char *path = AGENT_PATH;
+	const char *carrier = AGENT_CARRIER_TYPE;
 
 	g_free(neard_service);
 	neard_service = NULL;
@@ -166,6 +172,9 @@ static void unregister_agent(void)
 	dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &path,
 						DBUS_TYPE_INVALID);
 
+	dbus_message_append_args(message, DBUS_TYPE_STRING, &carrier,
+							DBUS_TYPE_INVALID);
+
 	if (!g_dbus_send_message(btd_get_dbus_connection(), message))
 		error("D-Bus send failed");
 
-- 
1.8.1.1


^ permalink raw reply related

* [PATCH v2 4/6] neard: Update copyright information
From: Szymon Janc @ 2013-02-15 12:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1360930159-25658-1-git-send-email-szymon.janc@tieto.com>

---
 plugins/neard.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/plugins/neard.c b/plugins/neard.c
index 6025d89..2e583be 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -2,7 +2,7 @@
  *
  *  BlueZ - Bluetooth protocol stack for Linux
  *
- *  Copyright (C) 2012  Tieto Poland
+ *  Copyright (C) 2012-2013  Tieto Poland
  *
  *
  *  This program is free software; you can redistribute it and/or modify
-- 
1.8.1.1


^ permalink raw reply related

* [PATCH v2 3/6] neard: Use bool instead of gboolean for agent_register_postpone
From: Szymon Janc @ 2013-02-15 12:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1360930159-25658-1-git-send-email-szymon.janc@tieto.com>

There is no need to use gboolean as this flag is not used with any
glib function.
---
 plugins/neard.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/plugins/neard.c b/plugins/neard.c
index 88a6229..6025d89 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -50,7 +50,7 @@
 
 static guint watcher_id = 0;
 static char *neard_service = NULL;
-static gboolean agent_register_postpone = FALSE;
+static bool agent_register_postpone = false;
 
 /* For NFC mimetype limits max OOB EIR size */
 #define NFC_OOB_EIR_MAX UINT8_MAX
@@ -242,7 +242,7 @@ static void read_local_complete(struct btd_adapter *adapter,
 		dbus_message_unref(msg);
 
 		if (agent_register_postpone) {
-			agent_register_postpone = FALSE;
+			agent_register_postpone = false;
 			register_agent();
 		}
 
@@ -274,7 +274,7 @@ static void bonding_complete(struct btd_adapter *adapter,
 		dbus_message_unref(msg);
 
 		if (agent_register_postpone) {
-			agent_register_postpone = FALSE;
+			agent_register_postpone = false;
 			register_agent();
 		}
 
@@ -829,7 +829,7 @@ static void neard_appeared(DBusConnection *conn, void *user_data)
 	adapter = btd_adapter_get_default();
 
 	if (adapter && btd_adapter_check_oob_handler(adapter))
-		agent_register_postpone = TRUE;
+		agent_register_postpone = true;
 	else
 		register_agent();
 }
-- 
1.8.1.1


^ permalink raw reply related

* [PATCH v2 2/6] neard: Restrict method calls only to neard process
From: Szymon Janc @ 2013-02-15 12:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1360930159-25658-1-git-send-email-szymon.janc@tieto.com>

Disallow methods calls from processes other than registered to as
agent.
---
 plugins/neard.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/plugins/neard.c b/plugins/neard.c
index 650ee3e..88a6229 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -637,6 +637,10 @@ static DBusMessage *push_oob(DBusConnection *conn, DBusMessage *msg, void *data)
 	uint8_t io_cap;
 	int err;
 
+	if (neard_service == NULL ||
+			!g_str_equal(neard_service, dbus_message_get_sender(msg)))
+		return error_reply(msg, EPERM);
+
 	DBG("");
 
 	adapter = btd_adapter_get_default();
@@ -714,6 +718,10 @@ static DBusMessage *request_oob(DBusConnection *conn, DBusMessage *msg,
 	struct btd_device *device;
 	int err;
 
+	if (neard_service == NULL ||
+			!g_str_equal(neard_service, dbus_message_get_sender(msg)))
+		return error_reply(msg, EPERM);
+
 	DBG("");
 
 	adapter = btd_adapter_get_default();
@@ -776,6 +784,10 @@ read_local:
 static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
 							void *user_data)
 {
+	if (neard_service == NULL ||
+			!g_str_equal(neard_service, dbus_message_get_sender(msg)))
+		return error_reply(msg, EPERM);
+
 	DBG("");
 
 	g_free(neard_service);
-- 
1.8.1.1


^ permalink raw reply related

* [PATCH v2 1/6] neard: Use service name and not boolean to track if registered to neard
From: Szymon Janc @ 2013-02-15 12:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 plugins/neard.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/plugins/neard.c b/plugins/neard.c
index a1b385e..650ee3e 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -49,7 +49,7 @@
 #define ERROR_INTERFACE "org.neard.HandoverAgent.Error"
 
 static guint watcher_id = 0;
-static gboolean agent_registered = FALSE;
+static char *neard_service = NULL;
 static gboolean agent_register_postpone = FALSE;
 
 /* For NFC mimetype limits max OOB EIR size */
@@ -115,7 +115,7 @@ static void register_agent_cb(DBusPendingCall *call, void *user_data)
 	}
 
 	dbus_message_unref(reply);
-	agent_registered = TRUE;
+	neard_service = g_strdup(dbus_message_get_sender(reply));
 }
 
 static void register_agent(void)
@@ -152,7 +152,8 @@ static void unregister_agent(void)
 	DBusMessage *message;
 	const char *path = AGENT_PATH;
 
-	agent_registered = FALSE;
+	g_free(neard_service);
+	neard_service = NULL;
 
 	message = dbus_message_new_method_call(NEARD_NAME, NEARD_PATH,
 			NEARD_MANAGER_INTERFACE, "UnregisterHandoverAgent");
@@ -237,7 +238,7 @@ static void read_local_complete(struct btd_adapter *adapter,
 
 	DBG("");
 
-	if (!agent_registered) {
+	if (neard_service == NULL) {
 		dbus_message_unref(msg);
 
 		if (agent_register_postpone) {
@@ -269,7 +270,7 @@ static void bonding_complete(struct btd_adapter *adapter,
 
 	DBG("");
 
-	if (!agent_registered) {
+	if (neard_service == NULL) {
 		dbus_message_unref(msg);
 
 		if (agent_register_postpone) {
@@ -777,7 +778,9 @@ static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
 {
 	DBG("");
 
-	agent_registered = FALSE;
+	g_free(neard_service);
+	neard_service = NULL;
+
 	g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
@@ -824,8 +827,10 @@ static void neard_vanished(DBusConnection *conn, void *user_data)
 	DBG("");
 
 	/* neard existed without unregistering agent */
-	if (agent_registered) {
-		agent_registered = FALSE;
+	if (neard_service != NULL) {
+		g_free(neard_service);
+		neard_service = NULL;
+
 		g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
 	}
 }
@@ -850,7 +855,7 @@ static void neard_exit(void)
 	g_dbus_remove_watch(btd_get_dbus_connection(), watcher_id);
 	watcher_id = 0;
 
-	if (agent_registered)
+	if (neard_service != NULL)
 		unregister_agent();
 }
 
-- 
1.8.1.1


^ permalink raw reply related

* Re: [PATCH BlueZ 0/2] Add device_set_trusted()
From: Antonio Ospite @ 2013-02-15 11:01 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <20130215092740.GB11352@x220>

On Fri, 15 Feb 2013 11:27:40 +0200
Johan Hedberg <johan.hedberg@gmail.com> wrote:

> Hi Antonio,
> 
> On Sun, Feb 03, 2013, Antonio Ospite wrote:
> > In patch 1 a device_set_trusted() function is proposed, which I plan to
> > use for the playstation-peripheral plugin; I am in the process of
> > rebasing the plugin on top of BlueZ 5.2.
> > 
> > In patch 2 the newly introduced function is used in order to avoid some
> > duplication.
> > 
> > device_set_trusted() looks a lot like device_set_temporary() and
> > device_set_legacy(), I hope it makes sense to you too.
> > 
> > Thanks,
> >    Antonio
> > 
> > Antonio Ospite (2):
> >   device: add a device_set_trusted() function
> >   device: use device_set_trusted() in set_trust()
> > 
> >  src/device.c |   30 +++++++++++++++++++-----------
> >  src/device.h |    1 +
> >  2 files changed, 20 insertions(+), 11 deletions(-)
> 
> Both patches are now applied (after adding some needed info to the
> commit messages for the justification of these changes).
> 

Thanks a lot, mentioning USB-based pairing in the commit message is a
useful hint indeed.

And thanks to Bastien for backing up the changes better than I would
have.

See you soon with a couple of more controversial patches :)

Regards,
   Antonio

-- 
Antonio Ospite
http://ao2.it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?

^ permalink raw reply

* Re: [PATCH BlueZ] A2DP: Fix invalid write
From: Johan Hedberg @ 2013-02-15 10:57 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1360332728-27051-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Fri, Feb 08, 2013, Luiz Augusto von Dentz wrote:
> Invalid write of size 8
>    at 0x41F297: setconf_cfm (a2dp.c:567)
>    by 0x42526B: session_cb (avdtp.c:3176)
>    by 0x39B0847A54: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
>    by 0x39B0847D87: ??? (in /usr/lib64/libglib-2.0.so.0.3400.2)
>    by 0x39B0848181: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3400.2)
>    by 0x409C3E: main (main.c:583)
>  Address 0x555fda8 is 40 bytes inside a block of size 88 free'd
>    at 0x4A077A6: free (vg_replace_malloc.c:446)
>    by 0x39B084D79E: g_free (in /usr/lib64/libglib-2.0.so.0.3400.2)
>    by 0x41E217: setup_cb_free (a2dp.c:191)
>    by 0x41E410: finalize_config (a2dp.c:234)
>    by 0x41F296: setconf_cfm (a2dp.c:566)
>    by 0x42526B: session_cb (avdtp.c:3176)
>    by 0x39B0847A54: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
>    by 0x39B0847D87: ??? (in /usr/lib64/libglib-2.0.so.0.3400.2)
>    by 0x39B0848181: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3400.2)
>    by 0x409C3E: main (main.c:583)
> ---
>  profiles/audio/a2dp.c | 2 ++
>  1 file changed, 2 insertions(+)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ] core: Fix calling profile .connect multiple times
From: Johan Hedberg @ 2013-02-15 10:53 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1360317088-18852-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Fri, Feb 08, 2013, Luiz Augusto von Dentz wrote:
> Sometimes profiles may complete the connection in different order
> than expected so the code has to check if it was actually the
> current pending profile to proceed to the next.
> ---
>  src/device.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH v2 1/5] adapter: Add is_default field to struct btd_adapter
From: Johan Hedberg @ 2013-02-15 10:51 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1360186838-16904-1-git-send-email-szymon@janc.net.pl>

Hi Szymon,

On Wed, Feb 06, 2013, Szymon Janc wrote:
> Instead of global default_adapter_id variable use is_default field
> to indicate if adapter is default one.
> ---
>  src/adapter.c | 26 +++++++++++++-------------
>  1 file changed, 13 insertions(+), 13 deletions(-)

All patches in this set have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ] core: Remove unused code from device_browse_sdp()
From: Johan Hedberg @ 2013-02-15 10:41 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1360024356-6838-1-git-send-email-anderson.lizardo@openbossa.org>

Hi Lizardo,

On Mon, Feb 04, 2013, Anderson Lizardo wrote:
> The "search" parameter was always NULL, and therefore code depending on
> it being non-NULL will never be reached.
> ---
>  src/device.c |   23 ++++++++---------------
>  1 file changed, 8 insertions(+), 15 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ 0/3] SDP library invalid memory access fixes
From: Johan Hedberg @ 2013-02-15 10:40 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1359940845-14451-1-git-send-email-anderson.lizardo@openbossa.org>

Hi Lizardo,

On Sun, Feb 03, 2013, Anderson Lizardo wrote:
> This small set of patches fixes a couple of invalid memory reads/writes
> detected by code inspection and confirmed by emulating invalid PDUs.
> 
> BTW, I have been silently working for some time on a tool now called "Blueish"
> (variant of "bluish", meaning "somewhat blue"). It is fully written in Python
> and allows to "easily" generate automated standalone test scripts (that also
> only require Python + D-Bus/GLib bindings) for testing scenarios difficult on
> real hardware. It uses VHCI for emulation.
> 
> For documentation and code, see: https://github.com/lizardo/blueish
> 
> The repository contains example data files for the latest patches I sent a
> while ago (and these ones).
> 
> I tried to make it easy to use by adopting YAML for HCI packet construction.
> Still, I'm aware that constructing HCI packets by hand is error prone, so I
> plan (someday) to have a nice GUI and even some sort of visualization for the
> packets (message sequence charts, maybe?).
> 
> That said, I'm still interested on helping with improving unit tests for BlueZ
> (specially code not touched for a while). I just could not come up with a nice
> way to integrate SDP client unit tests with the current server ones without too
> much code duplication.
> 
> Best Regards,
> 
> Anderson Lizardo (3):
>   lib: Fix buffer overflow when processing SDP response
>   lib: Add range check for SDP_SVC_ATTR_RSP/SDP_SVC_SEARCH_ATTR_RSP
>   lib: Check if SDP buffer has enough data on partial responses
> 
>  lib/sdp.c |   26 +++++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)

All three patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 02/12] Bluetooth: Add basic start/complete HCI transaction functions
From: Johan Hedberg @ 2013-02-15  9:52 UTC (permalink / raw)
  To: Szymon Janc; +Cc: Andre Guedes, linux-bluetooth@vger.kernel.org
In-Reply-To: <11735985.64bebk47LR@uw000953>

Hi Szymon,

On Fri, Feb 15, 2013, Szymon Janc wrote:
> > > > > > +int hci_start_transaction(struct hci_dev *hdev)
> > > > > > +{
> > > > > > +       struct hci_transaction *transaction;
> > > > > > +       int err;
> > > > > > +
> > > > > > +       hci_transaction_lock(hdev);
> > > > > > +
> > > > > > +       /* We can't start a new transaction if there's another one in
> > > > > > +        * progress of being built.
> > > > > > +        */
> > > > > > +       if (hdev->build_transaction) {
> > > > > > +               err = -EBUSY;
> > > > > > +               goto unlock;
> > > > > > +       }
> > > > > > +
> > > > > > +       transaction = kmalloc(sizeof(*transaction), GFP_ATOMIC);
> > > > > 
> > > > > I've failed to see why we need GFP_ATOMIC here. As this code is not
> > > > > running in any atomic section, we can allocate memory using
> > > > > GFP_KERNEL.
> > > > 
> > > > Since one of the intentions of this API is to create an async version of
> > > > hci_request() I think it's better to keep GFP_ATOMIC here. One situation
> > > > where you couldn't for sure use hci_request() is if you're in an atomic
> > > > section and then a HCI request would be the only other alternative.
> > > 
> > > You lock mutex in hci_start_transaction so it is non-atomic anyway..
> > 
> > This has me a bit confused since hci_dev_lock() also uses the same. Does
> > this mean that there's no code at all in the Bluetooth subsystem anymore
> > that can run in atomic context? (since most things require locking at
> > least the hdev struct). I remember seeing some time back (after the
> > whole workqueue conversion) bugs arising from incorrect GFP_ATOMIC ->
> > GFP_KERNEL conversions (none of which luckily made it to Linus' tree), so at
> > least some parts seemed to still be atomic. Do a grep for GFP_ATOMIC in
> > net/bluetooth/ and you'll find plenty of them.
> 
> The bug (by me btw:P) you are probably referring to was due to rwlock which
> is spin lock and raise sleeping in atomic warning even if run e.g. from wq.

Alright. I've just sent a v3 of the set which uses GFP_KERNEL for all
allocations.

Johan

^ 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