Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ 10/12] audio/A2DP: Add implemention of SEP close confirmation
From: Luiz Augusto von Dentz @ 2014-01-13 17:32 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389634333-25870-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 4cfcd0e..c1747f1 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -909,11 +909,26 @@ static void sep_suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 	setup_remove_by_id(endpoint->id);
 }
 
+static void sep_close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
+			struct avdtp_stream *stream, struct avdtp_error *err,
+			void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+
+	DBG("");
+
+	if (err)
+		return;
+
+	setup_remove_by_id(endpoint->id);
+}
+
 static struct avdtp_sep_cfm sep_cfm = {
 	.set_configuration	= sep_setconf_cfm,
 	.open			= sep_open_cfm,
 	.start			= sep_start_cfm,
 	.suspend		= sep_suspend_cfm,
+	.close			= sep_close_cfm,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 11/12] audio/A2DP: Add implemention of SEP abort confirmation
From: Luiz Augusto von Dentz @ 2014-01-13 17:32 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389634333-25870-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index c1747f1..f3cef0c 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -923,12 +923,27 @@ static void sep_close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 	setup_remove_by_id(endpoint->id);
 }
 
+static void sep_abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
+			struct avdtp_stream *stream, struct avdtp_error *err,
+			void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+
+	DBG("");
+
+	if (err)
+		return;
+
+	setup_remove_by_id(endpoint->id);
+}
+
 static struct avdtp_sep_cfm sep_cfm = {
 	.set_configuration	= sep_setconf_cfm,
 	.open			= sep_open_cfm,
 	.start			= sep_start_cfm,
 	.suspend		= sep_suspend_cfm,
 	.close			= sep_close_cfm,
+	.abort			= sep_abort_cfm,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 12/12] android/AVDTP: Fix invalid free of struct discover
From: Luiz Augusto von Dentz @ 2014-01-13 17:32 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389634333-25870-1-git-send-email-luiz.dentz@gmail.com>

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

If callback releases the last reference it can cause the following:
Invalid free() / delete / delete[] / realloc()
   at 0x4A07577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x386244EF7E: g_free (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x410356: finalize_discovery (avdtp.c:933)
   by 0x414462: session_cb (avdtp.c:2555)
   by 0x38624492A5: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x3862449627: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x3862449A39: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x403A95: main (main.c:439)
 Address 0x4cf7af0 is 0 bytes inside a block of size 24 free'd
   at 0x4A07577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x386244EF7E: g_free (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x410356: finalize_discovery (avdtp.c:933)
   by 0x4110BC: avdtp_unref (avdtp.c:1026)
   by 0x416491: a2dp_device_free (a2dp.c:122)
   by 0x4165DF: bt_a2dp_notify_state (a2dp.c:166)
   by 0x417170: discover_cb (a2dp.c:333)
   by 0x41034E: finalize_discovery (avdtp.c:931)
   by 0x414462: session_cb (avdtp.c:2555)
   by 0x38624492A5: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x3862449627: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x3862449A39: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3800.2)
---
 android/avdtp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/android/avdtp.c b/android/avdtp.c
index 473e02b..5da1206 100644
--- a/android/avdtp.c
+++ b/android/avdtp.c
@@ -923,6 +923,8 @@ static void finalize_discovery(struct avdtp *session, int err)
 	if (!discover)
 		return;
 
+	session->discover = NULL;
+
 	avdtp_error_init(&avdtp_err, AVDTP_ERRNO, err);
 
 	if (discover->id > 0)
@@ -931,7 +933,6 @@ static void finalize_discovery(struct avdtp *session, int err)
 	discover->cb(session, session->seps, err ? &avdtp_err : NULL,
 							discover->user_data);
 	g_free(discover);
-	session->discover = NULL;
 }
 
 static void release_stream(struct avdtp_stream *stream, struct avdtp *session)
-- 
1.8.4.2


^ permalink raw reply related

* Re: [PATCH] android/haltest: Fix double file close
From: Anderson Lizardo @ 2014-01-13 17:54 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: BlueZ development
In-Reply-To: <1389259565-995-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

I see that you are fixing some issues pointed by Coverity Scan. Last
month, I registered a project there for BlueZ. If you are interested
in coordinating fixes (so we don't end up working on fixing the same
issues), let know the email you registered there so I can add you as
member of the project.

The same invitation applies to any regular BlueZ developer that wants
to work on analyzing and fixing bugs reported by Coverity. You can
also request to apply on the project page:

https://scan.coverity.com/projects/1109

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

^ permalink raw reply

* [PATCH] android/README: Update documentation with AOSP 4.4
From: Szymon Janc @ 2014-01-13 22:47 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This includes:
 - sample repository to AOSP 4.4 based repository with support for
   Nexus 4 and Nexus 7 2013 devices.
 - adds info about snoop service
 - other random additions
---
 android/README | 71 +++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 50 insertions(+), 21 deletions(-)

diff --git a/android/README b/android/README
index 9c804a3..39ca9d2 100644
--- a/android/README
+++ b/android/README
@@ -13,26 +13,29 @@ in android/hal-apc-api.txt file.
 Building and running on Android
 ===============================
 
+Steps needed to build and run Android Open Source Project 4.4.2 with
+integrated BlueZ.
+
 Build requirements
 ==================
 
 - GLib - Android 4.2 or later don't provide GLib and one must provide it in
 'external/bluetooth/glib' folder of Android tree. Sample Android GLib port
-is available at https://code.google.com/p/android-bluez.glib/
+is available at https://code.google.com/p/aosp-bluez.glib/
 
-- Bionic support - BlueZ requires signalfd and timerfd APIs to be provided
-by libc library. Currently only 'master' branch available at
+- Bionic support - Currently only 'master' branch available at
 https://android.googlesource.com/platform/bionic provides all required
-functionality and running BlueZ on older branch requires backporting missing
-features. Sample Bionic for Android on Intel Architecture (Android-IA) with all
-required features backported is available at
-https://code.google.com/p/android-bluez.bionic/
+functionality and running BlueZ on release branch requires backporting missing
+features (currently only epoll_create1 call for Android 4.4.2). Sample
+Bionic for Android 4.4.2 with all required features backported is available at
+https://code.google.com/p/aosp-bluez.platform-bionic/
 
 Runtime requirements
 ====================
 
-BlueZ HAL library requires 'bluetoothd' service to be available on Android
-system. This can be done by defining service in init.rc file of targeted board:
+BlueZ HAL library requires 'bluetoothd' and 'bluetoothd-snoop' services to be
+available on Android system. This can be done by defining following services in
+init.rc file of targeted board:
 
 service bluetoothd /system/bin/logwrapper /system/bin/bluetoothd
   class main
@@ -40,34 +43,60 @@ service bluetoothd /system/bin/logwrapper /system/bin/bluetoothd
   disabled
   oneshot
 
