From: Andrei Emeltchenko <andrei.emeltchenko@xxxxxxxxx> 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 | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/android/socket.c b/android/socket.c index e580036..276c78c 100644 --- a/android/socket.c +++ b/android/socket.c @@ -27,8 +27,12 @@ #include <glib.h> #include <stdbool.h> +#include <unistd.h> +#include <errno.h> #include "lib/bluetooth.h" +#include "btio/btio.h" +#include "lib/sdp.h" #include "log.h" #include "hal-msg.h" #include "hal-ipc.h" @@ -37,13 +41,123 @@ static bdaddr_t adapter_addr; -static int handle_listen(void *buf) +/* Simple list of RFCOMM server sockets */ +GList *rfcomm_srv_list = NULL; + +/* Simple list of RFCOMM connected sockets */ +GList *rfcomm_connected_list = NULL; + +struct rfcomm_slot { + int fd; /* descriptor for communication with Java framework */ + int real_sock; /* real RFCOMM socket */ + int channel; /* RFCOMM channel */ +}; + +static struct rfcomm_slot *create_rfslot(int sock, int *hal_fd) { - DBG("Not implemented"); + int fds[2] = {-1, -1}; + struct rfcomm_slot *rfslot; + + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) { + error("socketpair(): %s", strerror(errno)); + return NULL; + } + + rfslot = g_malloc0(sizeof(*rfslot)); + rfslot->fd = fds[0]; + *hal_fd = fds[1]; + rfslot->real_sock = sock; + + return rfslot; +} + +static void cleanup_rfslot(struct rfcomm_slot *rfslot) +{ + DBG("Cleanup: rfslot: %p fd %d real_sock %d chan %u", + rfslot, rfslot->fd, rfslot->real_sock, rfslot->channel); + + if (rfslot->fd > 0) + close(rfslot->fd); + if (rfslot->real_sock > 0) + close(rfslot->real_sock); + + g_free(rfslot); +} + +static struct { + uint8_t uuid[16]; + uint8_t channel; +} uuid_to_chan[] = { + { .uuid = { + 0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB + }, +#define PBAP_DEFAULT_CHANNEL 15 + .channel = PBAP_DEFAULT_CHANNEL }, + { .uuid = { + 0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB + }, +#define OPP_DEFAULT_CHANNEL 9 + .channel = OPP_DEFAULT_CHANNEL }, + { {0} } +}; + +static int get_rfcomm_default_chan(const uint8_t *uuid) +{ + int i; + + for (i = 0; uuid_to_chan[i].channel; i++) { + if (!memcmp(uuid_to_chan[i].uuid, uuid, 16)) + return uuid_to_chan[i].channel; + } return -1; } +static void accept_cb(GIOChannel *io, GError *err, gpointer user_data) +{ +} + +static int handle_listen(void *buf) +{ + struct hal_cmd_sock_listen *cmd = buf; + struct rfcomm_slot *rfslot; + GIOChannel *io; + GError *err = NULL; + int hal_fd = -1; + int chan; + + DBG(""); + + chan = get_rfcomm_default_chan(cmd->uuid); + if (chan < 0) + return -1; + + DBG("rfcomm channel %d", chan); + + rfslot = create_rfslot(-1, &hal_fd); + + io = bt_io_listen(accept_cb, NULL, rfslot, NULL, &err, + BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, + BT_IO_OPT_CHANNEL, chan, + BT_IO_OPT_INVALID); + if (!io) { + error("Failed listen: %s", err->message); + g_error_free(err); + cleanup_rfslot(rfslot); + return -1; + } + + rfslot->real_sock = g_io_channel_unix_get_fd(io); + rfcomm_srv_list = g_list_append(rfcomm_srv_list, rfslot); + + DBG("real_sock %d fd %d hal_fd %d", + rfslot->real_sock, rfslot->fd, hal_fd); + + return hal_fd; +} + static int handle_connect(void *buf) { DBG("Not implemented"); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html