Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2 3/5] core: Add flags parameter to bt_search_service
From: Szymon Janc @ 2014-01-20 11:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1390216116-23670-1-git-send-email-szymon.janc@tieto.com>

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

This allows to pass custom SDP flags to sdp_connect.
---
 android/bluetooth.c        | 4 ++--
 android/hidhost.c          | 4 ++--
 android/socket.c           | 2 +-
 profiles/health/hdp_util.c | 6 +++---
 src/device.c               | 5 +++--
 src/profile.c              | 2 +-
 src/sdp-client.c           | 8 ++++----
 src/sdp-client.h           | 2 +-
 8 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 505d5a7..83612b4 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -693,7 +693,7 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
 	if (uuid_list[req->search_uuid]) {
 		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
 		bt_search_service(&adapter.bdaddr, &req->bdaddr, &uuid,
-						browse_cb, user_data, NULL);
+						browse_cb, user_data, NULL, 0);
 		return;
 	}
 
@@ -729,7 +729,7 @@ static uint8_t browse_remote_sdp(const bdaddr_t *addr)
 	sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
 
 	if (bt_search_service(&adapter.bdaddr,
-			&req->bdaddr, &uuid, browse_cb, req, NULL) < 0) {
+			&req->bdaddr, &uuid, browse_cb, req, NULL , 0) < 0) {
 		browse_req_free(req);
 		return HAL_STATUS_FAILED;
 	}
diff --git a/android/hidhost.c b/android/hidhost.c
index aed9899..d66e863 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -751,7 +751,7 @@ static void bt_hid_connect(const void *buf, uint16_t len)
 
 	bt_string2uuid(&uuid, HID_UUID);
 	if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
-					hid_sdp_search_cb, dev, NULL) < 0) {
+					hid_sdp_search_cb, dev, NULL, 0) < 0) {
 		error("Failed to search sdp details");
 		hid_device_free(dev);
 		status = HAL_STATUS_FAILED;
@@ -1254,7 +1254,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 		bt_string2uuid(&uuid, HID_UUID);
 		if (bt_search_service(&src, &dev->dst, &uuid,
-					hid_sdp_search_cb, dev, NULL) < 0) {
+					hid_sdp_search_cb, dev, NULL, 0) < 0) {
 			error("failed to search sdp details");
 			hid_device_free(dev);
 			return;
diff --git a/android/socket.c b/android/socket.c
index 69b39ee..f662e79 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -1091,7 +1091,7 @@ static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan,
 		rfsock->profile = get_profile_by_uuid(uuid);
 
 		if (bt_search_service(&adapter_addr, &rfsock->dst, &uu,
-					sdp_search_cb, rfsock, NULL) < 0) {
+					sdp_search_cb, rfsock, NULL, 0) < 0) {
 			error("Failed to search SDP records");
 			goto failed;
 		}
diff --git a/profiles/health/hdp_util.c b/profiles/health/hdp_util.c
index 7de87a8..b9a09e9 100644
--- a/profiles/health/hdp_util.c
+++ b/profiles/health/hdp_util.c
@@ -864,7 +864,7 @@ gboolean hdp_get_mdep(struct hdp_device *device, struct hdp_application *app,
 
 	bt_string2uuid(&uuid, HDP_UUID);
 	if (bt_search_service(src, dst, &uuid, get_mdep_cb, mdep_data,
-							free_mdep_data) < 0) {
+						free_mdep_data, 0) < 0) {
 		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
 						"Can't get remote SDP record");
 		g_free(mdep_data);
@@ -1092,7 +1092,7 @@ gboolean hdp_establish_mcl(struct hdp_device *device,
 
 	bt_string2uuid(&uuid, HDP_UUID);
 	if (bt_search_service(src, dst, &uuid, search_cb, conn_data,
-						destroy_con_mcl_data) < 0) {
+					destroy_con_mcl_data, 0) < 0) {
 		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
 						"Can't get remote SDP record");
 		g_free(conn_data);
@@ -1161,7 +1161,7 @@ gboolean hdp_get_dcpsm(struct hdp_device *device, hdp_continue_dcpsm_f func,
 
 	bt_string2uuid(&uuid, HDP_UUID);
 	if (bt_search_service(src, dst, &uuid, get_dcpsm_cb, dcpsm_data,
-							free_dcpsm_data) < 0) {
+						free_dcpsm_data, 0) < 0) {
 		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
 						"Can't get remote SDP record");
 		g_free(dcpsm_data);
diff --git a/src/device.c b/src/device.c
index bcc5561..1bd27a1 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2971,7 +2971,7 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
 		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
 		bt_search_service(btd_adapter_get_address(adapter),
 						&device->bdaddr, &uuid,
-						browse_cb, user_data, NULL);
+						browse_cb, user_data, NULL, 0);
 		return;
 	}
 
@@ -3513,7 +3513,8 @@ static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
 	sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
 
 	err = bt_search_service(btd_adapter_get_address(adapter),
-				&device->bdaddr, &uuid, browse_cb, req, NULL);
+				&device->bdaddr, &uuid, browse_cb, req, NULL,
+				0);
 	if (err < 0) {
 		browse_request_free(req);
 		return err;
diff --git a/src/profile.c b/src/profile.c
index 3c0d27c..e833181 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -1605,7 +1605,7 @@ static int resolve_service(struct ext_io *conn, const bdaddr_t *src,
 	bt_string2uuid(&uuid, ext->remote_uuid);
 	sdp_uuid128_to_uuid(&uuid);
 
-	err = bt_search_service(src, dst, &uuid, record_cb, conn, NULL);
+	err = bt_search_service(src, dst, &uuid, record_cb, conn, NULL, 0);
 	if (err == 0)
 		conn->resolving = true;
 
diff --git a/src/sdp-client.c b/src/sdp-client.c
index 0599626..ff06b4d 100644
--- a/src/sdp-client.c
+++ b/src/sdp-client.c
@@ -264,7 +264,7 @@ failed:
 static int create_search_context(struct search_context **ctxt,
 					const bdaddr_t *src,
 					const bdaddr_t *dst,
-					uuid_t *uuid)
+					uuid_t *uuid, uint16_t flags)
 {
 	sdp_session_t *s;
 	GIOChannel *chan;
@@ -276,7 +276,7 @@ static int create_search_context(struct search_context **ctxt,
 
 	s = get_cached_sdp_session(src, dst);
 	if (!s)
-		s = sdp_connect(src, dst, SDP_NON_BLOCKING);
+		s = sdp_connect(src, dst, SDP_NON_BLOCKING | flags);
 
 	if (!s)
 		return -errno;
@@ -311,7 +311,7 @@ static int create_search_context(struct search_context **ctxt,
 
 int bt_search_service(const bdaddr_t *src, const bdaddr_t *dst,
 			uuid_t *uuid, bt_callback_t cb, void *user_data,
-			bt_destroy_t destroy)
+			bt_destroy_t destroy, uint16_t flags)
 {
 	struct search_context *ctxt = NULL;
 	int err;
@@ -319,7 +319,7 @@ int bt_search_service(const bdaddr_t *src, const bdaddr_t *dst,
 	if (!cb)
 		return -EINVAL;
 
-	err = create_search_context(&ctxt, src, dst, uuid);
+	err = create_search_context(&ctxt, src, dst, uuid, flags);
 	if (err < 0)
 		return err;
 
diff --git a/src/sdp-client.h b/src/sdp-client.h
index 9191594..9aa5a4d 100644
--- a/src/sdp-client.h
+++ b/src/sdp-client.h
@@ -26,6 +26,6 @@ typedef void (*bt_destroy_t) (gpointer user_data);
 
 int bt_search_service(const bdaddr_t *src, const bdaddr_t *dst,
 			uuid_t *uuid, bt_callback_t cb, void *user_data,
-			bt_destroy_t destroy);
+			bt_destroy_t destroy, uint16_t flags);
 int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst);
 void bt_clear_cached_session(const bdaddr_t *src, const bdaddr_t *dst);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH v2 4/5] device: Add workaround for Sony Dualshock 4 broken SDP
From: Szymon Janc @ 2014-01-20 11:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1390216116-23670-1-git-send-email-szymon.janc@tieto.com>

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

Sony DualShock 4 is not respecting negotiated L2CAP MTU. This might
results in SDP response being dropped by kernel. Workaround this by
forcing SDP code to use bigger MTU while connecting.
---
 src/device.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/device.c b/src/device.c
index 1bd27a1..76b876e 100644
--- a/src/device.c
+++ b/src/device.c
@@ -118,6 +118,7 @@ struct browse_req {
 	int search_uuid;
 	int reconnect_attempt;
 	guint listener_id;
+	uint16_t sdp_flags;
 };
 
 struct included_search {
@@ -2971,7 +2972,8 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
 		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
 		bt_search_service(btd_adapter_get_address(adapter),
 						&device->bdaddr, &uuid,
-						browse_cb, user_data, NULL, 0);
+						browse_cb, user_data, NULL,
+						req->sdp_flags);
 		return;
 	}
 
@@ -3498,6 +3500,23 @@ done:
 	return 0;
 }
 
