device.c revision 93fbf4400a81f68cd3642084bd6d2aa51a173250
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 <errno.h>
31dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <stdlib.h>
32dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <stdarg.h>
335d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi#include <unistd.h>
34dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <sys/time.h>
356a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include <sys/stat.h>
366be25e8bc36656d6fd8ba61c8552f9596043eca6Marcel Holtmann#include <sys/ioctl.h>
37943b02e163e169795a010c36a3b3343cc5092a96Marcel Holtmann#include <sys/param.h>
38dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <sys/socket.h>
39dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
40dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/bluetooth.h>
41dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci.h>
42dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci_lib.h>
435d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp.h>
445d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp_lib.h>
45dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
4686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <glib.h>
4786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <dbus/dbus.h>
4815ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#include <gdbus.h>
4986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
5026e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann#include "hcid.h"
51eb4d49890ca8a4d8f567e81fdf82b6903d30f326Marcel Holtmann#include "sdpd.h"
5226e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann
5386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "logging.h"
546a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include "textfile.h"
55dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
562c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#include "adapter.h"
5786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "device.h"
58da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi#include "dbus-common.h"
594e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz#include "dbus-hci.h"
60de29b2ff1d8531fd0583e49e4b8840198681ffe8Marcel Holtmann#include "dbus-service.h"
617fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz#include "error.h"
623d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz#include "glib-helper.h"
63fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite#include "agent.h"
643d3cdef8da6b3e1b14c3cdccda8c099cbad4f3aeMarcel Holtmann#include "sdp-xml.h"
6586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
66c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz#define DEFAULT_XML_BUF_SIZE	1024
675d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi#define DISCONNECT_TIMER	2
68dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
692c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#define DEVICE_INTERFACE "org.bluez.Device"
702c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
71e3afaa0b7ff373d89fd3fa257110a34df7495df7Luiz Augusto von Dentzstruct btd_driver_data {
72b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode	struct btd_device_driver *driver;
73b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode	void *priv;
74b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode};
75b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
76555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct btd_device {
77ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	gchar		*address;
78ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	gchar		*path;
79ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	struct adapter	*adapter;
80ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	GSList		*uuids;
81b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode	GSList		*drivers;		/* List of driver_data */
82ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	gboolean	temporary;
83ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	struct agent	*agent;
84ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	guint		disconn_timer;
85ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	int		discov_active;		/* Service discovery active */
86ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	char		*discov_requestor;	/* discovery requestor unique name */
87ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	guint		discov_listener;
88ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode
89ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	/* For Secure Simple Pairing */
90ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	uint8_t		cap;
91ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode	uint8_t		auth;
92ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode};
93ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode
943d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentzstruct browse_req {
953d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	DBusConnection *conn;
963d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	DBusMessage *msg;
97555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device;
9836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	GSList *uuids_added;
9936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	GSList *uuids_removed;
100d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	int search_uuid;
101a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	gboolean browse;
1023d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz};
1033d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
104f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmannstatic GSList *drivers = NULL;
105f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
106d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmannstatic uint16_t uuid_list[] = {
107d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	PUBLIC_BROWSE_GROUP,
108f22b20c3d40bd7571944af6a4946f756dc39f812Marcel Holtmann	HID_SVCLASS_ID,
109d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	GENERIC_AUDIO_SVCLASS_ID,
110d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	ADVANCED_AUDIO_SVCLASS_ID,
111d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	AV_REMOTE_SVCLASS_ID,
112d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	0
113d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann};
114d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann
115e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic void device_free(gpointer user_data)
11686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{
117555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
118e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi
119fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite	if (device->agent)
120fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite		agent_destroy(device->agent, FALSE);
121f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann
122ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi	g_slist_foreach(device->uuids, (GFunc) g_free, NULL);
123ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi	g_slist_free(device->uuids);
124f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann
1255d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	if (device->disconn_timer)
1265d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi		g_source_remove(device->disconn_timer);
1275d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
128f4662ad94310c08fd83e2cd9acd4ab0a03379ceeLuiz Augusto von Dentz	g_free(device->address);
12986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	g_free(device->path);
13086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	g_free(device);
13186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann}
13286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
133555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic gboolean device_is_paired(struct btd_device *device)
134769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{
135769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
136769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	char filename[PATH_MAX + 1], *str;
137769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	gboolean ret;
138debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
139769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
140769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	create_name(filename, PATH_MAX, STORAGEDIR,
141debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode			source, "linkkeys");
142769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	str = textfile_caseget(filename, device->address);
143769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	ret = str ? TRUE : FALSE;
144769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	g_free(str);
145769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
146769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	return ret;
147769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz}
148769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
149555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic char *device_get_name(struct btd_device *device)
150769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{
151769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
152769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	char filename[PATH_MAX + 1];
153debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
154769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
155debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	create_name(filename, PATH_MAX, STORAGEDIR, source, "names");
156769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	return textfile_caseget(filename, device->address);
157769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz}
158769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
159e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *get_properties(DBusConnection *conn,
160e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				DBusMessage *msg, void *user_data)
1612c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{
162555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
1634e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	struct adapter *adapter = device->adapter;
1644e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	DBusMessage *reply;
1654e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	DBusMessageIter iter;
1664e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	DBusMessageIter dict;
1674e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	bdaddr_t src, dst;
168769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	char path[MAX_PATH_LENGTH];
1694e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	char buf[64];
1704e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	const char *ptr;
171769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	char *name, *ppath, **uuids;
1724e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_bool_t boolean;
1734e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	uint32_t class;
174769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	int i;
175769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	GSList *l;
176661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode	uint16_t dev_id = adapter_get_dev_id(adapter);
177debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
1784e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
1794e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	reply = dbus_message_new_method_return(msg);
1804e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	if (!reply)
181e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return NULL;
1824e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
1834e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_init_append(reply, &iter);
1844e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
1854e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1864e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1874e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
1884e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
1894e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
1904e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Address */
1914e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Address", DBUS_TYPE_STRING,
1924e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			&device->address);
1934e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
1944e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Name */
195769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	name = device_get_name(device);
1968afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	if (name) {
1974e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Name",
1988afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz				DBUS_TYPE_STRING, &name);
1994e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	}
2004e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
201debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	str2ba(source, &src);
2024e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	str2ba(device->address, &dst);
2034e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2044e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Class */
2054e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	if (read_remote_class(&src, &dst, &class) == 0) {
2064e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Class",
2074e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz				DBUS_TYPE_UINT32, &class);
2084e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	}
2094e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2104e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Alias */
211661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode	if (get_device_alias(dev_id, &dst, buf, sizeof(buf)) > 0) {
2124e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		ptr = buf;
2134e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Alias",
2144e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz				DBUS_TYPE_STRING, &ptr);
2158afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	} else if (name) {
2168afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Alias",
2178afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz				DBUS_TYPE_STRING, &name);
2188afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		free(name);
2194e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	}
2204e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2214e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Paired */
222769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	boolean = device_is_paired(device);
2234e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Paired",
2244e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_TYPE_BOOLEAN, &boolean);
2254e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2264e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Trusted */
2274e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	boolean = read_trust(&src, device->address, GLOBAL_TRUST);
2284e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Trusted",
2294e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_TYPE_BOOLEAN, &boolean);
2304e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2314e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Connected */
2324e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	if (g_slist_find_custom(adapter->active_conn, &dst,
2334e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz				active_conn_find_by_bdaddr))
2344e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		boolean = TRUE;
2354e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	else
2364e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		boolean = FALSE;
2374e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
2384e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Connected",
2394e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_TYPE_BOOLEAN, &boolean);
2404e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
241ba93fb91ea81a35be0834ac395650e020a6b3fd3Claudio Takahasi	/* UUIDs */
242769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
243769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	for (i = 0, l = device->uuids; l; l = l->next, i++)
244769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz		uuids[i] = l->data;
2458afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "UUIDs",
246769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz			DBUS_TYPE_ARRAY, &uuids);
247769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	g_free(uuids);
2484e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
24974fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz	/* Adapter */
25093fbf4400a81f68cd3642084bd6d2aa51a173250Marcel Holtmann	snprintf(path, sizeof(path), "%s/hci%d", "/org/bluez", dev_id);
25174fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz	ppath = path;
25274fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Adapter",
253fa7d18bdf518a3ea6cb379a1b765547c58155166Luiz Augusto von Dentz			DBUS_TYPE_OBJECT_PATH, &ppath);
25474fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz
2554e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_close_container(&iter, &dict);
2564e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
257e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return reply;
2582c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}
2592c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
2604e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentzstatic int remove_device_alias(const char *source, const char *destination)
2614e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentz{
2624e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentz	char filename[PATH_MAX + 1];
2634e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentz
2644e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentz	create_name(filename, PATH_MAX, STORAGEDIR, source, "aliases");
2654e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentz	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2664e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentz
2674e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentz	return textfile_del(filename, destination);
2684e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentz}
2694e63689794eaa0d5a3567efa8d150110aa648504Luiz Augusto von Dentz
270e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
2717fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					const char *alias, void *data)
2727fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{
273555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = data;
2747fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
2757fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	bdaddr_t bdaddr;
2767fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	int ecode;
277eec75a25f96e441e07f82fbffb3c476d2c998091Luiz Augusto von Dentz	char *str, filename[PATH_MAX + 1];
278661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode	uint16_t dev_id = adapter_get_dev_id(adapter);
279debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
2807fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
2817fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	str2ba(device->address, &bdaddr);
2827fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
2838afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	/* Remove alias if empty string */
2848afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	if (g_str_equal(alias, "")) {
285debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode		create_name(filename, PATH_MAX, STORAGEDIR, source,
2868afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz				"names");
2878afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		str = textfile_caseget(filename, device->address);
288debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode		ecode = remove_device_alias(source, device->address);
2898afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	} else {
2908afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		str = g_strdup(alias);
291661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode		ecode = set_device_alias(dev_id, &bdaddr, alias);
2928afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	}
2938afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
2947fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (ecode < 0)
295e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return g_dbus_create_error(msg,
296e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				ERROR_INTERFACE ".Failed",
297e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				strerror(-ecode));
2987fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
2997fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg),
3007fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					DEVICE_INTERFACE, "Alias",
3018afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz					DBUS_TYPE_STRING, &str);
3028afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
303cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz	g_free(str);
3047fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
305e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return dbus_message_new_method_return(msg);
3067fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz}
3077fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
308e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
3097fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					dbus_bool_t value, void *data)
3107fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{
311555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = data;
3127fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
3137fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	bdaddr_t local;
314debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
3157fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
316debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	str2ba(source, &local);
3177fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3187fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	write_trust(&local, device->address, GLOBAL_TRUST, value);
3197fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3207fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg),
3217fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					DEVICE_INTERFACE, "Trusted",
3227fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					DBUS_TYPE_BOOLEAN, &value);
3237fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
324e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return dbus_message_new_method_return(msg);
3257fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz}
3267fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
327e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic inline DBusMessage *invalid_args(DBusMessage *msg)
328e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi{
329e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return g_dbus_create_error(msg,
330e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			ERROR_INTERFACE ".InvalidArguments",
331e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			"Invalid arguments in method call");
332e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi}
333e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi
334e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_property(DBusConnection *conn,
335e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				DBusMessage *msg, void *data)
3362c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{
3377fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	DBusMessageIter iter;
3387fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	DBusMessageIter sub;
3397fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	const char *property;
3407fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3417fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (!dbus_message_iter_init(msg, &iter))
342e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return invalid_args(msg);
3437fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3447fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
345e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return invalid_args(msg);
3467fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3477fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
3487fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
3497fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3507fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
351e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return invalid_args(msg);
3527fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
3537fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3547fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (g_str_equal("Trusted", property)) {
3557fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		dbus_bool_t value;
3567fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3577fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
358e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			return invalid_args(msg);
3597fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &value);
3607fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3617fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		return set_trust(conn, msg, value, data);
3627fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	} else if (g_str_equal("Alias", property)) {
3637fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		char *alias;
3647fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3657fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
366e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			return invalid_args(msg);
3677fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &alias);
3687fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
3697fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		return set_alias(conn, msg, alias, data);
3707fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	}
3717fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
372e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return invalid_args(msg);
3732c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}
3742c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
375342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzstatic void discover_services_req_exit(void *user_data)
376342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz{
377555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
378342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	struct adapter *adapter = device->adapter;
379342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	bdaddr_t src, dst;
380debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
381342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
382342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	debug("DiscoverDevices requestor exited");
383342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
384debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	str2ba(source, &src);
385342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	str2ba(device->address, &dst);
386342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
387342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	bt_cancel_discovery(&src, &dst);
388342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz}
389342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
39094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *discover_services(DBusConnection *conn,
39194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann					DBusMessage *msg, void *user_data)
39294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{
393555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
39494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	const char *pattern;
395342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	int err;
396342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
397342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	if (device->discov_active)
398342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
399342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz							"Discover in progress");
40094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
40194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
40294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann						DBUS_TYPE_INVALID) == FALSE)
403342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		goto fail;
40494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
405a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	if (strlen(pattern) == 0) {
406040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		err = device_browse(device, conn, msg, NULL);
407342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		if (err < 0)
408342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz			goto fail;
409342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	} else {
410040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		uuid_t uuid;
411040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi
412040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		if (bt_string2uuid(&uuid, pattern) < 0)
413342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz			return invalid_args(msg);
414a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann
415040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		err = device_browse(device, conn, msg, &uuid);
416342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		if (err < 0)
417342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz			goto fail;
418342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	}
41994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
42094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	return NULL;
421342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
422342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzfail:
423342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
424342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz					"Discovery Failed");
42594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann}
42694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
42794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *cancel_discover(DBusConnection *conn,
42894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann					DBusMessage *msg, void *user_data)
42994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{
430555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
43119b4c8b0e51a20a1b95ede34b092ebc56e1183aeMarcel Holtmann	struct adapter *adapter = device->adapter;
4321e4c95e09bf53e50ad033febae0d6383517508b4Johan Hedberg	bdaddr_t src, dst;
433debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
43419b4c8b0e51a20a1b95ede34b092ebc56e1183aeMarcel Holtmann
435342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	if (!device->discov_active)
436342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		return g_dbus_create_error(msg,
437342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz				ERROR_INTERFACE ".Failed",
438342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz				"No pending discovery");
439342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
440342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	/* only the discover requestor can cancel the inquiry process */
441342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz	if (!device->discov_requestor ||
442342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz			strcmp(device->discov_requestor, dbus_message_get_sender(msg)))
443342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz		return g_dbus_create_error(msg,
444342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz				ERROR_INTERFACE ".NotAuthorized",
445342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz				"Not Authorized");
446342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz
447debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode 	str2ba(source, &src);
44819b4c8b0e51a20a1b95ede34b092ebc56e1183aeMarcel Holtmann	str2ba(device->address, &dst);
44919b4c8b0e51a20a1b95ede34b092ebc56e1183aeMarcel Holtmann
450289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz	if (bt_cancel_discovery(&src, &dst) < 0)
451289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz		return g_dbus_create_error(msg,
452289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz				ERROR_INTERFACE ".Failed",
453289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz				"No pending discover");
45494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
45594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	return dbus_message_new_method_return(msg);
45694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann}
45794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
4585d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasistatic gboolean disconnect_timeout(gpointer user_data)
4595d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi{
460555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
4615d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	struct active_conn_info *ci;
4625d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	GSList *l;
4635d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	disconnect_cp cp;
4645d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	bdaddr_t bda;
4655d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	int dd;
466661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode	uint16_t dev_id = adapter_get_dev_id(device->adapter);
4675d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4685d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	device->disconn_timer = 0;
4695d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4705d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	str2ba(device->address, &bda);
4715d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	l = g_slist_find_custom(device->adapter->active_conn,
4725d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi				&bda, active_conn_find_by_bdaddr);
4735d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	if (!l)
4745d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi		return FALSE;
4755d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4765d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	ci = l->data;
477661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode	dd = hci_open_dev(dev_id);
4785d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	if (dd < 0)
4795d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi		goto fail;
4805d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4815d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	memset(&cp, 0, sizeof(cp));
4825d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	cp.handle = htobs(ci->handle);
4835d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	cp.reason = HCI_OE_USER_ENDED_CONNECTION;
4845d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4855d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT,
4865d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi			DISCONNECT_CP_SIZE, &cp);
4875d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4885d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	close(dd);
4895d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
4905d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasifail:
4915d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	return FALSE;
4925d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi}
4935d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
49494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *disconnect(DBusConnection *conn,
49594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann					DBusMessage *msg, void *user_data)
49694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{
497555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = user_data;
4985d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	GSList *l;
4995d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	bdaddr_t bda;
5005d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
5015d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	str2ba(device->address, &bda);
5025d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	l = g_slist_find_custom(device->adapter->active_conn,
5035d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi				&bda, active_conn_find_by_bdaddr);
5045d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	if (!l)
5055d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi		return g_dbus_create_error(msg,
5065d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi				ERROR_INTERFACE ".NotConnected",
5075d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi				"Device is not connected");
5085d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
5095d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	g_dbus_emit_signal(conn, device->path,
5105d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi			DEVICE_INTERFACE, "DisconnectRequested",
5115d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi			DBUS_TYPE_INVALID);
5125d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi
5135d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi	device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,
5145d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi						disconnect_timeout, device);
51594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
51694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	return dbus_message_new_method_return(msg);
51794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann}
51894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann
519e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusMethodTable device_methods[] = {
520e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	{ "GetProperties",	"",	"a{sv}",	get_properties	},
521e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	{ "SetProperty",	"sv",	"",		set_property	},
522e0d13d6da4b527ee02838af6b9dd7d53615e4896Marcel Holtmann	{ "DiscoverServices",	"s",	"a{us}",	discover_services,
52394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann						G_DBUS_METHOD_FLAG_ASYNC},
52494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ "CancelDiscovery",	"",	"",		cancel_discover	},
525e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	{ "Disconnect",		"",	"",		disconnect	},
52694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ }
5272c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes};
5282c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
529e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusSignalTable device_signals[] = {
53094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ "PropertyChanged",		"sv"	},
53194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ "DisconnectRequested",	""	},
53294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann	{ }
5332c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes};
5342c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
535555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct btd_device *device_create(DBusConnection *conn, struct adapter *adapter,
53636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz					const gchar *address)
53786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{
538ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite	gchar *address_up;
539555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device;
540661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode	uint16_t dev_id = adapter_get_dev_id(adapter);
54186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
542555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	device = g_try_malloc0(sizeof(struct btd_device));
54386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	if (device == NULL)
54486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann		return NULL;
54586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
546ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite	address_up = g_ascii_strup(address, -1);
54793fbf4400a81f68cd3642084bd6d2aa51a173250Marcel Holtmann	device->path = g_strdup_printf("%s/hci%d/dev_%s", "/org/bluez",
54893fbf4400a81f68cd3642084bd6d2aa51a173250Marcel Holtmann							dev_id, address_up);
54986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	g_strdelimit(device->path, ":", '_');
550ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite	g_free(address_up);
55186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
55286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	debug("Creating device %s", device->path);
55386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
554e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE,
555e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				device_methods, device_signals, NULL,
556e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				device, device_free) == FALSE) {
55786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann		device_free(device);
55886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann		return NULL;
55986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	}
560da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi
5614e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	device->address = g_strdup(address);
562da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi	device->adapter = adapter;
563da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi
5646bfa88d706cc57a0c975c980dabec5d8ed67dcc0Claudio Takahasi	return device;
56586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann}
56686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
567555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_remove(DBusConnection *conn, struct btd_device *device)
56875add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi{
5696061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	GSList *list;
5706061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	struct btd_device_driver *driver;
571f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann	gchar *path = g_strdup(device->path);
572f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann
573f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann	debug("Removing device %s", path);
574f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann
5756061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	for (list = device->drivers; list; list = list->next) {
576b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		struct btd_driver_data *driver_data = list->data;
577b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		driver = driver_data->driver;
5786061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann
579b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		driver->remove(driver, device);
580b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		g_free(driver_data);
5816061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	}
5826061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann
583f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann	g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE);
58475add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi
585f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann	g_free(path);
58686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann}
587ff296428a08dee619db1cc702146faefa91087faCidorvan Leite
588555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegint device_address_cmp(struct btd_device *device, const gchar *address)
589ff296428a08dee619db1cc702146faefa91087faCidorvan Leite{
590ff296428a08dee619db1cc702146faefa91087faCidorvan Leite	return strcasecmp(device->address, address);
591ff296428a08dee619db1cc702146faefa91087faCidorvan Leite}
5923d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
5934b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsodesdp_record_t *get_record(sdp_list_t *recs, const char *uuid)
594dde6ea8284f922181318ee84fd58144e06ee39b2Marcel Holtmann{
5954b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode	sdp_list_t *seq;
5964b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode
5974b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode	for (seq = recs; seq; seq = seq->next) {
5984b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		sdp_record_t *rec = (sdp_record_t *) seq->data;
5994b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		sdp_list_t *svcclass = NULL;
6004b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		char *uuid_str;
6014b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode
6024b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		if (sdp_get_service_classes(rec, &svcclass) < 0)
6034b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode			continue;
6044b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode
6054b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		/* Extract the uuid */
6064b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		uuid_str = bt_uuid2string(svcclass->data);
6074b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		if (!uuid_str)
6084b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode			continue;
609dde6ea8284f922181318ee84fd58144e06ee39b2Marcel Holtmann
6104b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		if (!strcasecmp(uuid_str, uuid)) {
6114b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode			sdp_list_free(svcclass, free);
6124b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode			free(uuid_str);
6134b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode			return rec;
6144b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		}
6154b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		sdp_list_free(svcclass, free);
6164b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		free(uuid_str);
6174b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode	}
6184b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode	return NULL;
619dde6ea8284f922181318ee84fd58144e06ee39b2Marcel Holtmann}
620dde6ea8284f922181318ee84fd58144e06ee39b2Marcel Holtmann
6214b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsodevoid device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs)
622f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann{
6236061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	GSList *list;
6246061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	const char **uuid;
625f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann	int err;
626f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
627f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann	debug("Probe drivers for %s", device->path);
628f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
6296061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann	for (list = drivers; list; list = list->next) {
630e0863545e6239ac338fa7fbe9647a5748a60b436Marcel Holtmann		struct btd_device_driver *driver = list->data;
6314b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		GSList *records = NULL;
632f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
6336061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann		for (uuid = driver->uuids; *uuid; uuid++) {
634081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz			sdp_record_t *rec;
6354b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode
636081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz			if (!g_slist_find_custom(uuids, *uuid,
637081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz					(GCompareFunc) strcasecmp))
638081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz				continue;
639081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz
640081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz			rec = get_record(recs, *uuid);
641081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz			if (!rec)
642081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz				continue;
643081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz
644081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz			records = g_slist_append(records, rec);
645f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann		}
646f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
6474b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		if (records) {
648b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode			struct btd_driver_data *driver_data = g_new0(struct btd_driver_data, 1);
649b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
650b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode			err = driver->probe(driver, device, records);
651fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann			if (err < 0) {
652f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann				error("probe failed for driver %s",
653f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann							driver->name);
654b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
655b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode				g_free(driver_data);
656fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann				continue;
657fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann			}
658fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann
659b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode			driver_data->driver = driver;
660fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann			device->drivers = g_slist_append(device->drivers,
661b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode								driver_data);
662f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann		}
663f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann	}
66436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
66536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	for (list = uuids; list; list = list->next)
66636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		device->uuids = g_slist_insert_sorted(device->uuids,
66736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz				list->data, (GCompareFunc) strcmp);
66836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz}
66936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
6704b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsodevoid device_remove_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs)
67136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{
6724b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode	struct adapter *adapter = device_get_adapter(device);
673debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *src = adapter_get_address(adapter);
6744b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode	const gchar *dst = device_get_address(device);
67536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	GSList *list;
67636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
67736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	debug("Remove drivers for %s", device->path);
67836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
67936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	for (list = device->drivers; list; list = list->next) {
680b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		struct btd_driver_data *driver_data = list->data;
681b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode		struct btd_device_driver *driver = driver_data->driver;
68236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		const char **uuid;
68336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
68436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		for (uuid = driver->uuids; *uuid; uuid++) {
6859b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz			sdp_record_t *rec;
68636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
6879b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz			if (!g_slist_find_custom(uuids, *uuid,
6889b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz					(GCompareFunc) strcasecmp))
68936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz				continue;
69036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
691b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode			driver->remove(driver, device);
69236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			device->drivers = g_slist_remove(device->drivers,
693b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode								driver_data);
694b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
695b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode			g_free(driver_data);
696b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode
6979b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz			rec = get_record(recs, *uuid);
6989b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz			if (!rec)
6999b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz				continue;
7009b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz
7014b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode			delete_record(src, dst, rec->handle);
70236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		}
70336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	}
70436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
70536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	for (list = uuids; list; list = list->next)
70636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		device->uuids = g_slist_remove(device->uuids, list->data);
707f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann}
708f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
709bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmannstatic void iter_append_record(DBusMessageIter *dict, uint32_t handle,
710bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann							const char *record)
711bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann{
712bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	DBusMessageIter entry;
713bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
714bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
715bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann							NULL, &entry);
716bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
717bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
718bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
719bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
720bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
721bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	dbus_message_iter_close_container(dict, &entry);
722bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann}
723bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
724c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentzvoid append_and_grow_string(void *data, const char *str)
725c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz{
726c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	sdp_buf_t *buff = data;
727c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	int len;
728c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
729c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	len = strlen(str);
730c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
731c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	if (!buff->data) {
732c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		buff->data = malloc(DEFAULT_XML_BUF_SIZE);
733c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		if (!buff->data)
734c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz			return;
735c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		buff->buf_size = DEFAULT_XML_BUF_SIZE;
736c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	}
737c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
738c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	/* Grow string */
739c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	while (buff->buf_size < (buff->data_size + len + 1)) {
740c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		void *tmp;
741c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		uint32_t new_size;
742c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
743c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		/* Grow buffer by a factor of 2 */
744c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		new_size = (buff->buf_size << 1);
745c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
746c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		tmp = realloc(buff->data, new_size);
747c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		if (!tmp)
748c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz			return;
749c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
750c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		buff->data = tmp;
751c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz		buff->buf_size = new_size;
752c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	}
753c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
754c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	/* Include the NULL character */
755c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	memcpy(buff->data + buff->data_size, str, len + 1);
756c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz	buff->data_size += len;
757c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz}
758c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz
7591e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzstatic void discover_device_reply(struct browse_req *req, sdp_list_t *recs)
7601e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz{
7611e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	DBusMessage *reply;
7621e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	DBusMessageIter iter, dict;
7631e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	sdp_list_t *seq;
7641e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7651e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	reply = dbus_message_new_method_return(req->msg);
7661e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	if (!reply)
7671e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		return;
7681e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7691e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_message_iter_init_append(reply, &iter);
7701e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7711e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
7721e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
7731e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
7741e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
7751e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7761e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	for (seq = recs; seq; seq = seq->next) {
7771e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		sdp_record_t *rec = (sdp_record_t *) seq->data;
7781e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		sdp_buf_t result;
7791e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7801e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		if (!rec)
7811e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			break;
7821e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7831e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		memset(&result, 0, sizeof(sdp_buf_t));
7841e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7851e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		convert_sdp_record_to_xml(rec, &result,
7861e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz				append_and_grow_string);
7871e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7881e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		if (result.data) {
7891e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			const char *val = (char *) result.data;
7901e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			iter_append_record(&dict, rec->handle, val);
7911e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			free(result.data);
7921e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		}
7931e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	}
7941e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7951e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_message_iter_close_container(&iter, &dict);
7961e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
7971e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_connection_send(req->conn, reply, NULL);
7981e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	dbus_message_unref(reply);
7991e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz}
8001e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz
80136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void services_changed(struct browse_req *req)
8023d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{
803555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = req->device;
8043d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	char **uuids;
8053d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	GSList *l;
80636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	int i;
8073d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
80836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
80936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	for (i = 0, l = device->uuids; l; l = l->next, i++)
81036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		uuids[i] = l->data;
81136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
81236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	dbus_connection_emit_property_changed(req->conn, device->path,
81336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz					DEVICE_INTERFACE, "UUIDs",
81436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz					DBUS_TYPE_ARRAY, &uuids);
81536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
81636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	g_free(uuids);
81736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz}
81836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
81936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void update_services(struct browse_req *req, sdp_list_t *recs)
82036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{
821555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = req->device;
8224b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode	struct adapter *adapter = device_get_adapter(device);
823debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *src = adapter_get_address(adapter);
8244b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode	const gchar *dst = device_get_address(device);
82536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	sdp_list_t *seq;
8263d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
82736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	for (seq = recs; seq; seq = seq->next) {
8283d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		sdp_record_t *rec = (sdp_record_t *) seq->data;
82936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		sdp_list_t *svcclass = NULL;
83036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		gchar *uuid_str;
83136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		GSList *l;
8323d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
8333d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		if (!rec)
8343d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz			break;
8353d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
83636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		if (sdp_get_service_classes(rec, &svcclass) < 0)
83736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			continue;
8384b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		store_record(src, dst, rec);
83936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
84036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		/* Extract the first element and skip the remainning */
84136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		uuid_str = bt_uuid2string(svcclass->data);
84236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		if (!uuid_str)
84336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			continue;
84436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
84536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		l = g_slist_find_custom(device->uuids, uuid_str,
84636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz				(GCompareFunc) strcmp);
84736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		if (!l)
84836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			req->uuids_added = g_slist_append(req->uuids_added,
84936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz					uuid_str);
85036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		else {
85136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			req->uuids_removed = g_slist_remove(req->uuids_removed,
85236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz					l->data);
85336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz			g_free(uuid_str);
8543d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		}
8553d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
85636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		sdp_list_free(svcclass, free);
8573d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	}
85836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz}
85936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
860555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic void store(struct btd_device *device)
86136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{
86236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
86336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	bdaddr_t src, dst;
86436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	char *str;
865debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
8663d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
867debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	str2ba(source, &src);
8683d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	str2ba(device->address, &dst);
8693d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
87036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	if (!device->uuids) {
87136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		write_device_profiles(&src, &dst, "");
87236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		return;
87336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	}
87436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
87536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	str = bt_list2string(device->uuids);
87636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	write_device_profiles(&src, &dst, str);
87736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	g_free(str);
87836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz}
87936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
88036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
88136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{
88236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	struct browse_req *req = user_data;
883555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode	struct btd_device *device = req->device;
88436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
88536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	bdaddr_t src, dst;
88636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	uuid_t uuid;
88736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	DBusMessage *reply;
888debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
88936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
89036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	if (err < 0)
89136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		goto proceed;
89236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
89336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	update_services(req, recs);
89436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz
895a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	/* Public browsing successful or Single record requested */
896a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	if (req->browse == FALSE || (!req->search_uuid && recs))
897f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann		goto probe;
898d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann
899d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	if (uuid_list[++req->search_uuid]) {
900d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]);
901debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode		str2ba(source, &src);
90236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		str2ba(device->address, &dst);
903d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann		bt_search_service(&src, &dst, &uuid, browse_cb, user_data, NULL);
904d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann		return;
905d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	}
906d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann
90732033cb14df0294a742e9e8c6b5ffa8aa26c2cc1Marcel Holtmannprobe:
9082efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
90936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	if (!req->uuids_added && !req->uuids_removed)
91036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz		goto proceed;
9112efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
91236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	/* Probe matching drivers for services added */
91336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	if (req->uuids_added)
9144b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		device_probe_drivers(device, req->uuids_added, recs);
9152efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
91636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	/* Remove drivers for services removed */
91736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	if (req->uuids_removed)
9184b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode		device_remove_drivers(device, req->uuids_removed, recs);
9192efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
92036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	/* Store the device's profiles in the filesystem */
92136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	store(device);
9222efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
92336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	/* Propagate services changes */
92436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	services_changed(req);
925f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann
9267b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentzproceed:
9271e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz	if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
9281e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz			"DiscoverServices")) {
9291e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		discover_device_reply(req, recs);
9301e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		goto cleanup;
931a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann	}
932a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann
933f80a7215275b229a597cf8d2bbc7e4e208af522cMarcel Holtmann	g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg),
9348d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz				ADAPTER_INTERFACE, "DeviceCreated",
9358d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &device->path,
9368d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz				DBUS_TYPE_INVALID);
9378d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz
9383d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	/* Reply create device request */
9393d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	reply = dbus_message_new_method_return(req->msg);
9403d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	if (!reply)
9411e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz		goto cleanup;
9423d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
9433d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
944a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann							DBUS_TYPE_INVALID);
9453d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
9460472470e5059e702f0e7e69ee0155dfea11baa25Marcel Holtmann	dbus_connection_send(req->conn, reply, NULL);
9470472470e5059e702f0e7e69ee0155dfea11baa25Marcel Holtmann	dbus_message_unref(reply);
9483d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
9491e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzcleanup:
9502efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz	device->discov_active = 0;
9512efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
9522efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz	if (device->discov_requestor) {
9532efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz		g_dbus_remove_watch(req->conn, device->discov_listener);
9542efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz		device->discov_listener = 0;
9552efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz		g_free(device->discov_requestor);
9562efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz		device->discov_requestor = NULL;
9572efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz	}
9582efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz
959bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann	if (recs != NULL)
960bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann		sdp_list_free(recs, (sdp_free_func_t) sdp_record_free);
961bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann
9623d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	dbus_message_unref(req->msg);
9633d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	dbus_connection_unref(req->conn);
96436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	g_slist_free(req->uuids_added);
96536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	g_slist_free(req->uuids_removed);
9663d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	g_free(req);
9673d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}
9683d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
969555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeint device_browse(struct btd_device *device, DBusConnection *conn,
970040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi			DBusMessage *msg, uuid_t *search)
9713d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{
9723d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
9733d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	struct browse_req *req;
9743d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	bdaddr_t src, dst;
975d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	uuid_t uuid;
97636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz	GSList *l;
977debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	const gchar *source = adapter_get_address(adapter);
9783d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
9793d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req = g_new0(struct browse_req, 1);
9803d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req->conn = dbus_connection_ref(conn);
9813d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req->msg = dbus_message_ref(msg);
9823d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req->device = device;
9833d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
984debc2efd75e3211934c2f4262140e7c28f574945Alok Barsode	str2ba(source, &src);
9853d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	str2ba(device->address, &dst);
986a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann
987a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	if (search) {
988040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi		memcpy(&uuid, search, sizeof(uuid_t));
989a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann		req->browse = FALSE;
990a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	} else {
991a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]);
992a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann		req->browse = TRUE;
99362600e4b58d883456d446402106f60201b0ee954Luiz Augusto von Dentz		for (l = device->uuids; l; l = l->next)
99462600e4b58d883456d446402106f60201b0ee954Luiz Augusto von Dentz			req->uuids_removed = g_slist_append(req->uuids_removed,
99562600e4b58d883456d446402106f60201b0ee954Luiz Augusto von Dentz						l->data);
996a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann	}
997d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann
99895e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz	device->discov_active = 1;
99995e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz	device->discov_requestor = g_strdup(dbus_message_get_sender(msg));
1000040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi	/* Track the request owner to cancel it
1001040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi	 * automatically if the owner exits */
100295e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz	device->discov_listener = g_dbus_add_disconnect_watch(conn,
100395e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz						dbus_message_get_sender(msg),
100495e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz						discover_services_req_exit,
100595e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz						device, NULL);
100695e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz
1007d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann	return bt_search_service(&src, &dst, &uuid, browse_cb, req, NULL);
10083d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}
100924cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
1010555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct adapter *device_get_adapter(struct btd_device *device)
1011dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode{
1012dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode	if (!device)
1013dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode		return NULL;
1014dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode
1015dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode	return device->adapter;
1016dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode}
1017dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode
1018555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeconst gchar *device_get_address(struct btd_device *device)
1019aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode{
1020aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode	if (!device)
1021aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode		return NULL;
1022aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode
1023aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode	return device->address;
1024aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode}
1025aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode
1026555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeconst gchar *device_get_path(struct btd_device *device)
102746fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode{
102846fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode	if (!device)
102946fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode		return NULL;
103046fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode
103146fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode	return device->path;
103246fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode}
103346fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode
1034555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct agent *device_get_agent(struct btd_device *device)
1035a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode{
1036a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode	if (!device)
1037a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode		return NULL;
1038a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode
1039a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode	return  device->agent;
1040a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode}
1041a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode
1042555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_agent(struct btd_device *device, struct agent *agent)
1043d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode{
1044d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode	if (!device)
1045d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode		return;
1046d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode
1047d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode	device->agent = agent;
1048d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode}
1049d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode
1050555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_busy(struct btd_device *device)
10519f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode{
10529f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode	return device->discov_active ? TRUE : FALSE;
10539f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode}
10549f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode
1055555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_temporary(struct btd_device *device)
1056f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode{
1057f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode	return device->temporary;
1058f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode}
1059f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode
1060555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_temporary(struct btd_device *device, gboolean temporary)
1061595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode{
1062595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode	if (!device)
1063595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode		return;
1064595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode
1065595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode	device->temporary = temporary;
1066595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode}
1067595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode
1068555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_cap(struct btd_device *device, uint8_t cap)
1069491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode{
1070491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode	if (!device)
1071491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode		return;
1072491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode
1073491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode	device->cap = cap;
1074491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode}
1075491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode
1076555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_auth(struct btd_device *device, uint8_t auth)
107729227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode{
107829227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode	if (!device)
107929227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode		return;
108029227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode
108129227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode	device->auth = auth;
108229227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode}
108329227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode
1084555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeuint8_t device_get_auth(struct btd_device *device)
10852203f153c53189ec1c30df99b717e035681196e6Alok Barsode{
10862203f153c53189ec1c30df99b717e035681196e6Alok Barsode	return device->auth;
10872203f153c53189ec1c30df99b717e035681196e6Alok Barsode}
10882203f153c53189ec1c30df99b717e035681196e6Alok Barsode
108924cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmannint btd_register_device_driver(struct btd_device_driver *driver)
109024cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann{
109124cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	const char **uuid;
109224cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
1093f0e152e16102de80b7fe8510f455f993980ebb2fLuiz Augusto von Dentz	/* FIXME: hack to make hci to resolve service_req_auth symbol*/
1094f0e152e16102de80b7fe8510f455f993980ebb2fLuiz Augusto von Dentz	service_req_auth(NULL, NULL, NULL, NULL, NULL);
109524cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	drivers = g_slist_append(drivers, driver);
109624cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
109724cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	for (uuid = driver->uuids; *uuid; uuid++) {
109824cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann		debug("name %s uuid %s", driver->name, *uuid);
109924cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	}
110024cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
110124cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	return 0;
110224cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann}
110324cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
110424cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmannvoid btd_unregister_device_driver(struct btd_device_driver *driver)
110524cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann{
110624cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	drivers = g_slist_remove(drivers, driver);
110724cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann}
1108