Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH v2 1/3] various header include fixes for building with musl libc
From: Natanael Copa @ 2014-01-22 16:07 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: BlueZ development, Natanael Copa
In-Reply-To: <CAJdJm_Mo=hGHMYFhurEO2+L_UPpT3YPy-is020d1_CMrXzDeRw@mail.gmail.com>

On Wed, 22 Jan 2014 11:16:20 -0400
Anderson Lizardo <anderson.lizardo@openbossa.org> wrote:

> Hi Natanael,
> 
> On Wed, Jan 22, 2014 at 9:50 AM, Natanael Copa <natanael.copa@gmail.com> wrote:
> > diff --git a/src/textfile.h b/src/textfile.h
> > index b779bd2..e26da5d 100644
> > --- a/src/textfile.h
> > +++ b/src/textfile.h
> > @@ -24,6 +24,8 @@
> >  #ifndef __TEXTFILE_H
> >  #define __TEXTFILE_H
> >
> > +#include <sys/stat.h>
> > +
> 
> I believe the correct approach here is to include sys/stat.h on all
> files that include textfile.h. We (usually) don't #include system
> headers inside internal headers.

The header itself uses mode_t:
./src/textfile.h:27:1: error: unknown type name 'mode_t'

So all the files that include textfiles.h needs to include sys/stat.h
*before* the include textfile.h in that case.

I'd say that all filesm that uses mode_t including textfile.h should
include sys/stat.h.

I can make a new patch for either. Just let me know what you want.


-nc

^ permalink raw reply

* Re: [PATCH 1/2] android/ipc: trivial: Remove empty line
From: Szymon Janc @ 2014-01-22 16:40 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1390406638-16783-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Wednesday 22 of January 2014 18:03:57 Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> ---
>  android/hal-msg.h | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/android/hal-msg.h b/android/hal-msg.h
> index cfb5460..d46b428 100644
> --- a/android/hal-msg.h
> +++ b/android/hal-msg.h
> @@ -391,7 +391,6 @@ struct hal_cmd_pan_disconnect {
>  
>  /* Notifications and confirmations */
>  
> -
>  #define HAL_POWER_OFF			0x00
>  #define HAL_POWER_ON			0x01
>  
> 

Both patches applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH] android/hidhost: Fix vid and pid information
From: Andrzej Kaczmarek @ 2014-01-22 17:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

For HID device vendor, product and version numbers should be retrieved
using Device ID profile which is mandatory for devices implementing
HIDP.
---
 android/hidhost.c | 74 +++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 56 insertions(+), 18 deletions(-)

diff --git a/android/hidhost.c b/android/hidhost.c
index bb55f5e..23935da 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -648,18 +648,6 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 		sdp_record_t *rec = list->data;
 		sdp_data_t *data;
 
-		data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
-		if (data)
-			dev->vendor = data->val.uint16;
-
-		data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
-		if (data)
-			dev->product = data->val.uint16;
-
-		data = sdp_data_get(rec, SDP_ATTR_VERSION);
-		if (data)
-			dev->version = data->val.uint16;
-
 		data = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE);
 		if (data)
 			dev->country = data->val.uint8;
@@ -722,6 +710,56 @@ fail:
 	hid_device_free(dev);
 }
 
