1/*
2 *
3 *  BlueZ - Bluetooth protocol stack for Linux
4 *
5 *  Copyright (C) 2006-2007  Nokia Corporation
6 *  Copyright (C) 2004-2009  Marcel Holtmann <marcel@holtmann.org>
7 *
8 *
9 *  This program is free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or
12 *  (at your option) any later version.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <fcntl.h>
33#include <sys/stat.h>
34#include <errno.h>
35
36#include <bluetooth/bluetooth.h>
37#include <bluetooth/hci.h>
38#include <bluetooth/hci_lib.h>
39#include <bluetooth/l2cap.h>
40#include <bluetooth/sdp.h>
41#include <bluetooth/sdp_lib.h>
42
43#include <glib.h>
44#include <dbus/dbus.h>
45#include <gdbus.h>
46
47#include "logging.h"
48#include "textfile.h"
49
50#include "hcid.h"
51#include "adapter.h"
52#include "device.h"
53#include "dbus-common.h"
54#include "dbus-hci.h"
55#include "error.h"
56#include "glib-helper.h"
57#include "agent.h"
58#include "sdp-xml.h"
59#include "storage.h"
60#include "btio.h"
61
62#define DEFAULT_XML_BUF_SIZE	1024
63#define DISCONNECT_TIMER	2
64#define DISCOVERY_TIMER		2
65
66struct btd_driver_data {
67	guint id;
68	struct btd_device_driver *driver;
69	void *priv;
70};
71
72struct btd_disconnect_data {
73	guint id;
74	disconnect_watch watch;
75	void *user_data;
76	GDestroyNotify destroy;
77};
78
79struct bonding_req {
80	DBusConnection *conn;
81	DBusMessage *msg;
82	GIOChannel *io;
83	guint io_id;
84	guint listener_id;
85	struct btd_device *device;
86};
87
88struct authentication_req {
89	auth_type_t type;
90	void *cb;
91	struct agent *agent;
92	struct btd_device *device;
93};
94
95struct browse_req {
96	DBusConnection *conn;
97	DBusMessage *msg;
98	struct btd_device *device;
99	GSList *match_uuids;
100	GSList *profiles_added;
101	GSList *profiles_removed;
102	sdp_list_t *records;
103	int search_uuid;
104	int reconnect_attempt;
105	guint listener_id;
106	guint timer;
107};
108
109struct btd_device {
110	bdaddr_t	bdaddr;
111	gchar		*path;
112	char		name[MAX_NAME_LENGTH + 1];
113	struct btd_adapter	*adapter;
114	GSList		*uuids;
115	GSList		*drivers;		/* List of driver_data */
116	GSList		*watches;		/* List of disconnect_data */
117	gboolean	temporary;
118	struct agent	*agent;
119	guint		disconn_timer;
120	guint		discov_timer;
121	struct browse_req *browse;		/* service discover request */
122	struct bonding_req *bonding;
123	struct authentication_req *authr;	/* authentication request */
124	GSList		*disconnects;		/* disconnects message */
125
126	/* For Secure Simple Pairing */
127	uint8_t		cap;
128	uint8_t		auth;
129
130	uint16_t	handle;			/* Connection handle */
131
132	/* Whether were creating a security mode 3 connection */
133	gboolean	secmode3;
134
135	sdp_list_t	*tmp_records;
136
137	gboolean	renewed_key;
138
139	gboolean	authorizing;
140	gint		ref;
141};
142
143static uint16_t uuid_list[] = {
144	L2CAP_UUID,
145	PNP_INFO_SVCLASS_ID,
146	PUBLIC_BROWSE_GROUP,
147	0
148};
149
150static GSList *device_drivers = NULL;
151
152static DBusHandlerResult error_connection_attempt_failed(DBusConnection *conn,
153						DBusMessage *msg, int err)
154{
155	return error_common_reply(conn, msg,
156			ERROR_INTERFACE ".ConnectionAttemptFailed",
157			err > 0 ? strerror(err) : "Connection attempt failed");
158}
159
160static DBusHandlerResult error_failed(DBusConnection *conn,
161					DBusMessage *msg, const char * desc)
162{
163	return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc);
164}
165
166static DBusHandlerResult error_failed_errno(DBusConnection *conn,
167						DBusMessage *msg, int err)
168{
169	const char *desc = strerror(err);
170
171	return error_failed(conn, msg, desc);
172}
173
174static inline DBusMessage *no_such_adapter(DBusMessage *msg)
175{
176	return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchAdapter",
177							"No such adapter");
178}
179
180static inline DBusMessage *in_progress(DBusMessage *msg, const char *str)
181{
182	return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", str);
183}
184
185static void browse_request_free(struct browse_req *req)
186{
187	if (req->listener_id)
188		g_dbus_remove_watch(req->conn, req->listener_id);
189	if (req->msg)
190		dbus_message_unref(req->msg);
191	if (req->conn)
192		dbus_connection_unref(req->conn);
193	g_slist_foreach(req->profiles_added, (GFunc) g_free, NULL);
194	g_slist_free(req->profiles_added);
195	g_slist_free(req->profiles_removed);
196	if (req->records)
197		sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
198	g_free(req);
199}
200
201static void browse_request_cancel(struct browse_req *req)
202{
203	struct btd_device *device = req->device;
204	struct btd_adapter *adapter = device->adapter;
205	bdaddr_t src;
206
207	if (device_is_creating(device, NULL))
208		device_set_temporary(device, TRUE);
209
210	adapter_get_address(adapter, &src);
211
212	bt_cancel_discovery(&src, &device->bdaddr);
213
214	browse_request_free(req);
215	device->browse = NULL;
216}
217
218static void device_free(gpointer user_data)
219{
220	struct btd_device *device = user_data;
221	struct btd_adapter *adapter = device->adapter;
222	struct agent *agent = adapter_get_agent(adapter);
223
224	if (device->agent)
225		agent_destroy(device->agent, FALSE);
226
227	if (agent && (agent_is_busy(agent, device) ||
228				agent_is_busy(agent, device->authr)))
229		agent_cancel(agent);
230
231	g_slist_foreach(device->uuids, (GFunc) g_free, NULL);
232	g_slist_free(device->uuids);
233
234	if (device->disconn_timer)
235		g_source_remove(device->disconn_timer);
236
237	debug("device_free(%p)", device);
238
239	g_free(device->authr);
240	g_free(device->path);
241	g_free(device);
242}
243
244gboolean device_is_paired(struct btd_device *device)
245{
246	struct btd_adapter *adapter = device->adapter;
247	char filename[PATH_MAX + 1], *str;
248	char srcaddr[18], dstaddr[18];
249	gboolean ret;
250	bdaddr_t src;
251
252	adapter_get_address(adapter, &src);
253	ba2str(&src, srcaddr);
254	ba2str(&device->bdaddr, dstaddr);
255
256	create_name(filename, PATH_MAX, STORAGEDIR,
257			srcaddr, "linkkeys");
258	str = textfile_caseget(filename, dstaddr);
259	ret = str ? TRUE : FALSE;
260	g_free(str);
261
262	return ret;
263}
264
265static DBusMessage *get_properties(DBusConnection *conn,
266				DBusMessage *msg, void *user_data)
267{
268	struct btd_device *device = user_data;
269	struct btd_adapter *adapter = device->adapter;
270	DBusMessage *reply;
271	DBusMessageIter iter;
272	DBusMessageIter dict;
273	bdaddr_t src;
274	char name[MAX_NAME_LENGTH + 1], srcaddr[18], dstaddr[18];
275	char **uuids;
276	const char *ptr;
277	dbus_bool_t boolean;
278	uint32_t class;
279	int i;
280	GSList *l;
281
282	ba2str(&device->bdaddr, dstaddr);
283
284	reply = dbus_message_new_method_return(msg);
285	if (!reply)
286		return NULL;
287
288	dbus_message_iter_init_append(reply, &iter);
289
290	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
291			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
292			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
293			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
294
295	/* Address */
296	ptr = dstaddr;
297	dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr);
298
299	/* Name */
300	ptr = NULL;
301	memset(name, 0, sizeof(name));
302	adapter_get_address(adapter, &src);
303	ba2str(&src, srcaddr);
304
305	ptr = device->name;
306	dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr);
307
308	/* Alias (fallback to name or address) */
309	if (read_device_alias(srcaddr, dstaddr, name, sizeof(name)) < 1) {
310		if (strlen(ptr) == 0) {
311			g_strdelimit(dstaddr, ":", '-');
312			ptr = dstaddr;
313		}
314	} else
315		ptr = name;
316
317	dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr);
318
319	/* Class */
320	if (read_remote_class(&src, &device->bdaddr, &class) == 0) {
321		const char *icon = class_to_icon(class);
322
323		dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class);
324
325		if (icon)
326			dict_append_entry(&dict, "Icon",
327						DBUS_TYPE_STRING, &icon);
328	}
329
330	/* Paired */
331	boolean = device_is_paired(device);
332	dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean);
333
334	/* Trusted */
335	boolean = read_trust(&src, dstaddr, GLOBAL_TRUST);
336	dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean);
337
338	/* Connected */
339	boolean = (device->handle != 0);
340	dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN,
341				&boolean);
342
343	/* UUIDs */
344	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
345	for (i = 0, l = device->uuids; l; l = l->next, i++)
346		uuids[i] = l->data;
347	dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &uuids, i);
348	g_free(uuids);
349
350	/* Adapter */
351	ptr = adapter_get_path(adapter);
352	dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr);
353
354	dbus_message_iter_close_container(&iter, &dict);
355
356	return reply;
357}
358
359static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
360					const char *alias, void *data)
361{
362	struct btd_device *device = data;
363	struct btd_adapter *adapter = device->adapter;
364	char srcaddr[18], dstaddr[18];
365	bdaddr_t src;
366	int err;
367
368	adapter_get_address(adapter, &src);
369	ba2str(&src, srcaddr);
370	ba2str(&device->bdaddr, dstaddr);
371
372	/* Remove alias if empty string */
373	err = write_device_alias(srcaddr, dstaddr,
374			g_str_equal(alias, "") ? NULL : alias);
375	if (err < 0)
376		return g_dbus_create_error(msg,
377				ERROR_INTERFACE ".Failed",
378				strerror(-err));
379
380	emit_property_changed(conn, dbus_message_get_path(msg),
381				DEVICE_INTERFACE, "Alias",
382				DBUS_TYPE_STRING, &alias);
383
384	return dbus_message_new_method_return(msg);
385}
386
387static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
388					dbus_bool_t value, void *data)
389{
390	struct btd_device *device = data;
391	struct btd_adapter *adapter = device->adapter;
392	char srcaddr[18], dstaddr[18];
393	bdaddr_t src;
394
395	adapter_get_address(adapter, &src);
396	ba2str(&src, srcaddr);
397	ba2str(&device->bdaddr, dstaddr);
398
399	write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value);
400
401	emit_property_changed(conn, dbus_message_get_path(msg),
402				DEVICE_INTERFACE, "Trusted",
403				DBUS_TYPE_BOOLEAN, &value);
404
405	return dbus_message_new_method_return(msg);
406}
407
408static inline DBusMessage *invalid_args(DBusMessage *msg)
409{
410	return g_dbus_create_error(msg,
411			ERROR_INTERFACE ".InvalidArguments",
412			"Invalid arguments in method call");
413}
414
415static DBusMessage *set_property(DBusConnection *conn,
416				DBusMessage *msg, void *data)
417{
418	DBusMessageIter iter;
419	DBusMessageIter sub;
420	const char *property;
421
422	if (!dbus_message_iter_init(msg, &iter))
423		return invalid_args(msg);
424
425	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
426		return invalid_args(msg);
427
428	dbus_message_iter_get_basic(&iter, &property);
429	dbus_message_iter_next(&iter);
430
431	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
432		return invalid_args(msg);
433	dbus_message_iter_recurse(&iter, &sub);
434
435	if (g_str_equal("Trusted", property)) {
436		dbus_bool_t value;
437
438		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
439			return invalid_args(msg);
440		dbus_message_iter_get_basic(&sub, &value);
441
442		return set_trust(conn, msg, value, data);
443	} else if (g_str_equal("Alias", property)) {
444		const char *alias;
445
446		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
447			return invalid_args(msg);
448		dbus_message_iter_get_basic(&sub, &alias);
449
450		return set_alias(conn, msg, alias, data);
451	}
452
453	return invalid_args(msg);
454}
455
456static void discover_services_req_exit(DBusConnection *conn, void *user_data)
457{
458	struct browse_req *req = user_data;
459
460	debug("DiscoverServices requestor exited");
461
462	browse_request_cancel(req);
463}
464
465static DBusMessage *discover_services(DBusConnection *conn,
466					DBusMessage *msg, void *user_data)
467{
468	struct btd_device *device = user_data;
469	const char *pattern;
470	int err;
471
472	if (device->browse)
473		return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
474						"Discover in progress");
475
476	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
477						DBUS_TYPE_INVALID) == FALSE)
478		goto fail;
479
480	if (strlen(pattern) == 0) {
481		err = device_browse(device, conn, msg, NULL, FALSE);
482		if (err < 0)
483			goto fail;
484	} else {
485		uuid_t uuid;
486
487		if (bt_string2uuid(&uuid, pattern) < 0)
488			return invalid_args(msg);
489
490		sdp_uuid128_to_uuid(&uuid);
491
492		err = device_browse(device, conn, msg, &uuid, FALSE);
493		if (err < 0)
494			goto fail;
495	}
496
497	return NULL;
498
499fail:
500	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
501					"Discovery Failed");
502}
503
504static const char *browse_request_get_requestor(struct browse_req *req)
505{
506	if (!req->msg)
507		return NULL;
508
509	return dbus_message_get_sender(req->msg);
510}
511
512static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
513							const char *record)
514{
515	DBusMessageIter entry;
516
517	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
518							NULL, &entry);
519
520	dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
521
522	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
523
524	dbus_message_iter_close_container(dict, &entry);
525}
526
527static void discover_services_reply(struct browse_req *req, int err,
528							sdp_list_t *recs)
529{
530	DBusMessage *reply;
531	DBusMessageIter iter, dict;
532	sdp_list_t *seq;
533
534	if (err) {
535		const char *err_if;
536
537		if (err == -EHOSTDOWN)
538			err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
539		else
540			err_if = ERROR_INTERFACE ".Failed";
541
542		reply = dbus_message_new_error(req->msg, err_if,
543							strerror(-err));
544		g_dbus_send_message(req->conn, reply);
545		return;
546	}
547
548	reply = dbus_message_new_method_return(req->msg);
549	if (!reply)
550		return;
551
552	dbus_message_iter_init_append(reply, &iter);
553
554	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
555			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
556			DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
557			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
558
559	for (seq = recs; seq; seq = seq->next) {
560		sdp_record_t *rec = (sdp_record_t *) seq->data;
561		GString *result;
562
563		if (!rec)
564			break;
565
566		result = g_string_new(NULL);
567
568		convert_sdp_record_to_xml(rec, result,
569				(void *) g_string_append);
570
571		if (result->len)
572			iter_append_record(&dict, rec->handle, result->str);
573
574		g_string_free(result, TRUE);
575	}
576
577	dbus_message_iter_close_container(&iter, &dict);
578
579	g_dbus_send_message(req->conn, reply);
580}
581
582static DBusMessage *cancel_discover(DBusConnection *conn,
583					DBusMessage *msg, void *user_data)
584{
585	struct btd_device *device = user_data;
586	const char *sender = dbus_message_get_sender(msg);
587	const char *requestor;
588
589	if (!device->browse)
590		return g_dbus_create_error(msg,
591				ERROR_INTERFACE ".Failed",
592				"No pending discovery");
593
594	if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
595					"DiscoverServices"))
596		return g_dbus_create_error(msg,
597				ERROR_INTERFACE ".NotAuthorized",
598				"Not Authorized");
599
600	requestor = browse_request_get_requestor(device->browse);
601
602	/* only the discover requestor can cancel the inquiry process */
603	if (!requestor || !g_str_equal(requestor, sender))
604		return g_dbus_create_error(msg,
605				ERROR_INTERFACE ".NotAuthorized",
606				"Not Authorized");
607
608	discover_services_reply(device->browse, -ECANCELED, NULL);
609
610	browse_request_cancel(device->browse);
611
612	return dbus_message_new_method_return(msg);
613}
614
615static gboolean do_disconnect(gpointer user_data)
616{
617	struct btd_device *device = user_data;
618	disconnect_cp cp;
619	int dd;
620	uint16_t dev_id = adapter_get_dev_id(device->adapter);
621
622	device->disconn_timer = 0;
623
624	dd = hci_open_dev(dev_id);
625	if (dd < 0)
626		goto fail;
627
628	memset(&cp, 0, sizeof(cp));
629	cp.handle = htobs(device->handle);
630	cp.reason = HCI_OE_USER_ENDED_CONNECTION;
631
632	hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT,
633			DISCONNECT_CP_SIZE, &cp);
634
635	close(dd);
636
637fail:
638	return FALSE;
639}
640
641static void bonding_request_cancel(struct bonding_req *bonding)
642{
643	if (!bonding->io)
644		return;
645
646	if (bonding->io_id) {
647		g_source_remove(bonding->io_id);
648		bonding->io_id = 0;
649	}
650
651	g_io_channel_shutdown(bonding->io, TRUE, NULL);
652	g_io_channel_unref(bonding->io);
653	bonding->io = NULL;
654}
655
656void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
657{
658	GSList *l;
659	DBusConnection *conn = get_dbus_connection();
660
661	if (device->bonding)
662		bonding_request_cancel(device->bonding);
663
664	if (device->browse)
665		browse_request_cancel(device->browse);
666
667	if (msg)
668		device->disconnects = g_slist_append(device->disconnects,
669						dbus_message_ref(msg));
670
671	if (device->disconn_timer)
672		return;
673
674	l = device->watches;
675	while (l) {
676		struct btd_disconnect_data *data = l->data;
677
678		l = l->next;
679
680		if (data->watch)
681			/* temporary is set if device is going to be removed */
682			data->watch(device, device->temporary,
683					data->user_data);
684	}
685
686	g_slist_foreach(device->watches, (GFunc) g_free, NULL);
687	g_slist_free(device->watches);
688	device->watches = NULL;
689
690	device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,
691						do_disconnect, device);
692
693	g_dbus_emit_signal(conn, device->path,
694			DEVICE_INTERFACE, "DisconnectRequested",
695			DBUS_TYPE_INVALID);
696}
697
698static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
699							void *user_data)
700{
701	struct btd_device *device = user_data;
702
703	if (!device->handle)
704		return g_dbus_create_error(msg,
705				ERROR_INTERFACE ".NotConnected",
706				"Device is not connected");
707
708	device_request_disconnect(device, msg);
709
710	return NULL;
711}
712
713static DBusMessage *get_service_attribute_value_reply(DBusMessage *msg, DBusConnection *conn,
714							sdp_data_t *attr)
715{
716	DBusMessage *reply;
717	DBusMessageIter iter;
718
719	reply = dbus_message_new_method_return(msg);
720	if (!reply)
721		return NULL;
722	sdp_data_t *curr;
723	sdp_list_t *ap = 0;
724	for (; attr; attr = attr->next) {
725		sdp_list_t *pds = 0;
726		for (curr = attr->val.dataseq; curr; curr = curr->next)
727			pds = sdp_list_append(pds, curr->val.dataseq);
728		ap = sdp_list_append(ap, pds);
729	}
730
731	int ch = sdp_get_proto_port(ap, RFCOMM_UUID);
732	sdp_list_foreach(ap, (sdp_list_func_t) sdp_list_free, NULL);
733	sdp_list_free(ap, NULL);
734	ap = NULL;
735
736	dbus_message_append_args(reply, DBUS_TYPE_INT32, &ch, DBUS_TYPE_INVALID);
737
738	return reply;
739}
740
741static DBusMessage *get_service_attribute_value(DBusConnection *conn,
742						DBusMessage *msg,
743						void *user_data)
744{
745	struct btd_device *device = user_data;
746	sdp_record_t *rec;
747	sdp_data_t *attr_data;
748	const char *pattern;
749	uint16_t attrId;
750	int err;
751
752	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
753					DBUS_TYPE_UINT16, &attrId,
754					DBUS_TYPE_INVALID) == FALSE)
755		goto fail;
756
757	if (strlen(pattern) == 0)
758		return invalid_args(msg);
759
760	rec = btd_device_get_record(device, pattern);
761	if (rec == NULL) {
762		error("rec is NULL");
763		goto fail;
764	}
765
766	attr_data = sdp_data_get(rec, attrId);
767
768	if (attr_data == NULL) {
769		error("attr in null");
770		goto fail;
771	}
772	return get_service_attribute_value_reply(msg, conn, attr_data);
773fail:
774	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
775					"GetServiceAttribute Failed");
776}
777
778static GDBusMethodTable device_methods[] = {
779	{ "GetProperties",	"",	"a{sv}",	get_properties	},
780	{ "SetProperty",	"sv",	"",		set_property	},
781	{ "DiscoverServices",	"s",	"a{us}",	discover_services,
782						G_DBUS_METHOD_FLAG_ASYNC},
783	{ "CancelDiscovery",	"",	"",		cancel_discover	},
784	{ "Disconnect",		"",	"",		disconnect,
785						G_DBUS_METHOD_FLAG_ASYNC},
786	{ "GetServiceAttributeValue",  "sq", "i",       get_service_attribute_value},
787	{ }
788};
789
790static GDBusSignalTable device_signals[] = {
791	{ "PropertyChanged",		"sv"	},
792	{ "DisconnectRequested",	""	},
793	{ }
794};
795
796gboolean device_is_connected(struct btd_device *device)
797{
798	return (device->handle != 0);
799}
800
801static void device_set_connected(struct btd_device *device,
802					DBusConnection *conn,
803					gboolean connected)
804{
805	emit_property_changed(conn, device->path, DEVICE_INTERFACE,
806				"Connected", DBUS_TYPE_BOOLEAN, &connected);
807
808	if (connected && device->secmode3) {
809		struct btd_adapter *adapter = device_get_adapter(device);
810		bdaddr_t sba;
811
812		adapter_get_address(adapter, &sba);
813
814		device->secmode3 = FALSE;
815
816		hcid_dbus_bonding_process_complete(&sba, &device->bdaddr, 0);
817	}
818}
819
820void device_add_connection(struct btd_device *device, DBusConnection *conn,
821				uint16_t handle)
822{
823	if (device->handle) {
824		error("%s: Unable to add connection %u, %u already exist)",
825			device->path, handle, device->handle);
826		return;
827	}
828
829	device->handle = handle;
830
831	device_set_connected(device, conn, TRUE);
832}
833
834void device_remove_connection(struct btd_device *device, DBusConnection *conn,
835				uint16_t handle)
836{
837	if (handle && device->handle != handle) {
838		error("%s: Unable to remove connection %u, handle mismatch (%u)",
839			device->path, handle, device->handle);
840		return;
841	}
842
843	device->handle = 0;
844
845	while (device->disconnects) {
846		DBusMessage *msg = device->disconnects->data;
847
848		g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
849		device->disconnects = g_slist_remove(device->disconnects, msg);
850	}
851
852	device_set_connected(device, conn, FALSE);
853}
854
855gboolean device_has_connection(struct btd_device *device, uint16_t handle)
856{
857	return (handle == device->handle);
858}
859
860uint16_t device_get_handle(struct btd_device *device)
861{
862	return device->handle;
863}
864
865guint device_add_disconnect_watch(struct btd_device *device,
866				disconnect_watch watch, void *user_data,
867				GDestroyNotify destroy)
868{
869	struct btd_disconnect_data *data;
870	static guint id = 0;
871
872	data = g_new0(struct btd_disconnect_data, 1);
873	data->id = ++id;
874	data->watch = watch;
875	data->user_data = user_data;
876	data->destroy = destroy;
877
878	device->watches = g_slist_append(device->watches, data);
879
880	return data->id;
881}
882
883void device_remove_disconnect_watch(struct btd_device *device, guint id)
884{
885	GSList *l;
886
887	for (l = device->watches; l; l = l->next) {
888		struct btd_disconnect_data *data = l->data;
889
890		if (data->id == id) {
891			device->watches = g_slist_remove(device->watches,
892							data);
893			if (data->destroy)
894				data->destroy(data->user_data);
895			g_free(data);
896			return;
897		}
898	}
899}
900
901void device_set_secmode3_conn(struct btd_device *device, gboolean enable)
902{
903	device->secmode3 = enable;
904}
905
906struct btd_device *device_create(DBusConnection *conn,
907					struct btd_adapter *adapter,
908					const gchar *address)
909{
910	gchar *address_up;
911	struct btd_device *device;
912	const gchar *adapter_path = adapter_get_path(adapter);
913	bdaddr_t src;
914	char srcaddr[18];
915
916	device = g_try_malloc0(sizeof(struct btd_device));
917	if (device == NULL)
918		return NULL;
919
920	address_up = g_ascii_strup(address, -1);
921	device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
922	g_strdelimit(device->path, ":", '_');
923	g_free(address_up);
924
925	debug("Creating device %s", device->path);
926
927	if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE,
928				device_methods, device_signals, NULL,
929				device, device_free) == FALSE) {
930		device_free(device);
931		return NULL;
932	}
933
934	str2ba(address, &device->bdaddr);
935	device->adapter = adapter;
936	adapter_get_address(adapter, &src);
937	ba2str(&src, srcaddr);
938	read_device_name(srcaddr, address, device->name);
939
940	device->auth = 0xff;
941
942	return btd_device_ref(device);
943}
944
945void device_set_name(struct btd_device *device, const char *name)
946{
947	DBusConnection *conn = get_dbus_connection();
948	char alias[MAX_NAME_LENGTH + 1];
949	char srcaddr[18], dstaddr[18];
950	bdaddr_t src;
951
952	if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
953		return;
954
955	strncpy(device->name, name, MAX_NAME_LENGTH);
956
957	emit_property_changed(conn, device->path,
958				DEVICE_INTERFACE, "Name",
959				DBUS_TYPE_STRING, &name);
960
961	adapter_get_address(device->adapter, &src);
962	ba2str(&src, srcaddr);
963	ba2str(&device->bdaddr, dstaddr);
964
965	if (read_device_alias(srcaddr, dstaddr, alias, sizeof(alias)) == 0)
966		return;
967
968	emit_property_changed(conn, device->path,
969				DEVICE_INTERFACE, "Alias",
970				DBUS_TYPE_STRING, &name);
971}
972
973static void device_remove_bonding(struct btd_device *device,
974							DBusConnection *conn)
975{
976	char filename[PATH_MAX + 1];
977	char *str, srcaddr[18], dstaddr[18];
978	int dd, dev_id;
979	bdaddr_t bdaddr;
980	gboolean paired;
981
982	adapter_get_address(device->adapter, &bdaddr);
983	ba2str(&bdaddr, srcaddr);
984	ba2str(&device->bdaddr, dstaddr);
985
986	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr,
987			"linkkeys");
988
989	/* textfile_del doesn't return an error when the key is not found */
990	str = textfile_caseget(filename, dstaddr);
991	paired = str ? TRUE : FALSE;
992	g_free(str);
993
994	if (!paired)
995		return;
996
997	dev_id = adapter_get_dev_id(device->adapter);
998
999	dd = hci_open_dev(dev_id);
1000	if (dd < 0)
1001		return;
1002
1003	/* Delete the link key from storage */
1004	textfile_casedel(filename, dstaddr);
1005
1006	/* Delete the link key from the Bluetooth chip */
1007	hci_delete_stored_link_key(dd, &device->bdaddr, 0, HCI_REQ_TIMEOUT);
1008
1009	hci_close_dev(dd);
1010
1011	paired = FALSE;
1012	emit_property_changed(conn, device->path, DEVICE_INTERFACE,
1013				"Paired", DBUS_TYPE_BOOLEAN, &paired);
1014}
1015
1016static void device_remove_stored(struct btd_device *device,
1017					DBusConnection *conn)
1018{
1019	bdaddr_t src;
1020	char addr[18];
1021
1022	adapter_get_address(device->adapter, &src);
1023	ba2str(&device->bdaddr, addr);
1024
1025	device_remove_bonding(device, conn);
1026	delete_entry(&src, "profiles", addr);
1027	delete_entry(&src, "trusts", addr);
1028	delete_all_records(&src, &device->bdaddr);
1029}
1030
1031void device_remove(struct btd_device *device, DBusConnection *conn,
1032						gboolean remove_stored)
1033{
1034	GSList *list;
1035	struct btd_device_driver *driver;
1036
1037	debug("Removing device %s", device->path);
1038
1039	if (device->bonding)
1040		device_cancel_bonding(device, HCI_OE_USER_ENDED_CONNECTION);
1041
1042	if (device->browse)
1043		browse_request_cancel(device->browse);
1044
1045	if (device->handle)
1046		do_disconnect(device);
1047
1048	if (remove_stored)
1049		device_remove_stored(device, conn);
1050
1051	for (list = device->drivers; list; list = list->next) {
1052		struct btd_driver_data *driver_data = list->data;
1053		driver = driver_data->driver;
1054
1055		driver->remove(device);
1056		g_free(driver_data);
1057	}
1058
1059	btd_device_unref(device);
1060}
1061
1062gint device_address_cmp(struct btd_device *device, const gchar *address)
1063{
1064	char addr[18];
1065
1066	ba2str(&device->bdaddr, addr);
1067	return strcasecmp(addr, address);
1068}
1069
1070static gboolean record_has_uuid(const sdp_record_t *rec,
1071				const char *profile_uuid)
1072{
1073	sdp_list_t *pat;
1074
1075	for (pat = rec->pattern; pat != NULL; pat = pat->next) {
1076		char *uuid;
1077		int ret;
1078
1079		uuid = bt_uuid2string(pat->data);
1080		if (!uuid)
1081			continue;
1082
1083		ret = strcasecmp(uuid, profile_uuid);
1084
1085		g_free(uuid);
1086
1087		if (ret == 0)
1088			return TRUE;
1089	}
1090
1091	return FALSE;
1092}
1093
1094static GSList *device_match_pattern(struct btd_device *device,
1095					const char *match_uuid,
1096					GSList *profiles)
1097{
1098	GSList *l, *uuids = NULL;
1099
1100	for (l = profiles; l; l = l->next) {
1101		char *profile_uuid = l->data;
1102		const sdp_record_t *rec;
1103
1104		rec = btd_device_get_record(device, profile_uuid);
1105		if (!rec)
1106			continue;
1107
1108		if (record_has_uuid(rec, match_uuid))
1109			uuids = g_slist_append(uuids, profile_uuid);
1110	}
1111
1112	return uuids;
1113}
1114
1115static GSList *device_match_driver(struct btd_device *device,
1116					struct btd_device_driver *driver,
1117					GSList *profiles)
1118{
1119	const char **uuid;
1120	GSList *uuids = NULL;
1121
1122	for (uuid = driver->uuids; *uuid; uuid++) {
1123		GSList *match;
1124
1125		/* skip duplicated uuids */
1126		if (g_slist_find_custom(uuids, *uuid,
1127				(GCompareFunc) strcasecmp))
1128			continue;
1129
1130		/* match profile driver */
1131		match = g_slist_find_custom(profiles, *uuid,
1132					(GCompareFunc) strcasecmp);
1133		if (match) {
1134			uuids = g_slist_append(uuids, match->data);
1135			continue;
1136		}
1137
1138		/* match pattern driver */
1139		match = device_match_pattern(device, *uuid, profiles);
1140		for (; match; match = match->next)
1141			uuids = g_slist_append(uuids, match->data);
1142	}
1143
1144	return uuids;
1145}
1146
1147void device_probe_drivers(struct btd_device *device, GSList *profiles)
1148{
1149	GSList *list;
1150	int err;
1151
1152	debug("Probe drivers for %s", device->path);
1153
1154	for (list = device_drivers; list; list = list->next) {
1155		struct btd_device_driver *driver = list->data;
1156		GSList *probe_uuids;
1157		struct btd_driver_data *driver_data;
1158
1159		probe_uuids = device_match_driver(device, driver, profiles);
1160
1161		if (!probe_uuids)
1162			continue;
1163
1164		driver_data = g_new0(struct btd_driver_data, 1);
1165
1166		err = driver->probe(device, probe_uuids);
1167		if (err < 0) {
1168			error("probe failed with driver %s for device %s",
1169					driver->name, device->path);
1170
1171			g_free(driver_data);
1172			g_slist_free(probe_uuids);
1173			continue;
1174		}
1175
1176		driver_data->driver = driver;
1177		device->drivers = g_slist_append(device->drivers, driver_data);
1178		g_slist_free(probe_uuids);
1179	}
1180
1181	for (list = profiles; list; list = list->next) {
1182		GSList *l = g_slist_find_custom(device->uuids, list->data,
1183						(GCompareFunc) strcasecmp);
1184		if (l)
1185			continue;
1186
1187		device->uuids = g_slist_insert_sorted(device->uuids,
1188						g_strdup(list->data),
1189						(GCompareFunc) strcasecmp);
1190	}
1191
1192	if (device->tmp_records) {
1193		sdp_list_free(device->tmp_records,
1194				(sdp_free_func_t) sdp_record_free);
1195		device->tmp_records = NULL;
1196	}
1197}
1198
1199static void device_remove_drivers(struct btd_device *device, GSList *uuids)
1200{
1201	struct btd_adapter *adapter = device_get_adapter(device);
1202	GSList *list, *next;
1203	char srcaddr[18], dstaddr[18];
1204	bdaddr_t src;
1205	sdp_list_t *records;
1206
1207	adapter_get_address(adapter, &src);
1208	ba2str(&src, srcaddr);
1209	ba2str(&device->bdaddr, dstaddr);
1210
1211	records = read_records(&src, &device->bdaddr);
1212
1213	debug("Remove drivers for %s", device->path);
1214
1215	for (list = device->drivers; list; list = next) {
1216		struct btd_driver_data *driver_data = list->data;
1217		struct btd_device_driver *driver = driver_data->driver;
1218		const char **uuid;
1219
1220		next = list->next;
1221
1222		for (uuid = driver->uuids; *uuid; uuid++) {
1223			if (!g_slist_find_custom(uuids, *uuid,
1224					(GCompareFunc) strcasecmp))
1225				continue;
1226
1227			debug("UUID %s was removed from device %s",
1228							*uuid, dstaddr);
1229
1230			driver->remove(device);
1231			device->drivers = g_slist_remove(device->drivers,
1232								driver_data);
1233			g_free(driver_data);
1234
1235			break;
1236		}
1237	}
1238
1239	for (list = uuids; list; list = list->next) {
1240		sdp_record_t *rec;
1241
1242		device->uuids = g_slist_remove(device->uuids, list->data);
1243
1244		rec = find_record_in_list(records, list->data);
1245		if (!rec)
1246			continue;
1247
1248		delete_record(srcaddr, dstaddr, rec->handle);
1249
1250		records = sdp_list_remove(records, rec);
1251		sdp_record_free(rec);
1252
1253	}
1254
1255	if (records)
1256		sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
1257}
1258
1259static void services_changed(struct btd_device *device)
1260{
1261	DBusConnection *conn = get_dbus_connection();
1262	char **uuids;
1263	GSList *l;
1264	int i;
1265
1266	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
1267	for (i = 0, l = device->uuids; l; l = l->next, i++)
1268		uuids[i] = l->data;
1269
1270	emit_array_property_changed(conn, device->path, DEVICE_INTERFACE,
1271					"UUIDs", DBUS_TYPE_STRING, &uuids);
1272
1273	g_free(uuids);
1274}
1275
1276static int rec_cmp(const void *a, const void *b)
1277{
1278	const sdp_record_t *r1 = a;
1279	const sdp_record_t *r2 = b;
1280
1281	return r1->handle - r2->handle;
1282}
1283
1284static void update_services(struct browse_req *req, sdp_list_t *recs)
1285{
1286	struct btd_device *device = req->device;
1287	struct btd_adapter *adapter = device_get_adapter(device);
1288	sdp_list_t *seq;
1289	char srcaddr[18], dstaddr[18];
1290	bdaddr_t src;
1291
1292	adapter_get_address(adapter, &src);
1293	ba2str(&src, srcaddr);
1294	ba2str(&device->bdaddr, dstaddr);
1295
1296	for (seq = recs; seq; seq = seq->next) {
1297		sdp_record_t *rec = (sdp_record_t *) seq->data;
1298		sdp_list_t *svcclass = NULL;
1299		gchar *profile_uuid;
1300		GSList *l;
1301
1302		if (!rec)
1303			break;
1304
1305		if (sdp_get_service_classes(rec, &svcclass) < 0)
1306			continue;
1307
1308		/* Extract the first element and skip the remainning */
1309		profile_uuid = bt_uuid2string(svcclass->data);
1310		if (!profile_uuid) {
1311			sdp_list_free(svcclass, free);
1312			continue;
1313		}
1314
1315		if (!strcasecmp(profile_uuid, PNP_UUID)) {
1316			uint16_t source, vendor, product, version;
1317			sdp_data_t *pdlist;
1318
1319			pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
1320			source = pdlist ? pdlist->val.uint16 : 0x0000;
1321
1322			pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
1323			vendor = pdlist ? pdlist->val.uint16 : 0x0000;
1324
1325			pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
1326			product = pdlist ? pdlist->val.uint16 : 0x0000;
1327
1328			pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
1329			version = pdlist ? pdlist->val.uint16 : 0x0000;
1330
1331			if (source || vendor || product || version)
1332				store_device_id(srcaddr, dstaddr, source,
1333						vendor, product, version);
1334		}
1335
1336		/* Check for duplicates */
1337		if (sdp_list_find(req->records, rec, rec_cmp)) {
1338			g_free(profile_uuid);
1339			sdp_list_free(svcclass, free);
1340			continue;
1341		}
1342
1343		store_record(srcaddr, dstaddr, rec);
1344
1345		/* Copy record */
1346		req->records = sdp_list_append(req->records,
1347							sdp_copy_record(rec));
1348
1349		l = g_slist_find_custom(device->uuids, profile_uuid,
1350							(GCompareFunc) strcmp);
1351		if (!l)
1352			req->profiles_added =
1353					g_slist_append(req->profiles_added,
1354							profile_uuid);
1355		else {
1356			req->profiles_removed =
1357					g_slist_remove(req->profiles_removed,
1358							l->data);
1359			g_free(profile_uuid);
1360		}
1361
1362		sdp_list_free(svcclass, free);
1363	}
1364}
1365
1366static void store_profiles(struct btd_device *device)
1367{
1368	struct btd_adapter *adapter = device->adapter;
1369	bdaddr_t src;
1370	char *str;
1371
1372	adapter_get_address(adapter, &src);
1373
1374	if (!device->uuids) {
1375		write_device_profiles(&src, &device->bdaddr, "");
1376		return;
1377	}
1378
1379	str = bt_list2string(device->uuids);
1380	write_device_profiles(&src, &device->bdaddr, str);
1381	g_free(str);
1382}
1383
1384static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
1385{
1386	struct browse_req *req = user_data;
1387	struct btd_device *device = req->device;
1388	DBusMessage *reply;
1389
1390	if (err < 0) {
1391		error("%s: error updating services: %s (%d)",
1392				device->path, strerror(-err), -err);
1393		goto proceed;
1394	}
1395
1396	update_services(req, recs);
1397
1398	if (device->tmp_records && req->records) {
1399		sdp_list_free(device->tmp_records,
1400					(sdp_free_func_t) sdp_record_free);
1401		device->tmp_records = req->records;
1402		req->records = NULL;
1403	}
1404
1405	if (!req->profiles_added && !req->profiles_removed) {
1406		debug("%s: No service update", device->path);
1407		goto proceed;
1408	}
1409
1410	/* Probe matching drivers for services added */
1411	if (req->profiles_added)
1412		device_probe_drivers(device, req->profiles_added);
1413
1414	/* Remove drivers for services removed */
1415	if (req->profiles_removed)
1416		device_remove_drivers(device, req->profiles_removed);
1417
1418	/* Propagate services changes */
1419	services_changed(req->device);
1420
1421proceed:
1422	/* Store the device's profiles in the filesystem */
1423	store_profiles(device);
1424
1425	if (!req->msg)
1426		goto cleanup;
1427
1428	if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
1429					"DiscoverServices")) {
1430		discover_services_reply(req, err, req->records);
1431		goto cleanup;
1432	}
1433
1434	/* Reply create device request */
1435	reply = dbus_message_new_method_return(req->msg);
1436	if (!reply)
1437		goto cleanup;
1438
1439	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
1440							DBUS_TYPE_INVALID);
1441
1442	g_dbus_send_message(req->conn, reply);
1443
1444	device_set_temporary(device, FALSE);
1445
1446cleanup:
1447	browse_request_free(req);
1448	device->browse = NULL;
1449}
1450
1451static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
1452{
1453	struct browse_req *req = user_data;
1454	struct btd_device *device = req->device;
1455	struct btd_adapter *adapter = device->adapter;
1456	bdaddr_t src;
1457	uuid_t uuid;
1458
1459	/* If we have a valid response and req->search_uuid == 2, then L2CAP
1460	 * UUID & PNP searching was successful -- we are done */
1461	if (err < 0 || (req->search_uuid == 2 && req->records)) {
1462		if (err == -ECONNRESET && req->reconnect_attempt < 1) {
1463			req->search_uuid--;
1464			req->reconnect_attempt++;
1465		} else
1466			goto done;
1467	}
1468
1469	update_services(req, recs);
1470
1471	adapter_get_address(adapter, &src);
1472
1473	/* Search for mandatory uuids */
1474	if (uuid_list[req->search_uuid]) {
1475		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
1476		bt_search_service(&src, &device->bdaddr, &uuid,
1477						browse_cb, user_data, NULL);
1478		return;
1479	}
1480
1481done:
1482	search_cb(recs, err, user_data);
1483}
1484
1485static void init_browse(struct browse_req *req, gboolean reverse)
1486{
1487	GSList *l;
1488
1489	/* If we are doing reverse-SDP don't try to detect removed profiles
1490	 * since some devices hide their service records while they are
1491	 * connected
1492	 */
1493	if (reverse)
1494		return;
1495
1496	for (l = req->device->uuids; l; l = l->next)
1497		req->profiles_removed = g_slist_append(req->profiles_removed,
1498						l->data);
1499}
1500
1501int device_browse(struct btd_device *device, DBusConnection *conn,
1502			DBusMessage *msg, uuid_t *search, gboolean reverse)
1503{
1504	struct btd_adapter *adapter = device->adapter;
1505	struct browse_req *req;
1506	bdaddr_t src;
1507	uuid_t uuid;
1508	bt_callback_t cb;
1509	int err;
1510
1511	if (device->browse)
1512		return -EBUSY;
1513
1514	adapter_get_address(adapter, &src);
1515
1516	req = g_new0(struct browse_req, 1);
1517
1518	if (conn == NULL)
1519		conn = get_dbus_connection();
1520
1521	req->conn = dbus_connection_ref(conn);
1522	req->device = device;
1523
1524	if (search) {
1525		memcpy(&uuid, search, sizeof(uuid_t));
1526		cb = search_cb;
1527	} else {
1528		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
1529		init_browse(req, reverse);
1530		cb = browse_cb;
1531	}
1532
1533	device->browse = req;
1534
1535	if (msg) {
1536		const char *sender = dbus_message_get_sender(msg);
1537
1538		req->msg = dbus_message_ref(msg);
1539		/* Track the request owner to cancel it
1540		 * automatically if the owner exits */
1541		req->listener_id = g_dbus_add_disconnect_watch(conn,
1542						sender,
1543						discover_services_req_exit,
1544						req, NULL);
1545	}
1546
1547	err = bt_search_service(&src, &device->bdaddr,
1548				&uuid, cb, req, NULL);
1549	if (err < 0) {
1550		browse_request_free(req);
1551		device->browse = NULL;
1552	}
1553
1554	return err;
1555}
1556
1557struct btd_adapter *device_get_adapter(struct btd_device *device)
1558{
1559	if (!device)
1560		return NULL;
1561
1562	return device->adapter;
1563}
1564
1565void device_get_address(struct btd_device *device, bdaddr_t *bdaddr)
1566{
1567	bacpy(bdaddr, &device->bdaddr);
1568}
1569
1570const gchar *device_get_path(struct btd_device *device)
1571{
1572	if (!device)
1573		return NULL;
1574
1575	return device->path;
1576}
1577
1578struct agent *device_get_agent(struct btd_device *device)
1579{
1580	if (!device)
1581		return NULL;
1582
1583	return  device->agent;
1584}
1585
1586void device_set_agent(struct btd_device *device, struct agent *agent)
1587{
1588	if (!device)
1589		return;
1590
1591	device->agent = agent;
1592}
1593
1594gboolean device_is_busy(struct btd_device *device)
1595{
1596	return device->browse ? TRUE : FALSE;
1597}
1598
1599gboolean device_is_temporary(struct btd_device *device)
1600{
1601	return device->temporary;
1602}
1603
1604void device_set_temporary(struct btd_device *device, gboolean temporary)
1605{
1606	if (!device)
1607		return;
1608
1609	device->temporary = temporary;
1610}
1611
1612void device_set_cap(struct btd_device *device, uint8_t cap)
1613{
1614	if (!device)
1615		return;
1616
1617	device->cap = cap;
1618}
1619
1620uint8_t device_get_cap(struct btd_device *device)
1621{
1622	return device->cap;
1623}
1624
1625void device_set_auth(struct btd_device *device, uint8_t auth)
1626{
1627	if (!device)
1628		return;
1629
1630	device->auth = auth;
1631}
1632
1633uint8_t device_get_auth(struct btd_device *device)
1634{
1635	return device->auth;
1636}
1637
1638static gboolean start_discovery(gpointer user_data)
1639{
1640	struct btd_device *device = user_data;
1641
1642	device_browse(device, NULL, NULL, NULL, TRUE);
1643
1644	device->discov_timer = 0;
1645
1646	return FALSE;
1647}
1648
1649DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
1650{
1651	switch (status) {
1652	case 0x00: /* success */
1653		return dbus_message_new_method_return(msg);
1654
1655	case 0x04: /* page timeout */
1656		return dbus_message_new_error(msg,
1657				ERROR_INTERFACE ".ConnectionAttemptFailed",
1658				"Page Timeout");
1659	case 0x08: /* connection timeout */
1660		return dbus_message_new_error(msg,
1661				ERROR_INTERFACE ".ConnectionAttemptFailed",
1662				"Connection Timeout");
1663	case 0x10: /* connection accept timeout */
1664	case 0x22: /* LMP response timeout */
1665	case 0x28: /* instant passed - is this a timeout? */
1666		return dbus_message_new_error(msg,
1667					ERROR_INTERFACE ".AuthenticationTimeout",
1668					"Authentication Timeout");
1669	case 0x17: /* too frequent pairing attempts */
1670		return dbus_message_new_error(msg,
1671					ERROR_INTERFACE ".RepeatedAttempts",
1672					"Repeated Attempts");
1673
1674	case 0x06:
1675	case 0x18: /* pairing not allowed (e.g. gw rejected attempt) */
1676		return dbus_message_new_error(msg,
1677					ERROR_INTERFACE ".AuthenticationRejected",
1678					"Authentication Rejected");
1679
1680	case 0x07: /* memory capacity */
1681	case 0x09: /* connection limit */
1682	case 0x0a: /* synchronous connection limit */
1683	case 0x0d: /* limited resources */
1684	case 0x13: /* user ended the connection */
1685	case 0x14: /* terminated due to low resources */
1686	case 0x16: /* connection terminated */
1687		return dbus_message_new_error(msg,
1688					ERROR_INTERFACE ".AuthenticationCanceled",
1689					"Authentication Canceled");
1690
1691	case 0x05: /* authentication failure */
1692	case 0x0E: /* rejected due to security reasons - is this auth failure? */
1693	case 0x25: /* encryption mode not acceptable - is this auth failure? */
1694	case 0x26: /* link key cannot be changed - is this auth failure? */
1695	case 0x29: /* pairing with unit key unsupported - is this auth failure? */
1696	case 0x2f: /* insufficient security - is this auth failure? */
1697	default:
1698		return dbus_message_new_error(msg,
1699					ERROR_INTERFACE ".AuthenticationFailed",
1700					"Authentication Failed");
1701	}
1702}
1703
1704static void bonding_request_free(struct bonding_req *bonding)
1705{
1706	struct btd_device *device;
1707
1708	if (!bonding)
1709		return;
1710
1711	if (bonding->listener_id)
1712		g_dbus_remove_watch(bonding->conn, bonding->listener_id);
1713
1714	if (bonding->msg)
1715		dbus_message_unref(bonding->msg);
1716
1717	if (bonding->conn)
1718		dbus_connection_unref(bonding->conn);
1719
1720	if (bonding->io_id)
1721		g_source_remove(bonding->io_id);
1722
1723	if (bonding->io)
1724		g_io_channel_unref(bonding->io);
1725
1726	device = bonding->device;
1727	g_free(bonding);
1728
1729	if (!device)
1730		return;
1731
1732	device->bonding = NULL;
1733
1734	if (!device->agent)
1735		return;
1736
1737	agent_destroy(device->agent, FALSE);
1738	device->agent = NULL;
1739}
1740
1741static void device_set_paired(struct btd_device *device, gboolean value)
1742{
1743	DBusConnection *conn = get_dbus_connection();
1744
1745	emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired",
1746				DBUS_TYPE_BOOLEAN, &value);
1747}
1748
1749static void device_agent_removed(struct agent *agent, void *user_data)
1750{
1751	struct btd_device *device = user_data;
1752
1753	device_set_agent(device, NULL);
1754
1755	if (device->authr)
1756		device->authr->agent = NULL;
1757}
1758
1759static struct bonding_req *bonding_request_new(DBusConnection *conn,
1760						DBusMessage *msg,
1761						struct btd_device *device,
1762						const char *agent_path,
1763						uint8_t capability)
1764{
1765	struct bonding_req *bonding;
1766	const char *name = dbus_message_get_sender(msg);
1767	struct agent *agent;
1768
1769	debug("%s: requesting bonding", device->path);
1770
1771	if (!agent_path)
1772		goto proceed;
1773
1774	agent = agent_create(device->adapter, name, agent_path,
1775					capability,
1776					device_agent_removed,
1777					device);
1778	if (!agent) {
1779		error("Unable to create a new agent");
1780		return NULL;
1781	}
1782
1783	device->agent = agent;
1784
1785	debug("Temporary agent registered for %s at %s:%s",
1786			device->path, name, agent_path);
1787
1788proceed:
1789	bonding = g_new0(struct bonding_req, 1);
1790
1791	bonding->conn = dbus_connection_ref(conn);
1792	bonding->msg = dbus_message_ref(msg);
1793
1794	return bonding;
1795}
1796
1797static gboolean bonding_io_cb(GIOChannel *io, GIOCondition cond,
1798							gpointer user_data)
1799{
1800	struct btd_device *device = user_data;
1801	DBusMessage *reply;
1802
1803	if (!device->bonding)
1804		return FALSE;
1805
1806	reply = new_authentication_return(device->bonding->msg,
1807					HCI_CONNECTION_TERMINATED);
1808	g_dbus_send_message(device->bonding->conn, reply);
1809
1810	bonding_request_free(device->bonding);
1811
1812	return FALSE;
1813}
1814
1815static void bonding_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
1816{
1817	struct btd_device *device = user_data;
1818	struct hci_request rq;
1819	auth_requested_cp cp;
1820	evt_cmd_status rp;
1821	int dd;
1822	uint16_t handle;
1823
1824	if (!device->bonding) {
1825		if (!err)
1826			g_io_channel_shutdown(io, TRUE, NULL);
1827		return;
1828	}
1829
1830	if (err) {
1831		error("%s", err->message);
1832		error_connection_attempt_failed(device->bonding->conn,
1833						device->bonding->msg,
1834						ENETDOWN);
1835		goto cleanup;
1836	}
1837
1838	if (!bt_io_get(io, BT_IO_L2RAW, &err,
1839			BT_IO_OPT_HANDLE, &handle,
1840			BT_IO_OPT_INVALID)) {
1841		error("Unable to get connection handle: %s", err->message);
1842		error_connection_attempt_failed(device->bonding->conn,
1843						device->bonding->msg,
1844						ENETDOWN);
1845		g_error_free(err);
1846		goto failed;
1847	}
1848
1849	dd = hci_open_dev(adapter_get_dev_id(device->adapter));
1850	if (dd < 0) {
1851		DBusMessage *reply = no_such_adapter(device->bonding->msg);
1852		g_dbus_send_message(device->bonding->conn, reply);
1853		goto failed;
1854	}
1855
1856	memset(&rp, 0, sizeof(rp));
1857
1858	memset(&cp, 0, sizeof(cp));
1859	cp.handle = htobs(handle);
1860
1861	memset(&rq, 0, sizeof(rq));
1862	rq.ogf    = OGF_LINK_CTL;
1863	rq.ocf    = OCF_AUTH_REQUESTED;
1864	rq.cparam = &cp;
1865	rq.clen   = AUTH_REQUESTED_CP_SIZE;
1866	rq.rparam = &rp;
1867	rq.rlen   = EVT_CMD_STATUS_SIZE;
1868	rq.event  = EVT_CMD_STATUS;
1869
1870	if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) {
1871		error("Unable to send HCI request: %s (%d)",
1872					strerror(errno), errno);
1873		error_failed_errno(device->bonding->conn, device->bonding->msg,
1874				errno);
1875		hci_close_dev(dd);
1876		goto failed;
1877	}
1878
1879	if (rp.status) {
1880		error("HCI_Authentication_Requested failed with status 0x%02x",
1881				rp.status);
1882		error_failed_errno(device->bonding->conn, device->bonding->msg,
1883				bt_error(rp.status));
1884		hci_close_dev(dd);
1885		goto failed;
1886	}
1887
1888	hci_close_dev(dd);
1889
1890	device->bonding->io_id = g_io_add_watch(io,
1891					G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1892					bonding_io_cb, device);
1893
1894	return;
1895
1896failed:
1897	g_io_channel_shutdown(io, TRUE, NULL);
1898
1899cleanup:
1900	device->bonding->io_id = 0;
1901	bonding_request_free(device->bonding);
1902}
1903
1904static void create_bond_req_exit(DBusConnection *conn, void *user_data)
1905{
1906	struct btd_device *device = user_data;
1907
1908	debug("%s: requestor exited before bonding was completed", device->path);
1909
1910	if (device->authr)
1911		device_cancel_authentication(device, FALSE);
1912
1913	if (device->bonding) {
1914		device->bonding->listener_id = 0;
1915		device_request_disconnect(device, NULL);
1916	}
1917}
1918
1919DBusMessage *device_create_bonding(struct btd_device *device,
1920					DBusConnection *conn,
1921					DBusMessage *msg,
1922					const char *agent_path,
1923					uint8_t capability)
1924{
1925	char filename[PATH_MAX + 1];
1926	char *str, srcaddr[18], dstaddr[18];
1927	struct btd_adapter *adapter = device->adapter;
1928	struct bonding_req *bonding;
1929	bdaddr_t src;
1930	GError *err = NULL;
1931	GIOChannel *io;
1932
1933	adapter_get_address(adapter, &src);
1934	ba2str(&src, srcaddr);
1935	ba2str(&device->bdaddr, dstaddr);
1936
1937	if (device->bonding)
1938		return in_progress(msg, "Bonding in progress");
1939
1940	/* check if a link key already exists */
1941	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr,
1942			"linkkeys");
1943
1944	str = textfile_caseget(filename, dstaddr);
1945	if (str) {
1946		free(str);
1947		return g_dbus_create_error(msg,
1948				ERROR_INTERFACE ".AlreadyExists",
1949				"Bonding already exists");
1950	}
1951
1952
1953	io = bt_io_connect(BT_IO_L2RAW, bonding_connect_cb, device,
1954				NULL, &err,
1955				BT_IO_OPT_SOURCE_BDADDR, &src,
1956				BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
1957				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
1958				BT_IO_OPT_INVALID);
1959	if (io == NULL) {
1960		DBusMessage *reply;
1961		reply = g_dbus_create_error(msg,
1962				ERROR_INTERFACE ".ConnectionAttemptFailed",
1963				err->message);
1964		error("bt_io_connect: %s", err->message);
1965		g_error_free(err);
1966		return reply;
1967	}
1968
1969	bonding = bonding_request_new(conn, msg, device, agent_path,
1970					capability);
1971	if (!bonding) {
1972		g_io_channel_shutdown(io, TRUE, NULL);
1973		return NULL;
1974	}
1975
1976	bonding->io = io;
1977
1978	bonding->listener_id = g_dbus_add_disconnect_watch(conn,
1979						dbus_message_get_sender(msg),
1980						create_bond_req_exit, device,
1981						NULL);
1982
1983	device->bonding = bonding;
1984	bonding->device = device;
1985
1986	return NULL;
1987}
1988
1989void device_simple_pairing_complete(struct btd_device *device, uint8_t status)
1990{
1991	struct authentication_req *auth = device->authr;
1992
1993	if (auth && auth->type == AUTH_TYPE_NOTIFY && auth->agent)
1994		agent_cancel(auth->agent);
1995}
1996
1997void device_bonding_complete(struct btd_device *device, uint8_t status)
1998{
1999	struct bonding_req *bonding = device->bonding;
2000	struct authentication_req *auth = device->authr;
2001
2002	if (auth && auth->type == AUTH_TYPE_NOTIFY && auth->agent)
2003		agent_cancel(auth->agent);
2004
2005	if (status)
2006		goto failed;
2007
2008	device->auth = 0xff;
2009
2010	g_free(device->authr);
2011	device->authr = NULL;
2012
2013	if (device->renewed_key)
2014		return;
2015
2016	device_set_temporary(device, FALSE);
2017
2018	/* If we were initiators start service discovery immediately.
2019	 * However if the other end was the initator wait a few seconds
2020	 * before SDP. This is due to potential IOP issues if the other
2021	 * end starts doing SDP at the same time as us */
2022	if (bonding) {
2023		/* If we are initiators remove any discovery timer and just
2024		 * start discovering services directly */
2025		if (device->discov_timer) {
2026			g_source_remove(device->discov_timer);
2027			device->discov_timer = 0;
2028		}
2029
2030		device_browse(device, bonding->conn, bonding->msg,
2031				NULL, FALSE);
2032
2033		bonding_request_free(bonding);
2034	} else {
2035		if (!device->browse && !device->discov_timer &&
2036				main_opts.reverse_sdp) {
2037			/* If we are not initiators and there is no currently
2038			 * active discovery or discovery timer, set discovery
2039			 * timer */
2040			debug("setting timer for reverse service discovery");
2041			device->discov_timer = g_timeout_add_seconds(
2042							DISCOVERY_TIMER,
2043							start_discovery,
2044							device);
2045		}
2046	}
2047
2048	device_set_paired(device, TRUE);
2049
2050	return;
2051
2052failed:
2053	device_cancel_bonding(device, status);
2054}
2055
2056gboolean device_is_creating(struct btd_device *device, const char *sender)
2057{
2058	DBusMessage *msg;
2059
2060	if (device->bonding && device->bonding->msg)
2061		msg = device->bonding->msg;
2062	else if (device->browse && device->browse->msg)
2063		msg = device->browse->msg;
2064	else
2065		return FALSE;
2066
2067	if (!dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
2068						"CreatePairedDevice") &&
2069			!dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
2070							"CreateDevice"))
2071		return FALSE;
2072
2073	if (sender == NULL)
2074		return TRUE;
2075
2076	return g_str_equal(sender, dbus_message_get_sender(msg));
2077}
2078
2079gboolean device_is_bonding(struct btd_device *device, const char *sender)
2080{
2081	struct bonding_req *bonding = device->bonding;
2082
2083	if (!device->bonding)
2084		return FALSE;
2085
2086	if (!sender)
2087		return TRUE;
2088
2089	return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
2090}
2091
2092void device_cancel_bonding(struct btd_device *device, uint8_t status)
2093{
2094	struct bonding_req *bonding = device->bonding;
2095	DBusMessage *reply;
2096
2097	if (!bonding)
2098		return;
2099
2100	debug("%s: canceling bonding request", device->path);
2101
2102	if (device->authr)
2103		device_cancel_authentication(device, FALSE);
2104
2105	reply = new_authentication_return(bonding->msg, status);
2106	g_dbus_send_message(bonding->conn, reply);
2107
2108	bonding_request_cancel(bonding);
2109	bonding_request_free(bonding);
2110}
2111
2112static void pincode_cb(struct agent *agent, DBusError *err, const char *pincode,
2113			void *data)
2114{
2115	struct authentication_req *auth = data;
2116	struct btd_device *device = auth->device;
2117
2118	/* No need to reply anything if the authentication already failed */
2119	if (!auth->cb)
2120		return;
2121
2122	((agent_pincode_cb) auth->cb)(agent, err, pincode, device);
2123
2124	auth->cb = NULL;
2125}
2126
2127static void confirm_cb(struct agent *agent, DBusError *err, void *data)
2128{
2129	struct authentication_req *auth = data;
2130	struct btd_device *device = auth->device;
2131
2132	/* No need to reply anything if the authentication already failed */
2133	if (!auth->cb)
2134		return;
2135
2136	((agent_cb) auth->cb)(agent, err, device);
2137
2138	auth->cb = NULL;
2139}
2140
2141static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
2142			void *data)
2143{
2144	struct authentication_req *auth = data;
2145	struct btd_device *device = auth->device;
2146
2147	/* No need to reply anything if the authentication already failed */
2148	if (!auth->cb)
2149		return;
2150
2151	((agent_passkey_cb) auth->cb)(agent, err, passkey, device);
2152
2153	auth->cb = NULL;
2154}
2155
2156static void pairing_consent_cb(struct agent *agent, DBusError *err, void *data)
2157{
2158	struct authentication_req *auth = data;
2159	struct btd_device *device = auth->device;
2160
2161	/* No need to reply anything if the authentication already failed */
2162	if (!auth->cb)
2163		return;
2164
2165	((agent_cb) auth->cb)(agent, err, device);
2166
2167	auth->cb = NULL;
2168}
2169
2170int device_request_authentication(struct btd_device *device, auth_type_t type,
2171				uint32_t passkey, void *cb)
2172{
2173	struct authentication_req *auth;
2174	struct agent *agent;
2175	int ret;
2176
2177	debug("%s: requesting agent authentication", device->path);
2178
2179	agent = device->agent;
2180
2181	if (!agent)
2182		agent = adapter_get_agent(device->adapter);
2183
2184	if (!agent) {
2185		error("No agent available for %u request", type);
2186		return -EPERM;
2187	}
2188
2189	auth = g_new0(struct authentication_req, 1);
2190	auth->agent = agent;
2191	auth->device = device;
2192	auth->cb = cb;
2193	auth->type = type;
2194	device->authr = auth;
2195
2196	switch (type) {
2197	case AUTH_TYPE_PINCODE:
2198		ret = agent_request_pincode(agent, device, pincode_cb,
2199								auth, NULL);
2200		break;
2201	case AUTH_TYPE_PASSKEY:
2202		ret = agent_request_passkey(agent, device, passkey_cb,
2203								auth, NULL);
2204		break;
2205	case AUTH_TYPE_CONFIRM:
2206		ret = agent_request_confirmation(agent, device, passkey,
2207						confirm_cb, auth, NULL);
2208		break;
2209	case AUTH_TYPE_NOTIFY:
2210		ret = agent_display_passkey(agent, device, passkey);
2211		break;
2212	case AUTH_TYPE_AUTO:
2213		ret = 0;
2214		break;
2215	case AUTH_TYPE_PAIRING_CONSENT:
2216		ret = agent_request_pairing_consent(agent, device,
2217							pairing_consent_cb, auth, NULL);
2218		break;
2219	default:
2220		ret = -EINVAL;
2221	}
2222
2223	if (ret < 0) {
2224		error("Failed requesting authentication");
2225		g_free(auth);
2226		device->authr = NULL;
2227	}
2228
2229	return ret;
2230}
2231
2232static void cancel_authentication(struct authentication_req *auth)
2233{
2234	struct btd_device *device = auth->device;
2235	struct agent *agent = auth->agent;
2236	DBusError err;
2237
2238	if (!auth->cb)
2239		return;
2240
2241	dbus_error_init(&err);
2242	dbus_set_error_const(&err, "org.bluez.Error.Canceled", NULL);
2243
2244	switch (auth->type) {
2245	case AUTH_TYPE_PINCODE:
2246		((agent_pincode_cb) auth->cb)(agent, &err, NULL, device);
2247		break;
2248	case AUTH_TYPE_CONFIRM:
2249		((agent_cb) auth->cb)(agent, &err, device);
2250		break;
2251	case AUTH_TYPE_PASSKEY:
2252		((agent_passkey_cb) auth->cb)(agent, &err, 0, device);
2253		break;
2254	case AUTH_TYPE_PAIRING_CONSENT:
2255		((agent_cb) auth->cb) (agent, &err, device);
2256		break;
2257	case AUTH_TYPE_NOTIFY:
2258	case AUTH_TYPE_AUTO:
2259		/* User Notify/Auto doesn't require any reply */
2260		break;
2261	}
2262
2263	dbus_error_free(&err);
2264	auth->cb = NULL;
2265}
2266
2267void device_cancel_authentication(struct btd_device *device, gboolean aborted)
2268{
2269	struct authentication_req *auth = device->authr;
2270
2271	if (!auth)
2272		return;
2273
2274	debug("%s: canceling authentication request", device->path);
2275
2276	if (auth->agent)
2277		agent_cancel(auth->agent);
2278
2279	if (!aborted)
2280		cancel_authentication(auth);
2281
2282	device->authr = NULL;
2283	g_free(auth);
2284}
2285
2286gboolean device_is_authenticating(struct btd_device *device)
2287{
2288	return (device->authr != NULL);
2289}
2290
2291gboolean device_is_authorizing(struct btd_device *device)
2292{
2293	return device->authorizing;
2294}
2295
2296void device_set_authorizing(struct btd_device *device, gboolean auth)
2297{
2298	device->authorizing = auth;
2299}
2300
2301void device_set_renewed_key(struct btd_device *device, gboolean renewed)
2302{
2303	device->renewed_key = renewed;
2304}
2305
2306void btd_device_add_uuid(struct btd_device *device, const char *uuid)
2307{
2308	GSList *uuid_list;
2309	char *new_uuid;
2310
2311	if (g_slist_find_custom(device->uuids, uuid,
2312				(GCompareFunc) strcasecmp))
2313		return;
2314
2315	new_uuid = g_strdup(uuid);
2316	uuid_list = g_slist_append(NULL, new_uuid);
2317
2318	device_probe_drivers(device, uuid_list);
2319
2320	g_free(new_uuid);
2321	g_slist_free(uuid_list);
2322
2323	store_profiles(device);
2324	services_changed(device);
2325}
2326
2327const sdp_record_t *btd_device_get_record(struct btd_device *device,
2328						const char *uuid)
2329{
2330	bdaddr_t src;
2331
2332	if (device->tmp_records)
2333		return find_record_in_list(device->tmp_records, uuid);
2334
2335	adapter_get_address(device->adapter, &src);
2336
2337	device->tmp_records = read_records(&src, &device->bdaddr);
2338	if (!device->tmp_records)
2339		return NULL;
2340
2341	return find_record_in_list(device->tmp_records, uuid);
2342}
2343
2344int btd_register_device_driver(struct btd_device_driver *driver)
2345{
2346	device_drivers = g_slist_append(device_drivers, driver);
2347
2348	return 0;
2349}
2350
2351void btd_unregister_device_driver(struct btd_device_driver *driver)
2352{
2353	device_drivers = g_slist_remove(device_drivers, driver);
2354}
2355
2356struct btd_device *btd_device_ref(struct btd_device *device)
2357{
2358	device->ref++;
2359
2360	debug("btd_device_ref(%p): ref=%d", device, device->ref);
2361
2362	return device;
2363}
2364
2365void btd_device_unref(struct btd_device *device)
2366{
2367	DBusConnection *conn = get_dbus_connection();
2368	gchar *path;
2369
2370	device->ref--;
2371
2372	debug("btd_device_unref(%p): ref=%d", device, device->ref);
2373
2374	if (device->ref > 0)
2375		return;
2376
2377	path = g_strdup(device->path);
2378
2379	g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE);
2380
2381	g_free(path);
2382}
2383