-It is required that bluetooth user could start and stop bluetoothd service by
-setting 'ctl.start' or 'ctl.stop' property. This can be achieved by
-whitelisting bluetooth user and bluetoothd service in init source code.
+service bluetoothd-snoop /system/bin/bluetoothd-snoop
+  class main
+  group bluetooth net_admin
+  disabled
+  oneshot
+
+It is required that bluetooth user could start and stop bluetoothd and
+bluetoothd-snoop services by setting 'ctl.start' or 'ctl.stop' property. This
+can be achieved by whitelisting bluetooth user and bluetoothd and
+bluetoothd-snoop services in init source code.
 
 Required Android init system modifications can be found at
-https://code.google.com/p/android-bluez.system-core/
+https://code.google.com/p/aosp-bluez.platform-system-core/
+
+Some configuration changes like setting permissions, starting hciattach
+services etc. are device specific. For convenience examples are provided at:
+https://code.google.com/p/aosp-bluez.device-lge-mako/    (Nexus 4)
+https://code.google.com/p/aosp-bluez.device-asus-flo/    (Nexus 7 2013)
 
 Downloading and building
 ========================
 
-Building for Android requires full Android AOSP source tree. Sample Android-IA
-tree with all required components present is available at
-http://code.google.com/p/android-bluez/
+Building for Android requires full Android AOSP source tree. Sample Android
+4.4.2 tree with all required components present is available at
+http://code.google.com/p/aosp-bluez/
+
+This tree provides support for Nexus4 (target aosp_mako-userdebug) and
+Nexus 7 2013 (target aosp_flo-userdebug). Tree does not provide binary blobs
+needed to run Android on supported devices. Those can be obtained from
+https://developers.google.com/android/nexus/drivers. Binary blobs needs to be
+unpacked (EULA acceptance required) into 'vendor' directory of Android tree.
 
 Downloading:
-repo init -u https://code.google.com/p/android-bluez.manifest/ -m topics/bluez
+repo init -u https://code.google.com/p/aosp-bluez.platform-manifest -b kitkat
 repo sync
 
-Build for Intel ultrabook:
-'source build/envsetup.sh'
-'lunch core_mesa-eng'
-'make allimages -j8'
+Building:
+source build/envsetup.sh
+lunch aosp_mako-userdebug    or    lunch aosp_flo-userdebug
+make -j8
+
+Flashing:
+adb reboot bootloader
+fastboot flashall -w
 
 After full build is done it is possible to rebuild only BlueZ:
 'cd external/bluetooth/bluez/android/'
 'mm' (or 'mm -B' to force rebuilding of all files)
 'adb sync' to update target device.
 
+Linux Kernel requirements
+=========================
+TODO add section about kernel requirements
+
 =============================
 Building and running on Linux
 =============================
-- 
1.8.5.2


^ permalink raw reply related

* Re: [PATCH] tools/bluetooth-player: current-folder command
From: Luiz Augusto von Dentz @ 2014-01-14  9:20 UTC (permalink / raw)
  To: Sebastian Chlad; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1389633824-6871-1-git-send-email-sebastianx.chlad@intel.com>

Hi Sebastian,

On Mon, Jan 13, 2014 at 7:23 PM, Sebastian Chlad
<sebastianx.chlad@intel.com> wrote:
> Add current-folder command listing path to the current folder
> ---
>  tools/bluetooth-player.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>
> diff --git a/tools/bluetooth-player.c b/tools/bluetooth-player.c
> index f10d9be..1c0348e 100644
> --- a/tools/bluetooth-player.c
> +++ b/tools/bluetooth-player.c
> @@ -891,6 +891,23 @@ done:
>         rl_printf("Attempting to list items\n");
>  }
>
> +static void cmd_current_folder(int argc, char *argv[])
> +{
> +       GDBusProxy *proxy;
> +       GDBusProxy *folder;
> +
> +       if (check_default_player() == FALSE)
> +               return;
> +
> +       proxy = default_player;
> +       folder = find_folder(g_dbus_proxy_get_path(proxy));
> +
> +       if (folder == NULL)
> +               return;
> +
> +       print_property(folder, "Name");
> +}
> +
>  static void search_setup(DBusMessageIter *iter, void *user_data)
>  {
>         char *string = user_data;
> @@ -1023,6 +1040,8 @@ static const struct {
>                                                 "Change current folder" },
>         { "list-items", "[start] [end]",  cmd_list_items,
>                                         "List items of current folder" },
> +       { "current-folder", NULL,     cmd_current_folder,
> +                                       "Show current folder name and path" },
>         { "search",     "string",     cmd_search,
>                                         "Search items containing string" },
>         { "queue",       "<item>",    cmd_queue, "Add item to playlist queue" },
> --
> 1.8.3.2

Command show already prints the current folder, what I had in mind is
to print to prompt the address and folder e.g. XX:..:/folder> but
never had time to do it.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH] android/bluetooth: Fix discovering new devices
From: Szymon Janc @ 2014-01-14  9:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Device found events should be send also for known devices if this is
new discovery session. Otherwise Android will ignore those devices.
---
 android/bluetooth.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index f1e5458..735b03e 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -90,6 +90,8 @@ struct device {
 	uint32_t timestamp;
 
 	GSList *uuids;
+
+	bool found; /* if device is found in current discovery session */
 };
 
 struct browse_req {
@@ -924,10 +926,19 @@ static void mgmt_discovering_event(uint16_t index, uint16_t length,
 
 	DBG("new discovering state %u", ev->discovering);
 
-	if (adapter.discovering)
+	if (adapter.discovering) {
 		cp.state = HAL_DISCOVERY_STATE_STARTED;
-	else
+	} else {
+		GSList *l;
+
+		for(l = devices; l; l = g_slist_next(l)) {
+			struct device *dev = l->data;
+
+			dev->found = false;
+		}
+
 		cp.state = HAL_DISCOVERY_STATE_STOPPED;
+	}
 
 	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH,
 			HAL_EV_DISCOVERY_STATE_CHANGED, sizeof(cp), &cp);
@@ -966,6 +977,17 @@ static uint8_t bdaddr_type2android(uint8_t type)
 	return HAL_TYPE_LE;
 }
 
+static bool device_found_needed(struct device *dev)
+{
+	if (!dev)
+		return true;
+
+	if (dev->bond_state == HAL_BOND_STATE_BONDED)
+		return false;
+
+	return !dev->found;
+}
+
 static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 					int8_t rssi, bool confirm,
 					const uint8_t *data, uint8_t data_len)
@@ -983,12 +1005,15 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 	eir_parse(&eir, data, data_len);
 
 	dev = find_device(bdaddr);