+static void hid_sdp_did_search_cb(sdp_list_t *recs, int err, gpointer data)
+{
+	struct hid_device *dev = data;
+	sdp_list_t *list;
+	GError *gerr = NULL;
+	uuid_t uuid;
+
+	DBG("");
+
+	if (err < 0) {
+		error("Unable to get Device ID SDP record: %s", strerror(-err));
+		goto fail;
+	}
+
+	if (!recs || !recs->data) {
+		error("No SDP records found");
+		goto fail;
+	}
+
+	for (list = recs; list != NULL; list = list->next) {
+		sdp_record_t *rec = list->data;
+		sdp_data_t *data;
+
+		data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
+		if (data)
+			dev->vendor = data->val.uint16;
+
+		data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
+		if (data)
+			dev->product = data->val.uint16;
+
+		data = sdp_data_get(rec, SDP_ATTR_VERSION);
+		if (data)
+			dev->version = data->val.uint16;
+	}
+
+	bt_string2uuid(&uuid, HID_UUID);
+	if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
+				hid_sdp_search_cb, dev, NULL, 0) < 0) {
+		error("failed to search sdp details");
+		goto fail;
+	}
+
+	return;
+
+fail:
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
+	hid_device_free(dev);
+}
+
 static void bt_hid_connect(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_hidhost_connect *cmd = buf;
@@ -749,10 +787,10 @@ static void bt_hid_connect(const void *buf, uint16_t len)
 	ba2str(&dev->dst, addr);
 	DBG("connecting to %s", addr);
 
-	bt_string2uuid(&uuid, HID_UUID);
+	bt_string2uuid(&uuid, PNP_UUID);
 	if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
-					hid_sdp_search_cb, dev, NULL, 0) < 0) {
-		error("Failed to search sdp details");
+					hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
+		error("Failed to search did sdp details");
 		hid_device_free(dev);
 		status = HAL_STATUS_FAILED;
 		goto failed;
@@ -1242,10 +1280,10 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		dev->ctrl_io = g_io_channel_ref(chan);
 		dev->uhid_fd = -1;
 
-		bt_string2uuid(&uuid, HID_UUID);
+		bt_string2uuid(&uuid, PNP_UUID);
 		if (bt_search_service(&src, &dev->dst, &uuid,
-					hid_sdp_search_cb, dev, NULL, 0) < 0) {
-			error("failed to search sdp details");
+					hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
+			error("failed to search did sdp details");
 			hid_device_free(dev);
 			return;
 		}
-- 
1.8.5.2


^ permalink raw reply related

* Re: [PATCH v2 1/3] various header include fixes for building with musl libc
From: Anderson Lizardo @ 2014-01-22 18:06 UTC (permalink / raw)
  To: Natanael Copa; +Cc: BlueZ development, Natanael Copa
In-Reply-To: <20140122170730.35ecc008@ncopa-desktop.alpinelinux.org>

Hi Natanael,

On Wed, Jan 22, 2014 at 12:07 PM, Natanael Copa <natanael.copa@gmail.com> wrote:
> The header itself uses mode_t:
> ./src/textfile.h:27:1: error: unknown type name 'mode_t'
>
> So all the files that include textfiles.h needs to include sys/stat.h
> *before* the include textfile.h in that case.
>
> I'd say that all filesm that uses mode_t including textfile.h should
> include sys/stat.h.
>
> I can make a new patch for either. Just let me know what you want.

This is how we have done so far for files in src/* (for src/shared/ as
Marcel mentioned this is being done differently). So I suggest you do
this way.

Note that several files (about 5 out of 10) already include
sys/stat.h, according to a quick grep I did. Maybe they are just not
in the right order.

Best Regards,
-- 
Anderson Lizardo
INdT - Manaus - Brazil

^ permalink raw reply

* [PATCH] 6lowpan: add a license to 6lowpan_iphc module
From: Yann Droneaud @ 2014-01-22 19:25 UTC (permalink / raw)
  To: Alexander Smirnov, Dmitry Eremin-Solenikov, Marcel Holtmann,
	Gustavo Padovan, Johan Hedberg, David S. Miller
  Cc: Yann Droneaud, linux-zigbee-devel, linux-bluetooth, netdev,
	linux-kernel, Jukka Rissanen, Alexander Aring

Since commit 8df8c56a5abc, 6lowpan_iphc is a module of its own.

Unfortunately, it lacks some infrastructure to behave like a
good kernel citizen:

  kernel: 6lowpan_iphc: module license 'unspecified' taints kernel.
  kernel: Disabling lock debugging due to kernel taint

This patch adds the basic MODULE_LICENSE(); with GPL license:
the code was copied from net/ieee802154/6lowpan.c which is GPL
and the module exports symbol with EXPORT_SYMBOL_GPL();.

Cc: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Cc: Alexander Aring <alex.aring@gmail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
---
 net/ieee802154/6lowpan_iphc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/ieee802154/6lowpan_iphc.c b/net/ieee802154/6lowpan_iphc.c
index e14fe8b2c054..860aa2d445ba 100644
--- a/net/ieee802154/6lowpan_iphc.c
+++ b/net/ieee802154/6lowpan_iphc.c
@@ -52,6 +52,7 @@
 
 #include <linux/bitops.h>
 #include <linux/if_arp.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <net/ipv6.h>
 #include <net/af_ieee802154.h>
@@ -797,3 +798,5 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lowpan_header_compress);
+
+MODULE_LICENSE("GPL");
-- 
1.8.4.2

^ permalink raw reply related

* [PATCH v3] various header include fixes for building with musl libc
From: Natanael Copa @ 2014-01-22 21:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Natanael Copa
In-Reply-To: <CAJdJm_MB5gAK2-9--n=P-Mni1WBRK8o-zaLSkA=_+0Bc6cCVjQ@mail.gmail.com>

we need:
 sys/stat.h for mode_t
 limits.h for PATH_MAX

Fixes compile errors:
In file included from tools/hciconfig.c:45:0:
./src/textfile.h:27:1: error: unknown type name 'mode_t'
 int create_file(const char *filename, const mode_t mode);
 ^

tools/csr_usb.c: In function 'read_value':
tools/csr_usb.c:71:12: error: 'PATH_MAX' undeclared (first use in this function)
  char path[PATH_MAX];
            ^
---
Changes v2 -> v3:
 - include the sys/stat.h in hciconfig.c instead of textfile.h. This was
   the only needed change for defining mode_t everywhere.

 tools/csr_usb.c   | 1 +
 tools/hciconfig.c | 1 +
 tools/hid2hci.c   | 1 +
 3 files changed, 3 insertions(+)

diff --git a/tools/csr_usb.c b/tools/csr_usb.c
index a483bc1..5fb6bdc 100644
--- a/tools/csr_usb.c
+++ b/tools/csr_usb.c
@@ -33,6 +33,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <dirent.h>
+#include <limits.h>
 #include <sys/ioctl.h>
 
 #include "csr.h"
diff --git a/tools/hciconfig.c b/tools/hciconfig.c
index 6c7f8ed..a81dc9c 100644
--- a/tools/hciconfig.c
+++ b/tools/hciconfig.c
@@ -37,6 +37,7 @@
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
diff --git a/tools/hid2hci.c b/tools/hid2hci.c
index 95b4abf..2dbfca7 100644
--- a/tools/hid2hci.c
+++ b/tools/hid2hci.c
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <dirent.h>
 #include <getopt.h>
+#include <limits.h>
 #include <sys/ioctl.h>
 #include <linux/types.h>
 #include <linux/hiddev.h>
-- 
1.8.5.3


^ permalink raw reply related

* Re: [PATCH] 6lowpan: add a license to 6lowpan_iphc module
From: Marcel Holtmann @ 2014-01-22 22:49 UTC (permalink / raw)
  To: Yann Droneaud
  Cc: Alexander Smirnov, Dmitry Eremin-Solenikov, Gustavo F. Padovan,
	Johan Hedberg, David S. Miller, linux-zigbee-devel,
	BlueZ development, Network Development, linux-kernel,
	Jukka Rissanen, Alexander Aring
In-Reply-To: <1390418724-9804-1-git-send-email-ydroneaud@opteya.com>

Hi Yann,

> Since commit 8df8c56a5abc, 6lowpan_iphc is a module of its own.
> 
> Unfortunately, it lacks some infrastructure to behave like a
> good kernel citizen:
> 
>  kernel: 6lowpan_iphc: module license 'unspecified' taints kernel.
>  kernel: Disabling lock debugging due to kernel taint
> 
> This patch adds the basic MODULE_LICENSE(); with GPL license:
> the code was copied from net/ieee802154/6lowpan.c which is GPL
> and the module exports symbol with EXPORT_SYMBOL_GPL();.
> 
> Cc: Jukka Rissanen <jukka.rissanen@linux.intel.com>
> Cc: Alexander Aring <alex.aring@gmail.com>
> Cc: Marcel Holtmann <marcel@holtmann.org>
> Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
> ---
> net/ieee802154/6lowpan_iphc.c | 3 +++
> 1 file changed, 3 insertions(+)
> 
> diff --git a/net/ieee802154/6lowpan_iphc.c b/net/ieee802154/6lowpan_iphc.c
> index e14fe8b2c054..860aa2d445ba 100644
> --- a/net/ieee802154/6lowpan_iphc.c
> +++ b/net/ieee802154/6lowpan_iphc.c
> @@ -52,6 +52,7 @@
> 
> #include <linux/bitops.h>
> #include <linux/if_arp.h>
> +#include <linux/module.h>
> #include <linux/netdevice.h>
> #include <net/ipv6.h>
> #include <net/af_ieee802154.h>
> @@ -797,3 +798,5 @@ int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
> 	return 0;
> }
> EXPORT_SYMBOL_GPL(lowpan_header_compress);
> +
> +MODULE_LICENSE("GPL”);

looks good to me.

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel


^ permalink raw reply

* Re: [PATCH] android/hidhost: Fix vid and pid information
From: Szymon Janc @ 2014-01-22 23:09 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1390412797-23093-1-git-send-email-andrzej.kaczmarek@tieto.com>

Hi Andrzej,

On Wednesday 22 January 2014 18:46:37 Andrzej Kaczmarek wrote:
> For HID device vendor, product and version numbers should be retrieved
> using Device ID profile which is mandatory for devices implementing
> HIDP.
> ---
>  android/hidhost.c | 74
> +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 56
> insertions(+), 18 deletions(-)
> 
> diff --git a/android/hidhost.c b/android/hidhost.c
> index bb55f5e..23935da 100644
> --- a/android/hidhost.c
> +++ b/android/hidhost.c
> @@ -648,18 +648,6 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int
> err, gpointer data) sdp_record_t *rec = list->data;
>  		sdp_data_t *data;
> 
> -		data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
> -		if (data)
> -			dev->vendor = data->val.uint16;
> -
> -		data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
> -		if (data)
> -			dev->product = data->val.uint16;
> -
> -		data = sdp_data_get(rec, SDP_ATTR_VERSION);
> -		if (data)
> -			dev->version = data->val.uint16;
> -
>  		data = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE);
>  		if (data)
>  			dev->country = data->val.uint8;
> @@ -722,6 +710,56 @@ fail:
>  	hid_device_free(dev);
>  }
> 
> +static void hid_sdp_did_search_cb(sdp_list_t *recs, int err, gpointer data)
> +{
> +	struct hid_device *dev = data;
> +	sdp_list_t *list;
> +	GError *gerr = NULL;

gerr is not used in the function, but I've fixed this (and some other minors) 
and pushed patch upstream. Thanks.

> +	uuid_t uuid;
> +
> +	DBG("");
> +
> +	if (err < 0) {
> +		error("Unable to get Device ID SDP record: %s", strerror(-err));
> +		goto fail;
> +	}
> +
> +	if (!recs || !recs->data) {
> +		error("No SDP records found");
> +		goto fail;
> +	}
> +
> +	for (list = recs; list != NULL; list = list->next) {
> +		sdp_record_t *rec = list->data;
> +		sdp_data_t *data;
> +
> +		data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
> +		if (data)
> +			dev->vendor = data->val.uint16;
> +
> +		data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
> +		if (data)
> +			dev->product = data->val.uint16;
> +
> +		data = sdp_data_get(rec, SDP_ATTR_VERSION);
> +		if (data)
> +			dev->version = data->val.uint16;
> +	}
> +
> +	bt_string2uuid(&uuid, HID_UUID);
> +	if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
> +				hid_sdp_search_cb, dev, NULL, 0) < 0) {
> +		error("failed to search sdp details");
> +		goto fail;
> +	}
> +
> +	return;
> +
> +fail:
> +	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
> +	hid_device_free(dev);
> +}
> +
>  static void bt_hid_connect(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_hidhost_connect *cmd = buf;
> @@ -749,10 +787,10 @@ static void bt_hid_connect(const void *buf, uint16_t
> len) ba2str(&dev->dst, addr);
>  	DBG("connecting to %s", addr);
> 
> -	bt_string2uuid(&uuid, HID_UUID);
> +	bt_string2uuid(&uuid, PNP_UUID);
>  	if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
> -					hid_sdp_search_cb, dev, NULL, 0) < 0) {
> -		error("Failed to search sdp details");
> +					hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
> +		error("Failed to search did sdp details");
>  		hid_device_free(dev);
>  		status = HAL_STATUS_FAILED;
>  		goto failed;
> @@ -1242,10 +1280,10 @@ static void connect_cb(GIOChannel *chan, GError
> *err, gpointer user_data) dev->ctrl_io = g_io_channel_ref(chan);
>  		dev->uhid_fd = -1;
> 
> -		bt_string2uuid(&uuid, HID_UUID);
> +		bt_string2uuid(&uuid, PNP_UUID);
>  		if (bt_search_service(&src, &dev->dst, &uuid,
> -					hid_sdp_search_cb, dev, NULL, 0) < 0) {
> -			error("failed to search sdp details");
> +					hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
> +			error("failed to search did sdp details");
>  			hid_device_free(dev);
>  			return;
>  		}

-- 
Szymon K. Janc
szymon.janc@gmail.com

^ permalink raw reply

* Re: [PATCH] 6lowpan: add a license to 6lowpan_iphc module
From: David Miller @ 2014-01-23  5:59 UTC (permalink / raw)
  To: ydroneaud
  Cc: alex.bluesman.smirnov, dbaryshkov, marcel, gustavo, johan.hedberg,
	linux-zigbee-devel, linux-bluetooth, netdev, linux-kernel,
	jukka.rissanen, alex.aring
In-Reply-To: <1390418724-9804-1-git-send-email-ydroneaud@opteya.com>

From: Yann Droneaud <ydroneaud@opteya.com>
Date: Wed, 22 Jan 2014 20:25:24 +0100

> Since commit 8df8c56a5abc, 6lowpan_iphc is a module of its own.
> 
> Unfortunately, it lacks some infrastructure to behave like a
> good kernel citizen:
> 
>   kernel: 6lowpan_iphc: module license 'unspecified' taints kernel.
>   kernel: Disabling lock debugging due to kernel taint
> 
> This patch adds the basic MODULE_LICENSE(); with GPL license:
> the code was copied from net/ieee802154/6lowpan.c which is GPL
> and the module exports symbol with EXPORT_SYMBOL_GPL();.
> 
> Cc: Jukka Rissanen <jukka.rissanen@linux.intel.com>
> Cc: Alexander Aring <alex.aring@gmail.com>
> Cc: Marcel Holtmann <marcel@holtmann.org>
> Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>

Applied.

^ permalink raw reply

* [PATCH] btproxy: Fix resource leak
From: Andrei Emeltchenko @ 2014-01-23  9:07 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Close file descriptors before leaving.
---
 tools/btproxy.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/btproxy.c b/tools/btproxy.c
index be81bae..3503148 100644
--- a/tools/btproxy.c
+++ b/tools/btproxy.c
@@ -680,8 +680,11 @@ int main(int argc, char *argv[])
 			return EXIT_FAILURE;
 		}
 
-		if (!setup_proxy(host_fd, false, dev_fd, true))
+		if (!setup_proxy(host_fd, false, dev_fd, true)) {
+			close(dev_fd);
+			close(host_fd);
 			return EXIT_FAILURE;
+		}
 	} else {
 		int server_fd;
 
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH v3 00/10] android: Add SBC encoding
From: Luiz Augusto von Dentz @ 2014-01-23  9:43 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

Hi Andrzej,

On Wed, Jan 22, 2014 at 12:34 PM, Andrzej Kaczmarek
<andrzej.kaczmarek@tieto.com> wrote:
> Hi,
>
> v1 -> v2
> - fixed comments
> - added dependency to libsbc shared library on Android
>
> v2 -> v3
> - added comment explaining why we need to sleep in out_write
> - updated to new SBC API
> - libsbc shared library is now built from our Android.mk
> - implemented proper get_latency callback
>
>
>
> Andrzej Kaczmarek (10):
>   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/hal-audio: Return proper latency for stream
>
>  android/Android.mk  |  37 ++++++-
>  android/Makefile.am |   2 +
>  android/a2dp.c      |   8 +-
>  android/audio-msg.h |   1 +
>  android/hal-audio.c | 301 +++++++++++++++++++++++++++++++++++++++++++++++++---
>  configure.ac        |   7 ++
>  6 files changed, 338 insertions(+), 18 deletions(-)
>
> --
> 1.8.5.2

Pushed, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH SBC 1/2] sbc: Add sbc_reinit_a2dp
From: Luiz Augusto von Dentz @ 2014-01-23 12:20 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds sbc_reinit_a2dp that can be used to reconfigure a previous
initialized sbc_t with new A2DP configuration.
---
 sbc/sbc.c | 49 +++++++++++++++++++++++++++++++++++--------------
 sbc/sbc.h |  2 ++
 2 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index 51bca55..534027e 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -1087,19 +1087,14 @@ SBC_EXPORT int sbc_init_msbc(sbc_t *sbc, unsigned long flags)
 	return 0;
 }
 
-SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
+static int sbc_set_a2dp(sbc_t *sbc, unsigned long flags,
 					const void *conf, size_t conf_len)
 {
 	const struct a2dp_sbc *a2dp;
-	int err;
 
 	if (conf_len != sizeof(*a2dp))
 		return -EINVAL;
 
-	err = sbc_init(sbc, flags);
-	if (err < 0)
-		return err;
-
 	a2dp = conf;
 
 	switch (a2dp->frequency) {
@@ -1116,7 +1111,7 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
 		sbc->frequency = SBC_FREQ_48000;
 		break;
 	default:
-		goto failed;
+		return -EINVAL;
 	}
 
 	switch (a2dp->channel_mode) {
@@ -1133,7 +1128,7 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
 		sbc->mode = SBC_MODE_JOINT_STEREO;
 		break;
 	default:
-		goto failed;
+		return -EINVAL;
 	}
 
 	switch (a2dp->allocation_method) {
@@ -1144,7 +1139,7 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
 		sbc->allocation = SBC_AM_LOUDNESS;
 		break;
 	default:
-		goto failed;
+		return -EINVAL;
 	}
 
 	switch (a2dp->subbands) {
@@ -1155,7 +1150,7 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
 		sbc->subbands = SBC_SB_8;
 		break;
 	default:
-		goto failed;
+		return -EINVAL;
 	}
 
 	switch (a2dp->block_length) {
@@ -1172,14 +1167,40 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
 		sbc->blocks = SBC_BLK_16;
 		break;
 	default:
-		goto failed;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
+					const void *conf, size_t conf_len)
+{
+	int err;
+
+	err = sbc_init(sbc, flags);
+	if (err < 0)
+		return err;
+
+	err = sbc_set_a2dp(sbc, flags, conf, conf_len);
+	if (err < 0) {
+		sbc_finish(sbc);
+		return err;
 	}
 
 	return 0;
+}
+
+int sbc_reinit_a2dp(sbc_t *sbc, unsigned long flags,
+					const void *conf, size_t conf_len)
+{
+	int err;
+
+	err = sbc_reinit(sbc, flags);
+	if (err < 0)
+		return err;
 
-failed:
-	sbc_finish(sbc);
-	return -EINVAL;
+	return sbc_set_a2dp(sbc, flags, conf, conf_len);
 }
 
 SBC_EXPORT ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len)
diff --git a/sbc/sbc.h b/sbc/sbc.h
index a542845..d6f123e 100644
--- a/sbc/sbc.h
+++ b/sbc/sbc.h
@@ -87,6 +87,8 @@ int sbc_reinit(sbc_t *sbc, unsigned long flags);
 int sbc_init_msbc(sbc_t *sbc, unsigned long flags);
 int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
 					const void *conf, size_t conf_len);
+int sbc_reinit_a2dp(sbc_t *sbc, unsigned long flags,
+					const void *conf, size_t conf_len);
 
 ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len);
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH SBC 2/2] sbc: Add sbc_reinit_a2dp to sbc.sym
From: Luiz Augusto von Dentz @ 2014-01-23 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390479624-5858-1-git-send-email-luiz.dentz@gmail.com>

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

---
 sbc/sbc.sym | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sbc/sbc.sym b/sbc/sbc.sym
index 0c23a05..0642a0b 100644
--- a/sbc/sbc.sym
+++ b/sbc/sbc.sym
@@ -22,4 +22,5 @@ global:
 SBC_1.2 {
 global:
 	sbc_init_a2dp;
+	sbc_reinit_a2dp;
 } SBC_1.1;
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Rename L2CAP_CHAN_CONN_FIX_A2MP to L2CAP_CHAN_FIXED_CID
From: johan.hedberg @ 2014-01-23 13:22 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

There's no reason why A2DP should need or deserve its on channel type.
Instead we should be able to group all fixed CID users under a single
channel type and reuse as much code as possible for them. Where CID
specific exceptions are needed the chan-scid value can be used.

This patch renames the current A2DP channel type to a generic one and
thereby paves the way to allow converting ATT and SMP (and any future
fixed channel protocols) to use the new channel type.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/l2cap.h |  2 +-
 net/bluetooth/a2mp.c          |  8 ++++++--
 net/bluetooth/l2cap_core.c    | 15 ++++++---------
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 85cf40acc47e..eeb02f414255 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -651,7 +651,7 @@ struct l2cap_user {
 #define L2CAP_CHAN_RAW			1
 #define L2CAP_CHAN_CONN_LESS		2
 #define L2CAP_CHAN_CONN_ORIENTED	3
-#define L2CAP_CHAN_CONN_FIX_A2MP	4
+#define L2CAP_CHAN_FIXED_CID		4
 
 /* ----- L2CAP socket info ----- */
 #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index efcd108822c4..677b970cede6 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -235,7 +235,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
 			BT_DBG("chan %p state %s", chan,
 			       state_to_string(chan->state));
 
-			if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP)
+			if (chan->scid == L2CAP_CID_A2MP)
 				continue;
 
 			l2cap_chan_lock(chan);
