12ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann/*
22ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *
32ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  BlueZ - Bluetooth protocol stack for Linux
42ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *
59184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
62ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *
72ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *
82ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  This program is free software; you can redistribute it and/or modify
92ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  it under the terms of the GNU General Public License as published by
102ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  the Free Software Foundation; either version 2 of the License, or
112ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  (at your option) any later version.
122ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *
132ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  This program is distributed in the hope that it will be useful,
142ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  but WITHOUT ANY WARRANTY; without even the implied warranty of
152ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  GNU General Public License for more details.
172ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *
182ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  You should have received a copy of the GNU General Public License
192ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  along with this program; if not, write to the Free Software
202ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
212ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann *
222ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann */
232ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
242ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#ifdef HAVE_CONFIG_H
252ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#include <config.h>
262ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#endif
272ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
282ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#include <stdio.h>
292ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#include <errno.h>
302ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#include <unistd.h>
312ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#include <stdlib.h>
322ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#include <signal.h>
332ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#include <getopt.h>
342ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#include <string.h>
352ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
362ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann#include <dbus/dbus.h>
372ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmannstatic char *passkey_value = NULL;
39609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmannstatic int passkey_delay = 0;
402ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannstatic int do_reject = 0;
412ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
422ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannstatic volatile sig_atomic_t __io_canceled = 0;
432ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannstatic volatile sig_atomic_t __io_terminated = 0;
442ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
452ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannstatic void sig_term(int sig)
462ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
472ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	__io_canceled = 1;
482ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
492ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
502ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannstatic DBusHandlerResult agent_filter(DBusConnection *conn,
512ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann						DBusMessage *msg, void *data)
522ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
532ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	const char *name, *old, *new;
542ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
550b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg	if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS,
560b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg						"NameOwnerChanged"))
572ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
582ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
592ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!dbus_message_get_args(msg, NULL,
600b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg					DBUS_TYPE_STRING, &name,
610b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg					DBUS_TYPE_STRING, &old,
620b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg					DBUS_TYPE_STRING, &new,
630b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg					DBUS_TYPE_INVALID)) {
6497b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		fprintf(stderr, "Invalid arguments for NameOwnerChanged signal");
652ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
662ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
672ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
682ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!strcmp(name, "org.bluez") && *new == '\0') {
692ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Agent has been terminated\n");
702ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		__io_terminated = 1;
712ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
722ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
732ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
742ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
752ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
76012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedistatic DBusHandlerResult request_pincode_message(DBusConnection *conn,
772ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann						DBusMessage *msg, void *data)
782ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
792ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	DBusMessage *reply;
80012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	const char *path;
812ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
8297b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!passkey_value)
832ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
842ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
8597b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
8697b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann							DBUS_TYPE_INVALID)) {
87012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		fprintf(stderr, "Invalid arguments for RequestPinCode method");
882ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
892ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
902ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
912ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (do_reject) {
9297b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected", "");
932ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		goto send;
942ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
952ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
962ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	reply = dbus_message_new_method_return(msg);
972ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!reply) {
982ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Can't create reply message\n");
992ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return DBUS_HANDLER_RESULT_NEED_MEMORY;
1002ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
1012ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
102012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	printf("Pincode request for device %s\n", path);
1032ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
104609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann	if (passkey_delay) {
1057fefa9ead2c4ed2f70db20c70d55dacf645e14d7Marcel Holtmann		printf("Waiting for %d seconds\n", passkey_delay);
106609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann		sleep(passkey_delay);
107609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann	}
108609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann
10997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	dbus_message_append_args(reply, DBUS_TYPE_STRING, &passkey_value,
11097b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann							DBUS_TYPE_INVALID);
1112ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
1122ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannsend:
1132ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_send(conn, reply, NULL);
1142ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
1152ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_flush(conn);
1162ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
1172ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_message_unref(reply);
1182ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
1192ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	return DBUS_HANDLER_RESULT_HANDLED;
1202ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
1212ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
122012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedistatic DBusHandlerResult request_passkey_message(DBusConnection *conn,
1232ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann						DBusMessage *msg, void *data)
1242ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
1252ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	DBusMessage *reply;
126012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	const char *path;
12797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	unsigned int passkey;
128012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
12997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!passkey_value)
130012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
131012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
13297b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
13397b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann							DBUS_TYPE_INVALID)) {
134012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		fprintf(stderr, "Invalid arguments for RequestPasskey method");
135012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
136012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	}
137012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
138012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	if (do_reject) {
13997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected", "");
140012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		goto send;
141012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	}
142012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
143012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	reply = dbus_message_new_method_return(msg);
144012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	if (!reply) {
145012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		fprintf(stderr, "Can't create reply message\n");
146012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		return DBUS_HANDLER_RESULT_NEED_MEMORY;
147012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	}
148012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
149012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	printf("Passkey request for device %s\n", path);
150012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
151609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann	if (passkey_delay) {
1527fefa9ead2c4ed2f70db20c70d55dacf645e14d7Marcel Holtmann		printf("Waiting for %d seconds\n", passkey_delay);
153609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann		sleep(passkey_delay);
154609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann	}
155609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann
15697b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	passkey = strtoul(passkey_value, NULL, 10);
157012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
15897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &passkey,
15997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann							DBUS_TYPE_INVALID);
160012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
161012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedisend:
162012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	dbus_connection_send(conn, reply, NULL);
163012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
164012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	dbus_connection_flush(conn);
165012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
166012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	dbus_message_unref(reply);
167012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
168012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	return DBUS_HANDLER_RESULT_HANDLED;
169012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi}
170012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
17197b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmannstatic DBusHandlerResult request_confirmation_message(DBusConnection *conn,
172012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi						DBusMessage *msg, void *data)
173012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi{
174012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	DBusMessage *reply;
17597b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	const char *path;
17697b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	unsigned int passkey;
177012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
17897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
17997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann						DBUS_TYPE_UINT32, &passkey,
18097b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann							DBUS_TYPE_INVALID)) {
18197b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		fprintf(stderr, "Invalid arguments for RequestPasskey method");
1822ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1832ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
1842ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
18597b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (do_reject) {
18697b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected", "");
18797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		goto send;
18897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	}
1892ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
1902ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	reply = dbus_message_new_method_return(msg);
1912ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!reply) {
1922ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Can't create reply message\n");
1932ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return DBUS_HANDLER_RESULT_NEED_MEMORY;
1942ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
1952ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
19697b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	printf("Confirmation request of %u for device %s\n", passkey, path);
19797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
198609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann	if (passkey_delay) {
1997fefa9ead2c4ed2f70db20c70d55dacf645e14d7Marcel Holtmann		printf("Waiting for %d seconds\n", passkey_delay);
200609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann		sleep(passkey_delay);
201609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann	}
20297b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
20397b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmannsend:
2042ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_send(conn, reply, NULL);
2052ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
2062ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_flush(conn);
2072ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
2082ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_message_unref(reply);
2092ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
2102ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	return DBUS_HANDLER_RESULT_HANDLED;
2112ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
2122ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
21397b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmannstatic DBusHandlerResult authorize_message(DBusConnection *conn,
2142ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann						DBusMessage *msg, void *data)
2152ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
2162ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	DBusMessage *reply;
21797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	const char *path, *uuid;
2182ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
21997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
22097b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann						DBUS_TYPE_STRING, &uuid,
22197b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann							DBUS_TYPE_INVALID)) {
22297b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		fprintf(stderr, "Invalid arguments for Authorize method");
2232ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2242ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
2252ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
22697b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (do_reject) {
22797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected", "");
22897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		goto send;
22997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	}
2302ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
2312ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	reply = dbus_message_new_method_return(msg);
2322ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!reply) {
2332ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Can't create reply message\n");
2342ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return DBUS_HANDLER_RESULT_NEED_MEMORY;
2352ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
2362ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
23797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	printf("Authorizing request for %s\n", path);
23897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
23997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmannsend:
2402ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_send(conn, reply, NULL);
2412ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
2422ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_flush(conn);
2432ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
2442ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_message_unref(reply);
2452ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
2462ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	return DBUS_HANDLER_RESULT_HANDLED;
2472ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
2482ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
24997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmannstatic DBusHandlerResult cancel_message(DBusConnection *conn,
250012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi						DBusMessage *msg, void *data)
251012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi{
252012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	DBusMessage *reply;
253012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
25497b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID)) {
25597b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		fprintf(stderr, "Invalid arguments for passkey Confirm method");
256012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
257012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	}
258012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
25997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	printf("Request canceled\n");
260012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
261012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	reply = dbus_message_new_method_return(msg);
262012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	if (!reply) {
263012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		fprintf(stderr, "Can't create reply message\n");
264012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		return DBUS_HANDLER_RESULT_NEED_MEMORY;
265012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	}
266012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
26797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	dbus_connection_send(conn, reply, NULL);
26897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
26997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	dbus_connection_flush(conn);
27097b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
27197b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	dbus_message_unref(reply);
27297b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
27397b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	return DBUS_HANDLER_RESULT_HANDLED;
27497b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann}
27597b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
27697b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmannstatic DBusHandlerResult release_message(DBusConnection *conn,
27797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann						DBusMessage *msg, void *data)
27897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann{
27997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	DBusMessage *reply;
28097b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
28197b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID)) {
28297b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		fprintf(stderr, "Invalid arguments for Release method");
28397b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
28497b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	}
28597b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
28697b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!__io_canceled)
28797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		fprintf(stderr, "Agent has been released\n");
28897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
28997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	__io_terminated = 1;
29097b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
29197b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	reply = dbus_message_new_method_return(msg);
29297b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (!reply) {
29397b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		fprintf(stderr, "Can't create reply message\n");
29497b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		return DBUS_HANDLER_RESULT_NEED_MEMORY;
29597b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	}
296012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
297012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	dbus_connection_send(conn, reply, NULL);
298012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
299012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	dbus_connection_flush(conn);
300012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
301012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	dbus_message_unref(reply);
302012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
303012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi	return DBUS_HANDLER_RESULT_HANDLED;
304012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi}
305012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
3062ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannstatic DBusHandlerResult agent_message(DBusConnection *conn,
3072ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann						DBusMessage *msg, void *data)
3082ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
3090b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg	if (dbus_message_is_method_call(msg, "org.bluez.Agent",
3100b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg							"RequestPinCode"))
311012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		return request_pincode_message(conn, msg, data);
312012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi
3130b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg	if (dbus_message_is_method_call(msg, "org.bluez.Agent",
3140b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg							"RequestPasskey"))
315012c1469491fb9a3622ce01c2583026a09824d46Filippo Giunchedi		return request_passkey_message(conn, msg, data);
3162ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
31797b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (dbus_message_is_method_call(msg, "org.bluez.Agent",
31897b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann							"RequestConfirmation"))
31997b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		return request_confirmation_message(conn, msg, data);
32097b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
32197b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	if (dbus_message_is_method_call(msg, "org.bluez.Agent", "Authorize"))
32297b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann		return authorize_message(conn, msg, data);
32397b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann
3242ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (dbus_message_is_method_call(msg, "org.bluez.Agent", "Cancel"))
3252ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return cancel_message(conn, msg, data);
3262ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3272ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (dbus_message_is_method_call(msg, "org.bluez.Agent", "Release"))
3282ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return release_message(conn, msg, data);
3292ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3302ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3312ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
3322ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3332ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannstatic const DBusObjectPathVTable agent_table = {
3342ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	.message_function = agent_message,
3352ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann};
3362ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
337950ab387b2449f05fbb53a791a7d0fb80524101bFilippo Giunchedistatic int register_agent(DBusConnection *conn, const char *adapter_path,
3382ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann						const char *agent_path,
3392ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann						const char *capabilities)
3402ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
3412ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	DBusMessage *msg, *reply;
3422ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	DBusError err;
3432ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
344950ab387b2449f05fbb53a791a7d0fb80524101bFilippo Giunchedi	msg = dbus_message_new_method_call("org.bluez", adapter_path,
3452ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann					"org.bluez.Adapter", "RegisterAgent");
3462ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!msg) {
3472ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Can't allocate new method call\n");
3482ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return -1;
3492ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
3502ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3512ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
3522ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann					DBUS_TYPE_STRING, &capabilities,
3530b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg					DBUS_TYPE_INVALID);
3542ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3552ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_error_init(&err);
3562ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3572ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
3582ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3592ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_message_unref(msg);
3602ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3612ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!reply) {
3622ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Can't register agent\n");
3632ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		if (dbus_error_is_set(&err)) {
3642ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			fprintf(stderr, "%s\n", err.message);
3652ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			dbus_error_free(&err);
3662ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		}
3672ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return -1;
3682ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
3692ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3702ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_message_unref(reply);
3712ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3722ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_flush(conn);
3732ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3742ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	return 0;
3752ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
3762ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
377950ab387b2449f05fbb53a791a7d0fb80524101bFilippo Giunchedistatic int unregister_agent(DBusConnection *conn, const char *adapter_path,
3782ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann							const char *agent_path)
3792ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
3802ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	DBusMessage *msg, *reply;
3812ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	DBusError err;
3822ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
383950ab387b2449f05fbb53a791a7d0fb80524101bFilippo Giunchedi	msg = dbus_message_new_method_call("org.bluez", adapter_path,
3842ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann					"org.bluez.Adapter", "UnregisterAgent");
3852ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!msg) {
3862ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Can't allocate new method call\n");
3872ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return -1;
3882ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
3892ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3902ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
3912ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann							DBUS_TYPE_INVALID);
3922ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3932ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_error_init(&err);
3942ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3952ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
3962ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3972ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_message_unref(msg);
3982ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
3992ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!reply) {
4002ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Can't unregister agent\n");
4012ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		if (dbus_error_is_set(&err)) {
4022ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			fprintf(stderr, "%s\n", err.message);
4032ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			dbus_error_free(&err);
4042ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		}
4052ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		return -1;
4062ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
4072ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
4082ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_message_unref(reply);
4092ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
4102ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_flush(conn);
4112ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
4122ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_unregister_object_path(conn, agent_path);
4132ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
4142ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	return 0;
4152ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
4162ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
417950ab387b2449f05fbb53a791a7d0fb80524101bFilippo Giunchedistatic int create_paired_device(DBusConnection *conn, const char *adapter_path,
418e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi						const char *agent_path,
4190b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg						const char *capabilities,
420aec8360e716a2dd796a63f7d0d4ea535e02d2cd2Filippo Giunchedi						const char *device)
421e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi{
422e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	dbus_bool_t success;
423e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	DBusMessage *msg;
424e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi
425950ab387b2449f05fbb53a791a7d0fb80524101bFilippo Giunchedi	msg = dbus_message_new_method_call("org.bluez", adapter_path,
4260b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg						"org.bluez.Adapter",
4270b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg						"CreatePairedDevice");
428e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	if (!msg) {
429e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi		fprintf(stderr, "Can't allocate new method call\n");
430e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi		return -1;
431e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	}
432e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi
433aec8360e716a2dd796a63f7d0d4ea535e02d2cd2Filippo Giunchedi	dbus_message_append_args(msg, DBUS_TYPE_STRING, &device,
434e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi					DBUS_TYPE_OBJECT_PATH, &agent_path,
435e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi					DBUS_TYPE_STRING, &capabilities,
4360b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg					DBUS_TYPE_INVALID);
437e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi
438e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	success = dbus_connection_send(conn, msg, NULL);
439e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi
440e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	dbus_message_unref(msg);
441e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi
442e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	if (!success) {
443e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi		fprintf(stderr, "Not enough memory for message send\n");
444e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi		return -1;
445e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	}
446e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi
447e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	dbus_connection_flush(conn);
448e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi
449e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	return 0;
450e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi}
451e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi
4527b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedistatic char *get_default_adapter_path(DBusConnection *conn)
4532ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
454db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	DBusMessage *msg, *reply;
455db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	DBusError err;
4567b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	const char *reply_path;
4577b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	char *path;
4587b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
4597b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	msg = dbus_message_new_method_call("org.bluez", "/",
4607b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi					"org.bluez.Manager", "DefaultAdapter");
4617b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
4627b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	if (!msg) {
4637b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		fprintf(stderr, "Can't allocate new method call\n");
4647b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		return NULL;
4657b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	}
4667b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
4677b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	dbus_error_init(&err);
4687b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
4697b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
470db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
4717b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	dbus_message_unref(msg);
4727b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
4737b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	if (!reply) {
4747b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		fprintf(stderr,
4757b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi			"Can't get default adapter\n");
4767b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		if (dbus_error_is_set(&err)) {
4777b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi			fprintf(stderr, "%s\n", err.message);
4787b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi			dbus_error_free(&err);
4797b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		}
4807b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		return NULL;
481db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	}
482db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
4837b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	if (!dbus_message_get_args(reply, &err,
4847b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi					DBUS_TYPE_OBJECT_PATH, &reply_path,
4857b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi					DBUS_TYPE_INVALID)) {
4867b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		fprintf(stderr,
4877b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi			"Can't get reply arguments\n");
4887b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		if (dbus_error_is_set(&err)) {
4897b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi			fprintf(stderr, "%s\n", err.message);
4907b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi			dbus_error_free(&err);
4917b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		}
4927b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		return NULL;
4937b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	}
4947b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
4957b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	path = strdup(reply_path);
4967b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
4977b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	dbus_message_unref(reply);
4987b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
4997b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	dbus_connection_flush(conn);
5007b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
5017b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	return path;
5027b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi}
5037b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
5047b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedistatic char *get_adapter_path(DBusConnection *conn, const char *adapter)
5057b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi{
5067b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	DBusMessage *msg, *reply;
5077b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	DBusError err;
5087b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	const char *reply_path;
5097b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	char *path;
5107b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
5117b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	if (!adapter)
5127b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		return get_default_adapter_path(conn);
5137b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
514db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	msg = dbus_message_new_method_call("org.bluez", "/",
5157b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi					"org.bluez.Manager", "FindAdapter");
516db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
517db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	if (!msg) {
518db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi		fprintf(stderr, "Can't allocate new method call\n");
5197b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		return NULL;
520db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	}
521db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
5227b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	dbus_message_append_args(msg, DBUS_TYPE_STRING, &adapter,
5237b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi					DBUS_TYPE_INVALID);
5247b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi
525db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	dbus_error_init(&err);
526db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
527db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
528db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
529db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	dbus_message_unref(msg);
530db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
531db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	if (!reply) {
5320b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg		fprintf(stderr,
5337b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi			"Can't find adapter %s\n", adapter);
534db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi		if (dbus_error_is_set(&err)) {
535db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi			fprintf(stderr, "%s\n", err.message);
536db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi			dbus_error_free(&err);
537db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi		}
5387b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		return NULL;
539db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	}
540db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
541db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	if (!dbus_message_get_args(reply, &err,
5427b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi					DBUS_TYPE_OBJECT_PATH, &reply_path,
5430b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg					DBUS_TYPE_INVALID)) {
5440b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg		fprintf(stderr,
5457b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi			"Can't get reply arguments\n");
546db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi		if (dbus_error_is_set(&err)) {
547db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi			fprintf(stderr, "%s\n", err.message);
548db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi			dbus_error_free(&err);
549db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi		}
5507b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		return NULL;
551db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	}
5522ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
5537b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	path = strdup(reply_path);
554db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
555db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	dbus_message_unref(reply);
556db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi
557db656f343048597f20b26b36144dff2663a9fdf2Filippo Giunchedi	dbus_connection_flush(conn);
5582ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
5592ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	return path;
5602ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
5612ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
5622ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannstatic void usage(void)
5632ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
5642ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	printf("Bluetooth agent ver %s\n\n", VERSION);
5652ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
5662ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	printf("Usage:\n"
567aec8360e716a2dd796a63f7d0d4ea535e02d2cd2Filippo Giunchedi		"\tagent [--adapter adapter-path] [--path agent-path] <passkey> [<device>]\n"
5682ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		"\n");
5692ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
5702ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
5712ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannstatic struct option main_options[] = {
572112f88d310ca1ac5f64e27982d21e433bc311502Filippo Giunchedi	{ "adapter",	1, 0, 'a' },
5732ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	{ "path",	1, 0, 'p' },
5742ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	{ "capabilites",1, 0, 'c' },
575609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann	{ "delay",	1, 0, 'd' },
5762ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	{ "reject",	0, 0, 'r' },
5772ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	{ "help",	0, 0, 'h' },
5782ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	{ 0, 0, 0, 0 }
5792ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann};
5802ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
5812ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmannint main(int argc, char *argv[])
5822ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann{
5832ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	const char *capabilities = "DisplayYesNo";
5842ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	struct sigaction sa;
5852ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	DBusConnection *conn;
5866db7a480cdff7ca8bbfebd3b88b832481df3166eFilippo Giunchedi	char match_string[128], default_path[128], *adapter_id = NULL;
587aec8360e716a2dd796a63f7d0d4ea535e02d2cd2Filippo Giunchedi	char *adapter_path = NULL, *agent_path = NULL, *device = NULL;
5882ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	int opt;
5892ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
5902ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	snprintf(default_path, sizeof(default_path),
5912ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann					"/org/bluez/agent_%d", getpid());
5922ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
593609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann	while ((opt = getopt_long(argc, argv, "+a:p:c:d:rh", main_options, NULL)) != EOF) {
5942ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		switch(opt) {
595112f88d310ca1ac5f64e27982d21e433bc311502Filippo Giunchedi		case 'a':
5966db7a480cdff7ca8bbfebd3b88b832481df3166eFilippo Giunchedi			adapter_id = optarg;
5972ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			break;
5982ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		case 'p':
5992ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			if (optarg[0] != '/') {
6002ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann				fprintf(stderr, "Invalid path\n");
6012ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann				exit(1);
6022ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			}
6032ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			agent_path = strdup(optarg);
6042ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			break;
6052ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		case 'c':
6062ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			capabilities = optarg;
6072ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			break;
608609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann		case 'd':
609609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann			passkey_delay = atoi(optarg);
610609aa6f17c2237099eb737d02684af9bc43887b5Marcel Holtmann			break;
6112ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		case 'r':
6122ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			do_reject = 1;
6132ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			break;
6142ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		case 'h':
6152ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			usage();
6162ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			exit(0);
6172ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		default:
6182ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			exit(1);
6192ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		}
6202ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
6212ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6222ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	argc -= optind;
6232ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	argv += optind;
6242ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	optind = 0;
6252ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6262ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (argc < 1) {
6272ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		usage();
6282ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		exit(1);
6292ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
6302ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
63197b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	passkey_value = strdup(argv[0]);
6322ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
633e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	if (argc > 1)
634aec8360e716a2dd796a63f7d0d4ea535e02d2cd2Filippo Giunchedi		device = strdup(argv[1]);
635e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi
6362ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!agent_path)
6372ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		agent_path = strdup(default_path);
6382ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6392ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
6402ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!conn) {
6412ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Can't get on system bus");
6422ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		exit(1);
6432ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
6442ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6457b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi	adapter_path = get_adapter_path(conn, adapter_id);
6466db7a480cdff7ca8bbfebd3b88b832481df3166eFilippo Giunchedi	if (!adapter_path)
6477b050e571ee24a8a5a093a44b5de4bfdc605ffe4Filippo Giunchedi		exit(1);
6482ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
649a2d3bb25dad632a46ce297744933ef18105736f0Vinicius Costa Gomes	if (!dbus_connection_register_object_path(conn, agent_path,
650a2d3bb25dad632a46ce297744933ef18105736f0Vinicius Costa Gomes							&agent_table, NULL)) {
651a2d3bb25dad632a46ce297744933ef18105736f0Vinicius Costa Gomes		fprintf(stderr, "Can't register object path for agent\n");
652a2d3bb25dad632a46ce297744933ef18105736f0Vinicius Costa Gomes		exit(1);
653a2d3bb25dad632a46ce297744933ef18105736f0Vinicius Costa Gomes	}
654a2d3bb25dad632a46ce297744933ef18105736f0Vinicius Costa Gomes
655aec8360e716a2dd796a63f7d0d4ea535e02d2cd2Filippo Giunchedi	if (device) {
6566db7a480cdff7ca8bbfebd3b88b832481df3166eFilippo Giunchedi		if (create_paired_device(conn, adapter_path, agent_path,
657aec8360e716a2dd796a63f7d0d4ea535e02d2cd2Filippo Giunchedi						capabilities, device) < 0) {
658e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi			dbus_connection_unref(conn);
659e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi			exit(1);
660e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi		}
661e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi	} else {
6626db7a480cdff7ca8bbfebd3b88b832481df3166eFilippo Giunchedi		if (register_agent(conn, adapter_path, agent_path,
6630b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg							capabilities) < 0) {
664e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi			dbus_connection_unref(conn);
665e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi			exit(1);
666e3c5fd9319aa04e2d8705345a172ca2b69d8c1deFilippo Giunchedi		}
6672ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
6682ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6692ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	if (!dbus_connection_add_filter(conn, agent_filter, NULL, NULL))
6702ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		fprintf(stderr, "Can't add signal filter");
6712ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6722ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	snprintf(match_string, sizeof(match_string),
6732ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			"interface=%s,member=NameOwnerChanged,arg0=%s",
6740b0bbd589c6484ff6c06d1465e53baeca625311eJohan Hedberg			DBUS_INTERFACE_DBUS, "org.bluez");
6752ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6762ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_bus_add_match(conn, match_string, NULL);
6772ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6782ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	memset(&sa, 0, sizeof(sa));
6792ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	sa.sa_flags   = SA_NOCLDSTOP;
6802ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	sa.sa_handler = sig_term;
6812ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	sigaction(SIGTERM, &sa, NULL);
6822ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	sigaction(SIGINT,  &sa, NULL);
6832ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6842ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	while (!__io_canceled && !__io_terminated) {
6852ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann		if (dbus_connection_read_write_dispatch(conn, 500) != TRUE)
6862ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann			break;
6872ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	}
6882ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
689aec8360e716a2dd796a63f7d0d4ea535e02d2cd2Filippo Giunchedi	if (!__io_terminated && !device)
6906db7a480cdff7ca8bbfebd3b88b832481df3166eFilippo Giunchedi		unregister_agent(conn, adapter_path, agent_path);
6912ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6926db7a480cdff7ca8bbfebd3b88b832481df3166eFilippo Giunchedi	free(adapter_path);
6932ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	free(agent_path);
6942ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
69597b04507329ad5f0ddf875d9ff0b114df2c6eff9Marcel Holtmann	free(passkey_value);
6962ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6972ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	dbus_connection_unref(conn);
6982ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann
6992ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann	return 0;
7002ab16c09f43aabeaf6545d6d19ffa88c404c4abfMarcel Holtmann}
701