-	if (!dev) {
+	if (device_found_needed(dev)) {
 		struct hal_ev_device_found *ev = (void *) buf;
 		bdaddr_t android_bdaddr;
 		uint8_t android_type;
 
-		dev = create_device(bdaddr, bdaddr_type);
+		if (!dev)
+			dev = create_device(bdaddr, bdaddr_type);
+
+		dev->found = true;
 
 		size += sizeof(*ev);
 
-- 
1.8.3.2


^ permalink raw reply related

* RE: [PATCH] tools/bluetooth-player: current-folder command
From: Chlad, SebastianX @ 2014-01-14  9:44 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZLCqg+nNanXCv7J1kj=xzDB0S-FGonyyu4yHRzjs+KJOw@mail.gmail.com>


________________________________________
From: Luiz Augusto von Dentz [luiz.dentz@gmail.com]
Sent: Tuesday, January 14, 2014 11:20 AM
To: Chlad, SebastianX
Cc: linux-bluetooth@vger.kernel.org
Subject: Re: [PATCH] tools/bluetooth-player: current-folder command

Hi Sebastian,

On Mon, Jan 13, 2014 at 7:23 PM, Sebastian Chlad
<sebastianx.chlad@intel.com> wrote:
> Add current-folder command listing path to the current folder
> ---
>  tools/bluetooth-player.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>
> diff --git a/tools/bluetooth-player.c b/tools/bluetooth-player.c
> index f10d9be..1c0348e 100644
> --- a/tools/bluetooth-player.c
> +++ b/tools/bluetooth-player.c
> @@ -891,6 +891,23 @@ done:
>         rl_printf("Attempting to list items\n");
>  }
>
> +static void cmd_current_folder(int argc, char *argv[])
> +{
> +       GDBusProxy *proxy;
> +       GDBusProxy *folder;
> +
> +       if (check_default_player() == FALSE)
> +               return;
> +
> +       proxy = default_player;
> +       folder = find_folder(g_dbus_proxy_get_path(proxy));
> +
> +       if (folder == NULL)
> +               return;
> +
> +       print_property(folder, "Name");
> +}
> +
>  static void search_setup(DBusMessageIter *iter, void *user_data)
>  {
>         char *string = user_data;
> @@ -1023,6 +1040,8 @@ static const struct {
>                                                 "Change current folder" },
>         { "list-items", "[start] [end]",  cmd_list_items,
>                                         "List items of current folder" },
> +       { "current-folder", NULL,     cmd_current_folder,
> +                                       "Show current folder name and path" },
>         { "search",     "string",     cmd_search,
>                                         "Search items containing string" },
>         { "queue",       "<item>",    cmd_queue, "Add item to playlist queue" },
> --
> 1.8.3.2

Command show already prints the current folder, what I had in mind is
to print to prompt the address and folder e.g. XX:..:/folder> but
never had time to do it.

Yup, 'show' prints current folder, however I found it inconvenient to use while using bluetooth-player; if one wants to check the current folder, hitting 'show' cmd prints just to much info.
Anyhow I was thinking about same -> having prompt with both address and folder. Let me see what I could do about it.

Sebastian


--
Luiz Augusto von Dentz
---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply

* [BlueZ v2 01/12] audio/A2DP: Add implemention of SEP open indication
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth

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

---
 android/a2dp.c | 49 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 14 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 1f7678a..1a9adb8 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -581,9 +581,44 @@ static gboolean sep_setconf_ind(struct avdtp *session,
 	return TRUE;
 }
 
+static struct a2dp_setup *find_setup(uint8_t id)
+{
+	GSList *l;
+
+	for (l = setups; l; l = g_slist_next(l)) {
+		struct a2dp_setup *setup = l->data;
+
+		if (setup->endpoint->id == id)
+			return setup;
+	}
+
+	return NULL;
+}
+
+static gboolean sep_open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
+				struct avdtp_stream *stream, uint8_t *err,
+				void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+	struct a2dp_setup *setup;
+
+	DBG("");
+
+	setup = find_setup(endpoint->id);
+	if (!setup) {
+		error("Unable to find stream setup for endpoint %u",
+								endpoint->id);
+		*err = AVDTP_SEP_NOT_IN_USE;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 static struct avdtp_sep_ind sep_ind = {
 	.get_capability		= sep_getcap_ind,
 	.set_configuration	= sep_setconf_ind,
+	.open			= sep_open_ind,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
@@ -713,20 +748,6 @@ static void bt_audio_close(const void *buf, uint16_t len)
 	audio_ipc_send_rsp(AUDIO_OP_CLOSE, AUDIO_STATUS_SUCCESS);
 }
 
-static struct a2dp_setup *find_setup(uint8_t id)
-{
-	GSList *l;
-
-	for (l = setups; l; l = g_slist_next(l)) {
-		struct a2dp_setup *setup = l->data;
-
-		if (setup->endpoint->id == id)
-			return setup;
-	}
-
-	return NULL;
-}
-
 static void bt_stream_open(const void *buf, uint16_t len)
 {
 	const struct audio_cmd_open_stream *cmd = buf;
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 02/12] audio/A2DP: Add implemention of SEP close indication
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 1a9adb8..9aebc9d 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -514,6 +514,12 @@ static void setup_free(void *data)
 	g_free(setup);
 }
 
+static void setup_remove(struct a2dp_setup *setup)
+{
+	setups = g_slist_remove(setups, setup);
+	setup_free(setup);
+}
+
 static void setup_add(struct a2dp_device *dev, struct a2dp_endpoint *endpoint,
 			struct a2dp_preset *preset, struct avdtp_stream *stream)
 {
@@ -615,10 +621,35 @@ static gboolean sep_open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 	return TRUE;
 }
 
+static gboolean sep_close_ind(struct avdtp *session,
+						struct avdtp_local_sep *sep,
+						struct avdtp_stream *stream,
+						uint8_t *err,
+						void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+	struct a2dp_setup *setup;
+
+	DBG("");
+
+	setup = find_setup(endpoint->id);
+	if (!setup) {
+		error("Unable to find stream setup for endpoint %u",
+								endpoint->id);
+		*err = AVDTP_SEP_NOT_IN_USE;
+		return FALSE;
+	}
+
+	setup_remove(setup);
+
+	return TRUE;
+}
+
 static struct avdtp_sep_ind sep_ind = {
 	.get_capability		= sep_getcap_ind,
 	.set_configuration	= sep_setconf_ind,
 	.open			= sep_open_ind,
+	.close			= sep_close_ind,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 03/12] audio/A2DP: Add implemention of SEP start indication
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 9aebc9d..1b12767 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -645,11 +645,34 @@ static gboolean sep_close_ind(struct avdtp *session,
 	return TRUE;
 }
 
+static gboolean sep_start_ind(struct avdtp *session,
+						struct avdtp_local_sep *sep,
+						struct avdtp_stream *stream,
+						uint8_t *err,
+						void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+	struct a2dp_setup *setup;
+
+	DBG("");
+
+	setup = find_setup(endpoint->id);
+	if (!setup) {
+		error("Unable to find stream setup for endpoint %u",
+								endpoint->id);
+		*err = AVDTP_SEP_NOT_IN_USE;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 static struct avdtp_sep_ind sep_ind = {
 	.get_capability		= sep_getcap_ind,
 	.set_configuration	= sep_setconf_ind,
 	.open			= sep_open_ind,
 	.close			= sep_close_ind,
+	.start			= sep_start_ind,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 04/12] audio/A2DP: Add implemention of SEP suspend indication
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 1b12767..a483514 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -667,12 +667,35 @@ static gboolean sep_start_ind(struct avdtp *session,
 	return TRUE;
 }
 
+static gboolean sep_suspend_ind(struct avdtp *session,
+						struct avdtp_local_sep *sep,
+						struct avdtp_stream *stream,
+						uint8_t *err,
+						void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+	struct a2dp_setup *setup;
+
+	DBG("");
+
+	setup = find_setup(endpoint->id);
+	if (!setup) {
+		error("Unable to find stream setup for endpoint %u",
+								endpoint->id);
+		*err = AVDTP_SEP_NOT_IN_USE;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 static struct avdtp_sep_ind sep_ind = {
 	.get_capability		= sep_getcap_ind,
 	.set_configuration	= sep_setconf_ind,
 	.open			= sep_open_ind,
 	.close			= sep_close_ind,
 	.start			= sep_start_ind,
+	.suspend		= sep_suspend_ind,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 05/12] android/A2DP: Discover endpoints when initiator
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 244 +++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 184 insertions(+), 60 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index a483514..8d0884c 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -173,6 +173,166 @@ static void disconnect_cb(void *user_data)
 	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
 }
 
+static int sbc_check_config(void *caps, uint8_t caps_len, void *conf,
+							uint8_t conf_len)
+{
+	a2dp_sbc_t *cap, *config;
+
+	if (conf_len != caps_len || conf_len != sizeof(a2dp_sbc_t)) {
+		error("SBC: Invalid configuration size (%u)", conf_len);
+		return -EINVAL;
+	}
+
+	cap = caps;
+	config = conf;
+
+	if (!(cap->frequency & config->frequency)) {
+		error("SBC: Unsupported frequency (%u) by endpoint",
+							config->frequency);
+		return -EINVAL;
+	}
+
+	if (!(cap->channel_mode & config->channel_mode)) {
+		error("SBC: Unsupported channel mode (%u) by endpoint",
+							config->channel_mode);
+		return -EINVAL;
+	}
+
+	if (!(cap->block_length & config->block_length)) {
+		error("SBC: Unsupported block length (%u) by endpoint",
+							config->block_length);
+		return -EINVAL;
+	}
+
+	if (!(cap->allocation_method & config->allocation_method)) {
+		error("SBC: Unsupported allocation method (%u) by endpoint",
+							config->block_length);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int check_capabilities(struct a2dp_preset *preset,
+				struct avdtp_media_codec_capability *codec,
+				uint8_t codec_len)
+{
+	/* Codec specific */
+	switch (codec->media_codec_type) {
+	case A2DP_CODEC_SBC:
+		return sbc_check_config(codec->data, codec_len, preset->data,
+								preset->len);
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct a2dp_preset *select_preset(struct a2dp_endpoint *endpoint,
+						struct avdtp_remote_sep *rsep)
+{
+	struct avdtp_service_capability *service;
+	struct avdtp_media_codec_capability *codec;
+	GSList *l;
+
+	service = avdtp_get_codec(rsep);
+	codec = (struct avdtp_media_codec_capability *) service->data;
+
+	for (l = endpoint->presets; l; l = g_slist_next(l)) {
+		struct a2dp_preset *preset = l->data;
+
+		if (check_capabilities(preset, codec,
+					service->length - sizeof(*codec)) == 0)
+			return preset;
+	}
+
+	return NULL;
+}
+
+static void setup_add(struct a2dp_device *dev, struct a2dp_endpoint *endpoint,
+			struct a2dp_preset *preset, struct avdtp_stream *stream)
+{
+	struct a2dp_setup *setup;
+
+	setup = g_new0(struct a2dp_setup, 1);
+	setup->dev = dev;
+	setup->endpoint = endpoint;
+	setup->preset = preset;
+	setup->stream = stream;
+	setups = g_slist_append(setups, setup);
+}
+
+static int select_configuration(struct a2dp_device *dev,
+				struct a2dp_endpoint *endpoint,
+				struct avdtp_remote_sep *rsep)
+{
+	struct a2dp_preset *preset;
+	struct avdtp_stream *stream;
+	struct avdtp_service_capability *service;
+	struct avdtp_media_codec_capability *codec;
+	GSList *caps;
+	int err;
+
+	preset = select_preset(endpoint, rsep);
+	if (!preset) {
+		error("Unable to select codec preset");
+		return -EINVAL;
+	}
+
+	service = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, NULL, 0);
+	caps = g_slist_append(NULL, service);
+
+	codec = g_malloc0(sizeof(*codec) + preset->len);
+	codec->media_type = AVDTP_MEDIA_TYPE_AUDIO;
+	codec->media_codec_type = endpoint->codec;
+	memcpy(codec->data, preset->data, preset->len);
+
+	service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec,
+						sizeof(*codec) + preset->len);
+	caps = g_slist_append(caps, service);
+
+	err = avdtp_set_configuration(dev->session, rsep, endpoint->sep, caps,
+								&stream);
+	g_slist_free_full(caps, g_free);
+	if (err < 0) {
+		error("avdtp_set_configuration: %s", strerror(-err));
+		return err;
+	}
+
+	setup_add(dev, endpoint, preset, stream);
+
+	return 0;
+}
+
+static void discover_cb(struct avdtp *session, GSList *seps,
+				struct avdtp_error *err, void *user_data)
+{
+	struct a2dp_device *dev = user_data;
+	struct a2dp_endpoint *endpoint = NULL;
+	struct avdtp_remote_sep *rsep = NULL;
+	GSList *l;
+
+	for (l = endpoints; l; l = g_slist_next(l)) {
+		endpoint = l->data;
+
+		rsep = avdtp_find_remote_sep(session, endpoint->sep);
+		if (rsep)
+			break;
+	}
+
+	if (!rsep) {
+		error("Unable to find matching endpoint");
+		goto failed;
+	}
+
+	if (select_configuration(dev, endpoint, rsep) < 0)
+		goto failed;
+
+	return;
+
+failed:
+	avdtp_shutdown(session);
+}
+
 static void signaling_connect_cb(GIOChannel *chan, GError *err,
 							gpointer user_data)
 {
@@ -192,20 +352,17 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
 			BT_IO_OPT_OMTU, &omtu,
 			BT_IO_OPT_INVALID);
 	if (gerr) {
-		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
 		error("%s", gerr->message);
 		g_error_free(gerr);
-		return;
+		goto failed;
 	}
 
 	fd = g_io_channel_unix_get_fd(chan);
 
 	/* FIXME: Add proper version */
 	dev->session = avdtp_new(fd, imtu, omtu, 0x0100);
-	if (!dev->session) {
-		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
-		return;
-	}
+	if (!dev->session)
+		goto failed;
 
 	avdtp_add_disconnect_cb(dev->session, disconnect_cb, dev);
 
@@ -214,7 +371,23 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
 		dev->io = NULL;
 	}
 
+	/* Proceed to stream setup if initiator */
+	if (dev->state == HAL_A2DP_STATE_CONNECTING) {
+		int perr;
+
+		perr = avdtp_discover(dev->session, discover_cb, dev);
+		if (perr < 0) {
+			error("avdtp_discover: %s", strerror(-perr));
+			goto failed;
+		}
+	}
+
 	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTED);
+
+	return;
+
+failed:
+	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
 }
 
 static void bt_a2dp_connect(const void *buf, uint16_t len)
@@ -428,50 +601,11 @@ static gboolean sep_getcap_ind(struct avdtp *session,
 	return TRUE;
 }
 
-static int sbc_check_config(struct a2dp_endpoint *endpoint,
-						struct a2dp_preset *conf)
-{
-	a2dp_sbc_t *caps, *config;
-
-	if (conf->len != sizeof(a2dp_sbc_t)) {
-		error("SBC: Invalid configuration size (%u)", conf->len);
-		return -EINVAL;
-	}
-
-	caps = endpoint->caps->data;
-	config = conf->data;
-
-	if (!(caps->frequency & config->frequency)) {
-		error("SBC: Unsupported frequency (%u) by endpoint",
-							config->frequency);
-		return -EINVAL;
-	}
-
-	if (!(caps->channel_mode & config->channel_mode)) {
-		error("SBC: Unsupported channel mode (%u) by endpoint",
-							config->channel_mode);
-		return -EINVAL;
-	}
-
-	if (!(caps->block_length & config->block_length)) {
-		error("SBC: Unsupported block length (%u) by endpoint",
-							config->block_length);
-		return -EINVAL;
-	}
-
-	if (!(caps->allocation_method & config->allocation_method)) {
-		error("SBC: Unsupported allocation method (%u) by endpoint",
-							config->block_length);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static int check_config(struct a2dp_endpoint *endpoint,
 						struct a2dp_preset *config)
 {
 	GSList *l;
+	struct a2dp_preset *caps;
 
 	for (l = endpoint->presets; l; l = g_slist_next(l)) {
 		struct a2dp_preset *preset = l->data;
@@ -483,10 +617,13 @@ static int check_config(struct a2dp_endpoint *endpoint,
 			return 0;
 	}
 
+	caps = endpoint->caps;
+
 	/* Codec specific */
 	switch (endpoint->codec) {
 	case A2DP_CODEC_SBC:
-		return sbc_check_config(endpoint, config);
+		return sbc_check_config(caps->data, caps->len, config->data,
+								config->len);
 	default:
 		return -EINVAL;
 	}
@@ -520,19 +657,6 @@ static void setup_remove(struct a2dp_setup *setup)
 	setup_free(setup);
 }
 
-static void setup_add(struct a2dp_device *dev, struct a2dp_endpoint *endpoint,
-			struct a2dp_preset *preset, struct avdtp_stream *stream)
-{
-	struct a2dp_setup *setup;
-
-	setup = g_new0(struct a2dp_setup, 1);
-	setup->dev = dev;
-	setup->endpoint = endpoint;
-	setup->preset = preset;
-	setup->stream = stream;
-	setups = g_slist_append(setups, setup);
-}
-
 static gboolean sep_setconf_ind(struct avdtp *session,
 						struct avdtp_local_sep *sep,
 						struct avdtp_stream *stream,
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 06/12] audio/A2DP: Add implemention of SEP set_configuration confirmation
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 8d0884c..afc6331 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -822,6 +822,42 @@ static struct avdtp_sep_ind sep_ind = {
 	.suspend		= sep_suspend_ind,
 };
 
+static void sep_setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
+				struct avdtp_stream *stream,
+				struct avdtp_error *err, void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+	struct a2dp_setup *setup;
+	int ret;
+
+	DBG("");
+
+	setup = find_setup(endpoint->id);
+	if (!setup) {
+		error("Unable to find stream setup for endpoint %u",
+								endpoint->id);
+		return;
+	}
+
+	if (err)
+		goto failed;
+
+	ret = avdtp_open(session, stream);
+	if (ret < 0) {
+		error("avdtp_open: %s", strerror(-ret));
+		goto failed;
+	}
+
+	return;
+
+failed:
+	setup_remove(setup);
+}
+
+static struct avdtp_sep_cfm sep_cfm = {
+	.set_configuration	= sep_setconf_cfm,
+};
+
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
 							GSList *presets)
 {
@@ -834,8 +870,8 @@ static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
 	endpoint->codec = codec;
 	endpoint->sep = avdtp_register_sep(AVDTP_SEP_TYPE_SOURCE,
 						AVDTP_MEDIA_TYPE_AUDIO,
-						codec, FALSE, &sep_ind, NULL,
-						endpoint);
+						codec, FALSE, &sep_ind,
+						&sep_cfm, endpoint);
 	endpoint->caps = presets->data;
 	endpoint->presets = g_slist_copy(g_slist_nth(presets, 1));
 
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 07/12] audio/A2DP: Add implemention of SEP open confirmation
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 56 ++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index afc6331..59f8bf5 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -657,6 +657,33 @@ static void setup_remove(struct a2dp_setup *setup)
 	setup_free(setup);
 }
 
+static struct a2dp_setup *find_setup(uint8_t id)
+{
+	GSList *l;
+
+	for (l = setups; l; l = g_slist_next(l)) {
+		struct a2dp_setup *setup = l->data;
+
+		if (setup->endpoint->id == id)
+			return setup;
+	}
+
+	return NULL;
+}
+
+static void setup_remove_by_id(uint8_t id)
+{
+	struct a2dp_setup *setup;
+
+	setup = find_setup(id);
+	if (!setup) {
+		error("Unable to find stream setup for endpoint %u", id);
+		return;
+	}
+
+	setup_remove(setup);
+}
+
 static gboolean sep_setconf_ind(struct avdtp *session,
 						struct avdtp_local_sep *sep,
 						struct avdtp_stream *stream,
@@ -711,20 +738,6 @@ static gboolean sep_setconf_ind(struct avdtp *session,
 	return TRUE;
 }
 
-static struct a2dp_setup *find_setup(uint8_t id)
-{
-	GSList *l;
-
-	for (l = setups; l; l = g_slist_next(l)) {
-		struct a2dp_setup *setup = l->data;
-
-		if (setup->endpoint->id == id)
-			return setup;
-	}
-
-	return NULL;
-}
-
 static gboolean sep_open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 				struct avdtp_stream *stream, uint8_t *err,
 				void *user_data)
@@ -854,8 +867,23 @@ failed:
 	setup_remove(setup);
 }
 
+static void sep_open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
+			struct avdtp_stream *stream, struct avdtp_error *err,
+			void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+
+	DBG("");
+
+	if (!err)
+		return;
+
+	setup_remove_by_id(endpoint->id);
+}
+
 static struct avdtp_sep_cfm sep_cfm = {
 	.set_configuration	= sep_setconf_cfm,
+	.open			= sep_open_cfm,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 08/12] audio/A2DP: Add implemention of SEP start confirmation
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 59f8bf5..940cb9c 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -881,9 +881,24 @@ static void sep_open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 	setup_remove_by_id(endpoint->id);
 }
 