@@ -726,7 +726,11 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)
 
 	BT_DBG("chan %p", chan);
 
-	chan->chan_type = L2CAP_CHAN_CONN_FIX_A2MP;
+	chan->chan_type = L2CAP_CHAN_FIXED_CID;
+	chan->scid = L2CAP_CID_A2MP;
+	chan->dcid = L2CAP_CID_A2MP;
+	chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
+	chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
 	chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
 
 	chan->ops = &a2mp_chan_ops;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 138394ad3e51..84714541b48c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -519,11 +519,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 		chan->omtu = L2CAP_DEFAULT_MTU;
 		break;
 
-	case L2CAP_CHAN_CONN_FIX_A2MP:
-		chan->scid = L2CAP_CID_A2MP;
-		chan->dcid = L2CAP_CID_A2MP;
-		chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
-		chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
+	case L2CAP_CHAN_FIXED_CID:
+		/* Caller will set CID and CID specific MTU values */
 		break;
 
 	default:
@@ -571,7 +568,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
 
 		chan->conn = NULL;
 
-		if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
+		if (chan->scid != L2CAP_CID_A2MP)
 			hci_conn_drop(conn->hcon);
 
 		if (mgr && mgr->bredr_chan == chan)
@@ -1310,7 +1307,7 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
 		__clear_ack_timer(chan);
 	}
 
