* [PATCHv6 01/19] android/socket: Add get RFCOMM default channel
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 02/19] android/socket: Handling rfcomm sockets Andrei Emeltchenko
` (17 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/android/socket.c b/android/socket.c
index 04bb7d1..d4c7674 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,19 +27,71 @@
#include <glib.h>
#include <stdbool.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"
#include "ipc.h"
#include "socket.h"
+#define OPP_DEFAULT_CHANNEL 9
+#define PBAP_DEFAULT_CHANNEL 15
+
static bdaddr_t adapter_addr;
+static struct profile_info {
+ uint8_t uuid[16];
+ uint8_t channel;
+ uint8_t svc_hint;
+ BtIOSecLevel sec_level;
+ sdp_record_t * (*create_record)(uint8_t chan);
+} profiles[] = {
+ {
+ .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 struct profile_info *get_profile_by_uuid(const uint8_t *uuid)
+{
+ unsigned int i;
+
+ for (i = 0; i < G_N_ELEMENTS(profiles); i++) {
+ if (!memcmp(profiles[i].uuid, uuid, 16))
+ return &profiles[i];
+ }
+
+ return NULL;
+}
+
static int handle_listen(void *buf)
{
- DBG("Not implemented");
+ struct hal_cmd_sock_listen *cmd = buf;
+ struct profile_info *profile;
+ int chan;
+
+ DBG("");
+
+ profile = get_profile_by_uuid(cmd->uuid);
+ if (!profile)
+ return -1;
+
+ chan = profile->channel;
+
+ DBG("rfcomm channel %d", chan);
return -1;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 02/19] android/socket: Handling rfcomm sockets
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 01/19] android/socket: Add get RFCOMM default channel Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 13:06 ` Johan Hedberg
2013-11-20 10:24 ` [PATCHv6 03/19] android/socket: Implement listen on RFCOMM socket Andrei Emeltchenko
` (16 subsequent siblings)
18 siblings, 1 reply; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Implement functions creating and destroying rfcomm_socket structures.
---
android/socket.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)
diff --git a/android/socket.c b/android/socket.c
index d4c7674..e19b2aa 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,6 +27,7 @@
#include <glib.h>
#include <stdbool.h>
+#include <unistd.h>
#include <errno.h>
#include "lib/bluetooth.h"
@@ -43,6 +44,61 @@
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 */
+
+ guint rfcomm_watch;
+ guint stack_watch;
+};
+
+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);
+
+ if (rfsock->rfcomm_watch > 0)
+ if (!g_source_remove(rfsock->rfcomm_watch))
+ error("rfcomm_watch source was not found");
+
+ if (rfsock->stack_watch > 0)
+ if (!g_source_remove(rfsock->stack_watch))
+ error("stack_watch source was not found");
+
+ g_free(rfsock);
+}
+
static struct profile_info {
uint8_t uuid[16];
uint8_t channel;
@@ -81,6 +137,8 @@ static int handle_listen(void *buf)
{
struct hal_cmd_sock_listen *cmd = buf;
struct profile_info *profile;
+ struct rfcomm_sock *rfsock;
+ int hal_fd;
int chan;
DBG("");
@@ -93,7 +151,11 @@ static int handle_listen(void *buf)
DBG("rfcomm channel %d", chan);
- return -1;
+ rfsock = create_rfsock(-1, &hal_fd);
+ if (!rfsock)
+ return -1;
+
+ return hal_fd;
}
static int handle_connect(void *buf)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCHv6 02/19] android/socket: Handling rfcomm sockets
2013-11-20 10:24 ` [PATCHv6 02/19] android/socket: Handling rfcomm sockets Andrei Emeltchenko
@ 2013-11-20 13:06 ` Johan Hedberg
0 siblings, 0 replies; 22+ messages in thread
From: Johan Hedberg @ 2013-11-20 13:06 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
Hi Andrei,
On Wed, Nov 20, 2013, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Implement functions creating and destroying rfcomm_socket structures.
> ---
> android/socket.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 63 insertions(+), 1 deletion(-)
I've applied the first patch, but this one doesn't compile:
android/socket.c:81:13: error: ‘cleanup_rfsock’ defined but not used [-Werror=unused-function]
static void cleanup_rfsock(struct rfcomm_sock *rfsock)
Johan
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCHv6 03/19] android/socket: Implement listen on RFCOMM socket
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 01/19] android/socket: Add get RFCOMM default channel Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 02/19] android/socket: Handling rfcomm sockets Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 04/19] android/socket: Implement socket accepted event Andrei Emeltchenko
` (15 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index e19b2aa..b8d96f9 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -133,11 +133,17 @@ static struct profile_info *get_profile_by_uuid(const uint8_t *uuid)
return NULL;
}
+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 profile_info *profile;
struct rfcomm_sock *rfsock;
+ GIOChannel *io;
+ GError *err = NULL;
int hal_fd;
int chan;
@@ -155,6 +161,27 @@ static int handle_listen(void *buf)
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);
+
+ /* TODO: Add server watch */
+ g_io_channel_set_close_on_unref(io, TRUE);
+ g_io_channel_unref(io);
+
+ 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] 22+ messages in thread* [PATCHv6 04/19] android/socket: Implement socket accepted event
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (2 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 03/19] android/socket: Implement listen on RFCOMM socket Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 05/19] android/socket: Implement Android RFCOMM stack events Andrei Emeltchenko
` (14 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index b8d96f9..48afd4b 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -133,8 +133,74 @@ static struct profile_info *get_profile_by_uuid(const uint8_t *uuid)
return NULL;
}
+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;
+ GError *gerr = NULL;
+ bdaddr_t dst;
+ char address[18];
+ int sock_acc;
+ int hal_fd;
+ guint id;
+ GIOCondition cond;
+
+ if (err) {
+ error("%s", err->message);
+ return;
+ }
+
+ bt_io_get(io, &gerr,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ g_io_channel_shutdown(io, TRUE, NULL);
+ return;
+ }
+
+ ba2str(&dst, address);
+ DBG("Incoming connection from %s rfsock %p", address, rfsock);
+
+ sock_acc = g_io_channel_unix_get_fd(io);
+ rfsock_acc = create_rfsock(sock_acc, &hal_fd);
+ connections = g_list_append(connections, rfsock_acc);
+
+ DBG("rfsock: fd %d real_sock %d chan %u sock %d",
+ rfsock->fd, rfsock->real_sock, rfsock->channel,
+ sock_acc);
+
+ /* Handle events from Android */
+ cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
+ io_stack = g_io_channel_unix_new(rfsock_acc->fd);
+ id = g_io_add_watch(io_stack, cond, sock_stack_event_cb, rfsock_acc);
+ g_io_channel_unref(io_stack);
+
+ rfsock_acc->stack_watch = id;
+
+ /* Handle rfcomm events */
+ cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
+ id = g_io_add_watch(io, cond, sock_rfcomm_event_cb, rfsock_acc);
+
+ rfsock_acc->rfcomm_watch = id;
+
+ DBG("rfsock %p rfsock_acc %p stack_watch %d rfcomm_watch %d",
+ rfsock, rfsock_acc, rfsock_acc->stack_watch,
+ rfsock_acc->rfcomm_watch);
}
static int handle_listen(void *buf)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 05/19] android/socket: Implement Android RFCOMM stack events
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (3 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 04/19] android/socket: Implement socket accepted event Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 06/19] android/socket: Implement RFCOMM events Andrei Emeltchenko
` (13 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 48afd4b..49b7413 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -133,10 +133,69 @@ static struct profile_info *get_profile_by_uuid(const uint8_t *uuid)
return NULL;
}
+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 (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);
+ goto fail;
+ }
+
+ len = read(rfsock->fd, buf, sizeof(buf));
+ if (len <= 0) {
+ error("read(): %s", strerror(errno));
+ /* Read again */
+ return TRUE;
+ }
+
+ 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));
+ goto fail;
+ }
+
+ DBG("Written %d bytes", sent);
+
return TRUE;
+fail:
+ connections = g_list_remove(connections, rfsock);
+ cleanup_rfsock(rfsock);
+
+ return FALSE;
}
static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 06/19] android/socket: Implement RFCOMM events
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (4 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 05/19] android/socket: Implement Android RFCOMM stack events Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 07/19] android/socket: Send accept signal to Android framework Andrei Emeltchenko
` (12 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 49b7413..3e738a4 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -201,7 +201,43 @@ fail:
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 (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);
+ goto fail;
+ }
+
+ len = read(rfsock->real_sock, buf, sizeof(buf));
+ if (len <= 0) {
+ error("read(): %s", strerror(errno));
+ /* Read again */
+ return TRUE;
+ }
+
+ 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));
+ goto fail;
+ }
+
+ DBG("Written %d bytes", sent);
+
return TRUE;
+fail:
+ connections = g_list_remove(connections, rfsock);
+ cleanup_rfsock(rfsock);
+
+ return FALSE;
}
static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 07/19] android/socket: Send accept signal to Android framework
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (5 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 06/19] android/socket: Implement RFCOMM events Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 08/19] android/socket: Notify channel " Andrei Emeltchenko
` (11 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 3e738a4..5901d45 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
@@ -121,6 +122,45 @@ static struct profile_info {
}
};
+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 struct profile_info *get_profile_by_uuid(const uint8_t *uuid)
{
unsigned int i;
@@ -240,6 +280,28 @@ fail:
return FALSE;
}
+static bool sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr,
+ int fd_accepted)
+{
+ struct hal_sock_connect_signal cmd;
+ int len;
+
+ DBG("");
+
+ cmd.size = sizeof(cmd);
+ bdaddr2android(bdaddr, cmd.bdaddr);
+ cmd.channel = rfsock->channel;
+ cmd.status = 0;
+
+ len = bt_sock_send_fd(rfsock->fd, &cmd, sizeof(cmd), fd_accepted);
+ if (len != sizeof(cmd)) {
+ error("Error sending accept signal");
+ return false;
+ }
+
+ return true;
+}
+
static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct rfcomm_sock *rfsock = user_data;
@@ -279,6 +341,11 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
rfsock->fd, rfsock->real_sock, rfsock->channel,
sock_acc);
+ if (!sock_send_accept(rfsock, &dst, hal_fd)) {
+ cleanup_rfsock(rfsock_acc);
+ return;
+ }
+
/* Handle events from Android */
cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
io_stack = g_io_channel_unix_new(rfsock_acc->fd);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 08/19] android/socket: Notify channel to Android framework
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (6 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 07/19] android/socket: Send accept signal to Android framework Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 09/19] android/socket: Implement socket connect HAL method Andrei Emeltchenko
` (10 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 5901d45..90561dc 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -410,6 +410,12 @@ static int handle_listen(void *buf)
DBG("real_sock %d fd %d hal_fd %d", rfsock->real_sock, rfsock->fd,
hal_fd);
+ if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+ error("Error sending RFCOMM channel");
+ cleanup_rfsock(rfsock);
+ return -1;
+ }
+
return hal_fd;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 09/19] android/socket: Implement socket connect HAL method
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (7 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 08/19] android/socket: Notify channel " Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 10/19] android/socket: Parse SDP response and connect Andrei Emeltchenko
` (9 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index 90561dc..1815367 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"
@@ -58,6 +61,8 @@ struct rfcomm_sock {
guint rfcomm_watch;
guint stack_watch;
+
+ bdaddr_t dst;
};
static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
@@ -419,11 +424,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] 22+ messages in thread* [PATCHv6 10/19] android/socket: Parse SDP response and connect
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (8 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 09/19] android/socket: Implement socket connect HAL method Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 13:21 ` Johan Hedberg
2013-11-20 10:24 ` [PATCHv6 11/19] android/socket: Implement HAL connect call Andrei Emeltchenko
` (8 subsequent siblings)
18 siblings, 1 reply; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 1815367..a5b28b7 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -424,9 +424,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] 22+ messages in thread* Re: [PATCHv6 10/19] android/socket: Parse SDP response and connect
2013-11-20 10:24 ` [PATCHv6 10/19] android/socket: Parse SDP response and connect Andrei Emeltchenko
@ 2013-11-20 13:21 ` Johan Hedberg
0 siblings, 0 replies; 22+ messages in thread
From: Johan Hedberg @ 2013-11-20 13:21 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
Hi Andrei,
On Wed, Nov 20, 2013, Andrei Emeltchenko wrote:
> Parse SDP response, find RFCOMM channel and connect.
> ---
> android/socket.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
Patches 1-9 have been applied (I merged 2 and 3 to avoid the compilation
error reported earlier), but one issue here:
> + 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;
Looks like you're leaking a reference for the GIOChannel since you don't
store it anywhere and return from the function without doing a
g_io_channel_unref().
Johan
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCHv6 11/19] android/socket: Implement HAL connect call
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (9 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 10/19] android/socket: Parse SDP response and connect Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 12/19] android/socket: Send RFCOMM channel to framework Andrei Emeltchenko
` (7 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index a5b28b7..e188c3f 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -426,6 +426,53 @@ static int handle_listen(void *buf)
static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
+ struct rfcomm_sock *rfsock = user_data;
+ GIOChannel *io_stack;
+ GError *gerr = NULL;
+ bdaddr_t dst;
+ char address[18];
+ int chan = -1;
+ guint id;
+ GIOCondition cond;
+
+ if (err) {
+ error("%s", err->message);
+ goto fail;
+ }
+
+ bt_io_get(io, &gerr,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ 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 */
+ cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
+ io_stack = g_io_channel_unix_new(rfsock->fd);
+ id = g_io_add_watch(io_stack, cond, sock_stack_event_cb, rfsock);
+ g_io_channel_unref(io_stack);
+
+ rfsock->stack_watch = id;
+
+ /* Handle rfcomm events */
+ cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+ id = g_io_add_watch(io, cond, sock_rfcomm_event_cb, rfsock);
+
+ rfsock->rfcomm_watch = id;
+
+ 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] 22+ messages in thread* [PATCHv6 12/19] android/socket: Send RFCOMM channel to framework
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (10 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 11/19] android/socket: Implement HAL connect call Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 13/19] android/socket: Send connect signal to Android framework Andrei Emeltchenko
` (6 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 e188c3f..1d16bc7 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -530,6 +530,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] 22+ messages in thread* [PATCHv6 13/19] android/socket: Send connect signal to Android framework
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (11 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 12/19] android/socket: Send RFCOMM channel to framework Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 14/19] android/socket: Close file descriptor after sending Andrei Emeltchenko
` (5 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 1d16bc7..d8e922d 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -424,6 +424,33 @@ static int handle_listen(void *buf)
return hal_fd;
}
+static bool sock_send_connect(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr)
+{
+ struct hal_sock_connect_signal cmd;
+ int 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 false;
+ }
+
+ if (len != sizeof(cmd)) {
+ error("Error sending connect signal");
+ false;
+ }
+
+ return true;
+}
+
static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct rfcomm_sock *rfsock = user_data;
@@ -456,6 +483,9 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
rfsock->fd, rfsock->real_sock, rfsock->channel,
g_io_channel_unix_get_fd(io));
+ if (!sock_send_connect(rfsock, &dst))
+ goto fail;
+
/* Handle events from Android */
cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
io_stack = g_io_channel_unix_new(rfsock->fd);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 14/19] android/socket: Close file descriptor after sending
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (12 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 13/19] android/socket: Send connect signal to Android framework Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 15/19] android/socket: Add SDP record for OPP profile Andrei Emeltchenko
` (4 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 d8e922d..5862c9c 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -613,6 +613,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);
@@ -620,6 +621,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] 22+ messages in thread* [PATCHv6 15/19] android/socket: Add SDP record for OPP profile
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (13 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 14/19] android/socket: Close file descriptor after sending Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 16/19] android/socket: Add MAS uuid to profile table Andrei Emeltchenko
` (3 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 98 insertions(+), 1 deletion(-)
diff --git a/android/socket.c b/android/socket.c
index 5862c9c..06b2906 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -35,7 +35,9 @@
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
#include "src/sdp-client.h"
+#include "src/sdpd.h"
+#include "bluetooth.h"
#include "log.h"
#include "hal-msg.h"
#include "hal-ipc.h"
@@ -46,6 +48,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 */
@@ -63,6 +68,7 @@ struct rfcomm_sock {
guint stack_watch;
bdaddr_t dst;
+ uint32_t service_handle;
};
static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
@@ -102,9 +108,79 @@ static void cleanup_rfsock(struct rfcomm_sock *rfsock)
if (!g_source_remove(rfsock->stack_watch))
error("stack_watch source was not found");
+ if (rfsock->service_handle)
+ bt_adapter_remove_record(rfsock->service_handle);
+
g_free(rfsock);
}
+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;
+
+ record->handle = sdp_next_handle();
+
+ 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", NULL, NULL);
+
+ sdp_data_free(channel);
+ sdp_list_free(proto[0], NULL);
+ sdp_list_free(proto[1], NULL);
+ sdp_list_free(apseq, NULL);
+ sdp_list_free(pfseq, NULL);
+ sdp_list_free(aproto, NULL);
+ sdp_list_free(root, NULL);
+ sdp_list_free(svclass_id, NULL);
+
+ return record;
+}
+
static struct profile_info {
uint8_t uuid[16];
uint8_t channel;
@@ -123,10 +199,29 @@ static struct profile_info {
0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
},
- .channel = OPP_DEFAULT_CHANNEL
+ .channel = OPP_DEFAULT_CHANNEL,
+ .svc_hint = SVC_HINT_OBEX,
+ .create_record = create_opp_record
}
};
+static uint32_t sdp_service_register(struct profile_info *profile)
+{
+ sdp_record_t *record;
+
+ record = profile->create_record(profile->channel);
+ if (!record)
+ return 0;
+
+ if (bt_adapter_add_record(record, profile->svc_hint) < 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;
@@ -421,6 +516,8 @@ static int handle_listen(void *buf)
return -1;
}
+ rfsock->service_handle = sdp_service_register(profile);
+
return hal_fd;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 16/19] android/socket: Add MAS uuid to profile table
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (14 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 15/19] android/socket: Add SDP record for OPP profile Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 17/19] android/socket: Add SPP " Andrei Emeltchenko
` (2 subsequent siblings)
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 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 06b2906..07588d5 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -47,6 +47,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
@@ -202,6 +203,12 @@ static struct profile_info {
.channel = OPP_DEFAULT_CHANNEL,
.svc_hint = SVC_HINT_OBEX,
.create_record = create_opp_record
+ }, {
+ .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] 22+ messages in thread* [PATCHv6 17/19] android/socket: Add SPP uuid to profile table
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (15 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 16/19] android/socket: Add MAS uuid to profile table Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 18/19] android/socket: Add PBAP SDP record Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 19/19] android/socket: Add SPP " Andrei Emeltchenko
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/socket.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/android/socket.c b/android/socket.c
index 07588d5..32b2db6 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -45,6 +45,7 @@
#include "utils.h"
#include "socket.h"
+#define SPP_DEFAULT_CHANNEL 3
#define OPP_DEFAULT_CHANNEL 9
#define PBAP_DEFAULT_CHANNEL 15
#define MAS_DEFAULT_CHANNEL 16
@@ -209,7 +210,13 @@ static struct profile_info {
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
},
.channel = MAS_DEFAULT_CHANNEL
- }
+ }, {
+ .uuid = {
+ 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+ },
+ .channel = SPP_DEFAULT_CHANNEL
+ },
};
static uint32_t sdp_service_register(struct profile_info *profile)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 18/19] android/socket: Add PBAP SDP record
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (16 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 17/19] android/socket: Add SPP " Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
2013-11-20 10:24 ` [PATCHv6 19/19] android/socket: Add SPP " Andrei Emeltchenko
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This adds SDP service record like shown below:
Service Name: OBEX Phonebook Access Server
Service RecHandle: 0x10002
Service Class ID List:
"Phonebook Access - PSE" (0x112f)
Protocol Descriptor List:
"RFCOMM" (0x0003)
Channel: 15
"OBEX" (0x0008)
Profile Descriptor List:
"Phonebook Access" (0x1130)
Version: 0x0100
---
android/socket.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 64 insertions(+), 1 deletion(-)
diff --git a/android/socket.c b/android/socket.c
index 32b2db6..a71c51c 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -183,6 +183,67 @@ static sdp_record_t *create_opp_record(uint8_t chan)
return record;
}
+static sdp_record_t *create_pbap_record(uint8_t chan)
+{
+ sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+ uuid_t root_uuid, pbap_uuid, rfcomm_uuid, obex_uuid;
+ sdp_profile_desc_t profile[1];
+ sdp_list_t *aproto, *proto[2];
+ sdp_data_t *channel;
+ uint8_t formats[] = { 0x01 };
+ uint8_t dtd = SDP_UINT8;
+ sdp_data_t *sflist;
+ sdp_record_t *record;
+
+ record = sdp_record_alloc();
+ if (!record)
+ return NULL;
+
+ record->handle = sdp_next_handle();
+
+ sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+ root = sdp_list_append(NULL, &root_uuid);
+ sdp_set_browse_groups(record, root);
+
+ sdp_uuid16_create(&pbap_uuid, PBAP_PSE_SVCLASS_ID);
+ svclass_id = sdp_list_append(NULL, &pbap_uuid);
+ sdp_set_service_classes(record, svclass_id);
+
+ sdp_uuid16_create(&profile[0].uuid, PBAP_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);
+
+ sflist = sdp_data_alloc(dtd, formats);
+ sdp_attr_add(record, SDP_ATTR_SUPPORTED_REPOSITORIES, sflist);
+
+ sdp_set_info_attr(record, "OBEX Phonebook Access Server", NULL, NULL);
+
+ sdp_data_free(channel);
+ sdp_list_free(proto[0], NULL);
+ sdp_list_free(proto[1], NULL);
+ sdp_list_free(apseq, NULL);
+ sdp_list_free(pfseq, NULL);
+ sdp_list_free(root, NULL);
+ sdp_list_free(svclass_id, NULL);
+ sdp_list_free(aproto, NULL);
+
+ return record;
+}
+
static struct profile_info {
uint8_t uuid[16];
uint8_t channel;
@@ -195,7 +256,9 @@ static struct profile_info {
0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
},
- .channel = PBAP_DEFAULT_CHANNEL
+ .channel = PBAP_DEFAULT_CHANNEL,
+ .svc_hint = SVC_HINT_OBEX,
+ .create_record = create_pbap_record
}, {
.uuid = {
0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCHv6 19/19] android/socket: Add SPP SDP record
2013-11-20 10:24 [PATCHv6 00/19] Socket HAL Andrei Emeltchenko
` (17 preceding siblings ...)
2013-11-20 10:24 ` [PATCHv6 18/19] android/socket: Add PBAP SDP record Andrei Emeltchenko
@ 2013-11-20 10:24 ` Andrei Emeltchenko
18 siblings, 0 replies; 22+ messages in thread
From: Andrei Emeltchenko @ 2013-11-20 10:24 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/socket.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)
diff --git a/android/socket.c b/android/socket.c
index a71c51c..15aa77d 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -237,9 +237,69 @@ static sdp_record_t *create_pbap_record(uint8_t chan)
sdp_list_free(proto[1], NULL);
sdp_list_free(apseq, NULL);
sdp_list_free(pfseq, NULL);
+ sdp_list_free(aproto, NULL);
sdp_list_free(root, NULL);
sdp_list_free(svclass_id, NULL);
+
+ return record;
+}
+
+static sdp_record_t *create_spp_record(uint8_t chan)
+{
+ sdp_list_t *svclass_id, *apseq, *profiles, *root;
+ uuid_t root_uuid, sp_uuid, rfcomm;
+ sdp_profile_desc_t profile;
+ sdp_list_t *aproto, *proto[1];
+ sdp_data_t *channel;
+ sdp_record_t *record;
+
+ record = sdp_record_alloc();
+ if (!record)
+ return NULL;
+
+ record->handle = sdp_next_handle();
+
+ sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+ root = sdp_list_append(NULL, &root_uuid);
+ sdp_set_browse_groups(record, root);
+
+ sdp_uuid16_create(&sp_uuid, SERIAL_PORT_SVCLASS_ID);
+ svclass_id = sdp_list_append(NULL, &sp_uuid);
+ sdp_set_service_classes(record, svclass_id);
+
+ sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
+ profile.version = 0x0100;
+ profiles = sdp_list_append(NULL, &profile);
+ sdp_set_profile_descs(record, profiles);
+
+ sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
+ proto[0] = sdp_list_append(NULL, &rfcomm);
+ channel = sdp_data_alloc(SDP_UINT8, &chan);
+ proto[0] = sdp_list_append(proto[0], channel);
+ apseq = sdp_list_append(NULL, proto[0]);
+
+ aproto = sdp_list_append(NULL, apseq);
+ sdp_set_access_protos(record, aproto);
+
+ sdp_add_lang_attr(record);
+
+ sdp_set_info_attr(record, "Serial Port", "BlueZ", "COM Port");
+
+ sdp_set_url_attr(record, "http://www.bluez.org/",
+ "http://www.bluez.org/", "http://www.bluez.org/");
+
+ sdp_set_service_id(record, sp_uuid);
+ sdp_set_service_ttl(record, 0xffff);
+ sdp_set_service_avail(record, 0xff);
+ sdp_set_record_state(record, 0x00001234);
+
+ sdp_data_free(channel);
+ sdp_list_free(proto[0], NULL);
+ sdp_list_free(apseq, NULL);
sdp_list_free(aproto, NULL);
+ sdp_list_free(root, NULL);
+ sdp_list_free(svclass_id, NULL);
+ sdp_list_free(profiles, NULL);
return record;
}
@@ -278,7 +338,9 @@ static struct profile_info {
0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
},
- .channel = SPP_DEFAULT_CHANNEL
+ .channel = SPP_DEFAULT_CHANNEL,
+ .svc_hint = 0,
+ .create_record = create_spp_record
},
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 22+ messages in thread