diff options
| -rw-r--r-- | daemon/echo.c | 111 | 
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); | 