-	if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
+	if (chan->scid == L2CAP_CID_A2MP) {
 		l2cap_state_change(chan, BT_DISCONN);
 		return;
 	}
@@ -1508,7 +1505,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 
 		l2cap_chan_lock(chan);
 
-		if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
+		if (chan->scid == L2CAP_CID_A2MP) {
 			l2cap_chan_unlock(chan);
 			continue;
 		}
@@ -7245,7 +7242,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 		BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
 		       state_to_string(chan->state));
 
-		if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
+		if (chan->scid == L2CAP_CID_A2MP) {
 			l2cap_chan_unlock(chan);
 			continue;
 		}
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 2/2] Bluetooth: Switch ATT channels to use L2CAP_CHAN_FIXED_CID
From: johan.hedberg @ 2014-01-23 13:22 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390483368-21321-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

ATT channels are not connection oriented so having them use
L2CAP_CHAN_CONN_ORIENTED is quite confusing. Instead, use the new
L2CAP_CHAN_FIXED_CID type and ensure that the MTU and CID values get
properly set.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/l2cap_core.c | 21 +++++++++------------
 net/bluetooth/l2cap_sock.c |  6 ++++++
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 84714541b48c..c5c47667bfe0 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -498,18 +498,10 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 
 	switch (chan->chan_type) {
 	case L2CAP_CHAN_CONN_ORIENTED:
-		if (conn->hcon->type == LE_LINK) {
-			if (chan->dcid == L2CAP_CID_ATT) {
-				chan->omtu = L2CAP_DEFAULT_MTU;
-				chan->scid = L2CAP_CID_ATT;
-			} else {
-				chan->scid = l2cap_alloc_cid(conn);
-			}
-		} else {
-			/* Alloc CID for connection-oriented socket */
-			chan->scid = l2cap_alloc_cid(conn);
+		/* Alloc CID for connection-oriented socket */
+		chan->scid = l2cap_alloc_cid(conn);
+		if (conn->hcon->type == ACL_LINK)
 			chan->omtu = L2CAP_DEFAULT_MTU;
-		}
 		break;
 
 	case L2CAP_CHAN_CONN_LESS:
@@ -7025,7 +7017,12 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 		goto done;
 	}
 
