linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv4 00/17] Socket HAL
@ 2013-11-18 13:20 Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 01/17] android/socket: Add connect signal to socket Andrei Emeltchenko
                   ` (16 more replies)
  0 siblings, 17 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
  To: linux-bluetooth

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

This is initial code implementing socket HAL. OPP currently works with send/receive files. Probaly
other profiles works as well, not tested yet.

Changes:
	* v4: Changed name rfslot -> rfsock following Johan's comment and other cosmetic changes, fixed one bug in SDP
	record, use NULL instead of 0 for sdp functions.
	* v3: Fixed coding style with write/send between file descriptors.
	* v2: Following Marcel comments changed way copying between file descriptors works, added SDP record
	for OPP and now it is possible to send files through GUI. Merged one patch with structures with actual user.
	* 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

TODO:
	* Add SDP record for PBAP and other profiles
	* Use splice() (requires bionic change first)

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

create_rfslot sets hal_fd which is fd passed to Android framework with CMSG

Andrei Emeltchenko (17):
  android/socket: Add connect signal to socket
  android: trivial: Add comment making code consistent
  android/socket: Add get RFCOMM default channel
  android/socket: Define structs and implement listen
  android/socket: Implement socket accepted event
  android/socket: Implement Android RFCOMM stack events
  android/socket: Implement RFCOMM events
  android/socket: Implement accept signal over Android fd
  android/socket: Write channel to Android fd
  android/socket: Implement socket connect HAL method
  android/socket: Parse SDP response and connect
  android/socket: Implement HAL connect call
  android/socket: Send RFCOMM channel to framework
  android/socket: Send connect signal on connect
  android/socket: Close file descriptor after sending
  android/socket: Add SDP record for OPP profile
  android/socket: Add MAS uuid to channel mapping

 android/hal-msg.h |    2 +
 android/socket.c  |  612 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 android/socket.h  |    7 +
 3 files changed, 617 insertions(+), 4 deletions(-)

-- 
1.7.10.4


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

* [PATCHv4 01/17] android/socket: Add connect signal to socket
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 02/17] android: trivial: Add comment making code consistent Andrei Emeltchenko
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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/socket.h |    7 +++++++
 1 file changed, 7 insertions(+)

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] 19+ messages in thread

* [PATCHv4 02/17] android: trivial: Add comment making code consistent
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 01/17] android/socket: Add connect signal to socket Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-19  9:22   ` Johan Hedberg
  2013-11-18 13:20 ` [PATCHv4 03/17] android/socket: Add get RFCOMM default channel Andrei Emeltchenko
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
  To: linux-bluetooth

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

---
 android/hal-msg.h |    2 ++
 1 file changed, 2 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];
-- 
1.7.10.4


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

* [PATCHv4 03/17] android/socket: Add get RFCOMM default channel
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 01/17] android/socket: Add connect signal to socket Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 02/17] android: trivial: Add comment making code consistent Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 04/17] android/socket: Define structs and implement listen Andrei Emeltchenko
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
  To: linux-bluetooth

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

RFCOMM default channel is the same like in other BlueZ code, it is
defined in src/profile.c
---
 android/socket.c |   45 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index e580036..9c94c03 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -35,13 +35,54 @@
 #include "ipc.h"
 #include "socket.h"
 
+#define OPP_DEFAULT_CHANNEL	9
+#define PBAP_DEFAULT_CHANNEL	15
+
 static bdaddr_t adapter_addr;
 
+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
+		},
+		.channel = PBAP_DEFAULT_CHANNEL,
+	}, {
+		.uuid = {
+			0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
+			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+		  },
+		.channel = OPP_DEFAULT_CHANNEL
+	}
+};
+
+static int get_rfcomm_default_chan(const uint8_t *uuid)
+{
+	unsigned int i;
+
+	for (i = 0; i < G_N_ELEMENTS(uuid_to_chan); i++) {
+		if (!memcmp(uuid_to_chan[i].uuid, uuid, 16))
+			return uuid_to_chan[i].channel;
+	}
+
+	return -ENOENT;
+}
+
 static int handle_listen(void *buf)
 {
-	DBG("Not implemented");
+	int hal_fd;
+	int chan;
 
-	return -1;
+	DBG("");
+
+	chan = get_rfcomm_default_chan(cmd->uuid);
+	if (chan < 0)
+		return chan;
+
+	return hal_fd;
 }
 
 static int handle_connect(void *buf)
-- 
1.7.10.4


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

* [PATCHv4 04/17] android/socket: Define structs and implement listen
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (2 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 03/17] android/socket: Add get RFCOMM default channel Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 05/17] android/socket: Implement socket accepted event Andrei Emeltchenko
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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.
Handle HAL socket listen call. Create RFCOMM socket and wait for events.
---
 android/socket.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 9c94c03..0731bd9 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"
@@ -40,6 +44,50 @@
 
 static bdaddr_t adapter_addr;
 
+/* Simple list of RFCOMM server sockets */
+GList *servers = NULL;
+
+/* Simple list of RFCOMM connected sockets */
+GList *connections = NULL;
+
+struct rfcomm_sock {
+	int fd;		/* descriptor for communication with Java framework */
+	int real_sock;	/* real RFCOMM socket */
+	int channel;	/* RFCOMM channel */
+};
+
+static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
+{
+	int fds[2] = {-1, -1};
+	struct rfcomm_sock *rfsock;
+
+	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
+		error("socketpair(): %s", strerror(errno));
+		*hal_fd = -1;
+		return NULL;
+	}
+
+	rfsock = g_new0(struct rfcomm_sock, 1);
+	rfsock->fd = fds[0];
+	*hal_fd = fds[1];
+	rfsock->real_sock = sock;
+
+	return rfsock;
+}
+
+static void cleanup_rfsock(struct rfcomm_sock *rfsock)
+{
+	DBG("rfsock: %p fd %d real_sock %d chan %u",
+		rfsock, rfsock->fd, rfsock->real_sock, rfsock->channel);
+
+	if (rfsock->fd > 0)
+		close(rfsock->fd);
+	if (rfsock->real_sock > 0)
+		close(rfsock->real_sock);
+
+	g_free(rfsock);
+}
+
 static struct {
 	uint8_t uuid[16];
 	uint8_t channel;
@@ -71,8 +119,16 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
 	return -ENOENT;
 }
 
+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_sock *rfsock;
+	GIOChannel *io;
+	GError *err = NULL;
 	int hal_fd;
 	int chan;
 
@@ -82,6 +138,29 @@ static int handle_listen(void *buf)
 	if (chan < 0)
 		return chan;
 
+	DBG("rfcomm channel %d", chan);
+
+	rfsock = create_rfsock(-1, &hal_fd);
+	if (!rfsock)
+		return -1;
+
+	io = bt_io_listen(accept_cb, NULL, rfsock, 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_rfsock(rfsock);
+		return -1;
+	}
+
+	rfsock->real_sock = g_io_channel_unix_get_fd(io);
+	servers = g_list_append(servers, rfsock);
+
+	DBG("real_sock %d fd %d hal_fd %d",
+				rfsock->real_sock, rfsock->fd, hal_fd);
+
 	return hal_fd;
 }
 
-- 
1.7.10.4


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

* [PATCHv4 05/17] android/socket: Implement socket accepted event
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (3 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 04/17] android/socket: Define structs and implement listen Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 06/17] android/socket: Implement Android RFCOMM stack events Andrei Emeltchenko
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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 |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 0731bd9..12c3687 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -119,8 +119,59 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
 	return -ENOENT;
 }
 
+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_sock *rfsock = user_data;
+	struct rfcomm_sock *rfsock_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 rfsock %p", address, rfsock);
+
+	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
+		rfsock->fd, rfsock->real_sock, rfsock->channel,
+		g_io_channel_unix_get_fd(io));
+
+	sock_acc = g_io_channel_unix_get_fd(io);
+	rfsock_acc = create_rfsock(sock_acc, &hal_fd);
+	connections = g_list_append(connections, rfsock_acc);
+
+	/* Handle events from Android */
+	io_stack = g_io_channel_unix_new(rfsock_acc->fd);
+	g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+					sock_stack_event_cb, rfsock_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, rfsock_acc);
+
+	DBG("rfsock %p rfsock_acc %p", rfsock, rfsock_acc);
 }
 
 static int handle_listen(void *buf)
-- 
1.7.10.4


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

* [PATCHv4 06/17] android/socket: Implement Android RFCOMM stack events
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (4 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 05/17] android/socket: Implement socket accepted event Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 07/17] android/socket: Implement RFCOMM events Andrei Emeltchenko
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
  To: linux-bluetooth

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

Handle events from Android framework. Write everything to real RFCOMM
socket. Consider splice() in the future.
---
 android/socket.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 12c3687..3be8ff6 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -119,9 +119,69 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
 	return -ENOENT;
 }
 
+static int try_write_all(int fd, unsigned char *buf, int len)
+{
+	int sent = 0;
+
+	while (len > 0) {
+		int written;
+
+		written = write(fd, buf, len);
+		if (written < 0) {
+			if (errno == EINTR || errno == EAGAIN)
+				continue;
+			return -1;
+		}
+
+		if (!written)
+			return 0;
+
+		len -= written; buf += written; sent += written;
+	}
+
+	return sent;
+}
+
 static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 								gpointer data)
 {
+	struct rfcomm_sock *rfsock = data;
+	unsigned char buf[1024];
+	int len, sent;
+
+	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
+		rfsock->fd, rfsock->real_sock, rfsock->channel,
+		g_io_channel_unix_get_fd(io));
+
+	if (!g_list_find(connections, rfsock)) {
+		error("rfsock %p not found in the list", rfsock);
+		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);
+		connections = g_list_remove(connections, rfsock);
+		cleanup_rfsock(rfsock);
+		return FALSE;
+	}
+
+	len = read(rfsock->fd, buf, sizeof(buf));
+	if (len <= 0) {
+		error("read(): %s", strerror(errno));
+		return FALSE;
+	}
+
+	DBG("read %d bytes write to %d", len, rfsock->real_sock);
+
+	sent = try_write_all(rfsock->real_sock, buf, len);
+	if (sent < 0) {
+		error("write(): %s", strerror(errno));
+		return FALSE;
+	}
+
+	DBG("Written %d bytes", sent);
+
 	return TRUE;
 }
 
-- 
1.7.10.4


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

* [PATCHv4 07/17] android/socket: Implement RFCOMM events
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (5 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 06/17] android/socket: Implement Android RFCOMM stack events Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 08/17] android/socket: Implement accept signal over Android fd Andrei Emeltchenko
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
  To: linux-bluetooth

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

Copy data from RFCOMM socket to Android framework. Consider splice
in the future.
---
 android/socket.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 3be8ff6..154c330 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -188,6 +188,43 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 								gpointer data)
 {
+	struct rfcomm_sock *rfsock = data;
+	unsigned char buf[1024];
+	int len, sent;
+
+	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
+		rfsock->fd, rfsock->real_sock, rfsock->channel,
+		g_io_channel_unix_get_fd(io));
+
+	if (!g_list_find(connections, rfsock)) {
+		error("rfsock %p not found in the list", rfsock);
+		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);
+		connections = g_list_remove(connections, rfsock);
+		cleanup_rfsock(rfsock);
+		return FALSE;
+	}
+
+	len = read(rfsock->real_sock, buf, sizeof(buf));
+	if (len <= 0) {
+		error("read(): %s", strerror(errno));
+		return FALSE;
+	}
+
+	DBG("read %d bytes, write to fd %d", len, rfsock->fd);
+
+	sent = try_write_all(rfsock->fd, buf, len);
+	if (sent < 0) {
+		error("write(): %s", strerror(errno));
+		return FALSE;
+	}
+
+	DBG("Written %d bytes", sent);
+
 	return TRUE;
 }
 
-- 
1.7.10.4


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

* [PATCHv4 08/17] android/socket: Implement accept signal over Android fd
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (6 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 07/17] android/socket: Implement RFCOMM events Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 09/17] android/socket: Write channel to " Andrei Emeltchenko
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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 154c330..a02bb1e 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"
 
 #define OPP_DEFAULT_CHANNEL	9
@@ -107,6 +108,45 @@ static struct {
 	}
 };
 
+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)
 {
 	unsigned int i;
@@ -228,6 +268,21 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 	return TRUE;
 }
 
+static void sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr,
+							int fd_accepted)
+{
+	struct hal_sock_connect_signal cmd;
+
+	DBG("");
+
+	cmd.size = sizeof(cmd);
+	bdaddr2android(bdaddr, cmd.bdaddr);
+	cmd.channel = rfsock->channel;
+	cmd.status = 0;
+
+	bt_sock_send_fd(rfsock->fd, &cmd, sizeof(cmd), fd_accepted);
+}
+
 static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 {
 	struct rfcomm_sock *rfsock = user_data;
@@ -258,6 +313,8 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 	rfsock_acc = create_rfsock(sock_acc, &hal_fd);
 	connections = g_list_append(connections, rfsock_acc);
 
+	sock_send_accept(rfsock, &dst, hal_fd);
+
 	/* Handle events from Android */
 	io_stack = g_io_channel_unix_new(rfsock_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] 19+ messages in thread

* [PATCHv4 09/17] android/socket: Write channel to Android fd
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (7 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 08/17] android/socket: Implement accept signal over Android fd Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 10/17] android/socket: Implement socket connect HAL method Andrei Emeltchenko
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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 a02bb1e..bfe7ca6 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -363,6 +363,13 @@ static int handle_listen(void *buf)
 	rfsock->real_sock = g_io_channel_unix_get_fd(io);
 	servers = g_list_append(servers, rfsock);
 
+	/* TODO: Check this */
+	if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+		error("Error sending RFCOMM channel");
+		cleanup_rfsock(rfsock);
+		return -1;
+	}
+
 	DBG("real_sock %d fd %d hal_fd %d",
 				rfsock->real_sock, rfsock->fd, hal_fd);
 
-- 
1.7.10.4


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

* [PATCHv4 10/17] android/socket: Implement socket connect HAL method
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (8 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 09/17] android/socket: Write channel to " Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 11/17] android/socket: Parse SDP response and connect Andrei Emeltchenko
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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 bfe7ca6..7939eee 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"
@@ -55,6 +58,7 @@ struct rfcomm_sock {
 	int fd;		/* descriptor for communication with Java framework */
 	int real_sock;	/* real RFCOMM socket */
 	int channel;	/* RFCOMM channel */
+	bdaddr_t dst;
 };
 
 static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
@@ -376,11 +380,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_sock *rfsock;
+	bdaddr_t dst;
+	uuid_t uuid;
+	int hal_fd = -1;
 
-	return -1;
+	DBG("");
+
+	android2bdaddr(cmd->bdaddr, &dst);
+	rfsock = create_rfsock(-1, &hal_fd);
+	bacpy(&rfsock->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, rfsock,
+								NULL) < 0) {
+		error("Failed to search SDP records");
+		cleanup_rfsock(rfsock);
+		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] 19+ messages in thread

* [PATCHv4 11/17] android/socket: Parse SDP response and connect
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (9 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 10/17] android/socket: Implement socket connect HAL method Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 12/17] android/socket: Implement HAL connect call Andrei Emeltchenko
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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 7939eee..63c553a 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -380,9 +380,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_sock *rfsock = 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, 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, BT_IO_SEC_LOW,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("Failed connect: %s", gerr->message);
+		g_error_free(gerr);
+		goto fail;
+	}
+
+	rfsock->real_sock = g_io_channel_unix_get_fd(io);
+	rfsock->channel = chan;
+	connections = g_list_append(connections, rfsock);
+	return;
+
+fail:
+	cleanup_rfsock(rfsock);
 }
 
 static int handle_connect(void *buf)
-- 
1.7.10.4


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

* [PATCHv4 12/17] android/socket: Implement HAL connect call
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (10 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 11/17] android/socket: Parse SDP response and connect Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 13/17] android/socket: Send RFCOMM channel to framework Andrei Emeltchenko
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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 63c553a..5bedb60 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -380,8 +380,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_sock *rfsock = 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 rfsock %p chan %d", address, rfsock, chan);
+
+	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
+		rfsock->fd, rfsock->real_sock, rfsock->channel,
+		g_io_channel_unix_get_fd(io));
+
+	/* Handle events from Android */
+	io_stack = g_io_channel_unix_new(rfsock->fd);
+	g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+						sock_stack_event_cb, rfsock);
+	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, rfsock);
+
+	return;
+fail:
+	cleanup_rfsock(rfsock);
 }
 
 static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
-- 
1.7.10.4


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

* [PATCHv4 13/17] android/socket: Send RFCOMM channel to framework
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (11 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 12/17] android/socket: Implement HAL connect call Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 14/17] android/socket: Send connect signal on connect Andrei Emeltchenko
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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 5bedb60..bd8b9a2 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -480,6 +480,11 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 		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->channel = chan;
 	connections = g_list_append(connections, rfsock);
-- 
1.7.10.4


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

* [PATCHv4 14/17] android/socket: Send connect signal on connect
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (12 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 13/17] android/socket: Send RFCOMM channel to framework Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 15/17] android/socket: Close file descriptor after sending Andrei Emeltchenko
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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 bd8b9a2..03276a8 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -380,6 +380,33 @@ static int handle_listen(void *buf)
 	return hal_fd;
 }
 
+static ssize_t sock_send_connect(struct rfcomm_sock *rfsock, 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 = rfsock->channel;
+	cmd.status = 0;
+
+	len = write(rfsock->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_sock *rfsock = user_data;
@@ -410,6 +437,9 @@ static void connect_cb(GIOChannel *io, GError *conn_err, gpointer user_data)
 		rfsock->fd, rfsock->real_sock, rfsock->channel,
 		g_io_channel_unix_get_fd(io));
 
+	if (sock_send_connect(rfsock, &dst) < 0)
+		goto fail;
+
 	/* Handle events from Android */
 	io_stack = g_io_channel_unix_new(rfsock->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] 19+ messages in thread

* [PATCHv4 15/17] android/socket: Close file descriptor after sending
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (13 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 14/17] android/socket: Send connect signal on connect Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 16/17] android/socket: Add SDP record for OPP profile Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 17/17] android/socket: Add MAS uuid to channel mapping Andrei Emeltchenko
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 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 03276a8..3c4c238 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -563,6 +563,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);
@@ -570,6 +571,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] 19+ messages in thread

* [PATCHv4 16/17] android/socket: Add SDP record for OPP profile
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (14 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 15/17] android/socket: Close file descriptor after sending Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  2013-11-18 13:20 ` [PATCHv4 17/17] android/socket: Add MAS uuid to channel mapping Andrei Emeltchenko
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds SDP record for OPP shown below:

