summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--daemon/echo.c111
1 files changed, 98 insertions, 13 deletions
diff --git a/daemon/echo.c b/daemon/echo.c
index 996d0804..97d7742c 100644
--- a/daemon/echo.c
+++ b/daemon/echo.c
@@ -66,11 +66,60 @@ static gboolean session_event(GIOChannel *chan, GIOCondition cond, gpointer data
return TRUE;
}
+static void authorization_callback(DBusPendingCall *call, void *data)
+{
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ GIOChannel *io = data;
+
+ debug("Authorization request returned");
+
+ if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == TRUE)
+ g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR,
+ session_event, NULL);
+
+ g_io_channel_unref(io);
+
+ dbus_message_unref(reply);
+}
+
+static int request_authorization(DBusConnection *conn,
+ GIOChannel *io, const char *address)
+{
+ DBusMessage *msg;
+ DBusPendingCall *pending;
+ const char *path = "";
+
+ info("Requesting authorization for %s", address);
+
+ msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+ "org.bluez.Database", "RequestAuthorization");
+ if (!msg) {
+ error("Allocation of method message failed");
+ return -1;
+ }
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &address,
+ DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID);
+
+ if (dbus_connection_send_with_reply(conn, msg, &pending, -1) == FALSE) {
+ error("Sending of authorization request failed");
+ return -1;
+ }
+
+ dbus_pending_call_set_notify(pending, authorization_callback, io, NULL);
+
+ dbus_message_unref(msg);
+
+ return 0;
+}
+
static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
+ DBusConnection *conn = data;
GIOChannel *io;
struct sockaddr_rc addr;
socklen_t optlen;
+ char address[18];
int sk, nsk;
sk = g_io_channel_unix_get_fd(chan);
@@ -85,15 +134,17 @@ static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data
io = g_io_channel_unix_new(nsk);
g_io_channel_set_close_on_unref(io, TRUE);
- g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR,
- session_event, NULL);
+ ba2str(&addr.rc_bdaddr, address);
- g_io_channel_unref(io);
+ if (request_authorization(conn, io, address) < 0) {
+ close(nsk);
+ return TRUE;
+ }
return TRUE;
}
-static GIOChannel *setup_rfcomm(uint8_t channel)
+static GIOChannel *setup_rfcomm(DBusConnection *conn, uint8_t channel)
{
GIOChannel *io;
struct sockaddr_rc addr;
@@ -121,7 +172,7 @@ static GIOChannel *setup_rfcomm(uint8_t channel)
io = g_io_channel_unix_new(sk);
g_io_channel_set_close_on_unref(io, TRUE);
- g_io_add_watch(io, G_IO_IN, connect_event, NULL);
+ g_io_add_watch(io, G_IO_IN, connect_event, conn);
return io;
}
@@ -182,6 +233,37 @@ static int setup_sdp(uint8_t channel)
return 0;
}
+static int register_standalone(DBusConnection *conn)
+{
+ DBusMessage *msg, *reply;
+ const char *ident = "echo", *name = "Echo service", *desc = "";
+
+ info("Registering service");
+
+ msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+ "org.bluez.Database", "RegisterService");
+ if (!msg) {
+ error("Allocation of method message failed");
+ return -1;
+ }
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &ident,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &desc, DBUS_TYPE_INVALID);
+
+ reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, NULL);
+ if (!reply) {
+ error("Registration of service failed");
+ return -1;
+ }
+
+ dbus_message_unref(reply);
+
+ dbus_connection_flush(conn);
+
+ return 0;
+}
+
static void sig_term(int sig)
{
g_main_loop_quit(main_loop);
@@ -209,22 +291,25 @@ int main(int argc, char *argv[])
main_loop = g_main_loop_new(NULL, FALSE);
- server_io = setup_rfcomm(23);
+ system_bus = init_dbus(NULL, NULL, NULL);
+ if (!system_bus) {
+ error("Connection to system bus failed");
+ g_main_loop_unref(main_loop);
+ exit(1);
+ }
+
+ server_io = setup_rfcomm(system_bus, 23);
if (!server_io) {
error("Creation of server channel failed");
+ dbus_connection_unref(system_bus);
g_main_loop_unref(main_loop);
exit(1);
}
setup_sdp(23);
- system_bus = init_dbus(NULL, NULL, NULL);
- if (!system_bus) {
- error("Connection to system bus failed");
- g_io_channel_unref(server_io);
- g_main_loop_unref(main_loop);
- exit(1);
- }
+ if (argc > 1 && !strcmp(argv[1], "-s"))
+ register_standalone(system_bus);
g_main_loop_run(main_loop);