linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Allow directly connect to RFCOMM channel
@ 2013-12-18 14:18 Andrei Emeltchenko
  2013-12-18 14:18 ` [PATCH 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Andrei Emeltchenko @ 2013-12-18 14:18 UTC (permalink / raw)
  To: linux-bluetooth

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

Since Android calls allows directly connect to specified channel numbers
refactor code which makes connect to function and reuse it from both
places. This allows to test connect without parsing SDP.

Andrei Emeltchenko (3):
  android/socket: Refactor connect to allow directly connect to rfcomm
  android/socket: Connect directly to RFCOMM chan is uuid is zero
  android/tester: Test that connect call returns channel number

 android/android-tester.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++
 android/socket.c         | 103 ++++++++++++++++++++++++-----------------
 2 files changed, 179 insertions(+), 41 deletions(-)

-- 
1.8.3.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] android/socket: Refactor connect to allow directly connect to rfcomm
  2013-12-18 14:18 [PATCH 0/3] Allow directly connect to RFCOMM channel Andrei Emeltchenko
@ 2013-12-18 14:18 ` Andrei Emeltchenko
  2013-12-18 14:18 ` [PATCH 2/3] android/socket: Connect directly to RFCOMM chan is uuid is zero Andrei Emeltchenko
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Andrei Emeltchenko @ 2013-12-18 14:18 UTC (permalink / raw)
  To: linux-bluetooth

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

Since Socket HAL allows us to specify RFCOMM channel number and directly
connect refactor send function to allow connect directly is uuid is zero
and channel number is specified.
---
 android/socket.c | 71 +++++++++++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index cee4b6e..656222e 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -838,13 +838,47 @@ fail:
 	cleanup_rfsock(rfsock);
 }
 
-static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+static bool do_connect(struct rfcomm_sock *rfsock, int chan)
 {
-	struct rfcomm_sock *rfsock = data;
 	BtIOSecLevel sec_level = BT_IO_SEC_MEDIUM;
+	GIOChannel *io;
 	GError *gerr = NULL;
+
+	if (rfsock->profile)
+		sec_level = rfsock->profile->sec_level;
+
+	io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
+				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+				BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
+				BT_IO_OPT_CHANNEL, chan,
+				BT_IO_OPT_SEC_LEVEL, sec_level,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("Failed connect: %s", gerr->message);
+		g_error_free(gerr);
+		return false;
+	}
+
+	g_io_channel_set_close_on_unref(io, FALSE);
+	g_io_channel_unref(io);
+
+	if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+		error("Error sending RFCOMM channel");
+		return false;
+	}
+
+	rfsock->real_sock = g_io_channel_unix_get_fd(io);
+	rfsock_set_buffer(rfsock);
+	rfsock->channel = chan;
+	connections = g_list_append(connections, rfsock);
+
+	return true;
+}
+
+static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+{
+	struct rfcomm_sock *rfsock = data;
 	sdp_list_t *list;
-	GIOChannel *io;
 	int chan;
 
 	DBG("");
@@ -885,36 +919,9 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 
 	DBG("Got RFCOMM channel %d", chan);
 
-	if (rfsock->profile)
-		sec_level = rfsock->profile->sec_level;
-
-	io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
-				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
-				BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
-				BT_IO_OPT_CHANNEL, chan,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
-				BT_IO_OPT_INVALID);
-	if (!io) {
-		error("Failed connect: %s", gerr->message);
-		g_error_free(gerr);
-		goto fail;
-	}
-
-	if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
-		error("Error sending RFCOMM channel");
-		goto fail;
-	}
-
-	rfsock->real_sock = g_io_channel_unix_get_fd(io);
-	rfsock_set_buffer(rfsock);
-	rfsock->channel = chan;
-	connections = g_list_append(connections, rfsock);
-
-	g_io_channel_unref(io);
-
-	return;
+	if (do_connect(rfsock, chan))
+		return;
 fail:
-	connections = g_list_remove(connections, rfsock);
 	cleanup_rfsock(rfsock);
 }
 
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] android/socket: Connect directly to RFCOMM chan is uuid is zero
  2013-12-18 14:18 [PATCH 0/3] Allow directly connect to RFCOMM channel Andrei Emeltchenko
  2013-12-18 14:18 ` [PATCH 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
@ 2013-12-18 14:18 ` Andrei Emeltchenko
  2013-12-19  8:09   ` Johan Hedberg
  2013-12-18 14:18 ` [PATCH 3/3] android/tester: Test that connect call returns channel number Andrei Emeltchenko
  2013-12-19  8:49 ` [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
  3 siblings, 1 reply; 9+ messages in thread
From: Andrei Emeltchenko @ 2013-12-18 14:18 UTC (permalink / raw)
  To: linux-bluetooth

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

Check uuid and connect to specified channel number directly.
---
 android/socket.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 656222e..7bc5b0b 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -925,10 +925,17 @@ fail:
 	cleanup_rfsock(rfsock);
 }
 
+static bool is_empty(const uint8_t *uuid)
+{
+	static uint8_t zero_uuid[16];
+
+	return memcmp(uuid, zero_uuid, sizeof(zero_uuid)) == 0;
+}
+
 static void handle_connect(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_sock_connect *cmd = buf;
-	struct rfcomm_sock *rfsock;
+	struct rfcomm_sock *rfsock = NULL;
 	uuid_t uuid;
 	int hal_fd = -1;
 
@@ -940,17 +947,21 @@ static void handle_connect(const void *buf, uint16_t len)
 
 	android2bdaddr(cmd->bdaddr, &rfsock->dst);
 
-	memset(&uuid, 0, sizeof(uuid));
-	uuid.type = SDP_UUID128;
-	memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
+	if (is_empty(cmd->uuid)) {
+		if (!do_connect(rfsock, cmd->channel))
+			goto failed;
+	} else {
+		memset(&uuid, 0, sizeof(uuid));
+		uuid.type = SDP_UUID128;
+		memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
 
-	rfsock->profile = get_profile_by_uuid(cmd->uuid);
+		rfsock->profile = get_profile_by_uuid(cmd->uuid);
 
-	if (bt_search_service(&adapter_addr, &rfsock->dst, &uuid,
+		if (bt_search_service(&adapter_addr, &rfsock->dst, &uuid,
 					sdp_search_cb, rfsock, NULL) < 0) {
-		error("Failed to search SDP records");
-		cleanup_rfsock(rfsock);
-		goto failed;
+			error("Failed to search SDP records");
+			goto failed;
+		}
 	}
 
 	ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT, 0, NULL,
@@ -962,6 +973,9 @@ failed:
 	ipc_send_rsp(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT,
 							HAL_STATUS_FAILED);
 
+	if (rfsock)
+		cleanup_rfsock(rfsock);
+
 	if (hal_fd >= 0)
 		close(hal_fd);
 }
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] android/tester: Test that connect call returns channel number
  2013-12-18 14:18 [PATCH 0/3] Allow directly connect to RFCOMM channel Andrei Emeltchenko
  2013-12-18 14:18 ` [PATCH 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
  2013-12-18 14:18 ` [PATCH 2/3] android/socket: Connect directly to RFCOMM chan is uuid is zero Andrei Emeltchenko
@ 2013-12-18 14:18 ` Andrei Emeltchenko
  2013-12-19  8:49 ` [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
  3 siblings, 0 replies; 9+ messages in thread
From: Andrei Emeltchenko @ 2013-12-18 14:18 UTC (permalink / raw)
  To: linux-bluetooth

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

The test connects to emulated bthost and read channel number
---
 android/android-tester.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index 55fa702..8a2861e 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1080,6 +1080,27 @@ static void setup_socket_interface(const void *test_data)
 	tester_setup_complete();
 }
 
+static void setup_socket_interface_enabled(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	const void *sock;
+	bt_status_t status;
+
+	setup(data);
+
+	sock = data->if_bluetooth->get_profile_interface(BT_PROFILE_SOCKETS_ID);
+	if (!sock) {
+		tester_setup_failed();
+		return;
+	}
+
+	data->if_sock = sock;
+
+	status = data->if_bluetooth->enable();
+	if (status != BT_STATUS_SUCCESS)
+		tester_setup_failed();
+}
+
 static void test_generic_listen(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
@@ -1148,6 +1169,97 @@ clean:
 		close(sock_fd);
 }
 
+static gboolean socket_chan_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	int sock_fd = g_io_channel_unix_get_fd(io);
+	struct test_data *data = tester_get_data();
+	const struct socket_data *test = data->test_data;
+	int channel, len;
+
+	tester_print("%s", __func__);
+
+	if (cond & G_IO_HUP) {
+		tester_warn("Socket %d hang up", sock_fd);
+		goto failed;
+	}
+
+	if (cond & (G_IO_ERR | G_IO_NVAL)) {
+		tester_warn("Socket error: sock %d cond %d", sock_fd, cond);
+		goto failed;
+	}
+
+	if (test->test_channel) {
+		len = read(sock_fd, &channel, sizeof(channel));
+		if (len != sizeof(channel) || channel != test->channel)
+			goto failed;
+
+		tester_print("read correct channel: %d", channel);
+		tester_test_passed();
+		return FALSE;
+	}
+
+failed:
+	tester_test_failed();
+	return FALSE;
+}
+
+static void test_socket_real_connect(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	const struct socket_data *test = data->test_data;
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+	const uint8_t *client_bdaddr;
+	bt_bdaddr_t emu_bdaddr;
+	bt_status_t status;
+	int sock_fd = -1;
+
+	client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
+	if (!client_bdaddr) {
+		tester_warn("No client bdaddr");
+		tester_test_failed();
+		return;
+	}
+
+	bdaddr2android((bdaddr_t *) client_bdaddr, &emu_bdaddr);
+
+	bthost_set_server_psm(bthost, 0x0003);
+
+	status = data->if_sock->connect(&emu_bdaddr, test->sock_type,
+					test->service_uuid, test->channel,
+					&sock_fd, test->flags);
+	if (status != test->expected_status) {
+		tester_test_failed();
+		goto clean;
+	}
+
+	/* Check that file descriptor is valid */
+	if (status == BT_STATUS_SUCCESS && fcntl(sock_fd, F_GETFD) == -1) {
+		tester_test_failed();
+		return;
+	}
+
+	tester_print("status %d sock_fd %d", status, sock_fd);
+
+	if (status == BT_STATUS_SUCCESS) {
+		GIOChannel *io;
+
+		io = g_io_channel_unix_new(sock_fd);
+		g_io_channel_set_close_on_unref(io, TRUE);
+
+		g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				socket_chan_cb, NULL);
+
+		g_io_channel_unref(io);
+	}
+
+	return;
+
+clean:
+	if (sock_fd >= 0)
+		close(sock_fd);
+}
+
 #define test_bredrle(name, data, test_setup, test, test_teardown) \
 	do { \
 		struct test_data *user; \
@@ -1267,5 +1379,10 @@ int main(int argc, char *argv[])
 			&btsock_inv_param_bdaddr,
 			setup_socket_interface, test_generic_connect, teardown);
 