Service Name: OBEX Object Push
Service RecHandle: 0x10002
Service Class ID List:
  "OBEX Object Push" (0x1105)
Protocol Descriptor List:
  "RFCOMM" (0x0003)
    Channel: 9
  "OBEX" (0x0008)
Profile Descriptor List:
  "OBEX Object Push" (0x1105)
    Version: 0x0100
---
 android/socket.c |   94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 3c4c238..5e25b14 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -36,6 +36,7 @@
 #include "lib/sdp_lib.h"
 #include "src/sdp-client.h"
 
+#include "bluetooth.h"
 #include "log.h"
 #include "hal-msg.h"
 #include "hal-ipc.h"
@@ -46,6 +47,9 @@
 #define OPP_DEFAULT_CHANNEL	9
 #define PBAP_DEFAULT_CHANNEL	15
 
+/* Use Object Transfer for all services */
+#define SVC_HINT_OBEX 0x10
+
 static bdaddr_t adapter_addr;
 
 /* Simple list of RFCOMM server sockets */
@@ -59,6 +63,7 @@ struct rfcomm_sock {
 	int real_sock;	/* real RFCOMM socket */
 	int channel;	/* RFCOMM channel */
 	bdaddr_t dst;
+	uint32_t service_handle;
 };
 
 static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
