Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ] core: Do not change service state in btd_service_connect if it fails
From: Luiz Augusto von Dentz @ 2013-11-14 12:27 UTC (permalink / raw)
  To: linux-bluetooth

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

If .connect fails and the service state changes it may re-enter
connect_next, inverting the order and messing up the error of each
connect request.
---
 src/service.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/service.c b/src/service.c
index 52a8291..7a480d6 100644
--- a/src/service.c
+++ b/src/service.c
@@ -198,18 +198,16 @@ int btd_service_connect(struct btd_service *service)
 		return -EBUSY;
 	}
 
-	change_state(service, BTD_SERVICE_STATE_CONNECTING, 0);
-
 	err = profile->connect(service);
-	if (err == 0)
+	if (err == 0) {
+		change_state(service, BTD_SERVICE_STATE_CONNECTING, 0);
 		return 0;
+	}
 
 	ba2str(device_get_address(service->device), addr);
 	error("%s profile connect failed for %s: %s", profile->name, addr,
 								strerror(-err));
 
-	btd_service_connecting_complete(service, err);
-
 	return err;
 }
 
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH v2 0/8] android: Some adapter and mgmt handling code cleanup
From: Johan Hedberg @ 2013-11-14 12:59 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, Szymon Janc
In-Reply-To: <1384300100-8941-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Tue, Nov 12, 2013, Szymon Janc wrote:
> v2:
>  - addressed Johan comments about using static adapter structure instead of
>    bunch of static adapter_* variables
>  - Added a patch for utilizing mgmt library for passing adapter ready callback
>    (patch 3)
> 
> v1:
>   This patchset moves mgmt initalization handling from main.c to adapter.c so
>   now all mgmt handling is done from adaper.c. Adapter.c is also renamed to
>   bluetooth.c to match service name implemented by it.
> 
>   Startup and shutdown timeouts are still handled in main.c (mostly due to
>   both resulting in mainloop shutdown so extra callback are avoided).
> 
>   IO handling and commands dispatch is still done in main.c
> 
> 
> Comments are welcome.
> 
> -- 
> BR
> Szymon Janc
> 
> Szymon Janc (8):
>   android: Make adapter static
>   android: Move adapter initialization to adapter.c
>   android: Don't use static pointer for storing adapter_ready callback
>   android/hidhost: Use adapter address provided on register
>   android: Report adapter address in adapter_ready callback
>   android: Remove not needed bt_adapter_get_address function
>   android: Rename adapter.c to bluetooth.c
>   android: Rename bluetooth service functions to match service name
> 
>  android/Android.mk  |    2 +-
>  android/Makefile.am |    4 +-
>  android/adapter.c   | 2008 -----------------------------------------------
>  android/adapter.h   |   37 -
>  android/bluetooth.c | 2177 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  android/bluetooth.h |   38 +
>  android/hidhost.c   |   21 +-
>  android/main.c      |  314 ++------
>  8 files changed, 2287 insertions(+), 2314 deletions(-)
>  delete mode 100644 android/adapter.c
>  delete mode 100644 android/adapter.h
>  create mode 100644 android/bluetooth.c
>  create mode 100644 android/bluetooth.h

All patches in this set have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ] core: Do not change service state in btd_service_connect if it fails
From: Johan Hedberg @ 2013-11-14 12:59 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1384432071-2703-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Thu, Nov 14, 2013, Luiz Augusto von Dentz wrote:
> If .connect fails and the service state changes it may re-enter
> connect_next, inverting the order and messing up the error of each
> connect request.
> ---
>  src/service.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 1/2] android: Add PTS PICS for GAP
From: Jakub Tyszkowski @ 2013-11-14 13:26 UTC (permalink / raw)
  To: linux-bluetooth

PTS PICS for GAP, targeting Android 4.4.

---
 android/pics-gap.txt | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 201 insertions(+)
 create mode 100644 android/pics-gap.txt

