All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv1 00/16] Socket HAL
@ 2013-11-14 15:11 Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 01/16] android/hal-sock: Add debug flag printing Andrei Emeltchenko
                   ` (15 more replies)
  0 siblings, 16 replies; 21+ messages in thread
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	[flat|nested] 21+ messages in thread

* [PATCHv1 01/16] android/hal-sock: Add debug flag printing
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 02/16] android/hal-sock: Use static local adapter address Andrei Emeltchenko
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 02/16] android/hal-sock: Use static local adapter address
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 01/16] android/hal-sock: Add debug flag printing Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 03/16] android/hal-sock: Add connect signal to socket Andrei Emeltchenko
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 03/16] android/hal-sock: Add connect signal to socket
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 01/16] android/hal-sock: Add debug flag printing Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 02/16] android/hal-sock: Use static local adapter address Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 04/16] android/hal-sock: Define structures for socket HAL Andrei Emeltchenko
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 04/16] android/hal-sock: Define structures for socket HAL
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (2 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 03/16] android/hal-sock: Add connect signal to socket Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-15 12:29   ` Luiz Augusto von Dentz
  2013-11-14 15:11 ` [PATCHv1 05/16] android/hal-sock: Initial listen handle Andrei Emeltchenko
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 05/16] android/hal-sock: Initial listen handle
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (3 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 04/16] android/hal-sock: Define structures for socket HAL Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 06/16] android/hal-sock: Implement socket accepted event Andrei Emeltchenko
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 06/16] android/hal-sock: Implement socket accepted event
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (4 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 05/16] android/hal-sock: Initial listen handle Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events Andrei Emeltchenko
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (5 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 06/16] android/hal-sock: Implement socket accepted event Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-15  0:00   ` Marcel Holtmann
  2013-11-14 15:11 ` [PATCHv1 08/16] android/hal-sock: Implement RFCOMM events Andrei Emeltchenko
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 08/16] android/hal-sock: Implement RFCOMM events
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (6 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 09/16] android/hal-sock: Implement accept signal over Android fd Andrei Emeltchenko
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 09/16] android/hal-sock: Implement accept signal over Android fd
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (7 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 08/16] android/hal-sock: Implement RFCOMM events Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 10/16] android/hal-sock: Write channel to " Andrei Emeltchenko
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 10/16] android/hal-sock: Write channel to Android fd
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (8 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 09/16] android/hal-sock: Implement accept signal over Android fd Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 11/16] android/hal-sock: Implement socket connect HAL method Andrei Emeltchenko
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 11/16] android/hal-sock: Implement socket connect HAL method
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (9 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 10/16] android/hal-sock: Write channel to " Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 12/16] android/hal-sock: Parse SDP response and connect Andrei Emeltchenko
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 12/16] android/hal-sock: Parse SDP response and connect
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (10 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 11/16] android/hal-sock: Implement socket connect HAL method Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 13/16] android/hal-sock: Implement HAL connect call Andrei Emeltchenko
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 13/16] android/hal-sock: Implement HAL connect call
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (11 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 12/16] android/hal-sock: Parse SDP response and connect Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 14/16] android/hal-sock: Send RFCOMM channel to framework Andrei Emeltchenko
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 14/16] android/hal-sock: Send RFCOMM channel to framework
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (12 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 13/16] android/hal-sock: Implement HAL connect call Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 15/16] android/hal-sock: Send connect signal on connect Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 16/16] android/hal-sock: Close file descriptor after sending Andrei Emeltchenko
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 15/16] android/hal-sock: Send connect signal on connect
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (13 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 14/16] android/hal-sock: Send RFCOMM channel to framework Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  2013-11-14 15:11 ` [PATCHv1 16/16] android/hal-sock: Close file descriptor after sending Andrei Emeltchenko
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* [PATCHv1 16/16] android/hal-sock: Close file descriptor after sending
  2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
                   ` (14 preceding siblings ...)
  2013-11-14 15:11 ` [PATCHv1 15/16] android/hal-sock: Send connect signal on connect Andrei Emeltchenko
@ 2013-11-14 15:11 ` Andrei Emeltchenko
  15 siblings, 0 replies; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-14 15:11 UTC (permalink / raw)
  To: linux-bluetooth

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	[flat|nested] 21+ messages in thread

* Re: [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events
  2013-11-14 15:11 ` [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events Andrei Emeltchenko
@ 2013-11-15  0:00   ` Marcel Holtmann
  2013-11-15  9:23     ` Andrei Emeltchenko
  0 siblings, 1 reply; 21+ messages in thread
From: Marcel Holtmann @ 2013-11-15  0:00 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org development

Hi Andrei,

> 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 };

