Linux bluetooth development
 help / color / mirror / Atom feed
* [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

* [PATCH v3 0/3] Fixes for incoming connection and bonding
From: Lukasz Rymanowski @ 2013-11-14 15:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski

V3:
Removed adapter bonding state
Added device list in order to track bonding state per device.
Fix for incoming legacy paring. We act here same as Bluedroid.

V2:
Bonding state added.

V1:
With those patches it is possible to bond from remote device and in addition
you will see the name of remote device on Android pairing request pop up.

Lukasz Rymanowski (3):
  android: Update bond state on incoming bonding
  android: Update bond state on auth and connect failed
  android: Change TODO with explaining comment

 android/bluetooth.c | 168 ++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 130 insertions(+), 38 deletions(-)

-- 
1.8.4


^ permalink raw reply

* [PATCH v3 1/3] android: Update bond state on incoming bonding
From: Lukasz Rymanowski @ 2013-11-14 15:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski
In-Reply-To: <1384442660-2730-1-git-send-email-lukasz.rymanowski@tieto.com>

Before sending any ssp request or pin code request up to HAL library we
need to send bond state change with bonding state. Otherwise incoming
bonding is not correctly handled by Bluetooth.apk.
In this patch also device list has been added in order to e.g track
bonding state.

Note: For incoming legacy paring there is need to send
HAL_EVE_REMOTE_DEVICE_PROPS before HAL_EV_PIN_REQUEST.
It is because Android will crash due to bug in pinRequestCallback
function in java. Android checks if device is already in HashMap and if
not then creates  device, but forget to use that one, but instead do
operations on NULL. By sending HAL_BOND_STATE_BONDING event it works
better but we have race issue. It is because new device is added to
HashMap not in callback context but later after BONDING msg will be
received  by BondStateMachine. If it happens before pin_request_cb hits
java then we are fine, otherwise not. So for that reason we send
HAL_EV_REMOTE_DEVICE_PROPS so in the java handler class new device will
be added to HashMap in the  callback context.

In ssp case we don't have this problem as we send device found once acl
is created.
---
 android/bluetooth.c | 106 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 91 insertions(+), 15 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 39589fa..3ecd300 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -62,6 +62,8 @@ static uint16_t option_index = MGMT_INDEX_NONE;
 
 static int notification_sk = -1;
 
+#define BASELEN_REMOTE_DEV_PROP (sizeof(struct hal_ev_remote_device_props) \
+					+ sizeof(struct hal_property))
 /* This list contains addresses which are asked for records */
 static GSList *browse_reqs;
 
@@ -91,6 +93,11 @@ static struct {
 	.uuids = NULL,
 };
 
+struct device {
+	bdaddr_t bdaddr;
+	int bond_state;
+};
+
 struct browse_req {
 	bdaddr_t bdaddr;
 	GSList *uuids;
@@ -106,6 +113,7 @@ static const uint16_t uuid_list[] = {
 };
 
 static GSList *found_devices = NULL;
+static GSList *devices = NULL;
 
 static void adapter_name_changed(const uint8_t *name)
 {
@@ -301,6 +309,14 @@ static void store_link_key(const bdaddr_t *dst, const uint8_t *key,
 
 }
 
+static int bdaddr_cmp(gconstpointer a, gconstpointer b)
+{
+	const bdaddr_t *bda = a;
+	const bdaddr_t *bdb = b;
+
+	return bacmp(bdb, bda);
+}
+
 static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
 								uint8_t state)
 {
@@ -314,6 +330,29 @@ static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
 			HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev, -1);
 }
 
+static void set_device_bond_state(const bdaddr_t *addr, uint8_t status,
+								int state) {
+
+	struct device *dev = NULL;
+	GSList *l;
+
+	l = g_slist_find_custom(devices, addr, bdaddr_cmp);
+	if (l)
+		dev = l->data;
+
+	if (!dev) {
+		dev = g_new0( struct device, 1);
+		bacpy(&dev->bdaddr, addr);
+		dev->bond_state = HAL_BOND_STATE_NONE;
+		devices = g_slist_prepend(devices, dev);
+	}
+
+	if (dev->bond_state != state) {
+		dev->bond_state = state;
+		send_bond_state_change(&dev->bdaddr, status, state);
+	}
+}
+
 static void browse_req_free(struct browse_req *req)
 {
 	g_slist_free_full(req->uuids, g_free);
@@ -497,12 +536,32 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
 								key->pin_len);
 	}
 
-	send_bond_state_change(&addr->bdaddr, HAL_STATUS_SUCCESS,
+	set_device_bond_state(&addr->bdaddr, HAL_STATUS_SUCCESS,
 							HAL_BOND_STATE_BONDED);
 
 	browse_remote_sdp(&addr->bdaddr);
 }
 