diff --git a/android/pics-gap.txt b/android/pics-gap.txt
new file mode 100644
index 0000000..bcb64cb
--- /dev/null
+++ b/android/pics-gap.txt
@@ -0,0 +1,201 @@
+GAP PICS for the PTS tool.
+
+* - different than PTS defaults
+
++------------------+------------+
+|  Parameter Name  |  Selected  |
++------------------+------------+
+| TSPC_GAP_0_1     |   False    |
+| TSPC_GAP_0_2     |   False    |
+| TSPC_GAP_0_3     |   True*    |
+| TSPC_GAP_0A_1    |   False    |
+| TSPC_GAP_1_1     |   True*    |
+| TSPC_GAP_1_2     |   False    |
+| TSPC_GAP_1_3     |   True*    |
+| TSPC_GAP_1_4     |   True*    |
+| TSPC_GAP_1_5     |   True     |
+| TSPC_GAP_1_6     |   False    |
+| TSPC_GAP_1_7     |   True*    |
+| TSPC_GAP_2_1     |   True*    |
+| TSPC_GAP_2_2     |   True*    |
+| TSPC_GAP_2_3     |   True*    |
+| TSPC_GAP_2_4     |   False    |
+| TSPC_GAP_2_5     |   True*    |
+| TSPC_GAP_2_6     |   False    |
+| TSPC_GAP_2_7     |   True*    |
+| TSPC_GAP_2_8     |   True*    |
+| TSPC_GAP_2_9     |   True*    |
+| TSPC_GAP_2_10    |   False    |
+| TSPC_GAP_3_1     |   True*    |
+| TSPC_GAP_3_2     |   False    |
+| TSPC_GAP_3_3     |   True*    |
+| TSPC_GAP_3_4     |   True*    |
+| TSPC_GAP_3_5     |   True*    |
+| TSPC_GAP_3_6     |   True*    |
+| TSPC_GAP_4_1     |   True     |
+| TSPC_GAP_4_2     |   True     |
+| TSPC_GAP_4_3     |   True*    |
+| TSPC_GAP_4_4     |   True     |
+| TSPC_GAP_4_5     |   True*    |
+| TSPC_GAP_4_6     |   True*    |
+| TSPC_GAP_5_1     |   False*   |
+| TSPC_GAP_5_2     |   False    |
+| TSPC_GAP_5_3     |   False*   |
+| TSPC_GAP_5_4     |   True*    |
+| TSPC_GAP_6_1     |   False*   |
+| TSPC_GAP_6_2     |   False    |
+| TSPC_GAP_7_1     |   False*   |
+| TSPC_GAP_7_2     |   False*   |
+| TSPC_GAP_8_1     |   False*   |
+| TSPC_GAP_8_2     |   False    |
+| TSPC_GAP_8A_1    |   False    |
+| TSPC_GAP_8A_2    |   False    |
+| TSPC_GAP_8A_3    |   False*   |
+| TSPC_GAP_8A_4    |   False    |
+| TSPC_GAP_8A_5    |   False    |
+| TSPC_GAP_8A_6    |   False    |
+| TSPC_GAP_8A_7    |   False    |
+| TSPC_GAP_8A_8    |   False    |
+| TSPC_GAP_8A_9    |   False    |
+| TSPC_GAP_8A_10   |   False    |
+| TSPC_GAP_9_1     |   False*   |
+| TSPC_GAP_10_1    |   False*   |
+| TSPC_GAP_11_1    |   False    |
+| TSPC_GAP_11_2    |   False    |
+| TSPC_GAP_12_1    |   True     |
+| TSPC_GAP_12_2    |   False    |
+| TSPC_GAP_13_1    |   True     |
+| TSPC_GAP_13_2    |   True     |
+| TSPC_GAP_14_1    |   True     |
+| TSPC_GAP_14_2    |   False    |
+| TSPC_GAP_15_1    |   True     |
+| TSPC_GAP_16_1    |   True     |
+| TSPC_GAP_17_1    |   False    |
+| TSPC_GAP_17_2    |   False    |
+| TSPC_GAP_17_3    |   False    |
+| TSPC_GAP_17_4    |   False    |
+| TSPC_GAP_18_1    |   False    |
+| TSPC_GAP_18_2    |   False    |
+| TSPC_GAP_19_1    |   False    |
+| TSPC_GAP_19_2    |   False    |
+| TSPC_GAP_19_3    |   False    |
+| TSPC_GAP_20_1    |   False    |
+| TSPC_GAP_20_2    |   False    |
+| TSPC_GAP_20_3    |   False    |
+| TSPC_GAP_20_4    |   False    |
+| TSPC_GAP_20A_1   |   False    |
+| TSPC_GAP_20A_2   |   False    |
+| TSPC_GAP_20A_3   |   False    |
+| TSPC_GAP_20A_4   |   False    |
+| TSPC_GAP_20A_5   |   False    |
+| TSPC_GAP_20A_6   |   False    |
+| TSPC_GAP_20A_7   |   False    |
+| TSPC_GAP_20A_8   |   False    |
+| TSPC_GAP_20A_9   |   False    |
+| TSPC_GAP_20A_10  |   False    |
+| TSPC_GAP_21_1    |   False*   |
+| TSPC_GAP_21_2    |   False*   |
+| TSPC_GAP_21_3    |   False    |
+| TSPC_GAP_21_4    |   False*   |
+| TSPC_GAP_21_5    |   False*   |
+| TSPC_GAP_21_6    |   False*   |
+| TSPC_GAP_22_1    |   False    |
+| TSPC_GAP_22_2    |   False    |
+| TSPC_GAP_22_3    |   False    |
+| TSPC_GAP_22_4    |   False    |
+| TSPC_GAP_23_1    |   False    |
+| TSPC_GAP_23_2    |   False    |
+| TSPC_GAP_23_3    |   False    |
+| TSPC_GAP_23_4    |   False    |
+| TSPC_GAP_23_5    |   False    |
+| TSPC_GAP_24_1    |   False    |
+| TSPC_GAP_24_2    |   False    |
+| TSPC_GAP_24_3    |   False    |
+| TSPC_GAP_24_4    |   False    |
+| TSPC_GAP_25_1    |   False    |
+| TSPC_GAP_25_2    |   False    |
+| TSPC_GAP_25_3    |   False    |
+| TSPC_GAP_25_4    |   False    |
+| TSPC_GAP_25_5    |   False    |
+| TSPC_GAP_25_6    |   False    |
+| TSPC_GAP_25_7    |   False    |
+| TSPC_GAP_25_8    |   False    |
+| TSPC_GAP_26_1    |   False    |
+| TSPC_GAP_26_2    |   False    |
+| TSPC_GAP_26_3    |   False    |
+| TSPC_GAP_27_1    |   False*   |
+| TSPC_GAP_27_2    |   False*   |
+| TSPC_GAP_27_3    |   False    |
+| TSPC_GAP_27_4    |   False    |
+| TSPC_GAP_27_5    |   False    |
+| TSPC_GAP_27_6    |   False    |
+| TSPC_GAP_27_7    |   False    |
+| TSPC_GAP_27_8    |   False    |
+| TSPC_GAP_28_1    |   True*    |
+| TSPC_GAP_28_2    |   True*    |
+| TSPC_GAP_29_1    |   True*    |
+| TSPC_GAP_29_2    |   True*    |
+| TSPC_GAP_29_3    |   True*    |
+| TSPC_GAP_29_4    |   True*    |
+| TSPC_GAP_30_1    |   True*    |
+| TSPC_GAP_30_2    |   True*    |
+| TSPC_GAP_31_1    |   True*    |
+| TSPC_GAP_31_2    |   True*    |
+| TSPC_GAP_31_3    |   True*    |
+| TSPC_GAP_31_4    |   True*    |
+| TSPC_GAP_31_5    |   True*    |
+| TSPC_GAP_31_6    |   True*    |
+| TSPC_GAP_32_1    |   False    |
+| TSPC_GAP_32_2    |   True*    |
+| TSPC_GAP_32_3    |   True*    |
+| TSPC_GAP_33_1    |   True*    |
+| TSPC_GAP_33_2    |   True*    |
+| TSPC_GAP_33_3    |   True*    |
+| TSPC_GAP_33_4    |   True*    |
+| TSPC_GAP_33_5    |   True*    |
+| TSPC_GAP_33_6    |   True*    |
+| TSPC_GAP_34_1    |   False    |
+| TSPC_GAP_34_2    |   True*    |
+| TSPC_GAP_34_3    |   True*    |
+| TSPC_GAP_35_1    |   True*    |
+| TSPC_GAP_35_2    |   True*    |
+| TSPC_GAP_35_3    |   True*    |
+| TSPC_GAP_35_4    |   True*    |
+| TSPC_GAP_35_5    |   True*    |
+| TSPC_GAP_35_6    |   True*    |
+| TSPC_GAP_35_7    |   False    |
+| TSPC_GAP_35_8    |   False    |
+| TSPC_GAP_36_1    |   False    |
+| TSPC_GAP_36_2    |   False    |
+| TSPC_GAP_36_3    |   False    |
+| TSPC_GAP_36_4    |   False    |
+| TSPC_GAP_37_1    |   True*    |
+| TSPC_GAP_37_2    |   True*    |
+| TSPC_GAP_38_1    |   False    |
+| TSPC_GAP_38_2    |   True*    |
+| TSPC_GAP_38_3    |   False    |
+| TSPC_GAP_38_4    |   True*    |
+| TSPC_GAP_39_1    |   True*    |
+| TSPC_GAP_39_2    |   True*    |
+| TSPC_GAP_39_3    |   True*    |
+| TSPC_GAP_39_4    |   True     |
+| TSPC_GAP_39_5    |   False    |
+| TSPC_GAP_39_6    |   True*    |
+| TSPC_GAP_40_1    |   True*    |
+| TSPC_GAP_40_2    |   False    |
+| TSPC_GAP_40_3    |   True*    |
+| TSPC_GAP_40_4    |   True*    |
+| TSPC_GAP_40_5    |   True*    |
+| TSPC_GAP_41_1    |   True     |
+| TSPC_GAP_42_1    |   False    |
+| TSPC_GAP_42_2    |   False    |
+| TSPC_GAP_42_3    |   False    |
+| TSPC_GAP_42_4    |   False*   |
+| TSPC_GAP_42_5    |   False    |
+| TSPC_GAP_42_6    |   False    |
+| TSPC_GAP_43_1    |   False*   |
+| TSPC_SM_1_1      |   False    |
+| TSPC_SM_1_2      |   False    |
+| TSPC_SM_2_4      |   False    |
+| TSPC_ALL         |   False    |
++------------------+------------+
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 2/2] android: Add PTS PICS for HID
From: Jakub Tyszkowski @ 2013-11-14 13:26 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384435587-12427-1-git-send-email-jakub.tyszkowski@tieto.com>