@@ -90,6 +95,9 @@ static void cleanup_rfsock(struct rfcomm_sock *rfsock)
 	if (rfsock->real_sock > 0)
 		close(rfsock->real_sock);
 
+	if (rfsock->service_handle)
+		bt_adapter_remove_record(rfsock->service_handle);
+
 	g_free(rfsock);
 }
 
@@ -112,6 +120,90 @@ static struct {
 	}
 };
 
+static sdp_record_t *create_opp_record(uint8_t chan)
+{
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, opush_uuid, rfcomm_uuid, obex_uuid;
+	sdp_profile_desc_t profile[1];
+	sdp_list_t *aproto, *proto[2];
+	uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff };
+	void *dtds[sizeof(formats)], *values[sizeof(formats)];
+	unsigned int i;
+	uint8_t dtd = SDP_UINT8;
+	sdp_data_t *sflist;
+	sdp_data_t *channel;
+	sdp_record_t *record;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+	root = sdp_list_append(NULL, &root_uuid);
+	sdp_set_browse_groups(record, root);
+
+	sdp_uuid16_create(&opush_uuid, OBEX_OBJPUSH_SVCLASS_ID);
+	svclass_id = sdp_list_append(NULL, &opush_uuid);
+	sdp_set_service_classes(record, svclass_id);
+
+	sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID);
+	profile[0].version = 0x0100;
+	pfseq = sdp_list_append(NULL, profile);
+	sdp_set_profile_descs(record, pfseq);
+
+	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
+	proto[0] = sdp_list_append(NULL, &rfcomm_uuid);
+	channel = sdp_data_alloc(SDP_UINT8, &chan);
+	proto[0] = sdp_list_append(proto[0], channel);
+	apseq = sdp_list_append(NULL, proto[0]);
+
+	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
+	proto[1] = sdp_list_append(NULL, &obex_uuid);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	aproto = sdp_list_append(NULL, apseq);
+	sdp_set_access_protos(record, aproto);
+
+	for (i = 0; i < sizeof(formats); i++) {
+		dtds[i] = &dtd;
+		values[i] = &formats[i];
+	}
+	sflist = sdp_seq_alloc(dtds, values, sizeof(formats));
+	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FORMATS_LIST, sflist);
+
+	sdp_set_info_attr(record, "OBEX Object Push", 0, 0);
+
+	sdp_data_free(channel);
+	sdp_list_free(proto[0], NULL);
+	sdp_list_free(proto[1], NULL);
+	sdp_list_free(apseq, NULL);
+	sdp_list_free(aproto, NULL);
+
+	return record;
+}
+
+static uint32_t sdp_service_register(uint8_t chan)
+{
+	sdp_record_t *record;
+
+	switch (chan) {
+	case OPP_DEFAULT_CHANNEL:
+		record = create_opp_record(chan);
+		break;
+	default:
+		DBG("Not implemented");
+		return 0;
+	}
+
+	if (bt_adapter_add_record(record, SVC_HINT_OBEX) < 0) {
+		error("Failed to register on SDP record");
+		sdp_record_free(record);
+		return 0;
+	}
+
+	return record->handle;
+}
+
 static int bt_sock_send_fd(int sock_fd, const void *buf, int len, int send_fd)
 {
 	ssize_t ret;
@@ -374,6 +466,8 @@ static int handle_listen(void *buf)
 		return -1;
 	}
 