+static void send_remote_device_name_prop(const bdaddr_t *bdaddr, char *name)
+{
+	struct hal_ev_remote_device_props *ev;
+	uint8_t buf[BASELEN_REMOTE_DEV_PROP + strlen(name)];
+
+	ev =  (void *) buf;
+	memset(buf, 0, sizeof(buf));
+
+	ev->status = HAL_STATUS_SUCCESS;
+	bdaddr2android(bdaddr, ev->bdaddr);
+	ev->num_props = 1;
+	ev->props[0].type = HAL_PROP_DEVICE_NAME;
+	ev->props[0].len = strlen(name);
+	memcpy(&ev->props[0].val, name, strlen(name));
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
+			HAL_EV_REMOTE_DEVICE_PROPS, sizeof(buf), ev, -1);
+}
+
 static void pin_code_request_callback(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -517,6 +576,13 @@ static void pin_code_request_callback(uint16_t index, uint16_t length,
 
 	ba2str(&ev->addr.bdaddr, dst);
 
+	/* Workaround for Android Bluetooth.apk issue: send remote
+	 * device property. Lets use address as a name for now */
+	send_remote_device_name_prop(&ev->addr.bdaddr, dst);
+
+	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
+						HAL_BOND_STATE_BONDING);
+
 	DBG("%s type %u secure %u", dst, ev->addr.type, ev->secure);
 
 	/* TODO name and CoD of remote devices should probably be cached */
@@ -556,6 +622,9 @@ static void user_confirm_request_callback(uint16_t index, uint16_t length,
 	ba2str(&ev->addr.bdaddr, dst);
 	DBG("%s confirm_hint %u", dst, ev->confirm_hint);
 
+	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
+						HAL_BOND_STATE_BONDING);
+
 	if (ev->confirm_hint)
 		send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_CONSENT, 0);
 	else
@@ -577,6 +646,9 @@ static void user_passkey_request_callback(uint16_t index, uint16_t length,
 	ba2str(&ev->addr.bdaddr, dst);
 	DBG("%s", dst);
 
+	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
+						HAL_BOND_STATE_BONDING);
+
 	send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_ENTRY, 0);
 }
 
@@ -595,9 +667,15 @@ static void user_passkey_notify_callback(uint16_t index, uint16_t length,
 	DBG("%s entered %u", dst, ev->entered);
 
 	/* HAL seems to not support entered characters */
-	if (!ev->entered)
-		send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_NOTIF,
+	if (ev->entered)
+		return;
+
+	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
+						HAL_BOND_STATE_BONDING);
+
+	send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_NOTIF,
 								ev->passkey);
 }
 
 static void mgmt_discovering_event(uint16_t index, uint16_t length,
@@ -647,14 +725,6 @@ static void confirm_device_name(const bdaddr_t *addr, uint8_t addr_type)
 		error("Failed to send confirm name request");
 }
 
-static int bdaddr_cmp(gconstpointer a, gconstpointer b)
-{
-	const bdaddr_t *bda = a;
-	const bdaddr_t *bdb = b;
-
-	return bacmp(bdb, bda);
-}
-
 static int fill_device_props(struct hal_property *prop, bdaddr_t *addr,
 					uint32_t cod, int8_t rssi, char *name)
 {
@@ -1838,7 +1908,7 @@ static void pair_device_complete(uint8_t status, uint16_t length,
 	if (status == MGMT_STATUS_SUCCESS)
 		return;
 
-	send_bond_state_change(&rp->addr.bdaddr, status_mgmt2hal(status),
+	set_device_bond_state(&rp->addr.bdaddr, status_mgmt2hal(status),
 							HAL_BOND_STATE_NONE);
 }
 
@@ -1855,7 +1925,7 @@ static bool create_bond(void *buf, uint16_t len)
 				&cp, pair_device_complete, NULL, NULL) == 0)
 		return false;
 
-	send_bond_state_change(&cp.addr.bdaddr, HAL_STATUS_SUCCESS,
+	set_device_bond_state(&cp.addr.bdaddr, HAL_STATUS_SUCCESS,
 						HAL_BOND_STATE_BONDING);
 
 	return true;
@@ -1865,12 +1935,18 @@ static bool cancel_bond(void *buf, uint16_t len)
 {
 	struct hal_cmd_cancel_bond *cmd = buf;
 	struct mgmt_addr_info cp;
+	bool result;
 
 	cp.type = BDADDR_BREDR;
 	android2bdaddr(cmd->bdaddr, &cp.bdaddr);
 
-	return mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter.index,
+	result = mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter.index,
 					sizeof(cp), &cp, NULL, NULL, NULL) > 0;
+	if (result)
+		set_device_bond_state(&cp.bdaddr, HAL_STATUS_SUCCESS,
+							HAL_BOND_STATE_NONE);
+
+	return result;
 }
 
 static void unpair_device_complete(uint8_t status, uint16_t length,
@@ -1883,7 +1959,7 @@ static void unpair_device_complete(uint8_t status, uint16_t length,
 	if (status != MGMT_STATUS_SUCCESS)
 		return;
 
-	send_bond_state_change(&rp->addr.bdaddr, HAL_STATUS_SUCCESS,
+	set_device_bond_state(&rp->addr.bdaddr, HAL_STATUS_SUCCESS,
 							HAL_BOND_STATE_NONE);
 }
 
-- 
1.8.4


^ permalink raw reply related

* [PATCH v3 2/3] android: Update bond state on auth and connect failed
From: Lukasz Rymanowski @ 2013-11-14 15:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski
In-Reply-To: <1384442660-2730-1-git-send-email-lukasz.rymanowski@tieto.com>

---
 android/bluetooth.c | 57 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 3ecd300..b4e74e5 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -939,16 +939,51 @@ static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
 			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev, -1);
 }
 