PTS PICS for HID, targeting Android 4.4.

---
 android/pics-hid.txt | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)
 create mode 100644 android/pics-hid.txt

diff --git a/android/pics-hid.txt b/android/pics-hid.txt
new file mode 100644
index 0000000..36c49bf
--- /dev/null
+++ b/android/pics-hid.txt
@@ -0,0 +1,105 @@
+HID PICS for the PTS tool.
+
+* - different than PTS defaults
+
++------------------+------------+
+|  Parameter Name  |  Selected  |
++------------------+------------+
+| TSPC_HID_1_1     |   True*    |
+| TSPC_HID_1_2     |   False    |
+| TSPC_HID_1_3     |   False    |
+| TSPC_HID_2_1     |   True     |
+| TSPC_HID_2_2     |   True     |
+| TSPC_HID_2_3     |   True     |
+| TSPC_HID_2_4     |   True     |
+| TSPC_HID_2_5     |   True     |
+| TSPC_HID_2_6     |   True     |
+| TSPC_HID_2_7     |   True     |
+| TSPC_HID_2_8     |   True     |
+| TSPC_HID_2_9     |   True     |
+| TSPC_HID_2_10    |   False    |
+| TSPC_HID_2_11    |   False    |
+| TSPC_HID_2_12    |   False    |
+| TSPC_HID_2_13    |   False    |
+| TSPC_HID_2_14    |   False    |
+| TSPC_HID_2_15    |   False    |
+| TSPC_HID_3_1     |   False    |
+| TSPC_HID_3_2     |   True*    |
+| TSPC_HID_3_3     |   True*    |
+| TSPC_HID_3_4     |   False    |
+| TSPC_HID_4_1     |   False    |
+| TSPC_HID_4_2     |   False    |
+| TSPC_HID_4_3     |   True*    |
+| TSPC_HID_4_4     |   False    |
+| TSPC_HID_5_1     |   False    |
+| TSPC_HID_5_2     |   False    |
+| TSPC_HID_5_3     |   False    |
+| TSPC_HID_5_4     |   False    |
+| TSPC_HID_5_5     |   False*   |
+| TSPC_HID_5_6     |   False*   |
+| TSPC_HID_6_1     |   False    |
+| TSPC_HID_6_2     |   False    |
+| TSPC_HID_6_3     |   False    |
+| TSPC_HID_6_4     |   False    |
+| TSPC_HID_6_5     |   False    |
+| TSPC_HID_6_6     |   False    |
+| TSPC_HID_6_7     |   False    |
+| TSPC_HID_6_8     |   True     |
+| TSPC_HID_6_9     |   True     |
+| TSPC_HID_6_10    |   True     |
+| TSPC_HID_6_11    |   False    |
+| TSPC_HID_6_12    |   True     |
+| TSPC_HID_6_13    |   False    |
+| TSPC_HID_7_1     |   True     |
+| TSPC_HID_7_2     |   False*   |
+| TSPC_HID_8_1     |   False    |
+| TSPC_HID_8_2     |   False    |
+| TSPC_HID_8_3     |   False    |
+| TSPC_HID_8_4     |   False    |
+| TSPC_HID_9_1     |   False    |
+| TSPC_HID_9_2     |   False*   |
+| TSPC_HID_9_3     |   False    |
+| TSPC_HID_9_4     |   False*   |
+| TSPC_HID_9_5     |   False    |
+| TSPC_HID_9_6     |   False    |
+| TSPC_HID_9_7     |   False    |
+| TSPC_HID_9_8     |   False    |
+| TSPC_HID_9_9     |   False    |
+| TSPC_HID_9_10    |   False    |
+| TSPC_HID_9_11    |   False    |
+| TSPC_HID_9_12    |   False    |
+| TSPC_HID_9_13    |   False    |
+| TSPC_HID_9_14    |   False    |
+| TSPC_HID_9_15    |   False    |
+| TSPC_HID_9_16    |   False    |
+| TSPC_HID_10_1    |   False    |
+| TSPC_HID_10_2    |   False    |
+| TSPC_HID_10_3    |   False    |
+| TSPC_HID_10_4    |   False    |
+| TSPC_HID_11_1    |   False    |
+| TSPC_HID_11_2    |   False    |
+| TSPC_HID_11_3    |   False    |
+| TSPC_HID_11_4    |   False    |
+| TSPC_HID_12_1    |   False    |
+| TSPC_HID_12_2    |   False    |
+| TSPC_HID_12_3    |   False    |
+| TSPC_HID_12_4    |   False    |
+| TSPC_HID_12_5    |   False    |
+| TSPC_HID_12_6    |   False    |
+| TSPC_HID_13_1    |   False    |
+| TSPC_HID_13_2    |   False    |
+| TSPC_HID_13_3    |   False    |
+| TSPC_HID_13_4    |   False    |
+| TSPC_HID_13_5    |   False    |
+| TSPC_HID_13_6    |   False    |
+| TSPC_HID_13_7    |   False    |
+| TSPC_HID_13_8    |   False    |
+| TSPC_HID_13_9    |   False    |
+| TSPC_HID_13_10   |   False    |
+| TSPC_HID_13_11   |   False    |
+| TSPC_HID_13_12   |   False    |
+| TSPC_HID_13_13   |   False    |
+| TSPC_HID_14_1    |   False    |
+| TSPC_HID_14_2    |   False*   |
+| TSPC_ALL         |   False    |
++------------------+------------+
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH BlueZ] android/a2dp: Add implementation of SDP record
From: Luiz Augusto von Dentz @ 2013-11-14 14:16 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds the following record:

Service Name: Audio Source
Service RecHandle: 0x10001
Service Class ID List:
  "Audio Source" (0x110a)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 25
  "AVDTP" (0x0019)
    uint16: 0x103
Profile Descriptor List:
  "Advanced Audio" (0x110d)
    Version: 0x0103
---
 android/a2dp.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 32b6aa3..d8fe416 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -27,6 +27,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -34,18 +35,23 @@
 
 #include "btio/btio.h"
 #include "lib/bluetooth.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
 #include "log.h"
 #include "a2dp.h"
 #include "hal-msg.h"
 #include "ipc.h"
 #include "utils.h"
+#include "bluetooth.h"
 
 #define L2CAP_PSM_AVDTP 0x19
+#define SVC_HINT_CAPTURING 0x08
 
 static int notification_sk = -1;
 static GIOChannel *server = NULL;
 static GSList *devices = NULL;
 static bdaddr_t adapter_addr;