+	rfsock->service_handle = sdp_service_register(chan);
+
 	DBG("real_sock %d fd %d hal_fd %d",
 				rfsock->real_sock, rfsock->fd, hal_fd);
 
-- 
1.7.10.4


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

* [PATCHv4 17/17] android/socket: Add MAS uuid to channel mapping
  2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
                   ` (15 preceding siblings ...)
  2013-11-18 13:20 ` [PATCHv4 16/17] android/socket: Add SDP record for OPP profile Andrei Emeltchenko
@ 2013-11-18 13:20 ` Andrei Emeltchenko
  16 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
  To: linux-bluetooth

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

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

diff --git a/android/socket.c b/android/socket.c
index 5e25b14..3e67a53 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -46,6 +46,7 @@
 
 #define OPP_DEFAULT_CHANNEL	9
 #define PBAP_DEFAULT_CHANNEL	15
+#define MAS_DEFAULT_CHANNEL	16
 
 /* Use Object Transfer for all services */
 #define SVC_HINT_OBEX 0x10
@@ -117,6 +118,12 @@ static struct {
 			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
 		  },
 		.channel = OPP_DEFAULT_CHANNEL
+	}, {
+		.uuid = {
+			0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00,
+			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+		},
+		.channel = MAS_DEFAULT_CHANNEL
 	}
 };
 
-- 
1.7.10.4


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

* Re: [PATCHv4 02/17] android: trivial: Add comment making code consistent
  2013-11-18 13:20 ` [PATCHv4 02/17] android: trivial: Add comment making code consistent Andrei Emeltchenko