+static uint8_t status_mgmt2hal(uint8_t mgmt)
+{
+	switch (mgmt) {
+	case MGMT_STATUS_SUCCESS:
+		return HAL_STATUS_SUCCESS;
+	case MGMT_STATUS_NO_RESOURCES:
+		return HAL_STATUS_NOMEM;
+	case MGMT_STATUS_BUSY:
+		return HAL_STATUS_BUSY;
+	case MGMT_STATUS_NOT_SUPPORTED:
+		return HAL_STATUS_UNSUPPORTED;
+	case MGMT_STATUS_INVALID_PARAMS:
+		return HAL_STATUS_INVALID;
+	case MGMT_STATUS_AUTH_FAILED:
+		return HAL_STATUS_AUTH_FAILURE;
+	case MGMT_STATUS_NOT_CONNECTED:
+		return HAL_STATUS_REMOTE_DEVICE_DOWN;
+	default:
+		return HAL_STATUS_FAILED;
+	}
+}
+
 static void mgmt_connect_failed_event(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
+	const struct mgmt_ev_connect_failed *ev = param;
+
 	DBG("");
+
+	/* In case legacy pairing, we will get connect failed event
+	* in case e.g wrong PIN code entered. Let's check if device is
+	* bonding, if so update bond state */
+	set_device_bond_state(&ev->addr.bdaddr, status_mgmt2hal(ev->status),
+							HAL_BOND_STATE_NONE);
 }
 
 static void mgmt_auth_failed_event(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
+	const struct mgmt_ev_auth_failed *ev = param;
+
 	DBG("");
+
+	set_device_bond_state(&ev->addr.bdaddr, status_mgmt2hal(ev->status),
+							HAL_BOND_STATE_NONE);
 }
 
 static void mgmt_device_unpaired_event(uint16_t index, uint16_t length,
@@ -1874,28 +1909,6 @@ static uint8_t set_property(void *buf, uint16_t len)
 	}
 }
 
-static uint8_t status_mgmt2hal(uint8_t mgmt)
-{
-	switch (mgmt) {
-	case MGMT_STATUS_SUCCESS:
-		return HAL_STATUS_SUCCESS;
-	case MGMT_STATUS_NO_RESOURCES:
-		return HAL_STATUS_NOMEM;
-	case MGMT_STATUS_BUSY:
-		return HAL_STATUS_BUSY;
-	case MGMT_STATUS_NOT_SUPPORTED:
-		return HAL_STATUS_UNSUPPORTED;
-	case MGMT_STATUS_INVALID_PARAMS:
-		return HAL_STATUS_INVALID;
-	case MGMT_STATUS_AUTH_FAILED:
-		return HAL_STATUS_AUTH_FAILURE;
-	case MGMT_STATUS_NOT_CONNECTED:
-		return HAL_STATUS_REMOTE_DEVICE_DOWN;
-	default:
-		return HAL_STATUS_FAILED;
-	}
-}
-
 static void pair_device_complete(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
-- 
1.8.4


^ permalink raw reply related

* [PATCH v3 3/3] android: Change TODO with explaining comment
From: Lukasz Rymanowski @ 2013-11-14 15:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski
In-Reply-To: <1384442660-2730-1-git-send-email-lukasz.rymanowski@tieto.com>

---
 android/bluetooth.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index b4e74e5..dfeb54b 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -598,7 +598,10 @@ static void send_ssp_request(const bdaddr_t *addr, uint8_t variant,
 {
 	struct hal_ev_ssp_request ev;
 
-	/* TODO name and CoD of remote devices should probably be cached */
+	/* It is ok to have empty name and CoD of remote devices here since
+	* those information has been already provided on device_connected event
+	* or during device scaning. Android will use that instead.
+	*/
 	memset(&ev, 0, sizeof(ev));
 	bdaddr2android(addr, ev.bdaddr);
 	ev.pairing_variant = variant;
-- 
1.8.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