+static uint32_t record_id = 0;
 
 struct a2dp_device {
 	bdaddr_t	dst;
@@ -258,9 +264,71 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	signaling_connect_cb(chan, err, dev);
 }
 
+static sdp_record_t *a2dp_record(void)
+{
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid;
+	sdp_profile_desc_t profile[1];
+	sdp_list_t *aproto, *proto[2];
+	sdp_record_t *record;
+	sdp_data_t *psm, *version, *features;
+	uint16_t lp = AVDTP_UUID;
+	uint16_t a2dp_ver = 0x0103, avdtp_ver = 0x0103, feat = 0x000f;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+	root = sdp_list_append(0, &root_uuid);
+	sdp_set_browse_groups(record, root);
+
+	sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID);
+	svclass_id = sdp_list_append(0, &a2dp_uuid);
+	sdp_set_service_classes(record, svclass_id);
+
+	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
+	profile[0].version = a2dp_ver;
+	pfseq = sdp_list_append(0, &profile[0]);
+	sdp_set_profile_descs(record, pfseq);
+
+	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
+	proto[0] = sdp_list_append(0, &l2cap_uuid);
+	psm = sdp_data_alloc(SDP_UINT16, &lp);
+	proto[0] = sdp_list_append(proto[0], psm);
+	apseq = sdp_list_append(0, proto[0]);
+
+	sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID);
+	proto[1] = sdp_list_append(0, &avdtp_uuid);
+	version = sdp_data_alloc(SDP_UINT16, &avdtp_ver);
+	proto[1] = sdp_list_append(proto[1], version);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	aproto = sdp_list_append(0, apseq);
+	sdp_set_access_protos(record, aproto);
+
+	features = sdp_data_alloc(SDP_UINT16, &feat);
+	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
+
+	sdp_set_info_attr(record, "Audio Source", 0, 0);
+
+	free(psm);
+	free(version);
+	sdp_list_free(proto[0], 0);
+	sdp_list_free(proto[1], 0);
+	sdp_list_free(apseq, 0);
+	sdp_list_free(pfseq, 0);
+	sdp_list_free(aproto, 0);
+	sdp_list_free(root, 0);
+	sdp_list_free(svclass_id, 0);
+
+	return record;
+}
+
 bool bt_a2dp_register(int sk, const bdaddr_t *addr)
 {
 	GError *err = NULL;
+	sdp_record_t *rec;
 
 	DBG("");
 
@@ -277,6 +345,16 @@ bool bt_a2dp_register(int sk, const bdaddr_t *addr)
 		return false;
 	}
 
+	rec = a2dp_record();
+	if (bt_adapter_add_record(rec, SVC_HINT_CAPTURING) < 0) {
+		error("Failed to register on A2DP record");
+		g_io_channel_shutdown(server, TRUE, NULL);
+		g_io_channel_unref(server);
+		server = NULL;
+		return false;
+	}
+	record_id = rec->handle;
+
 	notification_sk = sk;
 
 	return true;
@@ -288,6 +366,9 @@ void bt_a2dp_unregister(void)
 
 	notification_sk = -1;
 
+	bt_adapter_remove_record(record_id);
+	record_id = 0;
+
 	if (server) {
 		g_io_channel_shutdown(server, TRUE, NULL);
 		g_io_channel_unref(server);
-- 
1.8.3.1


^ permalink raw reply related

* Re: Adapter name reset on suspend/resume
From: Marcel Holtmann @ 2013-11-14 14:33 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384421473.2229.1.camel@nuvo>

Hi Bastien,

>>> After suspending and resuming my laptop, hci0's name is reset to what
>>> looks like the factory name:
>>> $ hciconfig -a | grep Name
>>> 	Name: 'BCM20702A'
>>> 
>>> This is the device in question:
>>> Bus 001 Device 004: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
>>> 
>>> And my laptop is a Lenovo X1 Carbon.
>>> 
>>> Neither udevadm nor btmon show the device going away on suspend and
>>> coming back on resume.
>> 
>> can you start btmon, call hciconfig hci0 name, then suspend, then
>> resume, call hciconfig hci0 name again.
> 
> Bluetooth monitor ver 5.10
> = New Index: F4:B7:E2:E8:99:E2 (BR/EDR,USB,hci0)                   [hci0] 0.176335
> < HCI Command: Read Local Name (0x03|0x0014) plen 0                [hci0] 9.797930
>> HCI Event: Command Complete (0x0e) plen 252                      [hci0] 9.813834
>      Read Local Name (0x03|0x0014) ncmd 1
>        Status: Success (0x00)
>        Name: nuvo
> < HCI Command: Read Local Name (0x03|0x0014) plen 0               [hci0] 33.109166
>> HCI Event: Command Complete (0x0e) plen 252                     [hci0] 33.125157
>      Read Local Name (0x03|0x0014) ncmd 1
>        Status: Success (0x00)
>        Name: BCM20702A
> 
>> I am wondering if for some reason the suspend/resume actually does a
>> HCI Reset without telling us. The name normally only gets reset to
>> BCM20702A when doing a full reset.
> 
> Looks like that's what it's doing.
> 
>> Another possibility is that we actually forgot to set it in the first
>> place. I am pretty sure I have intensively tested and that should not
>> happen, but you might just found a corner case.
> 
> It's set on a normal boot, it seems to be reset only when suspending.

I have no idea on how to fix this at the moment. The problem is actually that this kind of behavior with a silent HCI reset will break remote wakeup.

Regards

Marcel


^ permalink raw reply

* [PATCH v2 BlueZ] android/a2dp: Add implementation of SDP record
From: Luiz Augusto von Dentz @ 2013-11-14 15:01 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds the following record:

Service Name: Audio Source
Service RecHandle: 0x10001
Service Class ID List:
  "Audio Source" (0x110a)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 25
  "AVDTP" (0x0019)
    uint16: 0x103
Profile Descriptor List:
  "Advanced Audio" (0x110d)
    Version: 0x0103
---
v2: Fix leaking record if bt_adapter_add_record fails

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

diff --git a/android/a2dp.c b/android/a2dp.c
index 32b6aa3..936c28e 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -27,6 +27,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -34,18 +35,23 @@
 
 #include "btio/btio.h"
 #include "lib/bluetooth.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
 #include "log.h"
 #include "a2dp.h"
 #include "hal-msg.h"
 #include "ipc.h"
 #include "utils.h"
+#include "bluetooth.h"
 
 #define L2CAP_PSM_AVDTP 0x19
+#define SVC_HINT_CAPTURING 0x08
 
 static int notification_sk = -1;
 static GIOChannel *server = NULL;
 static GSList *devices = NULL;
 static bdaddr_t adapter_addr;
+static uint32_t record_id = 0;
 
 struct a2dp_device {
 	bdaddr_t	dst;
@@ -258,9 +264,71 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	signaling_connect_cb(chan, err, dev);
 }
 
+static sdp_record_t *a2dp_record(void)
+{
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid;
+	sdp_profile_desc_t profile[1];
+	sdp_list_t *aproto, *proto[2];
+	sdp_record_t *record;
+	sdp_data_t *psm, *version, *features;
+	uint16_t lp = AVDTP_UUID;
+	uint16_t a2dp_ver = 0x0103, avdtp_ver = 0x0103, feat = 0x000f;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+	root = sdp_list_append(0, &root_uuid);
+	sdp_set_browse_groups(record, root);
+
+	sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID);
+	svclass_id = sdp_list_append(0, &a2dp_uuid);
+	sdp_set_service_classes(record, svclass_id);
+
+	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
+	profile[0].version = a2dp_ver;
+	pfseq = sdp_list_append(0, &profile[0]);
+	sdp_set_profile_descs(record, pfseq);
+
+	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
+	proto[0] = sdp_list_append(0, &l2cap_uuid);
+	psm = sdp_data_alloc(SDP_UINT16, &lp);
+	proto[0] = sdp_list_append(proto[0], psm);
+	apseq = sdp_list_append(0, proto[0]);
+
+	sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID);
+	proto[1] = sdp_list_append(0, &avdtp_uuid);
+	version = sdp_data_alloc(SDP_UINT16, &avdtp_ver);
+	proto[1] = sdp_list_append(proto[1], version);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	aproto = sdp_list_append(0, apseq);
+	sdp_set_access_protos(record, aproto);
+
+	features = sdp_data_alloc(SDP_UINT16, &feat);
+	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
+
+	sdp_set_info_attr(record, "Audio Source", 0, 0);
+
+	free(psm);
+	free(version);
+	sdp_list_free(proto[0], 0);
+	sdp_list_free(proto[1], 0);
+	sdp_list_free(apseq, 0);
+	sdp_list_free(pfseq, 0);
+	sdp_list_free(aproto, 0);
+	sdp_list_free(root, 0);
+	sdp_list_free(svclass_id, 0);
+
+	return record;
+}
+
 bool bt_a2dp_register(int sk, const bdaddr_t *addr)
 {
 	GError *err = NULL;
+	sdp_record_t *rec;
 
 	DBG("");
 
@@ -277,6 +345,17 @@ bool bt_a2dp_register(int sk, const bdaddr_t *addr)
 		return false;
 	}
 