-	if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
+	if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !psm) {
+		err = -EINVAL;
+		goto done;
+	}
+
+	if (chan->chan_type == L2CAP_CHAN_FIXED_CID && !cid) {
 		err = -EINVAL;
 		goto done;
 	}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 4aa6704f0b33..45064d130308 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -101,6 +101,12 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
 	if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
 		return -EINVAL;
 
+	if (la.l2_cid) {
+		/* Update type from the default CONN_ORIENTED */
+		chan->chan_type = L2CAP_CHAN_FIXED_CID;
+		chan->omtu = L2CAP_DEFAULT_MTU;
+	}
+
 	if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
 		if (!enable_lecoc && la.l2_psm)
 			return -EINVAL;
-- 
1.8.5.3


^ permalink raw reply related

* Re: [PATCH] btproxy: Fix resource leak
From: Johan Hedberg @ 2014-01-23 13:24 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1390468048-8526-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Thu, Jan 23, 2014, Andrei Emeltchenko wrote:
> Close file descriptors before leaving.
> ---
>  tools/btproxy.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 1/3] android/pan: Fix control state change callback parameters order
From: Ravi kumar Veeramally @ 2014-01-23 13:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Callback declared in bt_pan.h is
'typedef void (*btpan_control_state_callback)
(btpan_control_state_t state, bt_status_t error, int local_role,
const char* ifname);

But PanService.Java defined it wrong way.
private void onControlStateChanged(int local_role, int state,
int error, String ifname).
First and third parameters are misplaced, so sending data according
to PanService.Java, discard this fix if issue fixed in PanService.Java.
---
 android/hal-pan.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/android/hal-pan.c b/android/hal-pan.c
index 8c0f8d8..a596ffd 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -45,9 +45,18 @@ static void handle_ctrl_state(void *buf, uint16_t len)
 {
 	struct hal_ev_pan_ctrl_state *ev = buf;
 
+	/* FIXME: Callback declared in bt_pan.h is 'typedef void
+	 * (*btpan_control_state_callback)(btpan_control_state_t state,
+	 * bt_status_t error, int local_role, const char* ifname);
+	 * But PanService.Java defined it wrong way.
+	 * private void onControlStateChanged(int local_role, int state,
+	 * int error, String ifname).
+	 * First and third parameters are misplaced, so sending data according
+	 * to PanService.Java, fix this if issue fixed in PanService.Java.
+	 */
 	if (cbs->control_state_cb)
-		cbs->control_state_cb(ev->state, ev->status,
-					ev->local_role, (char *)ev->name);
+		cbs->control_state_cb(ev->local_role, ev->state, ev->status,
+							(char *)ev->name);
 }
 
 /* handlers will be called from notification thread context,
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 2/3] android/pan: Handle error case properly in NAP registration
From: Ravi kumar Veeramally @ 2014-01-23 13:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1390484367-6332-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/pan.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 67c7556..67b62f2 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -471,8 +471,10 @@ static int set_forward_delay(void)
 	int fd, ret;
 
 	fd = open(FORWARD_DELAY_PATH, O_RDWR);
-	if (fd < 0)
+	if (fd < 0) {
+		error("open forward delay path : %s", strerror(errno));
 		return -errno;
+	}
 
 	ret = write(fd, "0", sizeof("0"));
 	close(fd);
@@ -728,7 +730,7 @@ bool bt_pan_register(const bdaddr_t *addr)
 	}
 
 	err = bnep_init();
-	if (err) {
+	if (err < 0) {
 		error("bnep init failed");
 		bt_adapter_remove_record(rec->handle);
 		return false;
@@ -736,6 +738,7 @@ bool bt_pan_register(const bdaddr_t *addr)
 
 	err = register_nap_server();
 	if (err < 0) {
+		error("Failed to register NAP");
 		bt_adapter_remove_record(rec->handle);
 		bnep_cleanup();
 		return false;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 3/3] android/pan: Fix bnep interface name
From: Ravi kumar Veeramally @ 2014-01-23 13:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1390484367-6332-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Android uses bt-pan static interface in PAN profile. In server role
it uses as bridge name. But current implementaion passes interface
names like bnep0, bnep1... Android Java layer unaware of this name
and unable to allocate IP address after profile connection setup.
---
 android/pan.c                 | 45 ++++++++++++++++++++++++++++++++++---------
 profiles/network/bnep.c       |  8 +++++---
 profiles/network/bnep.h       |  3 ++-
 profiles/network/connection.c |  5 +++--
 profiles/network/server.c     |  4 ++++
 5 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 67b62f2..8c545c0 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -51,7 +51,9 @@
 
 #define SVC_HINT_NETWORKING 0x02
 
-#define BNEP_BRIDGE "bnep"
+#define BNEP_BRIDGE "bt-pan"
+#define BNEP_PANU_INTERFACE "bt-pan"
+#define BNEP_NAP_INTERFACE "bt-pan%d"
 #define FORWARD_DELAY_PATH "/sys/class/net/"BNEP_BRIDGE"/bridge/forward_delay"
 
 static bdaddr_t adapter_addr;
@@ -71,11 +73,16 @@ struct pan_device {
 static struct {
 	uint32_t	record_id;
 	GIOChannel	*io;
+	bool		bridge;
 } nap_dev = {
 	.record_id = 0,
 	.io = NULL,
+	.bridge = false,
 };
 
+static int nap_create_bridge(void);
+static int nap_remove_bridge(void);
+
 static int device_cmp(gconstpointer s, gconstpointer user_data)
 {
 	const struct pan_device *dev = s;
@@ -102,8 +109,10 @@ static void pan_device_free(struct pan_device *dev)
 	devices = g_slist_remove(devices, dev);
 	g_free(dev);
 
-	if (g_slist_length(devices) == 0)
+	if (g_slist_length(devices) == 0) {
 		local_role = HAL_PAN_ROLE_NONE;
+		nap_remove_bridge();
+	}
 }
 
 static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
@@ -140,7 +149,11 @@ static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
 	ev.local_role = local_role;
 	ev.status = HAL_STATUS_SUCCESS;
 	memset(ev.name, 0, sizeof(ev.name));
-	memcpy(ev.name, dev->iface, sizeof(dev->iface));
+
+	if (local_role == HAL_PAN_ROLE_NAP)
+		memcpy(ev.name, BNEP_BRIDGE, sizeof(BNEP_BRIDGE));
+	else
+		memcpy(ev.name, dev->iface, sizeof(dev->iface));
 
 	ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CTRL_STATE, sizeof(ev),
 									&ev);
@@ -194,7 +207,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
 
 	sk = g_io_channel_unix_get_fd(dev->io);
 
-	dev->session = bnep_new(sk, l_role, r_role);
+	dev->session = bnep_new(sk, l_role, r_role, BNEP_PANU_INTERFACE);
 	if (!dev->session)
 		goto fail;
 
@@ -380,6 +393,9 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
 		goto failed;
 	}
 
+	if (nap_create_bridge() < 0)
+		goto failed;
+
 	if (bnep_server_add(sk, dst_role, BNEP_BRIDGE, dev->iface,
 							&dev->dst) < 0) {
 		error("server_connadd failed");
@@ -448,6 +464,9 @@ static void nap_confirm_cb(GIOChannel *chan, gpointer data)
 	local_role = HAL_PAN_ROLE_NAP;
 	dev->role = HAL_PAN_ROLE_PANU;
 
+	memset(dev->iface, 0, 16);
+	strcpy(dev->iface, BNEP_NAP_INTERFACE);
+
 	dev->io = g_io_channel_ref(chan);
 	g_io_channel_set_close_on_unref(dev->io, TRUE);
 
@@ -488,6 +507,9 @@ static int nap_create_bridge(void)
 
 	DBG("%s", BNEP_BRIDGE);
 
+	if (nap_dev.bridge == true)
+		return 0;
+
 	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
 	if (sk < 0)
 		return -EOPNOTSUPP;
@@ -506,6 +528,11 @@ static int nap_create_bridge(void)
 
 	close(sk);
 
+	if (err == 0)
+		nap_dev.bridge = true;
+	else
+		nap_dev.bridge = false;
+
 	return err;
 }
 
@@ -515,6 +542,11 @@ static int nap_remove_bridge(void)
 
 	DBG("%s", BNEP_BRIDGE);
 
+	if (nap_dev.bridge == false)
+		return 0;
+
+	nap_dev.bridge = false;
+
 	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
 	if (sk < 0)
 		return -EOPNOTSUPP;
@@ -544,14 +576,9 @@ static void destroy_nap_device(void)
 static int register_nap_server(void)
 {
 	GError *gerr = NULL;
-	int err;
 
 	DBG("");
 
-	err = nap_create_bridge();
-	if (err < 0)
-		return err;
-
 	nap_dev.io = bt_io_listen(NULL, nap_confirm_cb, NULL, NULL, &gerr,
 					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
 					BT_IO_OPT_PSM, BNEP_PSM,
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 2a74016..aed9260 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -173,9 +173,8 @@ static int bnep_connadd(int sk, uint16_t role, char *dev)
 {
 	struct bnep_connadd_req req;
 
-	memset(dev, 0, 16);
 	memset(&req, 0, sizeof(req));
-	strcpy(req.device, "bnep%d");
+	strcpy(req.device, dev);
 	req.sock = sk;
 	req.role = role;
 	if (ioctl(ctl, BNEPCONNADD, &req) < 0) {
@@ -384,7 +383,8 @@ static gboolean bnep_conn_req_to(gpointer user_data)
 	return FALSE;
 }
 
-struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role)
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role,
+								char *iface)
 {
 	struct bnep *session;
 	int dup_fd;
@@ -397,6 +397,8 @@ struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role)
 	session->io = g_io_channel_unix_new(dup_fd);
 	session->src = local_role;
 	session->dst = remote_role;
+	memset(session->iface, 0, 16);
+	strcpy(session->iface, iface);
 
 	g_io_channel_set_close_on_unref(session->io, TRUE);
 	session->watch = g_io_add_watch(session->io,
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 87cdacf..bc43d4f 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -30,7 +30,8 @@ uint16_t bnep_service_id(const char *svc);
 const char *bnep_uuid(uint16_t id);
 const char *bnep_name(uint16_t id);
 
-struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role,
+								char *iface);
 void bnep_free(struct bnep *session);
 
 typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index c66987d..d01d178 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -51,6 +51,7 @@
 #include "connection.h"
 
 #define NETWORK_PEER_INTERFACE "org.bluez.Network1"
+#define BNEP_INTERFACE	"bnep%d"
 
 typedef enum {
 	CONNECTED,
@@ -128,7 +129,7 @@ static void bnep_disconn_cb(gpointer data)
 
 	nc->state = DISCONNECTED;
 	memset(nc->dev, 0, sizeof(nc->dev));
-	strcpy(nc->dev, "bnep%d");
+	strcpy(nc->dev, BNEP_INTERFACE);
 
 	bnep_free(nc->session);
 	nc->session = NULL;
@@ -243,7 +244,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
 	}
 
 	sk = g_io_channel_unix_get_fd(nc->io);
-	nc->session = bnep_new(sk, BNEP_SVC_PANU, nc->id);
+	nc->session = bnep_new(sk, BNEP_SVC_PANU, nc->id, BNEP_INTERFACE);
 	if (!nc->session)
 		goto failed;
 
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 7cb5a1e..755db0d 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -53,6 +53,7 @@
 
 #define NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer1"
 #define SETUP_TIMEOUT		1
+#define BNEP_INTERFACE	"bnep%d"
 
 /* Pending Authorization */
 struct network_session {
@@ -348,6 +349,9 @@ static gboolean bnep_setup(GIOChannel *chan,
 		goto reply;
 	}
 
+	memset(na->setup->dev, 0, 16);
+	strcpy(na->setup->dev, BNEP_INTERFACE);
+
 	if (bnep_server_add(sk, dst_role, ns->bridge, na->setup->dev,
 							&na->setup->dst) < 0)
 		goto reply;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/2] android/hal-audio: Simplify and fix locking