+static uint16_t get_sdp_flags(struct btd_device *device)
+{
+	uint16_t vid, pid;
+
+	vid = btd_device_get_vendor(device);
+	pid = btd_device_get_product(device);
+
+	/* Sony DualShock 4 is not respecting negotiated L2CAP MTU. This might
+	 * results in SDP response being dropped by kernel. Workaround this by
+	 * forcing SDP code to use bigger MTU while connecting.
+	 */
+	if (vid == 0x054c && pid == 0x05c4)
+		return SDP_LARGE_MTU;
+
+	return 0;
+}
+
 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
 {
 	struct btd_adapter *adapter = device->adapter;
@@ -3512,9 +3531,11 @@ static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
 	req->device = device;
 	sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
 
+	req->sdp_flags = get_sdp_flags(device);
+
 	err = bt_search_service(btd_adapter_get_address(adapter),
 				&device->bdaddr, &uuid, browse_cb, req, NULL,
-				0);
+				req->sdp_flags);
 	if (err < 0) {
 		browse_request_free(req);
 		return err;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH v2 5/5] device: Match Dualshock4 with name and class
From: Szymon Janc @ 2014-01-20 11:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1390216116-23670-1-git-send-email-szymon.janc@tieto.com>

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

This allows to use DS4 with legacy adapters. This seems to require
general bonding to work correctly i.e. after dedicated bonding
connection is rejected with "Authentication Failure" error.
---
 src/device.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/device.c b/src/device.c
index 76b876e..8e2a515 100644
--- a/src/device.c
+++ b/src/device.c
@@ -3514,6 +3514,14 @@ static uint16_t get_sdp_flags(struct btd_device *device)
 	if (vid == 0x054c && pid == 0x05c4)
 		return SDP_LARGE_MTU;
 
+	if (btd_adapter_ssp_enabled(device->adapter))
+		return 0;
+
+	/* if no EIR try matching Sony DualShock 4 with name and class */
+	if (!strncmp(device->name, "Wireless Controller", MAX_NAME_LENGTH) &&
+			device->class == 0x2508)
+		return SDP_LARGE_MTU;
+
 	return 0;
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH BlueZ 1/2] android/hal-audio: Fix not closing audio_sk
From: Luiz Augusto von Dentz @ 2014-01-20 12:25 UTC (permalink / raw)
  To: linux-bluetooth

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

shutdown will only disconnect the peers but it is still needed to close
the file descriptor.
---
 android/hal-audio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 2f6f8c2..0b4577e 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -246,6 +246,7 @@ static void audio_ipc_cleanup(void)
 {
 	if (audio_sk >= 0) {
 		shutdown(audio_sk, SHUT_RDWR);
+		close(audio_sk);
 		audio_sk = -1;
 	}
 }
@@ -1090,6 +1091,7 @@ static void *ipc_handler(void *data)
 
 		if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
 			info("Audio HAL: Socket closed");
+			close(audio_sk);
 			audio_sk = -1;
 		}
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 2/2] android/A2DP: Fix sending notification on bt_a2dp_unregister
From: Luiz Augusto von Dentz @ 2014-01-20 12:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390220727-21494-1-git-send-email-luiz.dentz@gmail.com>

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

At this point IPC might have been closed already.
---
 android/a2dp.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 8ec03c8..5569691 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -119,8 +119,10 @@ static void unregister_endpoint(void *data)
 	g_free(endpoint);
 }
 
-static void a2dp_device_free(struct a2dp_device *dev)
+static void a2dp_device_free(void *data)
 {
+	struct a2dp_device *dev = data;
+
 	if (dev->idle_id > 0)
 		g_source_remove(dev->idle_id);
 
@@ -1471,13 +1473,6 @@ fail:
 	return false;
 }
 