+	rec = a2dp_record();
+	if (bt_adapter_add_record(rec, SVC_HINT_CAPTURING) < 0) {
+		error("Failed to register on A2DP record");
+		sdp_record_free(rec);
+		g_io_channel_shutdown(server, TRUE, NULL);
+		g_io_channel_unref(server);
+		server = NULL;
+		return false;
+	}
+	record_id = rec->handle;
+
 	notification_sk = sk;
 
 	return true;
@@ -288,6 +367,9 @@ void bt_a2dp_unregister(void)
 
 	notification_sk = -1;
 
+	bt_adapter_remove_record(record_id);
+	record_id = 0;
+
 	if (server) {
 		g_io_channel_shutdown(server, TRUE, NULL);
 		g_io_channel_unref(server);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCHv1 00/16] Socket HAL
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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

This is initial code implementing socket HAL. Receiving files
through OPP currently works.

Changes:
	* v1: Rebased and use static src address, hal_fd removed from structure and closed after sent to framework,
	added connect calls and SDP parsing, added cleanup_rfcomm function, minor fixes.
	* RFC Initial

For tracking rfcomm sockets I use structure rfslot which has following
fields:
 - real_sock - real RFCOMM socket
 - fd - fd to communicate with Android framework
 - hal_fd - fd passed to Android framework with CMSG