since why are we doing this { 0 } thing?

> +	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) */

I do not even understand this FIXME. Why not get it right in the fist place.

> +	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;
> +	}

Only problem is still that we now abort on errors like EINTR or EAGAIN. That is not what we want either.

Regards

Marcel


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

* Re: [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events
  2013-11-15  0:00   ` Marcel Holtmann
@ 2013-11-15  9:23     ` Andrei Emeltchenko
  2013-11-15  9:32       ` Marcel Holtmann
  0 siblings, 1 reply; 21+ messages in thread
From: Andrei Emeltchenko @ 2013-11-15  9:23 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org development

Hi Marcel,

On Fri, Nov 15, 2013 at 09:00:51AM +0900, Marcel Holtmann wrote:
> Hi Andrei,
> 
> > 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 };
> 
> since why are we doing this { 0 } thing?
> 
> > +	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) */
> 
> I do not even understand this FIXME. Why not get it right in the fist place.
> 
> > +	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;
> > +	}
> 
> Only problem is still that we now abort on errors like EINTR or EAGAIN. That is not what we want either.
> 

So shall we retry to send the several (say 3) times here?

Best regards 
Andrei Emeltchenko 

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

* Re: [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events
  2013-11-15  9:23     ` Andrei Emeltchenko
@ 2013-11-15  9:32       ` Marcel Holtmann
  0 siblings, 0 replies; 21+ messages in thread
From: Marcel Holtmann @ 2013-11-15  9:32 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org development

Hi Andrei,

>>> 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 };
>> 
>> since why are we doing this { 0 } thing?
>> 
>>> +	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) */
>> 
>> I do not even understand this FIXME. Why not get it right in the fist place.
>> 
>>> +	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;
>>> +	}
>> 
>> Only problem is still that we now abort on errors like EINTR or EAGAIN. That is not what we want either.
>> 
> 
> So shall we retry to send the several (say 3) times here?

you can have partial success here as well. You need to keep sending until you succeeded or get other errors then the ones mentioned above.

Regards

Marcel


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

* Re: [PATCHv1 04/16] android/hal-sock: Define structures for socket HAL
  2013-11-14 15:11 ` [PATCHv1 04/16] android/hal-sock: Define structures for socket HAL Andrei Emeltchenko
@ 2013-11-15 12:29   ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 21+ messages in thread
From: Luiz Augusto von Dentz @ 2013-11-15 12:29 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth

Hi Andrei,

On Thu, Nov 14, 2013 at 5:11 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> 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 */
> +};

Here you don't really need to define channel as int do you? Also if in
future we want to replace this with splice this should use a pipe to
communicate with the HAL.

Btw, introducing lists and struct without any implementation is never
very good to review, because I have no idea in what context they will
be used.



-- 
Luiz Augusto von Dentz

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

end of thread, other threads:[~2013-11-15 12:29 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-14 15:11 [PATCHv1 00/16] Socket HAL Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 01/16] android/hal-sock: Add debug flag printing Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 02/16] android/hal-sock: Use static local adapter address Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 03/16] android/hal-sock: Add connect signal to socket Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 04/16] android/hal-sock: Define structures for socket HAL Andrei Emeltchenko
2013-11-15 12:29   ` Luiz Augusto von Dentz
2013-11-14 15:11 ` [PATCHv1 05/16] android/hal-sock: Initial listen handle Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 06/16] android/hal-sock: Implement socket accepted event Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 07/16] android/hal-sock: Implement Android RFCOMM stack events Andrei Emeltchenko
2013-11-15  0:00   ` Marcel Holtmann
2013-11-15  9:23     ` Andrei Emeltchenko
2013-11-15  9:32       ` Marcel Holtmann
2013-11-14 15:11 ` [PATCHv1 08/16] android/hal-sock: Implement RFCOMM events Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 09/16] android/hal-sock: Implement accept signal over Android fd Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 10/16] android/hal-sock: Write channel to " Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 11/16] android/hal-sock: Implement socket connect HAL method Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 12/16] android/hal-sock: Parse SDP response and connect Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 13/16] android/hal-sock: Implement HAL connect call Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 14/16] android/hal-sock: Send RFCOMM channel to framework Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 15/16] android/hal-sock: Send connect signal on connect Andrei Emeltchenko
2013-11-14 15:11 ` [PATCHv1 16/16] android/hal-sock: Close file descriptor after sending Andrei Emeltchenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.