+static void sep_start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
+			struct avdtp_stream *stream, struct avdtp_error *err,
+			void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+
+	DBG("");
+
+	if (!err)
+		return;
+
+	setup_remove_by_id(endpoint->id);
+}
+
 static struct avdtp_sep_cfm sep_cfm = {
 	.set_configuration	= sep_setconf_cfm,
 	.open			= sep_open_cfm,
+	.start			= sep_start_cfm,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 09/12] audio/A2DP: Add implemention of SEP suspend confirmation
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 940cb9c..17f7a9f 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -895,10 +895,25 @@ static void sep_start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 	setup_remove_by_id(endpoint->id);
 }
 
+static void sep_suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
+			struct avdtp_stream *stream, struct avdtp_error *err,
+			void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+
+	DBG("");
+
+	if (!err)
+		return;
+
+	setup_remove_by_id(endpoint->id);
+}
+
 static struct avdtp_sep_cfm sep_cfm = {
 	.set_configuration	= sep_setconf_cfm,
 	.open			= sep_open_cfm,
 	.start			= sep_start_cfm,
+	.suspend		= sep_suspend_cfm,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 10/12] audio/A2DP: Add implemention of SEP close confirmation
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 17f7a9f..146abd3 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -909,11 +909,26 @@ static void sep_suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 	setup_remove_by_id(endpoint->id);
 }
 