Andrei Emeltchenko (16):
  android/hal-sock: Add debug flag printing
  android/hal-sock: Use static local adapter address
  android/hal-sock: Add connect signal to socket
  android/hal-sock: Define structures for socket HAL
  android/hal-sock: Initial listen handle
  android/hal-sock: Implement socket accepted event
  android/hal-sock: Implement Android RFCOMM stack events
  android/hal-sock: Implement RFCOMM events
  android/hal-sock: Implement accept signal over Android fd
  android/hal-sock: Write channel to Android fd
  android/hal-sock: Implement socket connect HAL method
  android/hal-sock: Parse SDP response and connect
  android/hal-sock: Implement HAL connect call
  android/hal-sock: Send RFCOMM channel to framework
  android/hal-sock: Send connect signal on connect
  android/hal-sock: Close file descriptor after sending

 android/hal-msg.h  |    2 +
 android/hal-sock.c |    8 +-
 android/socket.c   |  496 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 android/socket.h   |    7 +
 4 files changed, 505 insertions(+), 8 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* [PATCHv1 01/16] android/hal-sock: Add debug flag printing
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/hal-sock.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/android/hal-sock.c b/android/hal-sock.c
index b7bc88e..eafa451 100644
--- a/android/hal-sock.c
+++ b/android/hal-sock.c
@@ -55,8 +55,8 @@ static bt_status_t sock_listen(btsock_type_t type, const char *service_name,
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	DBG("uuid %s chan %d sock %p type %d service_name %s",
-			btuuid2str(uuid), chan, sock, type, service_name);
+	DBG("uuid %s chan %d sock %p type %d service_name %s flags 0x%02x",
+		btuuid2str(uuid), chan, sock, type, service_name, flags);
 
 	switch (type) {
 	case BTSOCK_RFCOMM:
@@ -82,8 +82,8 @@ static bt_status_t sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	DBG("uuid %s chan %d sock %p type %d", btuuid2str(uuid), chan, sock,
-									type);
+	DBG("uuid %s chan %d sock %p type %d flags 0x%02x",
+		btuuid2str(uuid), chan, sock, type, flags);
 
 	if (type != BTSOCK_RFCOMM) {
 		error("Socket type %u not supported", type);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 02/16] android/hal-sock: Use static local adapter address
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/socket.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index c283c5f..e580036 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -35,6 +35,7 @@
 #include "ipc.h"
 #include "socket.h"
 
+static bdaddr_t adapter_addr;
 
 static int handle_listen(void *buf)
 {
@@ -81,6 +82,8 @@ bool bt_socket_register(int sk, const bdaddr_t *addr)
 {
 	DBG("");
 
+	bacpy(&adapter_addr, addr);
+
 	return true;
 }
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 03/16] android/hal-sock: Add connect signal to socket
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Connect signal is used to pass information to framework that socket
is accepted.
---
 android/hal-msg.h |    2 ++
 android/socket.h  |    7 +++++++
 2 files changed, 9 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 44fd5c8..9e3a81f 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -232,6 +232,8 @@ struct hal_cmd_sock_connect {
 	uint8_t  flags;
 } __attribute__((packed));
 
+/* Bluetooth Hidhost HAL api */
+
 #define HAL_OP_HIDHOST_CONNECT		0x01
 struct hal_cmd_hidhost_connect {
 	uint8_t bdaddr[6];
diff --git a/android/socket.h b/android/socket.h
index 7aa5574..ba56c9b 100644
--- a/android/socket.h
+++ b/android/socket.h
@@ -21,6 +21,13 @@
  *
  */
 
+struct hal_sock_connect_signal {
+	short   size;
+	uint8_t bdaddr[6];
+	int     channel;
+	int     status;
+} __attribute__((packed));
+
 void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
 
 bool bt_socket_register(int sk, const bdaddr_t *addr);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 04/16] android/hal-sock: Define structures for socket HAL
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

This defines structures for socket HAL. We need to emulate Android
sockets by sending connect/accept signals over file descriptor.
---
 android/socket.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index e580036..4699dce 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -37,6 +37,18 @@
 
 static bdaddr_t adapter_addr;
 
+/* Simple list of RFCOMM server sockets */
+GList *rfcomm_srv_list = NULL;
+
+/* Simple list of RFCOMM connected sockets */
+GList *rfcomm_connected_list = NULL;
+
+struct rfcomm_slot {
+	int fd;		/* descriptor for communication with Java framework */
+	int real_sock;	/* real RFCOMM socket */
+	int channel;	/* RFCOMM channel */
+};
+
 static int handle_listen(void *buf)
 {
 	DBG("Not implemented");
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 05/16] android/hal-sock: Initial listen handle
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Handle HAL socket listen call. Create RFCOMM socket and wait for events.
---
 android/socket.c |  106 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 104 insertions(+), 2 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 4699dce..276c78c 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,8 +27,12 @@
 
 #include <glib.h>
 #include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
 
 #include "lib/bluetooth.h"
+#include "btio/btio.h"
+#include "lib/sdp.h"
 #include "log.h"
 #include "hal-msg.h"
 #include "hal-ipc.h"
@@ -49,13 +53,111 @@ struct rfcomm_slot {
 	int channel;	/* RFCOMM channel */
 };
 
-static int handle_listen(void *buf)
+static struct rfcomm_slot *create_rfslot(int sock, int *hal_fd)
 {
-	DBG("Not implemented");
+	int fds[2] = {-1, -1};
+	struct rfcomm_slot *rfslot;
+
+	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
+		error("socketpair(): %s", strerror(errno));
+		return NULL;
+	}
+
+	rfslot = g_malloc0(sizeof(*rfslot));
+	rfslot->fd = fds[0];
+	*hal_fd = fds[1];
+	rfslot->real_sock = sock;
+
+	return rfslot;
+}
+
+static void cleanup_rfslot(struct rfcomm_slot *rfslot)
+{
+	DBG("Cleanup: rfslot: %p fd %d real_sock %d chan %u",
+		rfslot, rfslot->fd, rfslot->real_sock, rfslot->channel);
+
+	if (rfslot->fd > 0)
+		close(rfslot->fd);
+	if (rfslot->real_sock > 0)
+		close(rfslot->real_sock);
+
+	g_free(rfslot);
+}
+
+static struct {
+	uint8_t uuid[16];
+	uint8_t channel;
+} uuid_to_chan[] = {
+	{ .uuid = {
+	0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
+	0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+	},
+#define PBAP_DEFAULT_CHANNEL	15
+	.channel = PBAP_DEFAULT_CHANNEL },
+	{ .uuid = {
+	0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
+	0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+	},
+#define OPP_DEFAULT_CHANNEL	9
+	.channel = OPP_DEFAULT_CHANNEL },
+	{ {0} }
+};
+
+static int get_rfcomm_default_chan(const uint8_t *uuid)
+{
+	int i;
+
+	for (i = 0; uuid_to_chan[i].channel; i++) {
+		if (!memcmp(uuid_to_chan[i].uuid, uuid, 16))
+			return uuid_to_chan[i].channel;
+	}
 
 	return -1;
 }
 
+static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
+{
+}
+
+static int handle_listen(void *buf)
+{
+	struct hal_cmd_sock_listen *cmd = buf;
+	struct rfcomm_slot *rfslot;
+	GIOChannel *io;
+	GError *err = NULL;
+	int hal_fd = -1;
+	int chan;
+
+	DBG("");
+
+	chan = get_rfcomm_default_chan(cmd->uuid);
+	if (chan < 0)
+		return -1;
+
+	DBG("rfcomm channel %d", chan);
+
+	rfslot = create_rfslot(-1, &hal_fd);
+
+	io = bt_io_listen(accept_cb, NULL, rfslot, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+				BT_IO_OPT_CHANNEL, chan,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("Failed listen: %s", err->message);
+		g_error_free(err);
+		cleanup_rfslot(rfslot);
+		return -1;
+	}
+
+	rfslot->real_sock = g_io_channel_unix_get_fd(io);
+	rfcomm_srv_list = g_list_append(rfcomm_srv_list, rfslot);
+
+	DBG("real_sock %d fd %d hal_fd %d",
+				rfslot->real_sock, rfslot->fd, hal_fd);
+
+	return hal_fd;
+}
+
 static int handle_connect(void *buf)
 {
 	DBG("Not implemented");
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 06/16] android/hal-sock: Implement socket accepted event
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

When we get accepted event we create rfcomm slot and start listening
for events from Android framework and from RFCOMM real socket.
---
 android/socket.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 276c78c..c9ee32f 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -115,8 +115,60 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
 	return -1;
 }
 
+static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
+								gpointer data)
+{
+	return TRUE;
+}
+
+static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
+								gpointer data)
+{
+	return TRUE;
+}
+
 static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 {
+	struct rfcomm_slot *rfslot = user_data;
+	struct rfcomm_slot *rfslot_acc;
+	GIOChannel *io_stack;
+	bdaddr_t dst;
+	char address[18];
+	int sock_acc;
+	int hal_fd = -1;
+
+	bt_io_get(io, &err,
+			BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_io_channel_shutdown(io, TRUE, NULL);
+		return;
+	}
+
+	ba2str(&dst, address);
+	DBG("Incoming connection from %s rfslot %p", address, rfslot);
+
+	DBG("rfslot: fd %d real_sock %d chan %u sock %d",
+		rfslot->fd, rfslot->real_sock, rfslot->channel,
+		g_io_channel_unix_get_fd(io));
+
+	sock_acc = g_io_channel_unix_get_fd(io);
+	rfslot_acc = create_rfslot(sock_acc, &hal_fd);
+	rfcomm_connected_list =
+			g_list_append(rfcomm_connected_list, rfslot_acc);
+
+	/* Handle events from Android */
+	io_stack = g_io_channel_unix_new(rfslot_acc->fd);
+	g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+					sock_stack_event_cb, rfslot_acc);
+	g_io_channel_unref(io_stack);
+
+	/* Handle rfcomm events */
+	g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+				sock_rfcomm_event_cb, rfslot_acc);
+
+	DBG("rfslot %p rfslot_acc %p", rfslot, rfslot_acc);
 }
 
 static int handle_listen(void *buf)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Handle events from Android framework. Write everything to real RFCOMM