+	test_bredrle("Socket Connect - Check returned chan",
+			&btsock_success_check_chan,
+			setup_socket_interface_enabled,
+			test_socket_real_connect, teardown);
+
 	return tester_run();
 }
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/3] android/socket: Connect directly to RFCOMM chan is uuid is zero
  2013-12-18 14:18 ` [PATCH 2/3] android/socket: Connect directly to RFCOMM chan is uuid is zero Andrei Emeltchenko
@ 2013-12-19  8:09   ` Johan Hedberg
  0 siblings, 0 replies; 9+ messages in thread
From: Johan Hedberg @ 2013-12-19  8:09 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth

Hi Andrei,

On Wed, Dec 18, 2013, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> Check uuid and connect to specified channel number directly.
> ---
>  android/socket.c | 32 +++++++++++++++++++++++---------
>  1 file changed, 23 insertions(+), 9 deletions(-)

Please fix the commit message: capital UUID, s/is/if/ and
s/chan/channel/ in the subject.

> +static bool is_empty(const uint8_t *uuid)
> +{
> +	static uint8_t zero_uuid[16];
> +
> +	return memcmp(uuid, zero_uuid, sizeof(zero_uuid)) == 0;
> +}
> +
>  static void handle_connect(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_sock_connect *cmd = buf;
> -	struct rfcomm_sock *rfsock;
> +	struct rfcomm_sock *rfsock = NULL;

Firstly this rfsock = NULL seems completely unrelated to this patch, and
secondly it's not even needed. Please remove it.

>  	uuid_t uuid;
>  	int hal_fd = -1;
>  
> @@ -940,17 +947,21 @@ static void handle_connect(const void *buf, uint16_t len)
>  
>  	android2bdaddr(cmd->bdaddr, &rfsock->dst);
>  
> -	memset(&uuid, 0, sizeof(uuid));
> -	uuid.type = SDP_UUID128;
> -	memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
> +	if (is_empty(cmd->uuid)) {
> +		if (!do_connect(rfsock, cmd->channel))
> +			goto failed;

If this is_empty function was really needed it should at least be called
uuid_is_empty to make it clear what it's for. However, since it's a
one-line function and you've only got a single place needing it, I'd
just declare a static const uint8_t zero_uuuid[16] in handle_connect()
and do the memcmp directly there.

Johan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm
  2013-12-18 14:18 [PATCH 0/3] Allow directly connect to RFCOMM channel Andrei Emeltchenko
                   ` (2 preceding siblings ...)
  2013-12-18 14:18 ` [PATCH 3/3] android/tester: Test that connect call returns channel number Andrei Emeltchenko
@ 2013-12-19  8:49 ` Andrei Emeltchenko
  2013-12-19  8:49   ` [PATCHv2 2/3] android/socket: Connect directly to RFCOMM channel if uuid is zero Andrei Emeltchenko
                     ` (2 more replies)
  3 siblings, 3 replies; 9+ messages in thread
From: Andrei Emeltchenko @ 2013-12-19  8:49 UTC (permalink / raw)
  To: linux-bluetooth

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

Since Socket HAL allows us to specify RFCOMM channel number and directly
connect refactor send function to allow connect directly is uuid is zero
and channel number is specified.
---
 android/socket.c | 71 +++++++++++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index cee4b6e..656222e 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -838,13 +838,47 @@ fail:
 	cleanup_rfsock(rfsock);
 }
 
-static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+static bool do_connect(struct rfcomm_sock *rfsock, int chan)
 {
-	struct rfcomm_sock *rfsock = data;
 	BtIOSecLevel sec_level = BT_IO_SEC_MEDIUM;
+	GIOChannel *io;
 	GError *gerr = NULL;
+
+	if (rfsock->profile)
+		sec_level = rfsock->profile->sec_level;
+
+	io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
+				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+				BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
+				BT_IO_OPT_CHANNEL, chan,
+				BT_IO_OPT_SEC_LEVEL, sec_level,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("Failed connect: %s", gerr->message);
+		g_error_free(gerr);
+		return false;
+	}
+
+	g_io_channel_set_close_on_unref(io, FALSE);
+	g_io_channel_unref(io);
+
+	if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+		error("Error sending RFCOMM channel");
+		return false;
+	}
+
+	rfsock->real_sock = g_io_channel_unix_get_fd(io);
+	rfsock_set_buffer(rfsock);
+	rfsock->channel = chan;
+	connections = g_list_append(connections, rfsock);
+
+	return true;
+}
+
+static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+{
+	struct rfcomm_sock *rfsock = data;
 	sdp_list_t *list;
-	GIOChannel *io;
 	int chan;
 
 	DBG("");
@@ -885,36 +919,9 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 
 	DBG("Got RFCOMM channel %d", chan);
 
-	if (rfsock->profile)
-		sec_level = rfsock->profile->sec_level;
-
-	io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
-				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
-				BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
-				BT_IO_OPT_CHANNEL, chan,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
-				BT_IO_OPT_INVALID);
-	if (!io) {
-		error("Failed connect: %s", gerr->message);
-		g_error_free(gerr);
-		goto fail;
-	}
-
-	if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
-		error("Error sending RFCOMM channel");
-		goto fail;
-	}
-
-	rfsock->real_sock = g_io_channel_unix_get_fd(io);
-	rfsock_set_buffer(rfsock);
-	rfsock->channel = chan;
-	connections = g_list_append(connections, rfsock);
-
-	g_io_channel_unref(io);
-
-	return;
+	if (do_connect(rfsock, chan))
+		return;
 fail:
-	connections = g_list_remove(connections, rfsock);
 	cleanup_rfsock(rfsock);
 }
 
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv2 2/3] android/socket: Connect directly to RFCOMM channel if uuid is zero
  2013-12-19  8:49 ` [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
@ 2013-12-19  8:49   ` Andrei Emeltchenko
  2013-12-19  8:49   ` [PATCHv2 3/3] android/tester: Test that connect call returns channel number Andrei Emeltchenko
  2013-12-19  9:08   ` [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Johan Hedberg
  2 siblings, 0 replies; 9+ messages in thread
From: Andrei Emeltchenko @ 2013-12-19  8:49 UTC (permalink / raw)
  To: linux-bluetooth

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

Check uuid and connect to specified RFCOMM channel directly if uuid is
zeroed.
---
 android/socket.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 656222e..94a44fc 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -929,6 +929,7 @@ static void handle_connect(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_sock_connect *cmd = buf;
 	struct rfcomm_sock *rfsock;
+	static uint8_t zero_uuid[16];
 	uuid_t uuid;
 	int hal_fd = -1;
 
@@ -940,17 +941,21 @@ static void handle_connect(const void *buf, uint16_t len)
 
 	android2bdaddr(cmd->bdaddr, &rfsock->dst);
 
-	memset(&uuid, 0, sizeof(uuid));
-	uuid.type = SDP_UUID128;
-	memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
+	if (!memcmp(cmd->uuid, zero_uuid, sizeof(zero_uuid))) {
+		if (!do_connect(rfsock, cmd->channel))
+			goto failed;
+	} else {
+		memset(&uuid, 0, sizeof(uuid));
+		uuid.type = SDP_UUID128;
+		memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
 
-	rfsock->profile = get_profile_by_uuid(cmd->uuid);
+		rfsock->profile = get_profile_by_uuid(cmd->uuid);
 
-	if (bt_search_service(&adapter_addr, &rfsock->dst, &uuid,
+		if (bt_search_service(&adapter_addr, &rfsock->dst, &uuid,
 					sdp_search_cb, rfsock, NULL) < 0) {
-		error("Failed to search SDP records");
-		cleanup_rfsock(rfsock);
-		goto failed;
+			error("Failed to search SDP records");
+			goto failed;
+		}
 	}
 
 	ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT, 0, NULL,
@@ -962,6 +967,9 @@ failed:
 	ipc_send_rsp(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT,
 							HAL_STATUS_FAILED);
 
+	if (rfsock)
+		cleanup_rfsock(rfsock);
+
 	if (hal_fd >= 0)
 		close(hal_fd);
 }
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv2 3/3] android/tester: Test that connect call returns channel number
  2013-12-19  8:49 ` [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
  2013-12-19  8:49   ` [PATCHv2 2/3] android/socket: Connect directly to RFCOMM channel if uuid is zero Andrei Emeltchenko
@ 2013-12-19  8:49   ` Andrei Emeltchenko
  2013-12-19  9:08   ` [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Johan Hedberg
  2 siblings, 0 replies; 9+ messages in thread
From: Andrei Emeltchenko @ 2013-12-19  8:49 UTC (permalink / raw)
  To: linux-bluetooth

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

The test connects to emulated bthost and read channel number
---
 android/android-tester.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index 55fa702..8a2861e 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1080,6 +1080,27 @@ static void setup_socket_interface(const void *test_data)
 	tester_setup_complete();
 }
 
+static void setup_socket_interface_enabled(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	const void *sock;
+	bt_status_t status;
+
+	setup(data);
+
+	sock = data->if_bluetooth->get_profile_interface(BT_PROFILE_SOCKETS_ID);
+	if (!sock) {
+		tester_setup_failed();
+		return;
+	}
+
+	data->if_sock = sock;
+
+	status = data->if_bluetooth->enable();
+	if (status != BT_STATUS_SUCCESS)
+		tester_setup_failed();
+}
+
 static void test_generic_listen(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
@@ -1148,6 +1169,97 @@ clean:
 		close(sock_fd);
 }
 
+static gboolean socket_chan_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	int sock_fd = g_io_channel_unix_get_fd(io);
+	struct test_data *data = tester_get_data();
+	const struct socket_data *test = data->test_data;
+	int channel, len;
+
+	tester_print("%s", __func__);
+
+	if (cond & G_IO_HUP) {
+		tester_warn("Socket %d hang up", sock_fd);
+		goto failed;
+	}
+
+	if (cond & (G_IO_ERR | G_IO_NVAL)) {
+		tester_warn("Socket error: sock %d cond %d", sock_fd, cond);
+		goto failed;
+	}
+
+	if (test->test_channel) {
+		len = read(sock_fd, &channel, sizeof(channel));
+		if (len != sizeof(channel) || channel != test->channel)
+			goto failed;
+
+		tester_print("read correct channel: %d", channel);
+		tester_test_passed();
+		return FALSE;
+	}
+
+failed:
+	tester_test_failed();
+	return FALSE;
+}
+
+static void test_socket_real_connect(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	const struct socket_data *test = data->test_data;
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+	const uint8_t *client_bdaddr;
+	bt_bdaddr_t emu_bdaddr;
+	bt_status_t status;
+	int sock_fd = -1;
+
+	client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
+	if (!client_bdaddr) {
+		tester_warn("No client bdaddr");
+		tester_test_failed();
+		return;
+	}
+
+	bdaddr2android((bdaddr_t *) client_bdaddr, &emu_bdaddr);
+
+	bthost_set_server_psm(bthost, 0x0003);
+
+	status = data->if_sock->connect(&emu_bdaddr, test->sock_type,
+					test->service_uuid, test->channel,
+					&sock_fd, test->flags);
+	if (status != test->expected_status) {
+		tester_test_failed();
+		goto clean;
+	}
+
+	/* Check that file descriptor is valid */
+	if (status == BT_STATUS_SUCCESS && fcntl(sock_fd, F_GETFD) == -1) {
+		tester_test_failed();
+		return;
+	}
+
+	tester_print("status %d sock_fd %d", status, sock_fd);
+
+	if (status == BT_STATUS_SUCCESS) {
+		GIOChannel *io;
+
+		io = g_io_channel_unix_new(sock_fd);
+		g_io_channel_set_close_on_unref(io, TRUE);
+
+		g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				socket_chan_cb, NULL);
+
+		g_io_channel_unref(io);
+	}
+
+	return;
+
+clean:
+	if (sock_fd >= 0)
+		close(sock_fd);
+}
+
 #define test_bredrle(name, data, test_setup, test, test_teardown) \
 	do { \
 		struct test_data *user; \
@@ -1267,5 +1379,10 @@ int main(int argc, char *argv[])
 			&btsock_inv_param_bdaddr,
 			setup_socket_interface, test_generic_connect, teardown);
 
+	test_bredrle("Socket Connect - Check returned chan",
+			&btsock_success_check_chan,
+			setup_socket_interface_enabled,
+			test_socket_real_connect, teardown);
+
 	return tester_run();
 }
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm
  2013-12-19  8:49 ` [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
  2013-12-19  8:49   ` [PATCHv2 2/3] android/socket: Connect directly to RFCOMM channel if uuid is zero Andrei Emeltchenko
  2013-12-19  8:49   ` [PATCHv2 3/3] android/tester: Test that connect call returns channel number Andrei Emeltchenko
@ 2013-12-19  9:08   ` Johan Hedberg
  2 siblings, 0 replies; 9+ messages in thread
From: Johan Hedberg @ 2013-12-19  9:08 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth

Hi Andrei,

On Thu, Dec 19, 2013, Andrei Emeltchenko wrote:
> Since Socket HAL allows us to specify RFCOMM channel number and directly
> connect refactor send function to allow connect directly is uuid is zero
> and channel number is specified.
> ---
>  android/socket.c | 71 +++++++++++++++++++++++++++++++-------------------------
>  1 file changed, 39 insertions(+), 32 deletions(-)

All three patches have been applied. Thanks.

Johan

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-12-19  9:08 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-18 14:18 [PATCH 0/3] Allow directly connect to RFCOMM channel Andrei Emeltchenko
2013-12-18 14:18 ` [PATCH 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
2013-12-18 14:18 ` [PATCH 2/3] android/socket: Connect directly to RFCOMM chan is uuid is zero Andrei Emeltchenko
2013-12-19  8:09   ` Johan Hedberg
2013-12-18 14:18 ` [PATCH 3/3] android/tester: Test that connect call returns channel number Andrei Emeltchenko
2013-12-19  8:49 ` [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Andrei Emeltchenko
2013-12-19  8:49   ` [PATCHv2 2/3] android/socket: Connect directly to RFCOMM channel if uuid is zero Andrei Emeltchenko
2013-12-19  8:49   ` [PATCHv2 3/3] android/tester: Test that connect call returns channel number Andrei Emeltchenko
2013-12-19  9:08   ` [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm Johan Hedberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).