-static void a2dp_device_disconnected(gpointer data, gpointer user_data)
-{
-	struct a2dp_device *dev = data;
-
-	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
-}
-
 void bt_a2dp_unregister(void)
 {
 	DBG("");
@@ -1488,7 +1483,7 @@ void bt_a2dp_unregister(void)
 	g_slist_free_full(endpoints, unregister_endpoint);
 	endpoints = NULL;
 
-	g_slist_foreach(devices, a2dp_device_disconnected, NULL);
+	g_slist_free_full(devices, a2dp_device_free);
 	devices = NULL;
 
 	ipc_unregister(HAL_SERVICE_ID_A2DP);
-- 
1.8.4.2


^ permalink raw reply related

* Re: [PATCH 1/3] android/pts: Add PTS test results document for A2DP
From: Szymon Janc @ 2014-01-20 12:32 UTC (permalink / raw)
  To: Jakub Tyszkowski; +Cc: linux-bluetooth
In-Reply-To: <1390208087-22838-1-git-send-email-jakub.tyszkowski@tieto.com>

Hi Jakub,

On Monday 20 of January 2014 09:54:45 Jakub Tyszkowski wrote:
> This will allow for better tracking of current state of implementation.
> ---
>  android/Makefile.am  |  1 +
>  android/pts-a2dp.txt | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 58 insertions(+)
>  create mode 100644 android/pts-a2dp.txt
> 
> diff --git a/android/Makefile.am b/android/Makefile.am
> index f24b754..d4508a4 100644
> --- a/android/Makefile.am
> +++ b/android/Makefile.am
> @@ -167,4 +167,5 @@ EXTRA_DIST += android/Android.mk android/README \
>  				android/pts-hid.txt \
>  				android/pts-opp.txt \
>  				android/pts-map.txt \
> +				android/pts-a2dp.txt \
>  				android/pts-pbap.txt
> diff --git a/android/pts-a2dp.txt b/android/pts-a2dp.txt
> new file mode 100644
> index 0000000..a269ec1
> --- /dev/null
> +++ b/android/pts-a2dp.txt
> @@ -0,0 +1,57 @@
> +PTS test results for A2DP
> +
> +PTS version: 5.0
> +Tested: --not yet tested--
> +
> +Results:
> +PASS	test passed
> +FAIL	test failed
> +INC	test is inconclusive
> +N/A	test is disabled due to PICS setup
> +
> +		Source (SRC)
> +-------------------------------------------------------------------------------
> +Test Name		Result	Notes
> +-------------------------------------------------------------------------------
> +TC_SRC_CC_BV_09_I	INC
> +TC_SRC_CC_BV_10_I	N/A
> +TC_SRC_REL_BV_01_I	INC
> +TC_SRC_REL_BV_02_I	INC
> +TC_SRC_SET_BV_01_I	INC
> +TC_SRC_SET_BV_02_I	INC
> +TC_SRC_SET_BV_03_I	INC
> +TC_SRC_SET_BV_04_I	INC
> +TC_SRC_SET_BV_05_I	INC
> +TC_SRC_SET_BV_06_I	INC
> +TC_SRC_SUS_BV_01_I	INC
> +TC_SRC_SUS_BV_02_I	INC
> +TC_SRC_SDP_BV_01_I	INC
> +TC_SRC_AS_BV_01_I	INC
> +-------------------------------------------------------------------------------
> +
> +
> +		Sink (SNK)
> +-------------------------------------------------------------------------------
> +Test Name		Result	Notes
> +-------------------------------------------------------------------------------
> +TC_SNK_CC_BV_01_I	N/A
> +TC_SNK_CC_BV_02_I	N/A
> +TC_SNK_CC_BV_03_I	N/A
> +TC_SNK_CC_BV_04_I	N/A
> +TC_SNK_CC_BV_05_I	N/A
> +TC_SNK_CC_BV_06_I	N/A
> +TC_SNK_CC_BV_07_I	N/A
> +TC_SNK_CC_BV_08_I	N/A
> +TC_SNK_REL_BV_01_I	N/A
> +TC_SNK_REL_BV_02_I	N/A
> +TC_SNK_SET_BV_01_I	N/A
> +TC_SNK_SET_BV_02_I	N/A
> +TC_SNK_SET_BV_03_I	N/A
> +TC_SNK_SET_BV_04_I	N/A
> +TC_SNK_SET_BV_05_I	N/A
> +TC_SNK_SET_BV_06_I	N/A
> +TC_SNK_SUS_BV_01_I	N/A
> +TC_SNK_SUS_BV_02_I	N/A
> +TC_SNK_SDP_BV_02_I	N/A
> +TC_SNK_AS_BV_01_I	N/A
> +-------------------------------------------------------------------------------
> 

All 3 patches applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH 1/2] tools/bluetooth-player: dispaly searchable value
From: Sebastian Chlad @ 2014-01-20 13:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad

---
 tools/bluetooth-player.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/bluetooth-player.c b/tools/bluetooth-player.c
index 1c0348e..32d295c 100644
--- a/tools/bluetooth-player.c
+++ b/tools/bluetooth-player.c
@@ -654,6 +654,7 @@ static void cmd_show(int argc, char *argv[])
 	rl_printf("Player %s\n", g_dbus_proxy_get_path(proxy));
 
 	print_property(proxy, "Name");
+	print_property(proxy, "Searchable");
 	print_property(proxy, "Repeat");
 	print_property(proxy, "Equalizer");
 	print_property(proxy, "Shuffle");
-- 
1.8.3.2

---------------------------------------------------------------------
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 related

* [PATCH 2/2] tools/bluetooth-player: check CT for searchable value
From: Sebastian Chlad @ 2014-01-20 13:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad
In-Reply-To: <1390223078-29096-1-git-send-email-sebastianx.chlad@intel.com>

Simple check if the remote client is searchable.
---
 tools/bluetooth-player.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/bluetooth-player.c b/tools/bluetooth-player.c
index 32d295c..13471c2 100644
--- a/tools/bluetooth-player.c
+++ b/tools/bluetooth-player.c
@@ -945,6 +945,7 @@ static void cmd_search(int argc, char *argv[])
 {
 	GDBusProxy *proxy;
 	char *string;
+	DBusMessageIter iter;
 
 	if (argc < 2) {
 		rl_printf("Missing string argument\n");
@@ -962,6 +963,11 @@ static void cmd_search(int argc, char *argv[])
 
 	string = g_strdup(argv[1]);
 
+	if (g_dbus_proxy_get_property(proxy, "Searchable", &iter) == FALSE) {
+		rl_printf("Search not supported on the client side\n");
+		return;
+	}
+
 	if (g_dbus_proxy_method_call(proxy, "Search", search_setup,
 				search_reply, string, g_free) == FALSE) {
 		rl_printf("Failed to search\n");
-- 
1.8.3.2

---------------------------------------------------------------------
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 related

* Re: [PATCH v2 1/5] lib: Add flag to force large MTU size used for SDP connection
From: Johan Hedberg @ 2014-01-20 13:20 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, Szymon Janc
In-Reply-To: <1390216116-23670-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Mon, Jan 20, 2014, Szymon Janc wrote:
> This will allow to workaround Dualshock4 not respecting L2CAP MTU
> size while sending SDP response. Use same L2CAP MTU value base on
> RFCOMM.
> ---
>  lib/sdp.c     | 27 +++++++++++++++++++++++++++
>  lib/sdp_lib.h |  1 +
>  2 files changed, 28 insertions(+)

All patches in this set have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH] build: Bump D-Bus dependency to 1.6
From: Szymon Janc @ 2014-01-20 13:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

dbus_validate_path() was introduced in D-Bus 1.6 and it is no longer
possible to build with 1.4.

 CCLD   tools/bluetooth-player
tools/bluetooth-player.o: In function `cmd_change_folder':
tools/bluetooth-player.c:741: undefined reference to `dbus_validate_path'
collect2: ld returned 1 exit status
---
 configure.ac | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index c85f208..ddbd584 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,8 +62,8 @@ if (test "${enable_threads}" = "yes"); then
 	GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
 fi
 
-PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.4, dummy=yes,
-				AC_MSG_ERROR(D-Bus >= 1.4 is required))
+PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.6, dummy=yes,
+				AC_MSG_ERROR(D-Bus >= 1.6 is required))
 AC_SUBST(DBUS_CFLAGS)
 AC_SUBST(DBUS_LIBS)
 
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH] build: Bump D-Bus dependency to 1.6
From: Johan Hedberg @ 2014-01-20 14:45 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1390226087-14202-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Mon, Jan 20, 2014, Szymon Janc wrote:
> dbus_validate_path() was introduced in D-Bus 1.6 and it is no longer
> possible to build with 1.4.
> 
>  CCLD   tools/bluetooth-player
> tools/bluetooth-player.o: In function `cmd_change_folder':
> tools/bluetooth-player.c:741: undefined reference to `dbus_validate_path'
> collect2: ld returned 1 exit status
> ---
>  configure.ac | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH v2 0/9] android: Add SBC encoding
From: Andrzej Kaczmarek @ 2014-01-20 14:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