socket.
---
 android/socket.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index c9ee32f..07743f6 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -118,6 +118,48 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
 static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 								gpointer data)
 {
+	struct rfcomm_slot *rfslot = data;
+	unsigned char buf[1024] = { 0 };
+	int len, sent;
+
+	DBG("rfslot: fd %d real_sock %d chan %u sock %d",
+		rfslot->fd, rfslot->real_sock, rfslot->channel,
+		g_io_channel_unix_get_fd(io));
+
+	if (!g_list_find(rfcomm_connected_list, rfslot)) {
+		error("rfslot %p not found in the list", rfslot);
+		return FALSE;
+	}
+
+	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+		error("Socket error: sock %d cond %d",
+					g_io_channel_unix_get_fd(io), cond);
+		rfcomm_connected_list = g_list_remove(rfcomm_connected_list,
+								rfslot);
+		cleanup_rfslot(rfslot);
+		return FALSE;
+	}
+
+	/* FIXME check fd vs sock(io) */
+	len = recv(rfslot->fd, buf, sizeof(buf), 0);
+	if (len <= 0) {
+		error("recv(): %s", strerror(errno));
+		return FALSE;
+	}
+
+	DBG("read %d bytes write to %d", len, rfslot->real_sock);
+
+	sent = send(rfslot->real_sock, buf, len, 0);
+	if (sent < 0) {
+		error("send(): %s", strerror(errno));
+		return FALSE;
+	}
+
+	if (sent != len) {
+		error("send(): sent %d bytes out of %d", sent, len);
+		return FALSE;
+	}
+
 	return TRUE;
 }
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 08/16] android/hal-sock: Implement RFCOMM events
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Copy data from RFCOMM socket to Android framework.
---
 android/socket.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 07743f6..01c73db 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -166,6 +166,48 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 								gpointer data)
 {
+	struct rfcomm_slot *rfslot = data;
+	unsigned char buf[1024] = { 0 };
+	int len, sent;
+
+	DBG("rfslot: fd %d real_sock %d chan %u sock %d",
+		rfslot->fd, rfslot->real_sock, rfslot->channel,
+		g_io_channel_unix_get_fd(io));
+
+	if (!g_list_find(rfcomm_connected_list, rfslot)) {
+		error("rfslot %p not found in the list", rfslot);
+		return FALSE;
+	}
+
+	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+		error("Socket error: sock %d cond %d",
+					g_io_channel_unix_get_fd(io), cond);
+		rfcomm_connected_list = g_list_remove(rfcomm_connected_list,
+								rfslot);
+		cleanup_rfslot(rfslot);
+		return FALSE;
+	}
+
+	/* FIXME check real_sock vs sock(io) */
+	len = recv(rfslot->real_sock, buf, sizeof(buf), 0);
+	if (len <= 0) {
+		error("recv(): %s sock %d", strerror(errno), rfslot->real_sock);
+		return FALSE;
+	}
+
+	DBG("read %d bytes, write to fd %d", len, rfslot->fd);
+
+	sent = send(rfslot->fd, buf, len, 0);
+	if (sent < 0) {
+		error("send(): %s sock %d", strerror(errno), rfslot->fd);
+		return FALSE;
+	}
+
+	if (sent != len) {
+		error("send(): sent %d bytes out of %d", sent, len);
+		return FALSE;
+	}
+
 	return TRUE;
 }
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 09/16] android/hal-sock: Implement accept signal over Android fd
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Android expects to get accept signal over file descriptor which was
set during listen HAL call.
---
 android/socket.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 01c73db..7d1ada8 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -37,6 +37,7 @@
 #include "hal-msg.h"
 #include "hal-ipc.h"
 #include "ipc.h"
+#include "utils.h"
 #include "socket.h"
 
 static bdaddr_t adapter_addr;
@@ -103,6 +104,45 @@ static struct {
 	{ {0} }
 };
 
+static int bt_sock_send_fd(int sock_fd, const void *buf, int len, int send_fd)
+{
+	ssize_t ret;
+	struct msghdr msg;
+	struct cmsghdr *cmsg;
+	struct iovec iv;
+	char msgbuf[CMSG_SPACE(1)];
+
+	DBG("len %d sock_fd %d send_fd %d", len, sock_fd, send_fd);
+
+	if (sock_fd == -1 || send_fd == -1)
+		return -1;
+
+	memset(&msg, 0, sizeof(msg));
+
+	msg.msg_control = msgbuf;
+	msg.msg_controllen = sizeof(msgbuf);
+	cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
+	memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd));
+
+	iv.iov_base = (unsigned char *) buf;
+	iv.iov_len = len;
+
+	msg.msg_iov = &iv;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
+	if (ret < 0) {
+		error("sendmsg(): sock_fd %d send_fd %d: %s",
+					sock_fd, send_fd, strerror(errno));
+		return ret;
+	}
+
+	return ret;
+}
+
 static int get_rfcomm_default_chan(const uint8_t *uuid)
 {
 	int i;
@@ -211,6 +251,21 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 	return TRUE;
 }
 
+static void sock_send_accept(struct rfcomm_slot *rfslot, bdaddr_t *bdaddr,
+							int fd_accepted)
+{
+	struct hal_sock_connect_signal cmd;
+
+	DBG("");
+
+	cmd.size = sizeof(cmd);
+	bdaddr2android(bdaddr, cmd.bdaddr);
+	cmd.channel = rfslot->channel;
+	cmd.status = 0;
+
+	bt_sock_send_fd(rfslot->fd, &cmd, sizeof(cmd), fd_accepted);
+}
+
 static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 {
 	struct rfcomm_slot *rfslot = user_data;
@@ -242,6 +297,8 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 	rfcomm_connected_list =
 			g_list_append(rfcomm_connected_list, rfslot_acc);
 
+	sock_send_accept(rfslot, &dst, hal_fd);
+
 	/* Handle events from Android */
 	io_stack = g_io_channel_unix_new(rfslot_acc->fd);
 	g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 10/16] android/hal-sock: Write channel to Android fd
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Android framework expects to receive channel number as int.
---
 android/socket.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 7d1ada8..3e0c9f1 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -345,6 +345,13 @@ static int handle_listen(void *buf)
 	rfslot->real_sock = g_io_channel_unix_get_fd(io);
 	rfcomm_srv_list = g_list_append(rfcomm_srv_list, rfslot);
 
+	/* TODO: Check this */
+	if (write(rfslot->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+		error("Error sending RFCOMM channel");
+		cleanup_rfslot(rfslot);
+		return -1;
+	}
+
 	DBG("real_sock %d fd %d hal_fd %d",
 				rfslot->real_sock, rfslot->fd, hal_fd);
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 11/16] android/hal-sock: Implement socket connect HAL method
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

First step is to query remote device for RFCOMM channel.
---
 android/socket.c |   34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 3e0c9f1..256f9f0 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -33,6 +33,9 @@
 #include "lib/bluetooth.h"
 #include "btio/btio.h"
 #include "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "src/sdp-client.h"
+
 #include "log.h"
 #include "hal-msg.h"
 #include "hal-ipc.h"
@@ -52,6 +55,7 @@ struct rfcomm_slot {
 	int fd;		/* descriptor for communication with Java framework */
 	int real_sock;	/* real RFCOMM socket */
 	int channel;	/* RFCOMM channel */
+	bdaddr_t dst;
 };
 
 static struct rfcomm_slot *create_rfslot(int sock, int *hal_fd)
@@ -358,11 +362,37 @@ static int handle_listen(void *buf)
 	return hal_fd;
 }
 