@ 2013-11-19  9:22   ` Johan Hedberg
  0 siblings, 0 replies; 19+ messages in thread
From: Johan Hedberg @ 2013-11-19  9:22 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth

Hi Andrei,

On Mon, Nov 18, 2013, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> ---
>  android/hal-msg.h |    2 ++
>  1 file changed, 2 insertions(+)

The first two patches have been applied. Thanks.

Johan

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

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

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-18 13:20 [PATCHv4 00/17] Socket HAL Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 01/17] android/socket: Add connect signal to socket Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 02/17] android: trivial: Add comment making code consistent Andrei Emeltchenko
2013-11-19  9:22   ` Johan Hedberg
2013-11-18 13:20 ` [PATCHv4 03/17] android/socket: Add get RFCOMM default channel Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 04/17] android/socket: Define structs and implement listen Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 05/17] android/socket: Implement socket accepted event Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 06/17] android/socket: Implement Android RFCOMM stack events Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 07/17] android/socket: Implement RFCOMM events Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 08/17] android/socket: Implement accept signal over Android fd Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 09/17] android/socket: Write channel to " Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 10/17] android/socket: Implement socket connect HAL method Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 11/17] android/socket: Parse SDP response and connect Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 12/17] android/socket: Implement HAL connect call Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 13/17] android/socket: Send RFCOMM channel to framework Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 14/17] android/socket: Send connect signal on connect Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 15/17] android/socket: Close file descriptor after sending Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 16/17] android/socket: Add SDP record for OPP profile Andrei Emeltchenko
2013-11-18 13:20 ` [PATCHv4 17/17] android/socket: Add MAS uuid to channel mapping Andrei Emeltchenko

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).