+static void sep_close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
+			struct avdtp_stream *stream, struct avdtp_error *err,
+			void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+
+	DBG("");
+
+	if (err)
+		return;
+
+	setup_remove_by_id(endpoint->id);
+}
+
 static struct avdtp_sep_cfm sep_cfm = {
 	.set_configuration	= sep_setconf_cfm,
 	.open			= sep_open_cfm,
 	.start			= sep_start_cfm,
 	.suspend		= sep_suspend_cfm,
+	.close			= sep_close_cfm,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 11/12] audio/A2DP: Add implemention of SEP abort confirmation
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 146abd3..9f3164a 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -923,12 +923,27 @@ static void sep_close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 	setup_remove_by_id(endpoint->id);
 }
 
+static void sep_abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
+			struct avdtp_stream *stream, struct avdtp_error *err,
+			void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+
+	DBG("");
+
+	if (err)
+		return;
+
+	setup_remove_by_id(endpoint->id);
+}
+
 static struct avdtp_sep_cfm sep_cfm = {
 	.set_configuration	= sep_setconf_cfm,
 	.open			= sep_open_cfm,
 	.start			= sep_start_cfm,
 	.suspend		= sep_suspend_cfm,
 	.close			= sep_close_cfm,
+	.abort			= sep_abort_cfm,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 12/12] android/AVDTP: Fix invalid free of struct discover
From: Luiz Augusto von Dentz @ 2014-01-14 10:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

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