Hi,

v1 -> v2
- fixed comments
- added dependency to libsbc shared library on Android

Note that configure.ac requires SBC 1.2 which does not exist at the
moment, but I added this since now sbc_init_a2dp() is used which
does not exist in SBC 1.1 and requires patches from Luiz to be
merged so I expect that we'll have SBC 1,2 once this is done (if
accepted, of course).


Andrzej Kaczmarek (9):
  android: Add MTU data to Open Stream Audio IPC
  android: Build Audio HAL with SBC
  android/hal-audio: Rename sbc_init to avoid collision with libsbc
  android/hal-audio: Initialize SBC encoder
  android/hal-audio: Calculate SBC stream parameters
  android/hal-audio: Add resume to codec callbacks
  android/hal-audio: Return proper buffer size to AudioFlinger
  android/hal-audio: Read fd from Output Stream response
  android/hal-audio: Add proper SBC encoding

 android/Android.mk  |   7 +-
 android/Makefile.am |   2 +
 android/a2dp.c      |   8 +-
 android/audio-msg.h |   1 +
 android/hal-audio.c | 270 +++++++++++++++++++++++++++++++++++++++++++++++++---
 configure.ac        |   7 ++
 6 files changed, 278 insertions(+), 17 deletions(-)

-- 
1.8.5.2


^ permalink raw reply

* [PATCH v2 1/9] android: Add MTU data to Open Stream Audio IPC
From: Andrzej Kaczmarek @ 2014-01-20 14:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390229943-29609-1-git-send-email-andrzej.kaczmarek@tieto.com>

MTU value for transport channel is sent in Open Stream response, which
is required to calculate number of frames which can be packed into
single media packet.

This is to avoid including GPLv2 licensed headers in Audio HAL
implementation.
---
 android/a2dp.c      | 8 ++++++--
 android/audio-msg.h | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 8ec03c8..5562ba5 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -1297,6 +1297,7 @@ static void bt_stream_open(const void *buf, uint16_t len)
 	struct audio_rsp_open_stream *rsp;
 	struct a2dp_setup *setup;
 	int fd;
+	uint16_t omtu;
 
 	DBG("");
 
@@ -1307,14 +1308,17 @@ static void bt_stream_open(const void *buf, uint16_t len)
 		return;
 	}
 
-	if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, NULL, NULL)) {
+	if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, &omtu,
+						NULL)) {
 		error("avdtp_stream_get_transport: failed");
 		audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED);
 		return;
 	}
 
-	len = sizeof(struct audio_preset) + setup->preset->len;
+	len = sizeof(struct audio_rsp_open_stream) +
+			sizeof(struct audio_preset) + setup->preset->len;
 	rsp = g_malloc0(len);
+	rsp->mtu = omtu;
 	rsp->preset->len = setup->preset->len;
 	memcpy(rsp->preset->data, setup->preset->data, setup->preset->len);
 
diff --git a/android/audio-msg.h b/android/audio-msg.h
index 8f03274..17cde09 100644
--- a/android/audio-msg.h
+++ b/android/audio-msg.h
@@ -63,6 +63,7 @@ struct audio_cmd_open_stream {
 } __attribute__((packed));
 
 struct audio_rsp_open_stream {
+	uint16_t mtu;
 	struct audio_preset preset[0];
 } __attribute__((packed));
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v2 2/9] android: Build Audio HAL with SBC
From: Andrzej Kaczmarek @ 2014-01-20 14:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390229943-29609-1-git-send-email-andrzej.kaczmarek@tieto.com>

Build for Android requires libsbc to be built as shared library and
includes to be available in external/bluetooth/sbc. Build for host
requires libsbc package to be installed.
---
 android/Android.mk  | 7 +++++--
 android/Makefile.am | 2 ++
 configure.ac        | 7 +++++++
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index afa3a51..cf7a224 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -3,8 +3,9 @@ LOCAL_PATH := $(call my-dir)
 # Retrieve BlueZ version from configure.ac file
 BLUEZ_VERSION := $(shell grep ^AC_INIT $(LOCAL_PATH)/../configure.ac | cpp -P -D'AC_INIT(_,v)=v')
 
-# Specify pathmap for glib
-pathmap_INCL += glib:external/bluetooth/glib
+# Specify pathmap for glib and sbc
+pathmap_INCL += glib:external/bluetooth/glib \
+	sbc:external/bluetooth/sbc
 
 # Specify common compiler flags
 BLUEZ_COMMON_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\" \
@@ -225,9 +226,11 @@ LOCAL_SRC_FILES := hal-audio.c
 LOCAL_C_INCLUDES = \
 	$(call include-path-for, system-core) \
 	$(call include-path-for, libhardware) \
+	$(call include-path-for, sbc) \
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
+	libsbc \
 
 LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) \
 
diff --git a/android/Makefile.am b/android/Makefile.am
index 924917a..69ea6d5 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -130,6 +130,8 @@ android_audio_a2dp_default_la_SOURCES = android/audio-msg.h \
 
 android_audio_a2dp_default_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
 
+android_audio_a2dp_default_la_LIBADD = @SBC_LIBS@
+
 android_audio_a2dp_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
 					-no-undefined -pthread
 
diff --git a/configure.ac b/configure.ac
index c85f208..8e4053f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -252,6 +252,13 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
 					[enable_android=${enableval}])
 AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
 
+if (test "${enable_android}" = "yes"); then
+	PKG_CHECK_MODULES(SBC, sbc >= 1.2, dummy=yes,
+					AC_MSG_ERROR(SBC library >= 1.2 is required))
+	AC_SUBST(SBC_CFLAGS)
+	AC_SUBST(SBC_LIBS)
+fi
+
 AC_DEFINE_UNQUOTED(ANDROID_STORAGEDIR, "${storagedir}/android",
 			[Directory for the Android daemon storage files])
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v2 3/9] android/hal-audio: Rename sbc_init to avoid collision with libsbc
From: Andrzej Kaczmarek @ 2014-01-20 14:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390229943-29609-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 android/hal-audio.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 2f6f8c2..f53dba0 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -56,7 +56,7 @@ struct sbc_data {
 };
 
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
-static int sbc_init(struct audio_preset *preset, void **codec_data);
+static int sbc_codec_init(struct audio_preset *preset, void **codec_data);
 static int sbc_cleanup(void *codec_data);
 static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
@@ -80,7 +80,7 @@ static const struct audio_codec audio_codecs[] = {
 
 		.get_presets = sbc_get_presets,
 
-		.init = sbc_init,
+		.init = sbc_codec_init,
 		.cleanup = sbc_cleanup,
 		.get_config = sbc_get_config,
 	}
@@ -184,7 +184,7 @@ static int sbc_get_presets(struct audio_preset *preset, size_t *len)
 	return i;
 }
 
-static int sbc_init(struct audio_preset *preset, void **codec_data)
+static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 {
 	struct sbc_data *sbc_data;
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v2 4/9] android/hal-audio: Initialize SBC encoder
From: Andrzej Kaczmarek @ 2014-01-20 14:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390229943-29609-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 android/hal-audio.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index f53dba0..8e932ef 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -32,6 +32,7 @@
 #include "hal-log.h"
 #include "hal-msg.h"
 #include "../profiles/audio/a2dp-codecs.h"
