device.c revision a4145c63530b4c3575b7da5f117c0df352f939fc
1dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann/*
2dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *
3dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  BlueZ - Bluetooth protocol stack for Linux
4dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *
5f1659f19cfb3ef0c0c09b5f5b7e2b06d90d079abMarcel Holtmann *  Copyright (C) 2006-2007  Nokia Corporation
6e823c15e43a6f924779e466d434c51157002d9eeMarcel Holtmann *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
7dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *
8dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *
9dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  This program is free software; you can redistribute it and/or modify
10dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  it under the terms of the GNU General Public License as published by
11dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  the Free Software Foundation; either version 2 of the License, or
12dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  (at your option) any later version.
13dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *
14dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  This program is distributed in the hope that it will be useful,
15dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  GNU General Public License for more details.
18dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *
19dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  You should have received a copy of the GNU General Public License
20dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  along with this program; if not, write to the Free Software
21dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann *
23dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann */
24dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
25dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#ifdef HAVE_CONFIG_H
26dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <config.h>
27dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#endif
28dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
29dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <stdio.h>
30dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <stdlib.h>
315d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi#include <unistd.h>
326a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include <sys/stat.h>
331af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg#include <errno.h>
34dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
35dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/bluetooth.h>
36dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci.h>
37dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci_lib.h>
385d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp.h>
395d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp_lib.h>
40dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
4186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <glib.h>
4286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <dbus/dbus.h>
4315ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#include <gdbus.h>
4486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
4586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "logging.h"
466a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include "textfile.h"
47dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
48506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "hcid.h"
492c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#include "adapter.h"
5086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "device.h"
51da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi#include "dbus-common.h"
524e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz#include "dbus-hci.h"
537fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz#include "error.h"
543d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz#include "glib-helper.h"
55fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite#include "agent.h"
563d3cdef8da6b3e1b14c3cdccda8c099cbad4f3aeMarcel Holtmann#include "sdp-xml.h"
57506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "storage.h"
5886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
59c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz#define DEFAULT_XML_BUF_SIZE	1024
605d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi#define DISCONNECT_TIMER	2
61013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg#define DISCOVERY_TIMER		2000
62dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
63e3afaa0b7ff373d89fd3fa257110a34df7495df7Luiz Augusto von Dentzstruct btd_driver_data {
64b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode	struct btd_device_driver *driver;
65b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode	void *priv;
66b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode};
67b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
68555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct btd_device {
69cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t	bdaddr;
70ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	gchar		*path;
7118614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter	*adapter;
72ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	GSList		*uuids;
73b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode	GSList		*drivers;		/* List of driver_data */
74ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	gboolean	temporary;
75ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	struct agent	*agent;
76ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	guint		disconn_timer;
77ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	int		discov_active;		/* Service discovery active */
78ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	char		*discov_requestor;	/* discovery requestor unique name */
79ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	guint		discov_listener;
80013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg	guint		discov_timer;
81ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode
82ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	/* For Secure Simple Pairing */
83ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	uint8_t		cap;
84ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	uint8_t		auth;
85e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
86e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg	gboolean	connected;
87e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
88e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg	/* Whether were creating a security mode 3 connection */
89e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg	gboolean	secmode3;
90ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode};
91ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode
923d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentzstruct browse_req {
933d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	DBusConnection *conn;
943d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	DBusMessage *msg;
95555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device;
9658d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz	GSList *uuids;
9736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	GSList *uuids_added;
9836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	GSList *uuids_removed;
99681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz	sdp_list_t *records;
100d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	int search_uuid;
1013d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz};
1023d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
103d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmannstatic uint16_t uuid_list[] = {
104d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	PUBLIC_BROWSE_GROUP,
1051c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz	PNP_INFO_SVCLASS_ID,
106f22b20c3d40bd7571944af6a4946f756dc39f812Marcel Holtmann	HID_SVCLASS_ID,
107d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	GENERIC_AUDIO_SVCLASS_ID,
108d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	ADVANCED_AUDIO_SVCLASS_ID,
109d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	AV_REMOTE_SVCLASS_ID,
1101c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz	PANU_SVCLASS_ID,
1111c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz	GN_SVCLASS_ID,
1121c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz	NAP_SVCLASS_ID,
1131c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz	SERIAL_PORT_SVCLASS_ID,
114d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	0
115d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann};
116d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann
117c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzstatic GSList *device_drivers = NULL;
118c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz
119e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic void device_free(gpointer user_data)
12086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{
121555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
1222f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz	struct btd_adapter *adapter = device->adapter;
1232f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz	struct agent *agent = adapter_get_agent(adapter);
124e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi
125fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite	if (device->agent)
126fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite		agent_destroy(device->agent, FALSE);
127f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann
1282f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz	if (agent && agent_is_busy(agent, device))
1292f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz		agent_cancel(agent);
1302f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz
131ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi	g_slist_foreach(device->uuids, (GFunc) g_free, NULL);
132ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi	g_slist_free(device->uuids);
133f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann
1345d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	if (device->disconn_timer)
1355d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi		g_source_remove(device->disconn_timer);
1365d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
137401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz	if (device->discov_timer)
138401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz		g_source_remove(device->discov_timer);
139401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz
14086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	g_free(device->path);
14186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	g_free(device);
14286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann}
14386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
144555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic gboolean device_is_paired(struct btd_device *device)
145769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{
14618614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device->adapter;
147cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	char filename[PATH_MAX + 1], *str;
148cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	char srcaddr[18], dstaddr[18];
149769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	gboolean ret;
150cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t src;
1512a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
152cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	adapter_get_address(adapter, &src);
153cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&src, srcaddr);
154cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&device->bdaddr, dstaddr);
155769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
156769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	create_name(filename, PATH_MAX, STORAGEDIR,
157cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode			srcaddr, "linkkeys");
158cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	str = textfile_caseget(filename, dstaddr);
159769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	ret = str ? TRUE : FALSE;
160769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	g_free(str);
161769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
162769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	return ret;
163769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz}
164769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
165e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *get_properties(DBusConnection *conn,
166e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				DBusMessage *msg, void *user_data)
1672c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{
168555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
16918614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device->adapter;
1704e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	DBusMessage *reply;
1714e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	DBusMessageIter iter;
1724e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	DBusMessageIter dict;
173cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t src;
174cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	char name[248], srcaddr[18], dstaddr[18];
1758a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi	char **uuids;
1762a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	const char *ptr;
1774e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_bool_t boolean;
1784e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	uint32_t class;
179769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	int i;
180769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	GSList *l;
181bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode	struct active_conn_info *dev;
1824e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
183cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&device->bdaddr, dstaddr);
184cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode
1854e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	reply = dbus_message_new_method_return(msg);
1864e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	if (!reply)
187e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return NULL;
1884e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
1894e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_init_append(reply, &iter);
1904e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
1914e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1924e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1934e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
1944e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
1954e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
1964e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Address */
197cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ptr = dstaddr;
198afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann	dbus_message_iter_append_dict_entry(&dict, "Address",
199afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann						DBUS_TYPE_STRING, &ptr);
2004e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2014e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Name */
202506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi	ptr = NULL;
203506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi	memset(name, 0, sizeof(name));
2042a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	adapter_get_address(adapter, &src);
205cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&src, srcaddr);
2068a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi
207cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	if (read_device_name(srcaddr, dstaddr, name) == 0) {
208506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi		ptr = name;
2094e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Name",
210e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann						DBUS_TYPE_STRING, &ptr);
2114e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	}
2124e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
213afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann	/* Alias (fallback to name or address) */
214afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann	if (read_device_alias(srcaddr, dstaddr, name, sizeof(name)) < 1) {
215afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann		if (!ptr) {
216afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann			g_strdelimit(dstaddr, ":", '-');
217afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann			ptr = dstaddr;
218afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann		}
219afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann	} else
220506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi		ptr = name;
221506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi
222506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi	if (ptr)
223506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi		dbus_message_iter_append_dict_entry(&dict, "Alias",
224e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann						DBUS_TYPE_STRING, &ptr);
225506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi
2264e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Class */
227cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	if (read_remote_class(&src, &device->bdaddr, &class) == 0) {
228e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann		const char *icon = class_to_icon(class);
229e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann
2304e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Class",
231e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann						DBUS_TYPE_UINT32, &class);
232e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann
233e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann		if (icon)
234e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann			dbus_message_iter_append_dict_entry(&dict, "Icon",
235e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann						DBUS_TYPE_STRING, &icon);
2364e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	}
2374e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2384e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Paired */
239769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	boolean = device_is_paired(device);
2404e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Paired",
241e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann						DBUS_TYPE_BOOLEAN, &boolean);
2424e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2434e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Trusted */
244cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	boolean = read_trust(&src, dstaddr, GLOBAL_TRUST);
2454e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Trusted",
246e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann						DBUS_TYPE_BOOLEAN, &boolean);
2474e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2484e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Connected */
249cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	dev = adapter_search_active_conn_by_bdaddr(adapter, &device->bdaddr);
250bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode	if (dev)
2514e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		boolean = TRUE;
2524e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	else
2534e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		boolean = FALSE;
2544e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2554e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Connected",
256e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann						DBUS_TYPE_BOOLEAN, &boolean);
2574e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
258ba93fb91ea81a35be0834ac395650e020a6b3fd3Claudio Takahasi	/* UUIDs */
259769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
260769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	for (i = 0, l = device->uuids; l; l = l->next, i++)
261769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz		uuids[i] = l->data;
2628afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "UUIDs",
263e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann						DBUS_TYPE_ARRAY, &uuids);
264769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	g_free(uuids);
2654e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
26674fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz	/* Adapter */
2678a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi	ptr = adapter_get_path(adapter);
26874fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Adapter",
269e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann						DBUS_TYPE_OBJECT_PATH, &ptr);
27074fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz
2714e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_close_container(&iter, &dict);
2724e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
273e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return reply;
2742c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}
2752c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
276e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
2777fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					const char *alias, void *data)
2787fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{
279555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = data;
28018614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device->adapter;
281cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	char srcaddr[18], dstaddr[18];
282cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t src;
283506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi	int err;
2847fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
285cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	adapter_get_address(adapter, &src);
286cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&src, srcaddr);
287cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&device->bdaddr, dstaddr);
2882a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
289cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	/* Remove alias if empty string */
290cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	err = write_device_alias(srcaddr, dstaddr,
291506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi			g_str_equal(alias, "") ? NULL : alias);
292506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi	if (err < 0)
293e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return g_dbus_create_error(msg,
294e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				ERROR_INTERFACE ".Failed",
295506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi				strerror(-err));
2967fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
2977fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg),
2987fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					DEVICE_INTERFACE, "Alias",
299506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi					DBUS_TYPE_STRING, &alias);
3007fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
301e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return dbus_message_new_method_return(msg);
3027fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz}
3037fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
304e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
3057fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					dbus_bool_t value, void *data)
3067fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{
307555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = data;
30818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device->adapter;
309cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	char srcaddr[18], dstaddr[18];
310cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t src;
3112a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
3127fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
313cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	adapter_get_address(adapter, &src);
314cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&src, srcaddr);
315cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&device->bdaddr, dstaddr);
3162a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
317cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value);
3187fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3197fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg),
3207fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					DEVICE_INTERFACE, "Trusted",
3217fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					DBUS_TYPE_BOOLEAN, &value);
3227fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
323e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return dbus_message_new_method_return(msg);
3247fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz}
3257fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
326e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic inline DBusMessage *invalid_args(DBusMessage *msg)
327e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi{
328e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return g_dbus_create_error(msg,
329e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			ERROR_INTERFACE ".InvalidArguments",
330e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			"Invalid arguments in method call");
331e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi}
332e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi
333e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_property(DBusConnection *conn,
334e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				DBusMessage *msg, void *data)
3352c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{
3367fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	DBusMessageIter iter;
3377fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	DBusMessageIter sub;
3387fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	const char *property;
3397fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3407fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (!dbus_message_iter_init(msg, &iter))
341e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return invalid_args(msg);
3427fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3437fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
344e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return invalid_args(msg);
3457fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3467fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
3477fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
3487fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3497fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
350e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return invalid_args(msg);
3517fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
3527fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3537fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (g_str_equal("Trusted", property)) {
3547fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		dbus_bool_t value;
3557fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3567fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
357e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			return invalid_args(msg);
3587fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &value);
3597fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3607fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		return set_trust(conn, msg, value, data);
3617fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	} else if (g_str_equal("Alias", property)) {
362506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi		const char *alias;
3637fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3647fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
365e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			return invalid_args(msg);
3667fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &alias);
3677fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3687fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		return set_alias(conn, msg, alias, data);
3697fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	}
3707fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
371e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return invalid_args(msg);
3722c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}
3732c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
374342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzstatic void discover_services_req_exit(void *user_data)
375342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz{
376555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
37718614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device->adapter;
378cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t src;
3792a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
3802a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	adapter_get_address(adapter, &src);
381342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
382342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	debug("DiscoverDevices requestor exited");
383342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
384cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bt_cancel_discovery(&src, &device->bdaddr);
385342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz}
386342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
38794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *discover_services(DBusConnection *conn,
38894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann					DBusMessage *msg, void *user_data)
38994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{
390555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
39194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	const char *pattern;
392342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	int err;
393342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
394342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	if (device->discov_active)
395342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
396342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz							"Discover in progress");
39794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
39894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
39994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann						DBUS_TYPE_INVALID) == FALSE)
400342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		goto fail;
40194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
402a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	if (strlen(pattern) == 0) {
403040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		err = device_browse(device, conn, msg, NULL);
404342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		if (err < 0)
405342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz			goto fail;
406342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	} else {
407040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		uuid_t uuid;
408040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi
409040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		if (bt_string2uuid(&uuid, pattern) < 0)
410342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz			return invalid_args(msg);
411a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann
412040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		err = device_browse(device, conn, msg, &uuid);
413342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		if (err < 0)
414342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz			goto fail;
415342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	}
41694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
41794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	return NULL;
418342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
419342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzfail:
420342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
421342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz					"Discovery Failed");
42294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann}
42394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
42494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *cancel_discover(DBusConnection *conn,
42594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann					DBusMessage *msg, void *user_data)
42694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{
427555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
42818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device->adapter;
429cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t src;
4302a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
4312a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	adapter_get_address(adapter, &src);
43219b4c8b0e51a20a1b95ede34b092ebc56e1183aeMarcel Holtmann
433342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	if (!device->discov_active)
434342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		return g_dbus_create_error(msg,
435342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz				ERROR_INTERFACE ".Failed",
436342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz				"No pending discovery");
437342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
438342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	/* only the discover requestor can cancel the inquiry process */
439342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	if (!device->discov_requestor ||
440342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz			strcmp(device->discov_requestor, dbus_message_get_sender(msg)))
441342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		return g_dbus_create_error(msg,
442342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz				ERROR_INTERFACE ".NotAuthorized",
443342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz				"Not Authorized");
444342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
445cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	if (bt_cancel_discovery(&src, &device->bdaddr) < 0)
446289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz		return g_dbus_create_error(msg,
447289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz				ERROR_INTERFACE ".Failed",
448289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz				"No pending discover");
44994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
45094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	return dbus_message_new_method_return(msg);
45194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann}
45294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
4535d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasistatic gboolean disconnect_timeout(gpointer user_data)
4545d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi{
455555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
4565d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	struct active_conn_info *ci;
4575d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	disconnect_cp cp;
4585d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	int dd;
459661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode	uint16_t dev_id = adapter_get_dev_id(device->adapter);
4605d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4615d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	device->disconn_timer = 0;
4625d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
463cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ci = adapter_search_active_conn_by_bdaddr(device->adapter,
464cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode							&device->bdaddr);
465bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode
466bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode	if (!ci)
4675d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi		return FALSE;
4685d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
469661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode	dd = hci_open_dev(dev_id);
4705d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	if (dd < 0)
4715d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi		goto fail;
4725d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4735d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	memset(&cp, 0, sizeof(cp));
4745d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	cp.handle = htobs(ci->handle);
4755d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	cp.reason = HCI_OE_USER_ENDED_CONNECTION;
4765d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4775d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT,
4785d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi			DISCONNECT_CP_SIZE, &cp);
4795d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4805d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	close(dd);
4815d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4825d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasifail:
4835d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	return FALSE;
4845d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi}
4855d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
48694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *disconnect(DBusConnection *conn,
48794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann					DBusMessage *msg, void *user_data)
48894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{
489555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
490bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode	struct active_conn_info *dev;
4915d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
492cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	dev = adapter_search_active_conn_by_bdaddr(device->adapter,
493cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode							&device->bdaddr);
494bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode
495bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode	if (!dev)
4965d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi		return g_dbus_create_error(msg,
4975d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi				ERROR_INTERFACE ".NotConnected",
4985d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi				"Device is not connected");
4995d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
5005d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	g_dbus_emit_signal(conn, device->path,
5015d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi			DEVICE_INTERFACE, "DisconnectRequested",
5025d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi			DBUS_TYPE_INVALID);
5035d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
5045d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,
5055d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi						disconnect_timeout, device);
50694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
50794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	return dbus_message_new_method_return(msg);
50894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann}
50994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
510e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusMethodTable device_methods[] = {
511e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	{ "GetProperties",	"",	"a{sv}",	get_properties	},
512e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	{ "SetProperty",	"sv",	"",		set_property	},
513e0d13d6da4b527ee02838af6b9dd7d53615e4896Marcel Holtmann	{ "DiscoverServices",	"s",	"a{us}",	discover_services,
51494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann						G_DBUS_METHOD_FLAG_ASYNC},
51594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ "CancelDiscovery",	"",	"",		cancel_discover	},
516e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	{ "Disconnect",		"",	"",		disconnect	},
51794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ }
5182c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes};
5192c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
520e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusSignalTable device_signals[] = {
52194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ "PropertyChanged",		"sv"	},
52294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ "DisconnectRequested",	""	},
52394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ }
5242c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes};
5252c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
526e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberggboolean device_get_connected(struct btd_device *device)
527e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg{
528e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg	return device->connected;
529e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg}
530e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
531013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedbergvoid device_set_connected(DBusConnection *conn, struct btd_device *device,
532013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg			gboolean connected)
533013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{
534e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg	device->connected = connected;
535e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
536013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg	if (!connected && device->discov_timer) {
537013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg		g_source_remove(device->discov_timer);
538013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg		device->discov_timer = 0;
539013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg	}
540013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg
541013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg	dbus_connection_emit_property_changed(conn, device->path,
542013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg						DEVICE_INTERFACE,
543013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg						"Connected", DBUS_TYPE_BOOLEAN,
544013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg						&connected);
545e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
546e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg	if (connected && device->secmode3) {
547e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg		struct btd_adapter *adapter = device_get_adapter(device);
548e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg		bdaddr_t sba;
549e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
550e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg		adapter_get_address(adapter, &sba);
551e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
552e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg		device->secmode3 = FALSE;
553e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
554e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg		hcid_dbus_bonding_process_complete(&sba, &device->bdaddr, 0);
555e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg	}
556e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg}
557e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
558e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedbergvoid device_set_secmode3_conn(struct btd_device *device, gboolean enable)
559e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg{
560e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg	device->secmode3 = enable;
561013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg}
562013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg
56318614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter,
56436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz					const gchar *address)
56586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{
566ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite	gchar *address_up;
567555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device;
568661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode	uint16_t dev_id = adapter_get_dev_id(adapter);
56986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
570555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	device = g_try_malloc0(sizeof(struct btd_device));
57186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	if (device == NULL)
57286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann		return NULL;
57386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
574ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite	address_up = g_ascii_strup(address, -1);
57593fbf4400a81f68cd3642084bd6d2aa51a173250Marcel Holtmann	device->path = g_strdup_printf("%s/hci%d/dev_%s", "/org/bluez",
57693fbf4400a81f68cd3642084bd6d2aa51a173250Marcel Holtmann							dev_id, address_up);
57786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	g_strdelimit(device->path, ":", '_');
578ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite	g_free(address_up);
57986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
58086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	debug("Creating device %s", device->path);
58186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
582e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE,
583e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				device_methods, device_signals, NULL,
584e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				device, device_free) == FALSE) {
58586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann		device_free(device);
58686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann		return NULL;
58786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	}
588da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi
589cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	str2ba(address, &device->bdaddr);
590da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi	device->adapter = adapter;
591da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi
5926bfa88d706cc57a0c975c980dabec5d8ed67dcc0Claudio Takahasi	return device;
59386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann}
59486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
595555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_remove(DBusConnection *conn, struct btd_device *device)
59675add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi{
5976061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	GSList *list;
5986061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	struct btd_device_driver *driver;
599f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann	gchar *path = g_strdup(device->path);
600f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann
601f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann	debug("Removing device %s", path);
602f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann
6036061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	for (list = device->drivers; list; list = list->next) {
604b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		struct btd_driver_data *driver_data = list->data;
605b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		driver = driver_data->driver;
6066061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann
607e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz		driver->remove(device);
608b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		g_free(driver_data);
6096061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	}
6106061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann
611f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann	g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE);
61275add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi
613f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann	g_free(path);
61486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann}
615ff296428a08dee619db1cc702146faefa91087faCidorvan Leite
616555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegint device_address_cmp(struct btd_device *device, const gchar *address)
617ff296428a08dee619db1cc702146faefa91087faCidorvan Leite{
618cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	char addr[18];
619cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode
620cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&device->bdaddr, addr);
621cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	return strcasecmp(addr, address);
622ff296428a08dee619db1cc702146faefa91087faCidorvan Leite}
6233d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
6244b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsodevoid device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs)
625f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann{
626c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz	GSList *list;
6276061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	const char **uuid;
628f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann	int err;
629f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
630f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann	debug("Probe drivers for %s", device->path);
631f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
632c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz	for (list = device_drivers; list; list = list->next) {
633e0863545e6239ac338fa7fbe9647a5748a60b436Marcel Holtmann		struct btd_device_driver *driver = list->data;
6344b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		GSList *records = NULL;
635f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
6366061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann		for (uuid = driver->uuids; *uuid; uuid++) {
637081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz			sdp_record_t *rec;
6384b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode
639081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz			if (!g_slist_find_custom(uuids, *uuid,
640081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz					(GCompareFunc) strcasecmp))
641081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz				continue;
642081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz
64360af857dbc8a258eb91ef3fb6de06c17c8fb4ec2David Woodhouse			rec = find_record_in_list(recs, *uuid);
644081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz			if (!rec)
645081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz				continue;
646081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz
647081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz			records = g_slist_append(records, rec);
648f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann		}
649f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
6504b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		if (records) {
651b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode			struct btd_driver_data *driver_data = g_new0(struct btd_driver_data, 1);
652b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
653e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz			err = driver->probe(device, records);
654fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann			if (err < 0) {
655f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann				error("probe failed for driver %s",
656f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann							driver->name);
657b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
658b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode				g_free(driver_data);
659fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann				continue;
660fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann			}
661fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann
662b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode			driver_data->driver = driver;
663fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann			device->drivers = g_slist_append(device->drivers,
664b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode								driver_data);
665f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann		}
666f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann	}
66736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
668c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann	for (list = uuids; list; list = list->next) {
669c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann		GSList *l = g_slist_find_custom(device->uuids, list->data,
670c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann							(GCompareFunc) strcmp);
671c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann		if (l)
672c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann			continue;
673c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann
67436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		device->uuids = g_slist_insert_sorted(device->uuids,
675c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann					list->data, (GCompareFunc) strcmp);
676c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann	}
67736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz}
67836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
6794b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsodevoid device_remove_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs)
68036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{
68118614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device_get_adapter(device);
682352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg	GSList *list, *next;
683cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	char srcaddr[18], dstaddr[18];
6842a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	bdaddr_t src;
6852a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
6862a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	adapter_get_address(adapter, &src);
687cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&src, srcaddr);
688cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&device->bdaddr, dstaddr);
68936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
69036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	debug("Remove drivers for %s", device->path);
69136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
692352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg	for (list = device->drivers; list; list = next) {
693b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		struct btd_driver_data *driver_data = list->data;
694b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		struct btd_device_driver *driver = driver_data->driver;
69536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		const char **uuid;
69636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
697352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg		next = list->next;
698352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg
69936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		for (uuid = driver->uuids; *uuid; uuid++) {
7009b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz			sdp_record_t *rec;
70136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
7029b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz			if (!g_slist_find_custom(uuids, *uuid,
7039b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz					(GCompareFunc) strcasecmp))
70436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz				continue;
70536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
706e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz			driver->remove(device);
70736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			device->drivers = g_slist_remove(device->drivers,
708b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode								driver_data);
709b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
710b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode			g_free(driver_data);
711b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
71260af857dbc8a258eb91ef3fb6de06c17c8fb4ec2David Woodhouse			rec = find_record_in_list(recs, *uuid);
7139b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz			if (!rec)
7149b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz				continue;
7159b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz
716cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode			delete_record(srcaddr, dstaddr, rec->handle);
71736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		}
71836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	}
71936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
72036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	for (list = uuids; list; list = list->next)
72136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		device->uuids = g_slist_remove(device->uuids, list->data);
722f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann}
723f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
724bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmannstatic void iter_append_record(DBusMessageIter *dict, uint32_t handle,
725bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann							const char *record)
726bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann{
727bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	DBusMessageIter entry;
728bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
729bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
730bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann							NULL, &entry);
731bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
732bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
733bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
734bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
735bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
736bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	dbus_message_iter_close_container(dict, &entry);
737bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann}
738bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
739730775d1226a30c37ff551955f093ddfcd18e600Claudio Takahasistatic void append_and_grow_string(void *data, const char *str)
740c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz{
741c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	sdp_buf_t *buff = data;
742c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	int len;
743c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
744c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	len = strlen(str);
745c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
746c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	if (!buff->data) {
747c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		buff->data = malloc(DEFAULT_XML_BUF_SIZE);
748c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		if (!buff->data)
749c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz			return;
750c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		buff->buf_size = DEFAULT_XML_BUF_SIZE;
751c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	}
752c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
753c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	/* Grow string */
754c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	while (buff->buf_size < (buff->data_size + len + 1)) {
755c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		void *tmp;
756c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		uint32_t new_size;
757c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
758c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		/* Grow buffer by a factor of 2 */
759c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		new_size = (buff->buf_size << 1);
760c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
761c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		tmp = realloc(buff->data, new_size);
762c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		if (!tmp)
763c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz			return;
764c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
765c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		buff->data = tmp;
766c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		buff->buf_size = new_size;
767c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	}
768c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
769c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	/* Include the NULL character */
770c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	memcpy(buff->data + buff->data_size, str, len + 1);
771c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	buff->data_size += len;
772c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz}
773c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
7741e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzstatic void discover_device_reply(struct browse_req *req, sdp_list_t *recs)
7751e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz{
7761e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	DBusMessage *reply;
7771e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	DBusMessageIter iter, dict;
7781e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	sdp_list_t *seq;
7791e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7801e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	reply = dbus_message_new_method_return(req->msg);
7811e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	if (!reply)
7821e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		return;
7831e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7841e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_message_iter_init_append(reply, &iter);
7851e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7861e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
7871e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
7881e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
7891e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
7901e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7911e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	for (seq = recs; seq; seq = seq->next) {
7921e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		sdp_record_t *rec = (sdp_record_t *) seq->data;
7931e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		sdp_buf_t result;
7941e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7951e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		if (!rec)
7961e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			break;
7971e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7981e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		memset(&result, 0, sizeof(sdp_buf_t));
7991e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
8001e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		convert_sdp_record_to_xml(rec, &result,
8011e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz				append_and_grow_string);
8021e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
8031e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		if (result.data) {
8041e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			const char *val = (char *) result.data;
8051e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			iter_append_record(&dict, rec->handle, val);
8061e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			free(result.data);
8071e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		}
8081e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	}
8091e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
8101e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_message_iter_close_container(&iter, &dict);
8111e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
8121e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_connection_send(req->conn, reply, NULL);
8131e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_message_unref(reply);
8141e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz}
8151e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
81636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void services_changed(struct browse_req *req)
8173d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{
818533655873c4978091edf3698b20d2b96c43dafc8Johan Hedberg	DBusConnection *conn = get_dbus_connection();
819555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = req->device;
8203d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	char **uuids;
8213d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	GSList *l;
82236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	int i;
8233d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
82436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
82536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	for (i = 0, l = device->uuids; l; l = l->next, i++)
82636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		uuids[i] = l->data;
82736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
828533655873c4978091edf3698b20d2b96c43dafc8Johan Hedberg	dbus_connection_emit_property_changed(conn, device->path,
82936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz					DEVICE_INTERFACE, "UUIDs",
83036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz					DBUS_TYPE_ARRAY, &uuids);
83136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
83236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	g_free(uuids);
83336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz}
83436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
8358b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedbergstatic int rec_cmp(const void *a, const void *b)
8368b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg{
8378b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg	const sdp_record_t *r1 = a;
8388b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg	const sdp_record_t *r2 = b;
8398b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg
8408b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg	return r1->handle - r2->handle;
8418b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg}
8428b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg
84336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void update_services(struct browse_req *req, sdp_list_t *recs)
84436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{
845555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = req->device;
84618614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device_get_adapter(device);
84736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	sdp_list_t *seq;
848cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	char srcaddr[18], dstaddr[18];
8492a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	bdaddr_t src;
8502a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
8512a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	adapter_get_address(adapter, &src);
852cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&src, srcaddr);
853cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	ba2str(&device->bdaddr, dstaddr);
8543d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
85536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	for (seq = recs; seq; seq = seq->next) {
8563d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		sdp_record_t *rec = (sdp_record_t *) seq->data;
857681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz		sdp_buf_t pdu;
85836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		sdp_list_t *svcclass = NULL;
85936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		gchar *uuid_str;
86036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		GSList *l;
8613d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
8623d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		if (!rec)
8633d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz			break;
8643d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
86536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		if (sdp_get_service_classes(rec, &svcclass) < 0)
86636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			continue;
86736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
86836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		/* Extract the first element and skip the remainning */
86936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		uuid_str = bt_uuid2string(svcclass->data);
870aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg		if (!uuid_str) {
871aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg			sdp_list_free(svcclass, free);
87236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			continue;
873aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg		}
87436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
875e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse		if (!strcasecmp(uuid_str, PNP_UUID)) {
876fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann			uint16_t source, vendor, product, version;
877e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse			sdp_data_t *pdlist;
878e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse
879fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann			pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
880fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann			source = pdlist ? pdlist->val.uint16 : 0x0000;
881fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann
882e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse			pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
883e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse			vendor = pdlist ? pdlist->val.uint16 : 0x0000;
884e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse
885e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse			pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
886e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse			product = pdlist ? pdlist->val.uint16 : 0x0000;
887e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse
888e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse			pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
889e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse			version = pdlist ? pdlist->val.uint16 : 0x0000;
890e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse
891fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann			if (source || vendor || product || version)
892fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann				store_device_id(srcaddr, dstaddr, source,
893fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann						vendor, product, version);
894e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse		}
895e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse
896fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann		/* Driver UUID found */
89758d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz		l = g_slist_find_custom(req->uuids, uuid_str,
89858d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz				(GCompareFunc) strcasecmp);
899e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz		if (l) {
900e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz			char *uuid = l->data;
901e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz
902e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz			req->uuids = g_slist_remove(req->uuids, uuid);
903e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz			g_free(uuid);
904e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz		}
90558d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz
90637a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg		/* Check for duplicates */
907981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg		if (sdp_list_find(req->records, rec, rec_cmp)) {
908981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg			g_free(uuid_str);
909aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg			sdp_list_free(svcclass, free);
91037a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg			continue;
911981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg		}
91237a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg
913cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode		store_record(srcaddr, dstaddr, rec);
91437a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg
915681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz		/* Copy record */
916681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz		if (sdp_gen_record_pdu(rec, &pdu) == 0) {
917681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz			sdp_record_t *record;
918681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz			int scanned;
919681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz
920681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz			record = sdp_extract_pdu(pdu.data, pdu.data_size,
921681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz						&scanned);
9221d40bababe8114b88ec654b7764ff20c22a258c1Johan Hedberg			free(pdu.data);
923681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz			req->records = sdp_list_append(req->records, record);
924681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz		}
925681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz
92636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		l = g_slist_find_custom(device->uuids, uuid_str,
927c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann							(GCompareFunc) strcmp);
92836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		if (!l)
92936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			req->uuids_added = g_slist_append(req->uuids_added,
930c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann								uuid_str);
93136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		else {
93236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			req->uuids_removed = g_slist_remove(req->uuids_removed,
933c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann								l->data);
93436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			g_free(uuid_str);
9353d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		}
9363d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
93736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		sdp_list_free(svcclass, free);
9383d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	}
93936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz}
94036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
941555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic void store(struct btd_device *device)
94236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{
94318614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device->adapter;
944cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t src;
94536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	char *str;
9463d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
9472a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	adapter_get_address(adapter, &src);
9483d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
94936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	if (!device->uuids) {
950cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode		write_device_profiles(&src, &device->bdaddr, "");
95136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		return;
95236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	}
95336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
95436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	str = bt_list2string(device->uuids);
955cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	write_device_profiles(&src, &device->bdaddr, str);
95636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	g_free(str);
95736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz}
95836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
959a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentzstatic void browse_req_free(struct browse_req *req)
960a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz{
961a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	struct btd_device *device = req->device;
962a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz
963a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	device->discov_active = 0;
964a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz
965a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	if (device->discov_requestor) {
966a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz		g_dbus_remove_watch(req->conn, device->discov_listener);
967a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz		device->discov_listener = 0;
968a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz		g_free(device->discov_requestor);
969a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz		device->discov_requestor = NULL;
970a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	}
971a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz
972a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	if (req->msg)
973a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz		dbus_message_unref(req->msg);
974a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	if (req->conn)
975a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz		dbus_connection_unref(req->conn);
976a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	g_slist_free(req->uuids_added);
977a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	g_slist_free(req->uuids_removed);
978a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	if (req->records)
979a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz		sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
980a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	g_free(req);
981a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz}
982a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz
983da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void search_cb(sdp_list_t *recs, int err, gpointer user_data)
98436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{
98536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	struct browse_req *req = user_data;
986555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = req->device;
98736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	DBusMessage *reply;
9882a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
989681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz	if (err < 0) {
990681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz		error("%s: error updating services: %s (%d)",
991681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz				device->path, strerror(-err), -err);
99236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		goto proceed;
993681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz	}
99436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
99536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	update_services(req, recs);
99636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
997681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz	if (!req->uuids_added && !req->uuids_removed) {
998e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz		debug("%s: No service update", device->path);
99936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		goto proceed;
1000681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz	}
10012efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
100236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	/* Probe matching drivers for services added */
100336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	if (req->uuids_added)
1004681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz		device_probe_drivers(device, req->uuids_added, req->records);
10052efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
100636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	/* Remove drivers for services removed */
100736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	if (req->uuids_removed)
1008681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz		device_remove_drivers(device, req->uuids_removed, req->records);
10092efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
101036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	/* Propagate services changes */
101136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	services_changed(req);
1012f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
10137b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentzproceed:
1014681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz	/* Store the device's profiles in the filesystem */
1015681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz	store(device);
1016681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz
10172ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg	if (req->msg) {
10182ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg		if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
10192ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg						"DiscoverServices")) {
10202ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg			discover_device_reply(req, req->records);
10212ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg			goto cleanup;
10222ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg		}
1023a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann
10242ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg		g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg),
10258d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz				ADAPTER_INTERFACE, "DeviceCreated",
10268d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &device->path,
10278d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz				DBUS_TYPE_INVALID);
10282ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg	}
10298d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz
1030b5f810d74530a62bb389d40ade8581f7317bf3a9Luiz Augusto von Dentz	/* Update device list */
1031b5f810d74530a62bb389d40ade8581f7317bf3a9Luiz Augusto von Dentz	adapter_update_devices(device->adapter);
1032b5f810d74530a62bb389d40ade8581f7317bf3a9Luiz Augusto von Dentz
10332ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg	if (!req->msg)
10342ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg		goto cleanup;
10352ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg
10363d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	/* Reply create device request */
10373d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	reply = dbus_message_new_method_return(req->msg);
10383d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	if (!reply)
10391e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		goto cleanup;
10403d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
10413d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
1042a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann							DBUS_TYPE_INVALID);
10433d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
10440472470e5059e702f0e7e69ee0155dfea11baa25Marcel Holtmann	dbus_connection_send(req->conn, reply, NULL);
10450472470e5059e702f0e7e69ee0155dfea11baa25Marcel Holtmann	dbus_message_unref(reply);
10463d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
10471e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzcleanup:
1048a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	browse_req_free(req);
1049da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz}
1050da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz
1051da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
1052da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{
1053da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	struct browse_req *req = user_data;
1054da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	struct btd_device *device = req->device;
1055da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	struct btd_adapter *adapter = device->adapter;
1056cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t src;
1057da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	uuid_t uuid;
1058da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz
10597d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse	/* If we have a valid response and req->search_uuid == 1, then
10607d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse	   public browsing was successful -- we don't need any more */
10617d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse	if (err < 0 || (req->search_uuid == 1 && recs))
1062da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz		goto done;
1063da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz
1064da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	update_services(req, recs);
1065da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz
1066da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	adapter_get_address(adapter, &src);
1067da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz
1068da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	/* Search for mandatory uuids */
10697d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse	if (uuid_list[req->search_uuid]) {
10707d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
1071c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann		bt_search_service(&src, &device->bdaddr, &uuid,
1072c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann						browse_cb, user_data, NULL);
1073da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz		return;
1074da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	}
1075da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz
107658d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz	/* Search for drivers uuids */
107758d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz	if (req->uuids) {
1078e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz		char *uuid_str = req->uuids->data;
1079e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz
1080e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz		bt_string2uuid(&uuid, uuid_str);
1081e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz		req->uuids = g_slist_remove(req->uuids, uuid_str);
1082e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz		g_free(uuid_str);
1083c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann		bt_search_service(&src, &device->bdaddr, &uuid,
1084c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann						browse_cb, user_data, NULL);
108558d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz		return;
108678eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz	}
108778eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz
108878eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz	/* Search for l2cap uuid */
108978eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz	if (!req->records) {
109078eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz		sdp_uuid16_create(&uuid, L2CAP_UUID);
1091c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann		bt_search_service(&src, &device->bdaddr, &uuid,
1092c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann						search_cb, user_data, NULL);
109378eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz		return;
109458d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz	}
109558d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz
1096da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzdone:
1097da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	search_cb(recs, err, user_data);
1098da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz}
1099da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz
1100da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void init_browse(struct browse_req *req)
1101da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{
1102da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	GSList *l;
1103da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz
110458d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz	for (l = device_drivers; l; l = l->next) {
110558d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz		struct btd_device_driver *driver = l->data;
110658d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz		int i;
110758d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz
110858d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz		for (i = 0; driver->uuids[i]; i++) {
1109e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz			char *uuid;
11100144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse			int j;
11110144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse
11120144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse			/* Eliminate duplicates of UUIDs in uuid_list[]... */
11130144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse			if (strlen(driver->uuids[i]) == 36 &&
11140144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse			    !strncmp(driver->uuids[i], "0000", 4) &&
11150144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse			    !strcasecmp(driver->uuids[i] + 8,
11160144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse					"-0000-1000-8000-00805F9B34FB")) {
11170144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse				uint16_t uuid16 = strtol(driver->uuids[i],
11180144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse							 NULL, 16);
11190144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse				for (j = 0; uuid_list[j]; j++) {
11200144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse					if (uuid16 == uuid_list[j])
11210144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse						continue;
11220144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse				}
11232ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg
11240144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse			}
11250144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse			/* ... and of UUIDs another driver already asked for */
112658d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz			if (g_slist_find_custom(req->uuids, driver->uuids[i],
112758d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz					(GCompareFunc) strcasecmp))
11280144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse				continue;
1129e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz
1130e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz			uuid = g_strdup(driver->uuids[i]);
1131e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz			req->uuids = g_slist_append(req->uuids, uuid);
113258d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz		}
113358d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz	}
113458d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz
1135da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	for (l = req->device->uuids; l; l = l->next)
1136da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz		req->uuids_removed = g_slist_append(req->uuids_removed,
1137da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz						l->data);
11383d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}
11393d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
1140555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeint device_browse(struct btd_device *device, DBusConnection *conn,
1141040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi			DBusMessage *msg, uuid_t *search)
11423d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{
114318614bd2b008cb9f3879990883c569c37b72f195Alok Barsode	struct btd_adapter *adapter = device->adapter;
11443d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	struct browse_req *req;
1145cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bdaddr_t src;
1146d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	uuid_t uuid;
1147da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz	bt_callback_t cb;
1148a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	int err;
11492a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode
11501af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg	if (device->discov_active)
11511af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg		return -EBUSY;
11521af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg
11532a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode	adapter_get_address(adapter, &src);
11543d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11553d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req = g_new0(struct browse_req, 1);
11562ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg	if (conn && msg) {
11572ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg		req->conn = dbus_connection_ref(conn);
11582ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg		req->msg = dbus_message_ref(msg);
11592ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg	}
11603d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req->device = device;
11613d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
1162a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	if (search) {
1163040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		memcpy(&uuid, search, sizeof(uuid_t));
1164da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz		cb = search_cb;
1165a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	} else {
11667d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
1167da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz		init_browse(req);
1168da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz		cb = browse_cb;
1169a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	}
1170d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann
117195e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz	device->discov_active = 1;
1172d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg
1173d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg	if (msg) {
1174d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg		device->discov_requestor = g_strdup(dbus_message_get_sender(msg));
1175d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg		/* Track the request owner to cancel it
1176d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg		 * automatically if the owner exits */
1177d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg		device->discov_listener = g_dbus_add_disconnect_watch(conn,
117895e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz						dbus_message_get_sender(msg),
117995e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz						discover_services_req_exit,
118095e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz						device, NULL);
1181d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg	}
118295e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz
1183a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	err = bt_search_service(&src, &device->bdaddr,
1184a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz				&uuid, cb, req, NULL);
1185a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	if (err < 0)
1186a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz		browse_req_free(req);
1187a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz
1188a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz	return err;
11893d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}
119024cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
119118614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_adapter *device_get_adapter(struct btd_device *device)
1192dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode{
1193dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode	if (!device)
1194dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode		return NULL;
1195dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode
1196dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode	return device->adapter;
1197dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode}
1198dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode
119919ce4933f3dadf3b04a2a9bd84d66d750cc010c3Alok Barsodevoid device_get_address(struct btd_device *device, bdaddr_t *bdaddr)
1200aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode{
1201cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode	bacpy(bdaddr, &device->bdaddr);
1202aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode}
1203aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode
1204555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeconst gchar *device_get_path(struct btd_device *device)
120546fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode{
120646fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode	if (!device)
120746fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode		return NULL;
120846fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode
120946fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode	return device->path;
121046fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode}
121146fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode
1212555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct agent *device_get_agent(struct btd_device *device)
1213a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode{
1214a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode	if (!device)
1215a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode		return NULL;
1216a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode
1217a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode	return  device->agent;
1218a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode}
1219a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode
1220555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_agent(struct btd_device *device, struct agent *agent)
1221d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode{
1222d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode	if (!device)
1223d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode		return;
1224d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode
1225d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode	device->agent = agent;
1226d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode}
1227d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode
1228555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_busy(struct btd_device *device)
12299f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode{
12309f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode	return device->discov_active ? TRUE : FALSE;
12319f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode}
12329f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode
1233555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_temporary(struct btd_device *device)
1234f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode{
1235f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode	return device->temporary;
1236f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode}
1237f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode
1238555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_temporary(struct btd_device *device, gboolean temporary)
1239595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode{
1240595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode	if (!device)
1241595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode		return;
1242595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode
1243595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode	device->temporary = temporary;
1244595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode}
1245595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode
1246555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_cap(struct btd_device *device, uint8_t cap)
1247491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode{
1248491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode	if (!device)
1249491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode		return;
1250491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode
1251491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode	device->cap = cap;
1252491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode}
1253491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode
1254555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_auth(struct btd_device *device, uint8_t auth)
125529227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode{
125629227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode	if (!device)
125729227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode		return;
125829227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode
125929227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode	device->auth = auth;
126029227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode}
126129227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode
1262555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeuint8_t device_get_auth(struct btd_device *device)
12632203f153c53189ec1c30df99b717e035681196e6Alok Barsode{
12642203f153c53189ec1c30df99b717e035681196e6Alok Barsode	return device->auth;
12652203f153c53189ec1c30df99b717e035681196e6Alok Barsode}
1266c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz
1267013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedbergstatic gboolean start_discovery(gpointer user_data)
1268013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{
1269013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg	struct btd_device *device = user_data;
1270013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg
1271013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg	device_browse(device, NULL, NULL, NULL);
1272013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg
1273013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg	device->discov_timer = 0;
1274013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg
1275013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg	return FALSE;
1276013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg}
1277013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg
1278e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberggboolean device_set_paired(DBusConnection *conn, struct btd_device *device,
127968b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg			struct bonding_request_info *bonding)
1280013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{
128168b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg	dbus_bool_t paired = TRUE;
128268b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg
128368b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg	device_set_temporary(device, FALSE);
128468b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg
128568b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg	dbus_connection_emit_property_changed(conn, device->path,
128668b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg						DEVICE_INTERFACE, "Paired",
128768b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg						DBUS_TYPE_BOOLEAN, &paired);
128868b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg
1289013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg	if (device->discov_timer)
1290e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg		return FALSE;
1291013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg
129268b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg	/* If we were initiators start service discovery immediately.
129368b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg	 * However if the other end was the initator wait a few seconds
129468b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg	 * before SDP. This is due to potential IOP issues if the other
129568b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg	 * end starts doing SDP at the same time as us */
129668b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg	if (bonding)
129768b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg		device_browse(device, bonding->conn,
129868b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg				bonding->msg, NULL);
129968b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg	else
130068b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg		device->discov_timer = g_timeout_add(DISCOVERY_TIMER,
130168b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg							start_discovery,
130268b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg							device);
1303e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg
1304e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg	return TRUE;
1305013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg}
1306013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg
1307c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzint btd_register_device_driver(struct btd_device_driver *driver)
1308c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{
1309c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz	device_drivers = g_slist_append(device_drivers, driver);
1310c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz
1311c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz	return 0;
1312c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz}
1313c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz
1314c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzvoid btd_unregister_device_driver(struct btd_device_driver *driver)
1315c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{
1316c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz	device_drivers = g_slist_remove(device_drivers, driver);
1317c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz}
1318