diff --git a/android/socket.c b/android/socket.c
index d4c7674..b8d96f9 100644
--- a/android/socket.c
+++ b/android/socket.c
#include <glib.h>
#include <stdbool.h>
+#include <unistd.h>
#include <errno.h>
#include "lib/bluetooth.h"
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;
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;
DBG("");
DBG("rfcomm channel %d", chan);
- return -1;
+ 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);
+
+ /* 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;
}
static int handle_connect(void *buf)