From: Szymon Janc @ 2014-01-23 14:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This fix various issues with locking like missing unlock on
audio_ipc_cmd() return or accesing audio_sk without holding lock.
close_thread is removed to simplify code and shutdown on listen_sk is
used to indicate that that handler thread should stop.
---
 android/hal-audio.c | 68 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 36 insertions(+), 32 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 4326ccd..11b0767 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -44,10 +44,8 @@ static const uint8_t a2dp_src_uuid[] = {
 
 static int listen_sk = -1;
 static int audio_sk = -1;
-static bool close_thread = false;
 
 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
@@ -487,14 +485,6 @@ static ssize_t sbc_write_data(void *codec_data, const void *buffer,
 	return bytes;
 }
 
-static void audio_ipc_cleanup(void)
-{
-	if (audio_sk >= 0) {
-		shutdown(audio_sk, SHUT_RDWR);
-		audio_sk = -1;
-	}
-}
-
 static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 			void *param, size_t *rsp_len, void *rsp, int *fd)
 {
@@ -506,6 +496,8 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 	struct hal_status s;
 	size_t s_len = sizeof(s);
 
+	pthread_mutex_lock(&sk_mutex);
+
 	if (audio_sk < 0) {
 		error("audio: Invalid cmd socket passed to audio_ipc_cmd");
 		goto failed;
@@ -533,12 +525,9 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 	msg.msg_iov = iv;
 	msg.msg_iovlen = 2;
 
-	pthread_mutex_lock(&sk_mutex);
-
 	ret = sendmsg(audio_sk, &msg, 0);
 	if (ret < 0) {
 		error("audio: Sending command failed:%s", strerror(errno));
-		pthread_mutex_unlock(&sk_mutex);
 		goto failed;
 	}
 
@@ -570,12 +559,9 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 	if (ret < 0) {
 		error("audio: Receiving command response failed:%s",
 							strerror(errno));
-		pthread_mutex_unlock(&sk_mutex);
 		goto failed;
 	}
 
-	pthread_mutex_unlock(&sk_mutex);
-
 	if (ret < (ssize_t) sizeof(cmd)) {
 		error("audio: Too small response received(%zd bytes)", ret);
 		goto failed;
@@ -611,9 +597,13 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 			goto failed;
 		}
 
+		pthread_mutex_unlock(&sk_mutex);
+
 		return s->code;
 	}
 
+	pthread_mutex_unlock(&sk_mutex);
+
 	/* Receive auxiliary data in msg */
 	if (fd) {
 		struct cmsghdr *cmsg;
@@ -638,7 +628,8 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 failed:
 	/* Some serious issue happen on IPC - recover */
 	shutdown(audio_sk, SHUT_RDWR);
-	audio_sk = -1;
+	pthread_mutex_unlock(&sk_mutex);
+
 	return AUDIO_STATUS_FAILED;
 }
 
@@ -1311,10 +1302,8 @@ static int audio_close(hw_device_t *device)
 
 	DBG("");
 
-	pthread_mutex_lock(&close_mutex);
-	audio_ipc_cleanup();
-	close_thread = true;
-	pthread_mutex_unlock(&close_mutex);
+	shutdown(listen_sk, SHUT_RDWR);
+	shutdown(audio_sk, SHUT_RDWR);
 
 	pthread_join(ipc_th, NULL);
 
@@ -1329,19 +1318,31 @@ static void *ipc_handler(void *data)
 {
 	bool done = false;
 	struct pollfd pfd;
+	int sk;
 
 	DBG("");
 
 	while (!done) {
 		DBG("Waiting for connection ...");
-		audio_sk = accept(listen_sk, NULL, NULL);
-		if (audio_sk < 0) {
+
+		sk = accept(listen_sk, NULL, NULL);
+		if (sk < 0) {
 			int err = errno;
-			error("audio: Failed to accept socket: %d (%s)", err,
-								strerror(err));
-			continue;
+
+			if (err == EINTR)
+				continue;
+
+			if (err != ECONNABORTED && err != EINVAL)
+				error("audio: Failed to accept socket: %d (%s)",
+							err, strerror(err));
+
+			break;
 		}
 
+		pthread_mutex_lock(&sk_mutex);
+		audio_sk = sk;
+		pthread_mutex_unlock(&sk_mutex);
+
 		DBG("Audio IPC: Connected");
 
 		if (register_endpoints() != AUDIO_STATUS_SUCCESS) {
@@ -1349,7 +1350,12 @@ static void *ipc_handler(void *data)
 
 			unregister_endpoints();
 
+			pthread_mutex_lock(&sk_mutex);
 			shutdown(audio_sk, SHUT_RDWR);
+			close(audio_sk);
+			audio_sk = -1;
+			pthread_mutex_unlock(&sk_mutex);
+
 			continue;
 		}
 
@@ -1362,14 +1368,12 @@ static void *ipc_handler(void *data)
 
 		if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
 			info("Audio HAL: Socket closed");
+
+			pthread_mutex_lock(&sk_mutex);
+			close(audio_sk);
 			audio_sk = -1;
+			pthread_mutex_unlock(&sk_mutex);
 		}
-
-		/*Check if audio_dev is closed */
-		pthread_mutex_lock(&close_mutex);
-		done = close_thread;
-		close_thread = false;
-		pthread_mutex_unlock(&close_mutex);
 	}
 
 	unregister_endpoints();
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 2/2] android/hal-audio: Don't try to unregister endpoints on handler exit
From: Szymon Janc @ 2014-01-23 14:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1390486886-12350-1-git-send-email-szymon.janc@tieto.com>

audio_sk is already closed at this point so just cleanup any leftovers
in enpoints states.
---
 android/hal-audio.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 11b0767..0128622 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -1376,7 +1376,8 @@ static void *ipc_handler(void *data)
 		}
 	}
 