+#include <sbc/sbc.h>
 
 static const uint8_t a2dp_src_uuid[] = {
 		0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x10, 0x00,
@@ -53,6 +54,8 @@ struct audio_input_config {
 
 struct sbc_data {
 	a2dp_sbc_t sbc;
+
+	sbc_t enc;
 };
 
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
@@ -184,6 +187,19 @@ static int sbc_get_presets(struct audio_preset *preset, size_t *len)
 	return i;
 }
 
+static void sbc_init_encoder(struct sbc_data *sbc_data)
+{
+	a2dp_sbc_t *in = &sbc_data->sbc;
+	sbc_t *out = &sbc_data->enc;
+
+	DBG("");
+
+	sbc_init_a2dp(out, 0L, in);
+
+	out->endian = SBC_LE;
+	out->bitpool = in->max_bitpool;
+}
+
 static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 {
 	struct sbc_data *sbc_data;
@@ -199,6 +215,8 @@ static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 
 	memcpy(&sbc_data->sbc, preset->data, preset->len);
 
+	sbc_init_encoder(sbc_data);
+
 	*codec_data = sbc_data;
 
 	return AUDIO_STATUS_SUCCESS;
@@ -206,8 +224,11 @@ static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 
 static int sbc_cleanup(void *codec_data)
 {
+	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
+
 	DBG("");
 
+	sbc_finish(&sbc_data->enc);
 	free(codec_data);
 
 	return AUDIO_STATUS_SUCCESS;
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v2 5/9] android/hal-audio: Calculate SBC stream parameters
From: Andrzej Kaczmarek @ 2014-01-20 14:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390229943-29609-1-git-send-email-andrzej.kaczmarek@tieto.com>

This patch adds necessary calculations for SBC stream parameters.

Both input and output buffers are expected to have exact amount of
data to fill single media packet (based on transport channel MTU).

Frame duration will be used to synchronize input and output streams.
---
 android/hal-audio.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 97 insertions(+), 6 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 8e932ef..22dff53 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -46,6 +46,66 @@ static pthread_t ipc_th = 0;
 static pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+struct rtp_header {
+	unsigned cc:4;
+	unsigned x:1;
+	unsigned p:1;
+	unsigned v:2;
+
+	unsigned pt:7;
+	unsigned m:1;
+
+	uint16_t sequence_number;
+	uint32_t timestamp;
+	uint32_t ssrc;
+	uint32_t csrc[0];
+} __attribute__ ((packed));
+
+struct rtp_payload {
+	unsigned frame_count:4;
+	unsigned rfa0:1;
+	unsigned is_last_fragment:1;
+	unsigned is_first_fragment:1;
+	unsigned is_fragmented:1;
+} __attribute__ ((packed));
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+struct rtp_header {
+	unsigned v:2;
+	unsigned p:1;
+	unsigned x:1;
+	unsigned cc:4;
+
+	unsigned m:1;
+	unsigned pt:7;
+
+	uint16_t sequence_number;
+	uint32_t timestamp;
+	uint32_t ssrc;
+	uint32_t csrc[0];
+} __attribute__ ((packed));
+
+struct rtp_payload {
+	unsigned is_fragmented:1;
+	unsigned is_first_fragment:1;
+	unsigned is_last_fragment:1;
+	unsigned rfa0:1;
+	unsigned frame_count:4;
+} __attribute__ ((packed));
+
+#else
+#error "Unknown byte order"
+#endif
+
+struct media_packet {
+	struct rtp_header hdr;
+	struct rtp_payload payload;
+	uint8_t data[0];
+};
+
 struct audio_input_config {
 	uint32_t rate;
 	uint32_t channels;
@@ -56,10 +116,19 @@ struct sbc_data {
 	a2dp_sbc_t sbc;
 
 	sbc_t enc;
+
+	size_t in_frame_len;
+	size_t in_buf_size;
+
+	size_t out_buf_size;
+	uint8_t *out_buf;
+
+	unsigned frame_duration;
 };
 
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
-static int sbc_codec_init(struct audio_preset *preset, void **codec_data);
+static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
+				void **codec_data);
 static int sbc_cleanup(void *codec_data);
 static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
@@ -69,7 +138,8 @@ struct audio_codec {
 
 	int (*get_presets) (struct audio_preset *preset, size_t *len);
 
-	int (*init) (struct audio_preset *preset, void **codec_data);
+	int (*init) (struct audio_preset *preset, uint16_t mtu,
+				void **codec_data);
 	int (*cleanup) (void *codec_data);
 	int (*get_config) (void *codec_data,
 					struct audio_input_config *config);
@@ -200,9 +270,14 @@ static void sbc_init_encoder(struct sbc_data *sbc_data)
 	out->bitpool = in->max_bitpool;
 }
 
-static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
+static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
+				void **codec_data)
 {
 	struct sbc_data *sbc_data;
+	size_t hdr_len = sizeof(struct media_packet);
+	size_t in_frame_len;
+	size_t out_frame_len;
+	size_t num_frames;
 
 	DBG("");
 
@@ -217,6 +292,18 @@ static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 
 	sbc_init_encoder(sbc_data);
 
+	in_frame_len = sbc_get_codesize(&sbc_data->enc);
+	out_frame_len = sbc_get_frame_length(&sbc_data->enc);
+	num_frames = (mtu - hdr_len) / out_frame_len;
+
+	sbc_data->in_frame_len = in_frame_len;
+	sbc_data->in_buf_size = num_frames * in_frame_len;
+
+	sbc_data->out_buf_size = hdr_len + num_frames * out_frame_len;
+	sbc_data->out_buf = calloc(1, sbc_data->out_buf_size);
+
+	sbc_data->frame_duration = sbc_get_frame_duration(&sbc_data->enc);
+
 	*codec_data = sbc_data;
 
 	return AUDIO_STATUS_SUCCESS;
@@ -229,6 +316,7 @@ static int sbc_cleanup(void *codec_data)
 	DBG("");
 
 	sbc_finish(&sbc_data->enc);
+	free(sbc_data->out_buf);
 	free(codec_data);
 
 	return AUDIO_STATUS_SUCCESS;
@@ -460,7 +548,7 @@ static int ipc_close_cmd(uint8_t endpoint_id)
 	return result;
 }
 
-static int ipc_open_stream_cmd(uint8_t endpoint_id,
+static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu,
 					struct audio_preset **caps)
 {
 	char buf[BLUEZ_AUDIO_MTU];
@@ -483,6 +571,7 @@ static int ipc_open_stream_cmd(uint8_t endpoint_id,
 	if (result == AUDIO_STATUS_SUCCESS) {
 		size_t buf_len = sizeof(struct audio_preset) +
 					rsp->preset[0].len;
+		*mtu = rsp->mtu;
 		*caps = malloc(buf_len);
 		memcpy(*caps, &rsp->preset, buf_len);
 	} else {
@@ -868,6 +957,7 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 	struct a2dp_stream_out *out;
 	struct audio_preset *preset;
 	const struct audio_codec *codec;
+	uint16_t mtu;
 
 	out = calloc(1, sizeof(struct a2dp_stream_out));
 	if (!out)
@@ -895,7 +985,8 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 	/* TODO: for now we always use endpoint 0 */
 	out->ep = &audio_endpoints[0];
 
-	if (ipc_open_stream_cmd(out->ep->id, &preset) != AUDIO_STATUS_SUCCESS)
+	if (ipc_open_stream_cmd(out->ep->id, &mtu, &preset) !=
+			AUDIO_STATUS_SUCCESS)
 		goto fail;
 
 	if (!preset)
@@ -903,7 +994,7 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 
 	codec = out->ep->codec;
 
-	codec->init(preset, &out->ep->codec_data);
+	codec->init(preset, mtu, &out->ep->codec_data);
 	codec->get_config(out->ep->codec_data, &out->cfg);
 
 	DBG("rate=%d channels=%d format=%d", out->cfg.rate,
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v2 6/9] android/hal-audio: Add resume to codec callbacks
From: Andrzej Kaczmarek @ 2014-01-20 14:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390229943-29609-1-git-send-email-andrzej.kaczmarek@tieto.com>

Once stream is resumed it may be required to reset some state of codec,
i.e. in case of SBC we need to reset monotonic clock and frames count
which are used for synchronization.
---
 android/hal-audio.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 22dff53..adceab8 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -124,6 +124,9 @@ struct sbc_data {
 	uint8_t *out_buf;
 
 	unsigned frame_duration;
+
+	struct timespec start;
+	unsigned frames_sent;
 };
 
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
@@ -132,6 +135,7 @@ static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
 static int sbc_cleanup(void *codec_data);
 static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
+static void sbc_resume(void *codec_data);
 
 struct audio_codec {
 	uint8_t type;
@@ -143,6 +147,7 @@ struct audio_codec {
 	int (*cleanup) (void *codec_data);
 	int (*get_config) (void *codec_data,
 					struct audio_input_config *config);
+	void (*resume) (void *codec_data);
 	ssize_t (*write_data) (void *codec_data, const void *buffer,
 				size_t bytes);
 };
@@ -156,6 +161,7 @@ static const struct audio_codec audio_codecs[] = {
 		.init = sbc_codec_init,
 		.cleanup = sbc_cleanup,
 		.get_config = sbc_get_config,
+		.resume = sbc_resume,
 	}
 };
 
@@ -351,6 +357,17 @@ static int sbc_get_config(void *codec_data,
 	return AUDIO_STATUS_SUCCESS;
 }
 
+static void sbc_resume(void *codec_data)
+{
+	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
+
+	DBG("");
+
+	clock_gettime(CLOCK_MONOTONIC, &sbc_data->start);
+
+	sbc_data->frames_sent = 0;
+}
+
 static void audio_ipc_cleanup(void)
 {
 	if (audio_sk >= 0) {
@@ -673,6 +690,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
 		if (ipc_resume_stream_cmd(out->ep->id) != AUDIO_STATUS_SUCCESS)
 			return -1;
 
+		out->ep->codec->resume(out->ep->codec_data);
+
 		out->audio_state = AUDIO_A2DP_STATE_STARTED;
 	}
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v2 7/9] android/hal-audio: Return proper buffer size to AudioFlinger
From: Andrzej Kaczmarek @ 2014-01-20 14:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390229943-29609-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 android/hal-audio.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index adceab8..498ca48 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -135,6 +135,7 @@ static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
 static int sbc_cleanup(void *codec_data);
 static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
+static size_t sbc_get_buffer_size(void *codec_data);
 static void sbc_resume(void *codec_data);
 
 struct audio_codec {
@@ -147,6 +148,7 @@ struct audio_codec {
 	int (*cleanup) (void *codec_data);
 	int (*get_config) (void *codec_data,
 					struct audio_input_config *config);
+	size_t (*get_buffer_size) (void *codec_data);
 	void (*resume) (void *codec_data);
 	ssize_t (*write_data) (void *codec_data, const void *buffer,
 				size_t bytes);
@@ -161,6 +163,7 @@ static const struct audio_codec audio_codecs[] = {
 		.init = sbc_codec_init,
 		.cleanup = sbc_cleanup,
 		.get_config = sbc_get_config,
+		.get_buffer_size = sbc_get_buffer_size,
 		.resume = sbc_resume,
 	}
 };
@@ -357,6 +360,15 @@ static int sbc_get_config(void *codec_data,
 	return AUDIO_STATUS_SUCCESS;
 }
 
+static size_t sbc_get_buffer_size(void *codec_data)
+{
+	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
+
+	DBG("");
+
+	return sbc_data->in_buf_size;
+}
+
 static void sbc_resume(void *codec_data)
 {
 	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
@@ -730,8 +742,11 @@ static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
 
 static size_t out_get_buffer_size(const struct audio_stream *stream)
 {
+	struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+
 	DBG("");
-	return 20 * 512;
+
+	return out->ep->codec->get_buffer_size(out->ep->codec_data);
 }
 
 static uint32_t out_get_channels(const struct audio_stream *stream)
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v2 8/9] android/hal-audio: Read fd from Output Stream response
From: Andrzej Kaczmarek @ 2014-01-20 14:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390229943-29609-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 android/hal-audio.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 498ca48..f99476d 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -577,7 +577,7 @@ static int ipc_close_cmd(uint8_t endpoint_id)
 	return result;
 }
 
-static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu,
+static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu, int *fd,
 					struct audio_preset **caps)
 {
 	char buf[BLUEZ_AUDIO_MTU];
@@ -595,7 +595,7 @@ static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu,
 	cmd.id = endpoint_id;
 
 	result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
-				sizeof(cmd), &cmd, &rsp_len, rsp, NULL);
+				sizeof(cmd), &cmd, &rsp_len, rsp, fd);
 
 	if (result == AUDIO_STATUS_SUCCESS) {
 		size_t buf_len = sizeof(struct audio_preset) +
@@ -992,6 +992,7 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 	struct audio_preset *preset;
 	const struct audio_codec *codec;
 	uint16_t mtu;
+	int fd;
 
 	out = calloc(1, sizeof(struct a2dp_stream_out));
 	if (!out)
@@ -1019,13 +1020,15 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 	/* TODO: for now we always use endpoint 0 */
 	out->ep = &audio_endpoints[0];
 
-	if (ipc_open_stream_cmd(out->ep->id, &mtu, &preset) !=
+	if (ipc_open_stream_cmd(out->ep->id, &mtu, &fd, &preset) !=
 			AUDIO_STATUS_SUCCESS)
 		goto fail;
 
-	if (!preset)
+	if (!preset || fd < 0)
 		goto fail;
 
+	out->ep->fd = fd;
+
 	codec = out->ep->codec;
 
 	codec->init(preset, mtu, &out->ep->codec_data);
@@ -1059,6 +1062,11 @@ static void audio_close_output_stream(struct audio_hw_device *dev,
 
 	ipc_close_stream_cmd(ep->id);
 
+	if (ep->fd >= 0) {
+		close(ep->fd);
+		ep->fd = -1;
+	}
+
 	ep->codec->cleanup(ep->codec_data);
 	ep->codec_data = NULL;
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v2 9/9] android/hal-audio: Add proper SBC encoding
From: Andrzej Kaczmarek @ 2014-01-20 14:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390229943-29609-1-git-send-email-andrzej.kaczmarek@tieto.com>

Input and output stream is configured in a way that each input buffer
can be encoded to exactly one output buffer.

Reading from AudioFlinger is synchronized based on amounts of frames
which were expected to be sent since stream was resumed, i.e. as long
as we sent enough data we can wait for period of single media packet
before we need another buffer from input. Without synchronization
we'd receive next input buffer as soon as we process current one.
---
 android/hal-audio.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 93 insertions(+), 3 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index f99476d..1f0d22c 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -24,6 +24,7 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <unistd.h>
+#include <arpa/inet.h>
 
 #include <hardware/audio.h>
 #include <hardware/hardware.h>
@@ -127,8 +128,22 @@ struct sbc_data {
 
 	struct timespec start;
 	unsigned frames_sent;
+
+	uint16_t seq;
 };
 
+static inline void timespec_diff(struct timespec *a, struct timespec *b,
+					struct timespec *res)
+{
+	res->tv_sec = a->tv_sec - b->tv_sec;
+	res->tv_nsec = a->tv_nsec - b->tv_nsec;
+
+	if (res->tv_nsec < 0) {
+		res->tv_sec--;
+		res->tv_nsec += 1000000000; /* 1sec */
+	}
+}
+
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
 static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
 				void **codec_data);
@@ -137,6 +152,8 @@ static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
 static size_t sbc_get_buffer_size(void *codec_data);
 static void sbc_resume(void *codec_data);
+static ssize_t sbc_write_data(void *codec_data, const void *buffer,
+					size_t bytes, int fd);
 
 struct audio_codec {
 	uint8_t type;
@@ -151,7 +168,7 @@ struct audio_codec {
 	size_t (*get_buffer_size) (void *codec_data);
 	void (*resume) (void *codec_data);
 	ssize_t (*write_data) (void *codec_data, const void *buffer,
-				size_t bytes);
+				size_t bytes, int fd);
 };
 
 static const struct audio_codec audio_codecs[] = {
@@ -165,6 +182,7 @@ static const struct audio_codec audio_codecs[] = {
 		.get_config = sbc_get_config,
 		.get_buffer_size = sbc_get_buffer_size,
 		.resume = sbc_resume,
+		.write_data = sbc_write_data,
 	}
 };
 
@@ -380,6 +398,74 @@ static void sbc_resume(void *codec_data)
 	sbc_data->frames_sent = 0;
 }
 
+static ssize_t sbc_write_data(void *codec_data, const void *buffer,
+				size_t bytes, int fd)
+{
+	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
+	size_t consumed = 0;
+	size_t encoded = 0;
+	struct media_packet *mp = (struct media_packet *) sbc_data->out_buf;
+	size_t free_space = sbc_data->out_buf_size - sizeof(*mp);
+	struct timespec cur;
+	struct timespec diff;
+	unsigned expected_frames;
+	int ret;
+
+	mp->hdr.v = 2;
+	mp->hdr.pt = 1;
+	mp->hdr.sequence_number = htons(sbc_data->seq++);
+	mp->hdr.ssrc = htonl(1);
+	mp->payload.frame_count = 0;
+
+	while (bytes - consumed >= sbc_data->in_frame_len) {
+		ssize_t written = 0;
+
+		ret = sbc_encode(&sbc_data->enc, buffer + consumed,
+					sbc_data->in_frame_len,
+					mp->data + encoded, free_space,
+					&written);
+
+		if (ret < 0) {
+			DBG("failed to encode block");
+			break;
+		}
+
+		mp->payload.frame_count++;
+
+		consumed += ret;
+		encoded += written;
+		free_space -= written;
+	}
+
+	ret = write(fd, mp, sizeof(*mp) + encoded);
+	if (ret < 0) {
+		int err = errno;
+		DBG("error writing data: %d (%s)", err, strerror(err));
+	}
+
+	if (consumed != bytes || free_space != 0) {
+		/*
+		 * we should encode all input data and fill output buffer
+		 * if we did not, something went wrong but we can't really
+		 * handle this so this is just sanity check
+		 */
+		DBG("some data were not encoded");
+	}
+
+	sbc_data->frames_sent += mp->payload.frame_count;
+
+	clock_gettime(CLOCK_MONOTONIC, &cur);
+	timespec_diff(&cur, &sbc_data->start, &diff);
+	expected_frames = (diff.tv_sec * 1000000 + diff.tv_nsec / 1000) /
+				sbc_data->frame_duration;
+
+	if (sbc_data->frames_sent >= expected_frames)
+		usleep(sbc_data->frame_duration * mp->payload.frame_count);
+
+	/* we always assume that all data was processed and sent */
+	return bytes;
+}
+
 static void audio_ipc_cleanup(void)
 {
 	if (audio_sk >= 0) {
@@ -712,9 +798,13 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
 		return -1;
 	}
 
-	/* TODO: encode data using codec */
+	if (out->ep->fd < 0) {
+		DBG("no transport");
+		return -1;
+	}
 
-	return bytes;
+	return out->ep->codec->write_data(out->ep->codec_data, buffer,
+						bytes, out->ep->fd);
 }
 
 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
-- 
1.8.5.2


^ permalink raw reply related

* Re: [PATCH 02/11] android/hidhost: Fix miscalculation of get report event struct length
From: Szymon Janc @ 2014-01-20 15:22 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1389914751-18545-3-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Friday 17 of January 2014 01:25:42 Ravi kumar Veeramally wrote:
> ---
>  android/hal-hidhost.c | 3 ++-
>  android/hidhost.c     | 3 ++-
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
> index fd3ad2d..5445d08 100644
> --- a/android/hal-hidhost.c
> +++ b/android/hal-hidhost.c
> @@ -73,7 +73,8 @@ static void handle_get_report(void *buf, uint16_t len)
>  {
>  	struct hal_ev_hidhost_get_report *ev = buf;
>  
> -	if (len != sizeof(*ev) + ev->len) {
> +	if (len != sizeof(*ev) + sizeof(struct hal_ev_hidhost_get_report)
> +								+ ev->len) {

I don't understand this change. We have header and data len. There should be
no need for any extra calculations.


>  		error("invalid get report event, aborting");
>  		exit(EXIT_FAILURE);
>  	}
> diff --git a/android/hidhost.c b/android/hidhost.c
> index c004063..8a2668c 100644
> --- a/android/hidhost.c
> +++ b/android/hidhost.c
> @@ -371,13 +371,14 @@ static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
>  	ba2str(&dev->dst, address);
>  	DBG("device %s", address);
>  
> -	ev_len = sizeof(*ev) + sizeof(struct hal_ev_hidhost_get_report) + 1;
> +	ev_len = sizeof(*ev) + sizeof(struct hal_ev_hidhost_get_report);

I don't understand why there is double sizeof() in first place.(*ev is same type)

>  
>  	if (!((buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_INPUT)) ||
>  			(buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_OUTPUT)) ||
>  			(buf[0]	== (HID_MSG_DATA | HID_DATA_TYPE_FEATURE)))) {
>  		ev = g_malloc0(ev_len);
>  		ev->status = buf[0];
> +		ev->len = 0;
>  		bdaddr2android(&dev->dst, ev->bdaddr);
>  		goto send;
>  	}

I have a feeling that there is something wrong with ev_len calculations in
bt_hid_notify_get_report(). I'd rather prefer to have this function properly
fixed (and possibly refactored on how it handles ev data allocation).
 

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH 00/11] HIDHost E2E tests and fixes
From: Szymon Janc @ 2014-01-20 15:30 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Friday 17 of January 2014 01:25:40 Ravi kumar Veeramally wrote:
> Patch set contains few fixes which are noticed while writing
> tests and success test cases for hidhost.
> 
> Ravi kumar Veeramally (11):
>   android/hidhost: Fix connection state notification on profile
>     unregister
>   android/hidhost: Fix miscalculation of get report event struct length
>   android/hidhost: Remove unnecessary check
>   android/tester: Add HIDhost Connect test
>   android/tester: Add HIDhost Disconnect test
>   android/tester: Add HIDhost VirtualUnplug test
>   android/tester: Add HIDhost GetProtocol test
>   android/tester: Add HIDhost SetProtocol test
>   android/tester: Add HIDhost GetReport test
>   android/tester: Add HIDhost SetReport test
>   android/tester: Add HIDhost SendData test
> 
>  android/android-tester.c | 517 ++++++++++++++++++++++++++++++++++++++++++++++-
>  android/hal-hidhost.c    |   3 +-
>  android/hidhost.c        |  14 +-
>  3 files changed, 511 insertions(+), 23 deletions(-)
> 
> 

I've applied all patches except 2 and 9, thanks.
Please see comments for 02/11.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: Status of BlueZ GATT APIs
From: Claudio Takahasi @ 2014-01-20 16:54 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Arman Uguray, linux-bluetooth@vger.kernel.org development,
	Andre Guedes
In-Reply-To: <06DCDA5B-0724-489D-8039-1CD8E8CC62E8@holtmann.org>

Hi Arman/Marcel:

On Sat, Jan 18, 2014 at 5:42 AM, Marcel Holtmann <marcel@holtmann.org> wrot=
e:
> Hi Arman,
>
>> I was wondering what the current plans are for the GATT D-Bus API in
>> BlueZ. Can anyone give a rough estimate of when these APIs will be
>> available in BlueZ upstream and approximately when they could make to
>> into a release?
>
> I think the best person to answer this is Claudio. INdT has been working =
on these patches and we have discussed the APIs during the Plumbers Conf.
>
> Maybe they just need to re-submit a new version and we could include them=
. I honestly don=E2=80=99t know until I see an updated set of the patches.
>
> Regards
>
> Marcel

Ok. I will rebase and re-submit the patchset "[PATCH BlueZ v0 00/18]
GATT API: External Services".

Considering that some groups are interested in the GATT API again we
can start a task force to upstream the code that we have.

IMO, the GATT Server API will be more simple to upstream. We can keep
a completely separated implementation using unix socket to avoid
breaking the current implementation, and switch to the new attribute
server when we achieve a common sense.

However, before starting the Client implementation, the kernel patches
related connection and scanning sent from Andre are essential to have
a stable implementation. The GATT Client implementation needs to be
re-written from scratch, our old code was based on another "auto
connect" kernel patch approach.

Roughly speaking, our up-streaming plan is:
* GATT Server: External Services =3D> "[PATCH BlueZ v0 00/18] GATT API:
External Services"
* GATT Server: External Characteristics (Server) =3D> Ready to be submitted
* GATT Server: External Descriptors (Server) =3D> Copy from our old branch
* Replace attribute server
* Client:  Remove ATTIO and automatic connection mechanism from
userspace =3D> Requires kernel patches
* Client: Fix all GATT internal plugins
* Client: Remote Services API
* ...

Regards,
Claudio

^ permalink raw reply

* Re: [PATCH 1/5] lib: Add flag to double L2CAP IMTU size used for SDP connection
From: simon @ 2014-01-20 17:31 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, Szymon Janc
In-Reply-To: <1390177914-13529-1-git-send-email-szymon.janc@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1935 bytes --]