If callback releases the last reference it can cause the following:
Invalid free() / delete / delete[] / realloc()
   at 0x4A07577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x386244EF7E: g_free (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x410356: finalize_discovery (avdtp.c:933)
   by 0x414462: session_cb (avdtp.c:2555)
   by 0x38624492A5: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x3862449627: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x3862449A39: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x403A95: main (main.c:439)
 Address 0x4cf7af0 is 0 bytes inside a block of size 24 free'd
   at 0x4A07577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x386244EF7E: g_free (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x410356: finalize_discovery (avdtp.c:933)
   by 0x4110BC: avdtp_unref (avdtp.c:1026)
   by 0x416491: a2dp_device_free (a2dp.c:122)
   by 0x4165DF: bt_a2dp_notify_state (a2dp.c:166)
   by 0x417170: discover_cb (a2dp.c:333)
   by 0x41034E: finalize_discovery (avdtp.c:931)
   by 0x414462: session_cb (avdtp.c:2555)
   by 0x38624492A5: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x3862449627: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
   by 0x3862449A39: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3800.2)
---
 android/avdtp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/android/avdtp.c b/android/avdtp.c
index 473e02b..5da1206 100644
--- a/android/avdtp.c
+++ b/android/avdtp.c
@@ -923,6 +923,8 @@ static void finalize_discovery(struct avdtp *session, int err)
 	if (!discover)
 		return;
 
+	session->discover = NULL;
+
 	avdtp_error_init(&avdtp_err, AVDTP_ERRNO, err);
 
 	if (discover->id > 0)
@@ -931,7 +933,6 @@ static void finalize_discovery(struct avdtp *session, int err)
 	discover->cb(session, session->seps, err ? &avdtp_err : NULL,
 							discover->user_data);
 	g_free(discover);
-	session->discover = NULL;
 }
 
 static void release_stream(struct avdtp_stream *stream, struct avdtp *session)
-- 
1.8.4.2


^ permalink raw reply related