-	unregister_endpoints();
+	/* audio_sk is closed at this point, just cleanup endpoints states */
+	memset(audio_endpoints, 0, sizeof(audio_endpoints));
 
 	info("Closing Audio IPC thread");
 	return NULL;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH v2 1/2] android/hal-audio: Simplify and fix locking
From: Szymon Janc @ 2014-01-23 15:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This fix various issues with locking like missing unlock on
audio_ipc_cmd() return or accesing audio_sk without holding lock.
close_thread is removed to simplify code and shutdown on listen_sk is
used to indicate that that handler thread should stop.
---
v2: fix missing unregister_endpoints() on audio_close

 android/hal-audio.c | 70 +++++++++++++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 32 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 4326ccd..52f8894 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -44,10 +44,8 @@ static const uint8_t a2dp_src_uuid[] = {
 
 static int listen_sk = -1;
 static int audio_sk = -1;
-static bool close_thread = false;
 
 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
@@ -487,14 +485,6 @@ static ssize_t sbc_write_data(void *codec_data, const void *buffer,
 	return bytes;
 }
 
-static void audio_ipc_cleanup(void)
-{
-	if (audio_sk >= 0) {
-		shutdown(audio_sk, SHUT_RDWR);
-		audio_sk = -1;
-	}
-}
-
 static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 			void *param, size_t *rsp_len, void *rsp, int *fd)
 {
@@ -506,6 +496,8 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 	struct hal_status s;
 	size_t s_len = sizeof(s);
 
+	pthread_mutex_lock(&sk_mutex);
+
 	if (audio_sk < 0) {
 		error("audio: Invalid cmd socket passed to audio_ipc_cmd");
 		goto failed;
@@ -533,12 +525,9 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 	msg.msg_iov = iv;
 	msg.msg_iovlen = 2;
 
-	pthread_mutex_lock(&sk_mutex);
-
 	ret = sendmsg(audio_sk, &msg, 0);
 	if (ret < 0) {
 		error("audio: Sending command failed:%s", strerror(errno));
-		pthread_mutex_unlock(&sk_mutex);
 		goto failed;
 	}
 
@@ -570,12 +559,9 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 	if (ret < 0) {
 		error("audio: Receiving command response failed:%s",
 							strerror(errno));
-		pthread_mutex_unlock(&sk_mutex);
 		goto failed;
 	}
 
-	pthread_mutex_unlock(&sk_mutex);
-
 	if (ret < (ssize_t) sizeof(cmd)) {
 		error("audio: Too small response received(%zd bytes)", ret);
 		goto failed;
@@ -611,9 +597,13 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 			goto failed;
 		}
 
+		pthread_mutex_unlock(&sk_mutex);
+
 		return s->code;
 	}
 
+	pthread_mutex_unlock(&sk_mutex);
+
 	/* Receive auxiliary data in msg */
 	if (fd) {
 		struct cmsghdr *cmsg;
@@ -638,7 +628,8 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
 failed:
 	/* Some serious issue happen on IPC - recover */
 	shutdown(audio_sk, SHUT_RDWR);
-	audio_sk = -1;
+	pthread_mutex_unlock(&sk_mutex);
+
 	return AUDIO_STATUS_FAILED;
 }
 
@@ -1311,10 +1302,10 @@ static int audio_close(hw_device_t *device)
 
 	DBG("");
 
-	pthread_mutex_lock(&close_mutex);
-	audio_ipc_cleanup();
-	close_thread = true;
-	pthread_mutex_unlock(&close_mutex);
+	unregister_endpoints();
+
+	shutdown(listen_sk, SHUT_RDWR);
+	shutdown(audio_sk, SHUT_RDWR);
 
 	pthread_join(ipc_th, NULL);
 
@@ -1329,19 +1320,31 @@ static void *ipc_handler(void *data)
 {
 	bool done = false;
 	struct pollfd pfd;
+	int sk;
 
 	DBG("");
 
 	while (!done) {
 		DBG("Waiting for connection ...");
-		audio_sk = accept(listen_sk, NULL, NULL);
-		if (audio_sk < 0) {
+
+		sk = accept(listen_sk, NULL, NULL);
+		if (sk < 0) {
 			int err = errno;
-			error("audio: Failed to accept socket: %d (%s)", err,
-								strerror(err));
-			continue;
+
+			if (err == EINTR)
+				continue;
+
+			if (err != ECONNABORTED && err != EINVAL)
+				error("audio: Failed to accept socket: %d (%s)",
+							err, strerror(err));
+
+			break;
 		}
 
+		pthread_mutex_lock(&sk_mutex);
+		audio_sk = sk;
+		pthread_mutex_unlock(&sk_mutex);
+
 		DBG("Audio IPC: Connected");
 
 		if (register_endpoints() != AUDIO_STATUS_SUCCESS) {
@@ -1349,7 +1352,12 @@ static void *ipc_handler(void *data)
 
 			unregister_endpoints();
 
+			pthread_mutex_lock(&sk_mutex);
 			shutdown(audio_sk, SHUT_RDWR);
+			close(audio_sk);
+			audio_sk = -1;
+			pthread_mutex_unlock(&sk_mutex);
+
 			continue;
 		}
 
@@ -1362,14 +1370,12 @@ static void *ipc_handler(void *data)
 
 		if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
 			info("Audio HAL: Socket closed");
+
+			pthread_mutex_lock(&sk_mutex);
+			close(audio_sk);
 			audio_sk = -1;
+			pthread_mutex_unlock(&sk_mutex);
 		}
-
-		/*Check if audio_dev is closed */
-		pthread_mutex_lock(&close_mutex);
-		done = close_thread;
-		close_thread = false;
-		pthread_mutex_unlock(&close_mutex);
 	}
 
 	unregister_endpoints();
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH v2 2/2] android/hal-audio: Don't try to unregister endpoints on handler exit
From: Szymon Janc @ 2014-01-23 15:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1390490548-19697-1-git-send-email-szymon.janc@tieto.com>

audio_sk is already closed at this point so just cleanup any leftovers
in enpoints states.
---
 android/hal-audio.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 52f8894..6104183 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -1378,7 +1378,8 @@ static void *ipc_handler(void *data)
 		}
 	}
 