> This will allow to workaround Dualshock4 not respecting L2CAP MTU
> size while sending SDP response.

Maybe a little late (I see that there's a V2 of this patch series), but I
can confirm that I was able to get my 'crappy' laptop to connect to the
DS4 and stream the basic joystick data.

The connection was sensitive to technique, ie. it wouldn't 'pair then
connect' or allow pairing initiated by DS4.
--
[liveuser@localhost ~]$ bluetoothctl
[NEW] Controller 00:0F:B3:99:6B:CC localhost [default]
[bluetooth]# power on
[CHG] Controller 00:0F:B3:99:6B:CC Class: 0x00010c
Changing power on succeeded
[CHG] Controller 00:0F:B3:99:6B:CC Powered: yes
[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:0F:B3:99:6B:CC Discovering: yes
[NEW] Device 1C:66:6D:07:C3:E0 1C-66-6D-07-C3-E0
[CHG] Device 1C:66:6D:07:C3:E0 LegacyPairing: no
[CHG] Device 1C:66:6D:07:C3:E0 Name: Wireless Controller
[CHG] Device 1C:66:6D:07:C3:E0 Alias: Wireless Controller
[CHG] Device 1C:66:6D:07:C3:E0 LegacyPairing: yes <--------- wait for this!!
[bluetooth]# connect 1C:66:6D:07:C3:E0
Attempting to connect to 1C:66:6D:07:C3:E0
[CHG] Device 1C:66:6D:07:C3:E0 Connected: yes
[CHG] Device 1C:66:6D:07:C3:E0 Modalias: usb:v054Cp05C4d0100
[CHG] Device 1C:66:6D:07:C3:E0 Modalias: usb:v054Cp05C4d0100
[CHG] Device 1C:66:6D:07:C3:E0 UUIDs has unsupported type
Request PIN code
[agent] Enter PIN code: 0000
[CHG] Device 1C:66:6D:07:C3:E0 Paired: yes
Connection successful
[bluetooth]#
--

I also noticed a weird log at one point, although only saw this once and
don't know what triggered it.
--
[bluetooth]#
[CHG] Device 1C:66:6D:07:C3:E0 Class: 0x200404
[CHG] Device 1C:66:6D:07:C3:E0 Icon: audio-card <--------!!
[CHG] Device 1C:66:6D:07:C3:E0 Class: 0x002508
[CHG] Device 1C:66:6D:07:C3:E0 Icon: input-gaming
--

I will try with the V2 patch series.
Simon

[-- Attachment #2: crappy_hciconfig.txt --]
[-- Type: text/plain, Size: 638 bytes --]

root@atom:/home/simon# hciconfig -a
hci0:	Type: BR/EDR  Bus: USB
	BD Address: 00:0F:B3:99:6B:CC  ACL MTU: 192:8  SCO MTU: 64:8
	UP RUNNING PSCAN 
	RX bytes:672 acl:0 sco:0 events:22 errors:0
	TX bytes:337 acl:0 sco:0 commands:21 errors:0
	Features: 0xff 0xff 0x0f 0x00 0x00 0x00 0x00 0x00
	Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 
	Link policy: 
	Link mode: SLAVE ACCEPT 
	Name: 'atom-0'
	Class: 0x520100
	Service Classes: Networking, Object Transfer, Telephony
	Device Class: Computer, Uncategorized
	HCI Version: 1.1 (0x1)  Revision: 0x222
	LMP Version: 1.1 (0x1)  Subversion: 0x222
	Manufacturer: Cambridge Silicon Radio (10)

^ 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