* Re: [BlueZ v2 01/12] audio/A2DP: Add implemention of SEP open indication
From: Szymon Janc @ 2014-01-14 10:54 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1389696168-26947-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Tuesday 14 of January 2014 12:42:37 Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> ---
>  android/a2dp.c | 49 +++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 35 insertions(+), 14 deletions(-)
> 
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 1f7678a..1a9adb8 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -581,9 +581,44 @@ static gboolean sep_setconf_ind(struct avdtp *session,
>  	return TRUE;
>  }
>  
> +static struct a2dp_setup *find_setup(uint8_t id)
> +{
> +	GSList *l;
> +
> +	for (l = setups; l; l = g_slist_next(l)) {
> +		struct a2dp_setup *setup = l->data;
> +
> +		if (setup->endpoint->id == id)
> +			return setup;
> +	}
> +
> +	return NULL;
> +}
> +
> +static gboolean sep_open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
> +				struct avdtp_stream *stream, uint8_t *err,
> +				void *user_data)
> +{
> +	struct a2dp_endpoint *endpoint = user_data;
> +	struct a2dp_setup *setup;
> +
> +	DBG("");
> +
> +	setup = find_setup(endpoint->id);
> +	if (!setup) {
> +		error("Unable to find stream setup for endpoint %u",
> +								endpoint->id);
> +		*err = AVDTP_SEP_NOT_IN_USE;
> +		return FALSE;
> +	}
> +
> +	return TRUE;
> +}
> +
>  static struct avdtp_sep_ind sep_ind = {
>  	.get_capability		= sep_getcap_ind,
>  	.set_configuration	= sep_setconf_ind,
> +	.open			= sep_open_ind,
>  };
>  
>  static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
> @@ -713,20 +748,6 @@ static void bt_audio_close(const void *buf, uint16_t len)
>  	audio_ipc_send_rsp(AUDIO_OP_CLOSE, AUDIO_STATUS_SUCCESS);
>  }
>  
> -static struct a2dp_setup *find_setup(uint8_t id)
> -{
> -	GSList *l;
> -
> -	for (l = setups; l; l = g_slist_next(l)) {
> -		struct a2dp_setup *setup = l->data;
> -
> -		if (setup->endpoint->id == id)
> -			return setup;
> -	}
> -
> -	return NULL;
> -}
> -
>  static void bt_stream_open(const void *buf, uint16_t len)
>  {
>  	const struct audio_cmd_open_stream *cmd = buf;
> 

All patches in this set have been applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [RFC 0/5] Remote device cache support
From: Szymon Janc @ 2014-01-14 11:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Hi All,

This adds support for permanent cache of remote devices info. Cache size is
limited to DEVICES_CACHE_MAX (currently 100) and oldest devices (based on
timestamp) is removed if cache gets full.

notes:
 - there is still place for improvements in number of reads/writes done.
   Will work on that when current cache approach is accepted.
 - there is no need to cache SDP (we cache UUIDs)

Comments are welcome.

-- 
BR
Szymon Janc

Szymon Janc (5):
  android/bluetooth: Split devices list to devices and bonded_devices
  android/bluetooth: Use defines for settings and devices files paths
  android/bluetooth: Always store device info
  android/bluetooth: Add support for caching remote device info
  android/bluetooth: Add support for loading caches devices from storage

 android/bluetooth.c | 199 ++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 148 insertions(+), 51 deletions(-)

-- 
1.8.3.2


^ permalink raw reply

* [RFC 1/5] android/bluetooth: Split devices list to devices and bonded_devices
From: Szymon Janc @ 2014-01-14 11:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1389697905-18532-1-git-send-email-szymon.janc@tieto.com>

From: Szymon Janc <szymon.janc@gmail.com>

Bonded devices are permament until unbondedn. Non-bonded devices will
be held in (size limited) cache based on timestamp property so split
list to ease separation.
---
 android/bluetooth.c | 47 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 735b03e..78e98c1 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -133,6 +133,8 @@ static const uint16_t uuid_list[] = {
 };
 
 static struct mgmt *mgmt_if = NULL;
+
+static GSList *bonded_devices = NULL;
 static GSList *devices = NULL;
 
 /* This list contains addresses which are asked for records */
@@ -284,6 +286,10 @@ static struct device *find_device(const bdaddr_t *bdaddr)
 {
 	GSList *l;
 
+	l = g_slist_find_custom(bonded_devices, bdaddr, device_match);
+	if (l)
+		return l->data;
+
 	l = g_slist_find_custom(devices, bdaddr, device_match);
 	if (l)
 		return l->data;
@@ -560,12 +566,30 @@ static void set_device_bond_state(const bdaddr_t *addr, uint8_t status,
 	if (!dev)
 		return;
 
-	if (dev->bond_state != state) {
-		dev->bond_state = state;
-		send_bond_state_change(&dev->bdaddr, status, state);
+	if (dev->bond_state == state)
+		return;
 
-		store_device_info(dev);
+	switch (state) {
+	case HAL_BOND_STATE_NONE:
+		if (dev->bond_state == HAL_BOND_STATE_BONDED) {
+			bonded_devices = g_slist_remove(bonded_devices, dev);
+			devices = g_slist_prepend(devices, dev);
+		}
+		break;
+	case HAL_BOND_STATE_BONDED:
+		devices = g_slist_remove(devices, dev);
+		bonded_devices = g_slist_prepend(bonded_devices, dev);
+		break;
+	case HAL_BOND_STATE_BONDING:
+	default:
+		break;
 	}
+
+	dev->bond_state = state;
+
+	store_device_info(dev);
+
+	send_bond_state_change(&dev->bdaddr, status, state);
 }
 
 static  void send_device_property(const bdaddr_t *bdaddr, uint8_t type,
@@ -2134,18 +2158,15 @@ static uint8_t get_adapter_scan_mode(void)
 
 static uint8_t get_adapter_bonded_devices(void)
 {
-	uint8_t buf[sizeof(bdaddr_t) * g_slist_length(devices)];
+	uint8_t buf[sizeof(bdaddr_t) * g_slist_length(bonded_devices)];
 	int i = 0;
 	GSList *l;
 
 	DBG("");
 
-	for (l = devices; l; l = g_slist_next(l)) {
+	for (l = bonded_devices; l; l = g_slist_next(l)) {
 		struct device *dev = l->data;
 
-		if (dev->bond_state != HAL_BOND_STATE_BONDED)
-			continue;
-
 		bdaddr2android(&dev->bdaddr, buf + (i * sizeof(bdaddr_t)));
 		i++;
 	}
@@ -2697,11 +2718,10 @@ static void send_bonded_devices_props(void)
 {
 	GSList *l;
 
-	for (l = devices; l; l = g_slist_next(l)) {
+	for (l = bonded_devices; l; l = g_slist_next(l)) {
 		struct device *dev = l->data;
 
-		if (dev->bond_state == HAL_BOND_STATE_BONDED)
-			get_remote_device_props(dev);
+		get_remote_device_props(dev);
 	}
 }
 
@@ -3099,6 +3119,9 @@ void bt_bluetooth_unregister(void)
 {
 	DBG("");
 
+	g_slist_free_full(bonded_devices, (GDestroyNotify) free_device);
+	bonded_devices = NULL;
+
 	g_slist_free_full(devices, (GDestroyNotify) free_device);
 	devices = NULL;
 
-- 
1.8.3.2


^ permalink raw reply related

* [RFC 2/5] android/bluetooth: Use defines for settings and devices files paths
From: Szymon Janc @ 2014-01-14 11:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1389697905-18532-1-git-send-email-szymon.janc@tieto.com>

From: Szymon Janc <szymon.janc@gmail.com>

---
 android/bluetooth.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 78e98c1..23a528a 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -54,6 +54,9 @@
 
 #define DUT_MODE_FILE "/sys/kernel/debug/bluetooth/hci%u/dut_mode"
 
+#define SETTINGS_FILE ANDROID_STORAGEDIR"/settings"
+#define DEVICES_FILE ANDROID_STORAGEDIR"/devices"
+
 #define DEVICE_ID_SOURCE	0x0002	/* USB */
 #define DEVICE_ID_VENDOR	0x1d6b	/* Linux Foundation */
 #define DEVICE_ID_PRODUCT	0x0247	/* BlueZ for Android */
@@ -149,8 +152,7 @@ static void store_adapter_config(void)
 
 	key_file = g_key_file_new();
 
-	g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings", 0,
-									NULL);
+	g_key_file_load_from_file(key_file, SETTINGS_FILE, 0, NULL);
 
 	ba2str(&adapter.bdaddr, addr);
 
@@ -161,7 +163,7 @@ static void store_adapter_config(void)
 
 	data = g_key_file_to_data(key_file, &length, NULL);
 
-	g_file_set_contents(ANDROID_STORAGEDIR"/settings", data, length, NULL);
+	g_file_set_contents(SETTINGS_FILE, data, length, NULL);
 
 	g_free(data);
 	g_key_file_free(key_file);
@@ -174,8 +176,7 @@ static void load_adapter_config(void)
 	char *str;
 
 	key_file = g_key_file_new();
-	g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings", 0,
-									NULL);
+	g_key_file_load_from_file(key_file, SETTINGS_FILE, 0, NULL);
 
 	str = g_key_file_get_string(key_file, "General", "Address", NULL);
 	if (!str) {
@@ -217,8 +218,7 @@ static void store_device_info(struct device *dev)
 	ba2str(&dev->bdaddr, addr);
 
 	key_file = g_key_file_new();
-	g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/devices", 0,
-									NULL);
+	g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL);
 
 	if (dev->bond_state == HAL_BOND_STATE_NONE) {
 		g_key_file_remove_group(key_file, addr, NULL);
@@ -267,7 +267,7 @@ static void store_device_info(struct device *dev)
 
 done:
 	str = g_key_file_to_data(key_file, &length, NULL);
-	g_file_set_contents(ANDROID_STORAGEDIR"/devices", str, length, NULL);
+	g_file_set_contents(DEVICES_FILE, str, length, NULL);
 	g_free(str);
 
 	g_key_file_free(key_file);
@@ -522,8 +522,7 @@ static void store_link_key(const bdaddr_t *dst, const uint8_t *key,
 
 	key_file = g_key_file_new();
 
-	if (!g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/devices",
-								0, NULL))
+	if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL))
 		return;
 
 	ba2str(dst, addr);
@@ -538,7 +537,7 @@ static void store_link_key(const bdaddr_t *dst, const uint8_t *key,
 	g_key_file_set_integer(key_file, addr, "LinkKeyPinLength", pin_length);
 
 	data = g_key_file_to_data(key_file, &length, NULL);
-	g_file_set_contents(ANDROID_STORAGEDIR"/devices", data, length, NULL);
+	g_file_set_contents(DEVICES_FILE, data, length, NULL);
 	g_free(data);
 
 	g_key_file_free(key_file);
@@ -1732,8 +1731,7 @@ static void load_devices_info(bt_bluetooth_ready cb)
 
 	key_file = g_key_file_new();
 
-	g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/devices", 0,
-									NULL);
+	g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL);
 
 	devs = g_key_file_get_groups(key_file, &len);
 
-- 
1.8.3.2


^ permalink raw reply related

* [RFC 3/5] android/bluetooth: Always store device info
From: Szymon Janc @ 2014-01-14 11:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1389697905-18532-1-git-send-email-szymon.janc@tieto.com>

This allows to cache remote device informations.
---
 android/bluetooth.c | 42 +++++++++++++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 23a528a..8c91d87 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -208,23 +208,11 @@ static void store_device_info(struct device *dev)
 	char **uuids = NULL;
 	char *str;
 
-	/* We only store bonded devices and need to modify the storage
-	 * if the state is either NONE or BONDED.
-	 */
-	if (dev->bond_state != HAL_BOND_STATE_BONDED &&
-					dev->bond_state != HAL_BOND_STATE_NONE)
-		return;
-
 	ba2str(&dev->bdaddr, addr);
 
 	key_file = g_key_file_new();
 	g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL);
 
-	if (dev->bond_state == HAL_BOND_STATE_NONE) {
-		g_key_file_remove_group(key_file, addr, NULL);
-		goto done;
-	}
-
 	g_key_file_set_integer(key_file, addr, "Type", dev->bdaddr_type);
 
 	g_key_file_set_string(key_file, addr, "Name", dev->name);
@@ -265,7 +253,6 @@ static void store_device_info(struct device *dev)
 		g_key_file_remove_key(key_file, addr, "Services", NULL);
 	}
 
-done:
 	str = g_key_file_to_data(key_file, &length, NULL);
 	g_file_set_contents(DEVICES_FILE, str, length, NULL);
 	g_free(str);
@@ -543,6 +530,33 @@ static void store_link_key(const bdaddr_t *dst, const uint8_t *key,
 	g_key_file_free(key_file);
 }
 
+static void remove_stored_link_key(const bdaddr_t *dst)
+{
+	GKeyFile *key_file;
+	gsize length = 0;
+	char addr[18];
+	char *data;
+
+	key_file = g_key_file_new();
+
+	if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL))
+		return;
+
+	ba2str(dst, addr);
+
+	DBG("%s", addr);
+
+	g_key_file_remove_key(key_file, addr, "LinkKey", NULL);
+	g_key_file_remove_key(key_file, addr, "LinkKeyType", NULL);
+	g_key_file_remove_key(key_file, addr, "LinkKeyPinLength", NULL);
+
+	data = g_key_file_to_data(key_file, &length, NULL);
+	g_file_set_contents(DEVICES_FILE, data, length, NULL);
+	g_free(data);
+
+	g_key_file_free(key_file);
+}
+
 static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
 								uint8_t state)
 {
@@ -2449,6 +2463,8 @@ static void unpair_device_complete(uint8_t status, uint16_t length,
 	if (status != MGMT_STATUS_SUCCESS)
 		return;
 
+	remove_stored_link_key(&rp->addr.bdaddr);
+
 	set_device_bond_state(&rp->addr.bdaddr, HAL_STATUS_SUCCESS,
 							HAL_BOND_STATE_NONE);
 }
-- 
1.8.3.2


^ permalink raw reply related


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