+static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+{
+	DBG("");
+}
+
 static int handle_connect(void *buf)
 {
-	DBG("Not implemented");
+	struct hal_cmd_sock_connect *cmd = buf;
+	struct rfcomm_slot *rfslot;
+	bdaddr_t dst;
+	uuid_t uuid;
+	int hal_fd = -1;
 
-	return -1;
+	DBG("");
+
+	android2bdaddr(cmd->bdaddr, &dst);
+	rfslot = create_rfslot(-1, &hal_fd);
+	bacpy(&rfslot->dst, &dst);
+
+	memset(&uuid, 0, sizeof(uuid));
+	uuid.type = SDP_UUID128;
+	memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
+
+	if (bt_search_service(&adapter_addr, &dst, &uuid, sdp_search_cb, rfslot,
+								NULL) < 0) {
+		error("Failed to search SDP records");
+		cleanup_rfslot(rfslot);
+		return -1;
+	}
+
+	return hal_fd;
 }
 
 void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 12/16] android/hal-sock: Parse SDP response and connect
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Parse SDP response, find RFCOMM channel and connect.
---
 android/socket.c |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 256f9f0..73e86ba 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -362,9 +362,72 @@ static int handle_listen(void *buf)
 	return hal_fd;
 }
 
+static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
+{
+}
+
 static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 {
+	struct rfcomm_slot *rfslot = data;
+	GError *gerr = NULL;
+	sdp_list_t *list;
+	GIOChannel *io;
+	int chan;
+
 	DBG("");
+
+	if (err < 0) {
+		error("Unable to get 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_list_t *protos;
+
+		if (sdp_get_access_protos(rec, &protos) < 0) {
+			error("Unable to get proto list");
+			goto fail;
+		}
+
+		chan = sdp_get_proto_port(protos, RFCOMM_UUID);
+
+		sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free,
+									NULL);
+		sdp_list_free(protos, NULL);
+	}
+
+	if (chan <= 0) {
+		error("Could not get RFCOMM channel %d", chan);
+		goto fail;
+	}
+
+	DBG("Got RFCOMM channel %d", chan);
+
+	io = bt_io_connect(connect_cb, rfslot, NULL, &gerr,
+				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+				BT_IO_OPT_DEST_BDADDR, &rfslot->dst,
+				BT_IO_OPT_CHANNEL, chan,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("Failed connect: %s", gerr->message);
+		g_error_free(gerr);
+		goto fail;
+	}
+
+	rfslot->real_sock = g_io_channel_unix_get_fd(io);
+	rfslot->channel = chan;
+	rfcomm_connected_list = g_list_append(rfcomm_connected_list, rfslot);
+	return;
+
+fail:
+	cleanup_rfslot(rfslot);
 }
 
 static int handle_connect(void *buf)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 13/16] android/hal-sock: Implement HAL connect call
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

HAL connect uses similar event handlers like listen call.
---
 android/socket.c |   43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/android/socket.c b/android/socket.c
index 73e86ba..3c4e2fc 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -362,8 +362,49 @@ static int handle_listen(void *buf)
 	return hal_fd;
 }
 
-static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
+static void connect_cb(GIOChannel *io, GError *conn_err, gpointer user_data)
 {
+	struct rfcomm_slot *rfslot = user_data;
+	GIOChannel *io_stack;
+	GError *io_err = NULL;
+	bdaddr_t dst;
+	char address[18];
+	int chan = -1;
+
+	bt_io_get(io, &io_err,
+			BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_INVALID);
+	if (io_err) {
+		error("%s", io_err->message);
+		g_error_free(io_err);
+		goto fail;
+	}
+
+	if (conn_err) {
+		error("%s", conn_err->message);
+		goto fail;
+	}
+
+	ba2str(&dst, address);
+	DBG("Connected to %s rfslot %p chan %d", address, rfslot, chan);
+
+	DBG("rfslot: fd %d real_sock %d chan %u sock %d",
+		rfslot->fd, rfslot->real_sock, rfslot->channel,
+		g_io_channel_unix_get_fd(io));
+
+	/* Handle events from Android */
+	io_stack = g_io_channel_unix_new(rfslot->fd);
+	g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+						sock_stack_event_cb, rfslot);
+	g_io_channel_unref(io_stack);
+
+	/* Handle rfcomm events */
+	g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+				sock_rfcomm_event_cb, rfslot);
+
+	return;
+fail:
+	cleanup_rfslot(rfslot);
 }
 
 static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 14/16] android/hal-sock: Send RFCOMM channel to framework
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Framework expects channel to be send.
---
 android/socket.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 3c4e2fc..905def2 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -462,6 +462,11 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 		goto fail;
 	}
 
+	if (write(rfslot->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+		error("Error sending RFCOMM channel");
+		goto fail;
+	}
+
 	rfslot->real_sock = g_io_channel_unix_get_fd(io);
 	rfslot->channel = chan;
 	rfcomm_connected_list = g_list_append(rfcomm_connected_list, rfslot);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 15/16] android/hal-sock: Send connect signal on connect
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Android framework expects connect signal to be sent when
remote device is connected.
---
 android/socket.c |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 905def2..742c156 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -362,6 +362,33 @@ static int handle_listen(void *buf)
 	return hal_fd;
 }
 
+static ssize_t sock_send_connect(struct rfcomm_slot *rfslot, bdaddr_t *bdaddr)
+{
+	struct hal_sock_connect_signal cmd;
+	ssize_t len;
+
+	DBG("");
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.size = sizeof(cmd);
+	bdaddr2android(bdaddr, cmd.bdaddr);
+	cmd.channel = rfslot->channel;
+	cmd.status = 0;
+
+	len = write(rfslot->fd, &cmd, sizeof(cmd));
+	if (len < 0) {
+		error("%s", strerror(errno));
+		return len;
+	}
+
+	if (len != (ssize_t) sizeof(cmd)) {
+		error("Error sending connect signal");
+		return -1;
+	}
+
+	return len;
+}
+
 static void connect_cb(GIOChannel *io, GError *conn_err, gpointer user_data)
 {
 	struct rfcomm_slot *rfslot = user_data;
@@ -392,6 +419,9 @@ static void connect_cb(GIOChannel *io, GError *conn_err, gpointer user_data)
 		rfslot->fd, rfslot->real_sock, rfslot->channel,
 		g_io_channel_unix_get_fd(io));
 
+	if (sock_send_connect(rfslot, &dst) < 0)
+		goto fail;
+
 	/* Handle events from Android */
 	io_stack = g_io_channel_unix_new(rfslot->fd);
 	g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 16/16] android/hal-sock: Close file descriptor after sending
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384441915-23966-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/socket.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 742c156..a2193cc 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -545,6 +545,7 @@ void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 			break;
 
 		ipc_send(sk, HAL_SERVICE_ID_SOCK, opcode, 0, NULL, fd);
+		close(fd);
 		return;
 	case HAL_OP_SOCK_CONNECT:
 		fd = handle_connect(buf);
@@ -552,6 +553,7 @@ void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 			break;
 
 		ipc_send(sk, HAL_SERVICE_ID_SOCK, opcode, 0, NULL, fd);
+		close(fd);
 		return;
 	default:
 		DBG("Unhandled command, opcode 0x%x", opcode);
-- 
1.7.10.4


^ 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