-	unregister_endpoints();
+	/* audio_sk is closed at this point, just cleanup endpoints states */
+	memset(audio_endpoints, 0, sizeof(audio_endpoints));
 
 	info("Closing Audio IPC thread");
 	return NULL;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH] android/hal-audio: Workaround AudioFlinger issues
From: Andrzej Kaczmarek @ 2014-01-23 15:25 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

Audio HAL code calculates accurate input stream buffer size which
allows to fill media packets with as much data as possible. However,
in most cases calculated buffer size does not work well with Android
audio code which causes glitches when playing simultaneously to
different audio output (like notification) or crashes mediaserver
when disconnecting with headset.

This patch changes input buffer size to fixed magic value 20*512 which
is used in Bluedroid Audio HAL. Such change requires that we need to
drop assumption that each input buffer can be used to fill exactly one
media packet and need to use it to fill multiple media packets. To
avoid buffering in Audio HAL, we allow that last media packet can be
filled in non-optimal way, i.e. has less data that can fit.
---
 android/hal-audio.c | 86 ++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 56 insertions(+), 30 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 4326ccd..f4a4ee1 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -413,6 +413,42 @@ static void sbc_resume(void *codec_data)
 	sbc_data->frames_sent = 0;
 }
 
+static void write_media_packet(int fd, struct sbc_data *sbc_data,
+				struct media_packet *mp, size_t data_len)
+{
+	struct timespec cur;
+	struct timespec diff;
+	unsigned expected_frames;
+	int ret;
+
+	ret = write(fd, mp, sizeof(*mp) + data_len);
+	if (ret < 0) {
+		int err = errno;
+		DBG("error writing data: %d (%s)", err,
+						strerror(err));
+	}
+
+	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;
+
+	/* AudioFlinger does not seem to provide any *working*
+	 * API to provide data in some interval and will just
+	 * send another buffer as soon as we process current
+	 * one. To prevent overflowing L2CAP socket, we need to
+	 * introduce some artificial delay here base on how many
+	 * audio frames were sent so far, i.e. if we're not
+	 * lagging behind audio stream, we can sleep for
+	 * duration of single media packet.
+	 */
+	if (sbc_data->frames_sent >= expected_frames)
+		usleep(sbc_data->frame_duration *
+				mp->payload.frame_count);
+}
+
 static ssize_t sbc_write_data(void *codec_data, const void *buffer,
 				size_t bytes, int fd)
 {
@@ -421,9 +457,6 @@ static ssize_t sbc_write_data(void *codec_data, const void *buffer,
 	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;
@@ -450,39 +483,28 @@ static ssize_t sbc_write_data(void *codec_data, const void *buffer,
 		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));
+		/* write data if we either filled media packed or encoded all
+		 * input data
+		 */
+		if (mp->payload.frame_count == sbc_data->frames_per_packet ||
+				bytes == consumed) {
+			write_media_packet(fd, sbc_data, mp, encoded);
+
+			encoded = 0;
+			free_space = sbc_data->out_buf_size - sizeof(*mp);
+			mp->payload.frame_count = 0;
+		}
 	}
 
-	if (consumed != bytes || free_space != 0) {
-		/* we should encode all input data and fill output buffer
+	if (consumed != bytes) {
+		/* we should encode all input data
 		 * 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;
-
-	/* AudioFlinger does not seem to provide any *working* API to provide
-	 * data in some interval and will just send another buffer as soon as
-	 * we process current one. To prevent overflowing L2CAP socket, we need
-	 * to introduce some artificial delay here base on how many audio frames
-	 * were sent so far, i.e. if we're not lagging behind audio stream, we
-	 * can sleep for duration of single media packet.
-	 */
-	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;
 }
@@ -853,11 +875,15 @@ 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 out->ep->codec->get_buffer_size(out->ep->codec_data);
+	/* We should return proper buffer size calculated by codec (so each
+	 * input buffer is encoded into single media packed) but this does not
+	 * work well with AudioFlinger and causes problems. For this reason we
+	 * use magic value here and out_write code takes care of splitting
+	 * input buffer into multiple media packets.
+	 */
+	return 20 * 512;
 }
 
 static uint32_t out_get_channels(const struct audio_stream *stream)
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH] android/a2dp: Free device outside of notify function
From: Andrei Emeltchenko @ 2014-01-23 15:26 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

device_free() was used inside notify_state() function based on parameter
which makes it complex to follow. Change logic so that notify_state()
only notifies and the other code makes device_free().
---
 android/a2dp.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 572e0d1..d043c04 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -189,11 +189,6 @@ static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
 
 	ipc_send_notif(HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_CONN_STATE, sizeof(ev),
 									&ev);
-
-	if (state != HAL_A2DP_STATE_DISCONNECTED)
-		return;
-
-	a2dp_device_free(dev);
 }
 
 static void bt_audio_notify_state(struct a2dp_setup *setup, uint8_t state)
@@ -221,6 +216,7 @@ static void disconnect_cb(void *user_data)
 	struct a2dp_device *dev = user_data;
 
 	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+	a2dp_device_free(dev);
 }
 
 static int sbc_check_config(void *caps, uint8_t caps_len, void *conf,
@@ -460,6 +456,7 @@ static gboolean idle_timeout(gpointer user_data)
 
 	error("avdtp_discover: %s", strerror(-err));
 	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+	a2dp_device_free(dev);
 
 	return FALSE;
 }
@@ -474,6 +471,7 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
 
 	if (err) {
 		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+		a2dp_device_free(dev);
 		error("%s", err->message);
 		return;
 	}
@@ -519,6 +517,7 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
 
 failed:
 	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+	a2dp_device_free(dev);
 }
 
 static void bt_a2dp_connect(const void *buf, uint16_t len)
@@ -581,6 +580,7 @@ static void bt_a2dp_disconnect(const void *buf, uint16_t len)
 
 	if (dev->io) {
 		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+		a2dp_device_free(dev);
 		goto failed;
 	}
 
-- 
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