diff --git a/android/main.c b/android/main.c
index cfa728d..2581b87 100644
--- a/android/main.c
+++ b/android/main.c
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+#include <errno.h>
#include <sys/signalfd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include <glib.h>
#include "src/shared/mgmt.h"
#include "adapter.h"
+#include "hal-msg.h"
#define SHUTDOWN_GRACE_SECONDS 10
static uint16_t adapter_index = MGMT_INDEX_NONE;
+static GIOChannel *hal_cmd_io = NULL;
+static GIOChannel *hal_notif_io = NULL;
+
static volatile sig_atomic_t __terminated = 0;
+static gboolean watch_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ info("HAL socket closed, terminating");
+ g_main_loop_quit(event_loop);
+
+ return FALSE;
+}
+
+static GIOChannel *connect_hal(GIOFunc connect_cb)
+{
+ struct sockaddr_un addr;
+ GIOCondition cond;
+ GIOChannel *io;
+ int err, sk;
+
+ sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
+ if (sk < 0) {
+ err = errno;
+ error("Failed to create socket: %d (%s)", err, strerror(err));
+ return NULL;
+ }
+
+ io = g_io_channel_unix_new(sk);
+
+ g_io_channel_set_close_on_unref(io, TRUE);
+ g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+
+ memcpy(addr.sun_path, BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH));
+
+ err = connect(sk, (struct sockaddr *) &addr, sizeof(addr));
+ if (err < 0) {
+ err = -errno;
+ error("Failed to connect HAL socket: %d (%s)", errno,
+ strerror(errno));
+ g_io_channel_unref(io);
+ return NULL;
+ }
+
+ cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+ g_io_add_watch(io, cond, connect_cb, NULL);
+
+ return io;
+}
+
+static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ DBG("");
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+ g_main_loop_quit(event_loop);
+ return FALSE;
+ }
+
+ cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+ g_io_add_watch(io, cond, watch_cb, NULL);
+
+ info("Successfully connected to HAL");
+
+ /* TODO start handling commands */
+
+ return FALSE;
+}
+
+static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ DBG("");
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+ g_main_loop_quit(event_loop);
+ return FALSE;
+ }
+
+ cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+ g_io_add_watch(io, cond, watch_cb, NULL);
+
+ hal_notif_io = connect_hal(notif_connect_cb);
+ if (!hal_notif_io) {
+ error("Cannot connect to HAL, terminating");
+ g_main_loop_quit(event_loop);
+ }
+
+ return FALSE;
+}
+
static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
gpointer user_data)
{
}
info("Adapter initialized");
+
+ hal_cmd_io = connect_hal(cmd_connect_cb);
+ if (!hal_cmd_io) {
+ error("Cannot connect to HAL, terminating");
+ g_main_loop_quit(event_loop);
+ }
}
static void mgmt_index_added_event(uint16_t index, uint16_t length,
mgmt_if = NULL;
}
+static void cleanup_hal_connection(void)
+{
+ if (hal_cmd_io) {
+ g_io_channel_shutdown(hal_cmd_io, TRUE, NULL);
+ g_io_channel_unref(hal_cmd_io);
+ hal_cmd_io = NULL;
+ }
+
+ if (hal_notif_io) {
+ g_io_channel_shutdown(hal_notif_io, TRUE, NULL);
+ g_io_channel_unref(hal_notif_io);
+ hal_notif_io = NULL;
+ }
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
g_source_remove(signal);
+ cleanup_hal_connection();
stop_sdp_server();
cleanup_mgmt_interface();
g_main_loop_unref(event_loop);