device.c revision e2731d4c2e3ef7d1677a73aca5fa58f044075980
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>
33dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <sys/time.h>
346a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include <sys/stat.h>
35943b02e163e169795a010c36a3b3343cc5092a96Marcel Holtmann#include <sys/param.h>
36dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <sys/socket.h>
37dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
38dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/bluetooth.h>
39dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci.h>
40dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci_lib.h>
415d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp.h>
425d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp_lib.h>
43dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
4486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <glib.h>
4586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <dbus/dbus.h>
4615ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#include <gdbus.h>
4786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
4826e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann#include "hcid.h"
49eb4d49890ca8a4d8f567e81fdf82b6903d30f326Marcel Holtmann#include "sdpd.h"
5026e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann
5186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "logging.h"
526a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include "textfile.h"
53dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include "oui.h"
54dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
552c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#include "adapter.h"
5686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "device.h"
57da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi#include "dbus-common.h"
584e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz#include "dbus-hci.h"
59de29b2ff1d8531fd0583e49e4b8840198681ffe8Marcel Holtmann#include "dbus-service.h"
607fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz#include "error.h"
613d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz#include "glib-helper.h"
62fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite#include "agent.h"
6386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
64dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#define MAX_DEVICES 16
65dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
662c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#define DEVICE_INTERFACE "org.bluez.Device"
672c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
683d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentzstruct browse_req {
693d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	DBusConnection *conn;
703d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	DBusMessage *msg;
713d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	struct device *device;
723d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz};
733d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
74dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstruct hci_peer {
75dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct timeval lastseen;
76dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct timeval lastused;
77dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
78dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	bdaddr_t bdaddr;
79dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint32_t class;
80dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	int8_t   rssi;
81dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint8_t  data[240];
82dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint8_t  name[248];
83dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
84dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint8_t  pscan_rep_mode;
85dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint8_t  pscan_period_mode;
86dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint8_t  pscan_mode;
87dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint16_t clock_offset;
88dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
89dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_peer *next;
90dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann};
91dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
92dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstruct hci_conn {
93dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	bdaddr_t bdaddr;
94dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint16_t handle;
95dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
96dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_conn *next;
97dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann};
98dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
99dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstruct hci_dev {
10057eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann	int ignore;
10157eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann
102dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	bdaddr_t bdaddr;
103dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint8_t  features[8];
104dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint8_t  lmp_ver;
105dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint16_t lmp_subver;
1060d7408aa899f84210d0e6418ee528636292276bcMarcel Holtmann	uint16_t hci_rev;
107dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	uint16_t manufacturer;
108dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
1090b727924102df07d609be955800793c1f33d6952Marcel Holtmann	uint8_t  ssp_mode;
1106a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	uint8_t  name[248];
111277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi	uint8_t  class[3];
1126a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
113dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_peer *peers;
114dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_conn *conns;
115dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann};
116dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
117dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstatic struct hci_dev devices[MAX_DEVICES];
118dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
119dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#define ASSERT_DEV_ID { if (dev_id >= MAX_DEVICES) return -ERANGE; }
120dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
12152a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannvoid init_adapters(void)
122dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
123dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	int i;
124dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
125dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	for (i = 0; i < MAX_DEVICES; i++)
126dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann		memset(devices + i, 0, sizeof(struct hci_dev));
127dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
128dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
129ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedbergstatic int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr)
130ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg{
131dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi	int dd, err;
132ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg
133ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	dd = hci_open_dev(dev_id);
134ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	if (dd < 0) {
135dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
136fa7d18bdf518a3ea6cb379a1b765547c58155166Luiz Augusto von Dentz		error("Can't open device hci%d: %s (%d)",
137dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
138dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		return -err;
139ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	}
140ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg
141ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	if (hci_read_bd_addr(dd, bdaddr, 2000) < 0) {
142dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
143ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg		error("Can't read address for hci%d: %s (%d)",
144dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
145ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg		hci_close_dev(dd);
146fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim		return -err;
147ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	}
148ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg
149ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	hci_close_dev(dd);
150ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg
151ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	return 0;
152ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg}
153ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg
15452a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint add_adapter(uint16_t dev_id)
155dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
156dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_dev *dev;
157dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_dev_info di;
158dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
159dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ASSERT_DEV_ID;
160dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
161dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	dev = &devices[dev_id];
162dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
16357eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann	if (hci_devinfo(dev_id, &di) < 0) {
16457eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann		dev->ignore = 1;
165dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann		return -errno;
16657eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann	}
16757eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann
16857eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann	if (hci_test_bit(HCI_RAW, &di.flags)) {
16957eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann		info("Device hci%d is using raw mode", dev_id);
17057eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann		dev->ignore = 1;
17157eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann	}
172dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
173ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	if (bacmp(&di.bdaddr, BDADDR_ANY))
174ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg		bacpy(&dev->bdaddr, &di.bdaddr);
175ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	else {
1760b727924102df07d609be955800793c1f33d6952Marcel Holtmann		int err = device_read_bdaddr(dev_id, &dev->bdaddr);
1770b727924102df07d609be955800793c1f33d6952Marcel Holtmann		if (err < 0)
1780b727924102df07d609be955800793c1f33d6952Marcel Holtmann			return err;
179ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg	}
180dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	memcpy(dev->features, di.features, 8);
181dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
182dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	info("Device hci%d has been added", dev_id);
183dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
184dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	return 0;
185dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
186dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
18752a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint remove_adapter(uint16_t dev_id)
188dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
189dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_dev *dev;
190dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
191dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ASSERT_DEV_ID;
192dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
193dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	dev = &devices[dev_id];
194dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
195dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	memset(dev, 0, sizeof(struct hci_dev));
196dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
197dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	info("Device hci%d has been removed", dev_id);
198dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
199dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	return 0;
200dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
201dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
202b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmannstatic inline uint8_t get_inquiry_mode(struct hci_dev *dev)
203b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann{
204b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann	if (dev->features[6] & LMP_EXT_INQ)
205b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann		return 2;
206b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann
207b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann	if (dev->features[3] & LMP_RSSI_INQ)
208b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann		return 1;
209b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann
210e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann	if (dev->manufacturer == 11 &&
211e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann			dev->hci_rev == 0x00 && dev->lmp_subver == 0x0757)
212e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann		return 1;
213e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann
214431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann	if (dev->manufacturer == 15) {
215431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann		if (dev->hci_rev == 0x03 && dev->lmp_subver == 0x6963)
216431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann			return 1;
217431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann		if (dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963)
218431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann			return 1;
219b98c93ed852d29557fe71de5262357b704f85592Marcel Holtmann		if (dev->hci_rev == 0x00 && dev->lmp_subver == 0x6965)
220b98c93ed852d29557fe71de5262357b704f85592Marcel Holtmann			return 1;
221431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann	}
22219fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann
22319fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann	if (dev->manufacturer == 31 &&
22419fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann			dev->hci_rev == 0x2005 && dev->lmp_subver == 0x1805)
22519fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann		return 1;
22619fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann
227b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann	return 0;
228b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann}
229b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann
2300b727924102df07d609be955800793c1f33d6952Marcel Holtmannstatic void update_ext_inquiry_response(int dd, struct hci_dev *dev)
2310b727924102df07d609be955800793c1f33d6952Marcel Holtmann{
2320b727924102df07d609be955800793c1f33d6952Marcel Holtmann	uint8_t fec = 0, data[240];
2330b727924102df07d609be955800793c1f33d6952Marcel Holtmann
2340b727924102df07d609be955800793c1f33d6952Marcel Holtmann	if (!(dev->features[6] & LMP_EXT_INQ))
2350b727924102df07d609be955800793c1f33d6952Marcel Holtmann		return;
2360b727924102df07d609be955800793c1f33d6952Marcel Holtmann
2370b727924102df07d609be955800793c1f33d6952Marcel Holtmann	memset(data, 0, sizeof(data));
2380b727924102df07d609be955800793c1f33d6952Marcel Holtmann
239eb4d49890ca8a4d8f567e81fdf82b6903d30f326Marcel Holtmann	if (dev->ssp_mode > 0)
240eb4d49890ca8a4d8f567e81fdf82b6903d30f326Marcel Holtmann		create_ext_inquiry_response((char *) dev->name, data);
2410b727924102df07d609be955800793c1f33d6952Marcel Holtmann
2420b727924102df07d609be955800793c1f33d6952Marcel Holtmann	if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0)
2430b727924102df07d609be955800793c1f33d6952Marcel Holtmann		error("Can't write extended inquiry response: %s (%d)",
2440b727924102df07d609be955800793c1f33d6952Marcel Holtmann						strerror(errno), errno);
2450b727924102df07d609be955800793c1f33d6952Marcel Holtmann}
2460b727924102df07d609be955800793c1f33d6952Marcel Holtmann
24752a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint start_adapter(uint16_t dev_id)
248dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
249dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_dev *dev;
250dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_version ver;
251b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann	uint8_t features[8], inqmode;
2523dfe93f27c455e07be72a38239f4f8335ba6a860Marcel Holtmann	uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 };
2530b727924102df07d609be955800793c1f33d6952Marcel Holtmann	char name[249];
254277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi	int dd, err;
255dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
256dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ASSERT_DEV_ID;
257dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
258dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	dev = &devices[dev_id];
259dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
26057eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann	if (dev->ignore)
26157eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann		return 0;
26257eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann
263dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	dd = hci_open_dev(dev_id);
264dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	if (dd < 0) {
265dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
266dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		error("Can't open device hci%d: %s (%d)",
267dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
268dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		return -err;
269dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	}
270dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
271dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	if (hci_read_local_version(dd, &ver, 1000) < 0) {
272dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
27326e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann		error("Can't read version info for hci%d: %s (%d)",
274dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
275276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmann		hci_close_dev(dd);
276fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim		return -err;
277dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	}
278dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
2790fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann	dev->hci_rev = ver.hci_rev;
280dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	dev->lmp_ver = ver.lmp_ver;
281dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	dev->lmp_subver = ver.lmp_subver;
282dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	dev->manufacturer = ver.manufacturer;
283dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
284b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann	if (hci_read_local_features(dd, features, 1000) < 0) {
285277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi		err = errno;
286b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann		error("Can't read features for hci%d: %s (%d)",
287277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi					dev_id, strerror(err), err);
288276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmann		hci_close_dev(dd);
289fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim		return -err;
290b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann	}
291b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann
292b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann	memcpy(dev->features, features, 8);
293b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann
294277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi	if (hci_read_class_of_dev(dd, dev->class, 1000) < 0) {
295277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi		err = errno;
2960b727924102df07d609be955800793c1f33d6952Marcel Holtmann		error("Can't read class of device on hci%d: %s (%d)",
2970b727924102df07d609be955800793c1f33d6952Marcel Holtmann						dev_id, strerror(err), err);
298277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi		hci_close_dev(dd);
299277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi		return -err;
300277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi	}
301277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi
3020b727924102df07d609be955800793c1f33d6952Marcel Holtmann	if (hci_read_local_name(dd, sizeof(name), name, 2000) < 0) {
3030b727924102df07d609be955800793c1f33d6952Marcel Holtmann		err = errno;
3040b727924102df07d609be955800793c1f33d6952Marcel Holtmann		error("Can't read local name on hci%d: %s (%d)",
3050b727924102df07d609be955800793c1f33d6952Marcel Holtmann						dev_id, strerror(err), err);
3060b727924102df07d609be955800793c1f33d6952Marcel Holtmann		hci_close_dev(dd);
3070b727924102df07d609be955800793c1f33d6952Marcel Holtmann		return -err;
3080b727924102df07d609be955800793c1f33d6952Marcel Holtmann	}
309b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann
3100b727924102df07d609be955800793c1f33d6952Marcel Holtmann	memcpy(dev->name, name, 248);
3110b727924102df07d609be955800793c1f33d6952Marcel Holtmann
3120b727924102df07d609be955800793c1f33d6952Marcel Holtmann	if (!(features[6] & LMP_SIMPLE_PAIR))
3130b727924102df07d609be955800793c1f33d6952Marcel Holtmann		goto setup;
3140b727924102df07d609be955800793c1f33d6952Marcel Holtmann
3150b727924102df07d609be955800793c1f33d6952Marcel Holtmann	if (hci_read_simple_pairing_mode(dd, &dev->ssp_mode, 1000) < 0) {
3160b727924102df07d609be955800793c1f33d6952Marcel Holtmann		err = errno;
3170b727924102df07d609be955800793c1f33d6952Marcel Holtmann		error("Can't read simple pairing mode on hci%d: %s (%d)",
3180b727924102df07d609be955800793c1f33d6952Marcel Holtmann						dev_id, strerror(err), err);
319276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmann		hci_close_dev(dd);
320fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim		return -err;
321b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann	}
322b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann
3230b727924102df07d609be955800793c1f33d6952Marcel Holtmannsetup:
32457290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann	if (ver.hci_rev > 1) {
32557290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann		if (features[5] & LMP_SNIFF_SUBR)
32657290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann			events[5] |= 0x20;
32757290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann
328a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann		if (features[5] & LMP_PAUSE_ENC)
329a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann			events[5] |= 0x80;
330a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann
33157290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann		if (features[6] & LMP_EXT_INQ)
33257290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann			events[5] |= 0x40;
33357290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann
334a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann		if (features[6] & LMP_NFLUSH_PKTS)
335a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann			events[7] |= 0x01;
336f4051e4e1bc3a5a00fc74b5b5eb7eb3794f67310Johan Hedberg
33757290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann		if (features[7] & LMP_LSTO)
33857290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann			events[6] |= 0x80;
33957290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann
3400b727924102df07d609be955800793c1f33d6952Marcel Holtmann		if (features[6] & LMP_SIMPLE_PAIR) {
3410b727924102df07d609be955800793c1f33d6952Marcel Holtmann			events[6] |= 0x01;	/* IO Capability Request */
3420b727924102df07d609be955800793c1f33d6952Marcel Holtmann			events[6] |= 0x02;	/* IO Capability Response */
3430b727924102df07d609be955800793c1f33d6952Marcel Holtmann			events[6] |= 0x04;	/* User Confirmation Request */
3440b727924102df07d609be955800793c1f33d6952Marcel Holtmann			events[6] |= 0x08;	/* User Passkey Request */
3450b727924102df07d609be955800793c1f33d6952Marcel Holtmann			events[6] |= 0x10;	/* Remote OOB Data Request */
3460b727924102df07d609be955800793c1f33d6952Marcel Holtmann			events[6] |= 0x20;	/* Simple Pairing Complete */
3470b727924102df07d609be955800793c1f33d6952Marcel Holtmann			events[7] |= 0x04;	/* User Passkey Notification */
3480b727924102df07d609be955800793c1f33d6952Marcel Holtmann			events[7] |= 0x08;	/* Keypress Notification */
3490b727924102df07d609be955800793c1f33d6952Marcel Holtmann			events[7] |= 0x10;	/* Remote Host Supported Features Notification */
3500b727924102df07d609be955800793c1f33d6952Marcel Holtmann		}
3510b727924102df07d609be955800793c1f33d6952Marcel Holtmann
35257290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann		hci_send_cmd(dd, OGF_HOST_CTL, OCF_SET_EVENT_MASK,
35357290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann						sizeof(events), events);
35457290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann	}
35557290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann
356c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann	if (read_local_name(&dev->bdaddr, name) == 0) {
357c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann		memcpy(dev->name, name, 248);
358c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann		hci_write_local_name(dd, name, 5000);
359c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann        }
360c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann
3610b727924102df07d609be955800793c1f33d6952Marcel Holtmann	update_ext_inquiry_response(dd, dev);
3620b727924102df07d609be955800793c1f33d6952Marcel Holtmann
3630b727924102df07d609be955800793c1f33d6952Marcel Holtmann	inqmode = get_inquiry_mode(dev);
3640b727924102df07d609be955800793c1f33d6952Marcel Holtmann	if (inqmode < 1)
3650b727924102df07d609be955800793c1f33d6952Marcel Holtmann		goto done;
3660b727924102df07d609be955800793c1f33d6952Marcel Holtmann
3670b727924102df07d609be955800793c1f33d6952Marcel Holtmann	if (hci_write_inquiry_mode(dd, inqmode, 1000) < 0) {
368dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
3690b727924102df07d609be955800793c1f33d6952Marcel Holtmann		error("Can't write inquiry mode for hci%d: %s (%d)",
370dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi						dev_id, strerror(err), err);
3710b727924102df07d609be955800793c1f33d6952Marcel Holtmann		hci_close_dev(dd);
3720b727924102df07d609be955800793c1f33d6952Marcel Holtmann		return -err;
3730b727924102df07d609be955800793c1f33d6952Marcel Holtmann	}
3740b727924102df07d609be955800793c1f33d6952Marcel Holtmann
375276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmanndone:
376dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	hci_close_dev(dd);
377dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
378dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	info("Device hci%d has been activated", dev_id);
379dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
380dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	return 0;
381dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
382dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
38352a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint stop_adapter(uint16_t dev_id)
384dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
385dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ASSERT_DEV_ID;
386dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
387dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	info("Device hci%d has been disabled", dev_id);
388dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
389dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	return 0;
390dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
391dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
3920e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmannint update_adapter(uint16_t dev_id)
3930e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann{
3940e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	struct hci_dev *dev;
3950e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	int dd;
3960e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann
3970e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	ASSERT_DEV_ID;
3980e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann
3990e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	dev = &devices[dev_id];
4000e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann
4010e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	if (dev->ignore)
4020e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann		return 0;
4030e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann
4040e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	dd = hci_open_dev(dev_id);
4050e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	if (dd < 0) {
406dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		int err = errno;
407dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		error("Can't open device hci%d: %s (%d)",
408dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
409dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		return -err;
4100e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	}
4110e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann
4120e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	update_ext_inquiry_response(dd, dev);
4130e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann
4140e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	hci_close_dev(dd);
4150e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann
4160e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann	return 0;
4170e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann}
4180e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann
419dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_address(uint16_t dev_id, char *address, size_t size)
420dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
4218586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	struct hci_dev *dev;
4228586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
423dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ASSERT_DEV_ID;
424dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
425dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	if (size < 18)
426dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann		return -ENOBUFS;
427dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
4288586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	dev = &devices[dev_id];
4298586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
4308586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	return ba2str(&dev->bdaddr, address);
431dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
432dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
433277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasiint get_device_class(uint16_t dev_id, uint8_t *cls)
434277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi{
435277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi	struct hci_dev *dev;
436277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi
437277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi	ASSERT_DEV_ID;
438277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi
439277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi	dev = &devices[dev_id];
440277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi	memcpy(cls, dev->class, 3);
441277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi
442277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi	return 0;
443277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi}
444277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi
445f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmannint set_device_class(uint16_t dev_id, uint8_t *cls)
446f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann{
447f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann	struct hci_dev *dev;
448f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann
449f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann	ASSERT_DEV_ID;
450f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann	dev = &devices[dev_id];
451f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann	memcpy(dev->class, cls, 3);
452f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann
453f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann	return 0;
454f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann}
455f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann
456dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_version(uint16_t dev_id, char *version, size_t size)
457dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
458dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	struct hci_dev *dev;
459dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	char edr[7], *tmp;
460dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	int err;
461dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
462dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ASSERT_DEV_ID;
463dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
464dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	if (size < 14)
465dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann		return -ENOBUFS;
466dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
467dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	dev = &devices[dev_id];
468dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
46998329bfce1a1ce33cf2f46007196ecc63441465aMarcel Holtmann	if ((dev->lmp_ver == 0x03 || dev->lmp_ver == 0x04) &&
470dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann			(dev->features[3] & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M)))
471dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann		sprintf(edr, " + EDR");
472dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	else
473dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann		edr[0] = '\0';
474dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
475dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	tmp = lmp_vertostr(dev->lmp_ver);
476dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
477dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	if (strlen(tmp) == 0)
478dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann		err = snprintf(version, size, "not assigned");
479dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	else
480dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann		err = snprintf(version, size, "Bluetooth %s%s", tmp, edr);
481dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
482dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	bt_free(tmp);
483dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
484dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	return err;
485dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
486dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
4878586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmannstatic int digi_revision(uint16_t dev_id, char *revision, size_t size)
4888586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann{
4898586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	struct hci_request rq;
4908586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	unsigned char req[] = { 0x07 };
4918586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	unsigned char buf[102];
492dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi	int dd, err;
4938586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
4948586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	dd = hci_open_dev(dev_id);
4958586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	if (dd < 0) {
496dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
497fa7d18bdf518a3ea6cb379a1b765547c58155166Luiz Augusto von Dentz		error("Can't open device hci%d: %s (%d)",
498dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
499dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		return -err;
5008586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	}
5018586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
5028586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	memset(&rq, 0, sizeof(rq));
5038586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	rq.ogf    = OGF_VENDOR_CMD;
5048586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	rq.ocf    = 0x000e;
5058586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	rq.cparam = req;
5068586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	rq.clen   = sizeof(req);
5078586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	rq.rparam = &buf;
5088586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	rq.rlen   = sizeof(buf);
5098586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
5108586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	if (hci_send_req(dd, &rq, 2000) < 0) {
511dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
51226e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann		error("Can't read revision for hci%d: %s (%d)",
513dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
5144c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi		hci_close_dev(dd);
5154c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi		return -err;
5168586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	}
5178586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
5188586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	hci_close_dev(dd);
5198586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
5208586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	return snprintf(revision, size, "%s", buf + 1);
5218586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann}
5228586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
523dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_revision(uint16_t dev_id, char *revision, size_t size)
524dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
5258586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	struct hci_dev *dev;
5268586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	int err;
5278586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
528dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ASSERT_DEV_ID;
529dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
5308586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	dev = &devices[dev_id];
5318586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
5328586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	switch (dev->manufacturer) {
5338586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	case 10:
5348586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann		err = snprintf(revision, size, "Build %d", dev->lmp_subver);
5358586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann		break;
5368586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	case 12:
5378586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann		err = digi_revision(dev_id, revision, size);
5388586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann		break;
5390fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann	case 15:
5400fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann		err = snprintf(revision, size, "%d.%d / %d",
5410fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann				dev->hci_rev & 0xff,
5420fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann				dev->lmp_subver >> 8, dev->lmp_subver & 0xff);
5430fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann		break;
5448586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	default:
5458586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann		err = snprintf(revision, size, "0x%02x", dev->lmp_subver);
5468586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann		break;
5478586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	}
5488586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann
5498586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann	return err;
550dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
551dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
552dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_manufacturer(uint16_t dev_id, char *manufacturer, size_t size)
553dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
554dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	char *tmp;
555dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
556dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ASSERT_DEV_ID;
557dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
558dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	tmp = bt_compidtostr(devices[dev_id].manufacturer);
559dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
560dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	return snprintf(manufacturer, size, "%s", tmp);
561dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
562dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
563dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_company(uint16_t dev_id, char *company, size_t size)
564dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{
565dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	char *tmp, oui[9];
566dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	int err;
567dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
568dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ASSERT_DEV_ID;
569dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
570dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	ba2oui(&devices[dev_id].bdaddr, oui);
571dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	tmp = ouitocomp(oui);
572dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
573dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	err = snprintf(company, size, "%s", tmp);
574dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
575dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	free(tmp);
576dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann
577dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann	return err;
578dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}
5796a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
5800b727924102df07d609be955800793c1f33d6952Marcel Holtmannint set_simple_pairing_mode(uint16_t dev_id, uint8_t mode)
5810b727924102df07d609be955800793c1f33d6952Marcel Holtmann{
5820b727924102df07d609be955800793c1f33d6952Marcel Holtmann	struct hci_dev *dev;
5830b727924102df07d609be955800793c1f33d6952Marcel Holtmann	int dd;
5840b727924102df07d609be955800793c1f33d6952Marcel Holtmann
5850b727924102df07d609be955800793c1f33d6952Marcel Holtmann	ASSERT_DEV_ID;
5860b727924102df07d609be955800793c1f33d6952Marcel Holtmann
5870b727924102df07d609be955800793c1f33d6952Marcel Holtmann	dev = &devices[dev_id];
5880b727924102df07d609be955800793c1f33d6952Marcel Holtmann
5890b727924102df07d609be955800793c1f33d6952Marcel Holtmann	dev->ssp_mode = mode;
5900b727924102df07d609be955800793c1f33d6952Marcel Holtmann
5910b727924102df07d609be955800793c1f33d6952Marcel Holtmann	dd = hci_open_dev(dev_id);
5920b727924102df07d609be955800793c1f33d6952Marcel Holtmann	if (dd < 0) {
593dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		int err = errno;
594dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		error("Can't open device hci%d: %s (%d)",
595dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
596dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		return -err;
5970b727924102df07d609be955800793c1f33d6952Marcel Holtmann	}
5980b727924102df07d609be955800793c1f33d6952Marcel Holtmann
5990b727924102df07d609be955800793c1f33d6952Marcel Holtmann	update_ext_inquiry_response(dd, dev);
6000b727924102df07d609be955800793c1f33d6952Marcel Holtmann
6010b727924102df07d609be955800793c1f33d6952Marcel Holtmann	hci_close_dev(dd);
6020b727924102df07d609be955800793c1f33d6952Marcel Holtmann
6030b727924102df07d609be955800793c1f33d6952Marcel Holtmann	return 0;
6040b727924102df07d609be955800793c1f33d6952Marcel Holtmann}
6050b727924102df07d609be955800793c1f33d6952Marcel Holtmann
6066a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint get_device_name(uint16_t dev_id, char *name, size_t size)
6076a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{
6086a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	char tmp[249];
609dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi	int dd, err;
6106a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6116a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	ASSERT_DEV_ID;
6126a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6136a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	memset(tmp, 0, sizeof(tmp));
6146a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6156a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	dd = hci_open_dev(dev_id);
6166a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	if (dd < 0) {
617dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
618dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		error("Can't open device hci%d: %s (%d)",
619dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
620dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		return -err;
6216a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	}
6226a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6236a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	if (hci_read_local_name(dd, sizeof(tmp), tmp, 2000) < 0) {
624dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
62526e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann		error("Can't read name for hci%d: %s (%d)",
626dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
6274c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi		hci_close_dev(dd);
6284c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi		return -err;
6296a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	}
6306a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6316a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	hci_close_dev(dd);
6326a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6336a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	memcpy(devices[dev_id].name, tmp, 248);
6346a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6356a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	return snprintf(name, size, "%s", tmp);
6366a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann}
6376a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6386a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint set_device_name(uint16_t dev_id, const char *name)
6396a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{
640abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann	struct hci_dev *dev;
641dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi	int dd, err;
6426a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6436a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	ASSERT_DEV_ID;
6446a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
645abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann	dev = &devices[dev_id];
646abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann
6476a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	dd = hci_open_dev(dev_id);
6486a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	if (dd < 0) {
649dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
650dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		error("Can't open device hci%d: %s (%d)",
651dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
652dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		return -err;
6536a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	}
6546a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6556a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	if (hci_write_local_name(dd, name, 5000) < 0) {
656dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi		err = errno;
6573dec6f11d625a351bae0aada4160f3d2de429cddClaudio Takahasi		error("Can't write name for hci%d: %s (%d)",
658dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3Claudio Takahasi					dev_id, strerror(err), err);
6594c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi		hci_close_dev(dd);
6604c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi		return -err;
6616a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	}
6626a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
663272f467beabf0af74ae2beaf3529d076c36a3ee0Luiz Augusto von Dentz	strncpy((char *) dev->name, name, 248);
664abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann
6650b727924102df07d609be955800793c1f33d6952Marcel Holtmann	update_ext_inquiry_response(dd, dev);
666abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann
6676a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	hci_close_dev(dd);
6686a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6696a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	return 0;
6706a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann}
6716a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6726a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint get_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, char *alias, size_t size)
6736a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{
6746a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	char filename[PATH_MAX + 1], addr[18], *tmp;
6756a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	int err;
6766a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6776a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	ASSERT_DEV_ID;
6786a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6796a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	ba2str(&devices[dev_id].bdaddr, addr);
68017152022a5844275a6f3e3e71ef5b32dc2c0ec04Marcel Holtmann	create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases");
6816a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6826a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	ba2str(bdaddr, addr);
6836a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6846a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	tmp = textfile_get(filename, addr);
6856a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	if (!tmp)
6866a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann		return -ENXIO;
6876a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6886a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	err = snprintf(alias, size, "%s", tmp);
6896a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6906a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	free(tmp);
6916a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6926a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	return err;
6936a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann}
6946a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6956a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint set_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, const char *alias)
6966a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{
6976a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	char filename[PATH_MAX + 1], addr[18];
6986a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
6996a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	ASSERT_DEV_ID;
7006a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
7016a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	ba2str(&devices[dev_id].bdaddr, addr);
70217152022a5844275a6f3e3e71ef5b32dc2c0ec04Marcel Holtmann	create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases");
7036a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
7046a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
7056a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
7066a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	ba2str(bdaddr, addr);
7076a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann
7086a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann	return textfile_put(filename, addr, alias);
7096a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann}
710129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann
7118afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentzint remove_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr)
7128afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz{
7138afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	char filename[PATH_MAX + 1], addr[18];
7148afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
7158afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	ASSERT_DEV_ID;
7168afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
7178afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	ba2str(&devices[dev_id].bdaddr, addr);
7188afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases");
7198afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
7208afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
7218afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
7228afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	ba2str(bdaddr, addr);
7238afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
7248afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	return textfile_del(filename, addr);
7258afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz}
7268afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
727129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmannint get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr)
728129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann{
729129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann	struct hci_dev *dev;
730129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann	int size;
731129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann
732129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann	ASSERT_DEV_ID;
733129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann
734129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann	dev = &devices[dev_id];
735129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann
736129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann	switch (dev->manufacturer) {
737129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann	default:
738129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann		size = -ENOENT;
739129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann		break;
740129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann	}
741129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann
742129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann	return size;
743129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann}
74486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
745e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic void device_free(gpointer user_data)
74686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{
747e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	struct device *device = user_data;
748e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi
749fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite	if (device->agent)
750fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite		agent_destroy(device->agent, FALSE);
751ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi	g_slist_foreach(device->uuids, (GFunc) g_free, NULL);
752ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi	g_slist_free(device->uuids);
753f4662ad94310c08fd83e2cd9acd4ab0a03379ceeLuiz Augusto von Dentz	g_free(device->address);
75486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	g_free(device->path);
75586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	g_free(device);
75686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann}
75786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
758e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *disconnect(DBusConnection *conn,
759e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				DBusMessage *msg, void *user_data)
7602c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{
761e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return dbus_message_new_method_return(msg);
7622c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}
7632c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
764769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentzstatic gboolean device_is_paired(struct device *device)
765769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{
766769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
767769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	char filename[PATH_MAX + 1], *str;
768769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	gboolean ret;
769769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
770769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	create_name(filename, PATH_MAX, STORAGEDIR,
771769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz			adapter->address, "linkkeys");
772769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	str = textfile_caseget(filename, device->address);
773769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	ret = str ? TRUE : FALSE;
774769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	g_free(str);
775769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
776769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	return ret;
777769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz}
778769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
779769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentzstatic char *device_get_name(struct device *device)
780769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{
781769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
782769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	char filename[PATH_MAX + 1];
783769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
784769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names");
785769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	return textfile_caseget(filename, device->address);
786769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz}
787769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz
788e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *get_properties(DBusConnection *conn,
789e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				DBusMessage *msg, void *user_data)
7902c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{
7914e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	struct device *device = user_data;
7924e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	struct adapter *adapter = device->adapter;
7934e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	DBusMessage *reply;
7944e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	DBusMessageIter iter;
7954e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	DBusMessageIter dict;
7964e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	bdaddr_t src, dst;
797769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	char path[MAX_PATH_LENGTH];
7984e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	char buf[64];
7994e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	const char *ptr;
800769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	char *name, *ppath, **uuids;
8014e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_bool_t boolean;
8024e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	uint32_t class;
803769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	int i;
804769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	GSList *l;
8054e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8064e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	reply = dbus_message_new_method_return(msg);
8074e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	if (!reply)
808e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return NULL;
8094e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8104e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_init_append(reply, &iter);
8114e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8124e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
8134e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
8144e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
8154e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
8164e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8174e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Address */
8184e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Address", DBUS_TYPE_STRING,
8194e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			&device->address);
8204e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8214e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Name */
822769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	name = device_get_name(device);
8238afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	if (name) {
8244e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Name",
8258afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz				DBUS_TYPE_STRING, &name);
8264e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	}
8274e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8284e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	str2ba(adapter->address, &src);
8294e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	str2ba(device->address, &dst);
8304e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8314e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Class */
8324e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	if (read_remote_class(&src, &dst, &class) == 0) {
8334e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Class",
8344e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz				DBUS_TYPE_UINT32, &class);
8354e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	}
8364e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8374e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Alias */
8384e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	if (get_device_alias(adapter->dev_id, &dst, buf, sizeof(buf)) > 0) {
8394e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		ptr = buf;
8404e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Alias",
8414e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz				DBUS_TYPE_STRING, &ptr);
8428afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	} else if (name) {
8438afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		dbus_message_iter_append_dict_entry(&dict, "Alias",
8448afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz				DBUS_TYPE_STRING, &name);
8458afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		free(name);
8464e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	}
8474e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8484e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Paired */
849769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	boolean = device_is_paired(device);
8504e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Paired",
8514e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_TYPE_BOOLEAN, &boolean);
8524e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8534e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Trusted */
8544e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	boolean = read_trust(&src, device->address, GLOBAL_TRUST);
8554e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Trusted",
8564e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_TYPE_BOOLEAN, &boolean);
8574e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8584e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	/* Connected */
8594e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	if (g_slist_find_custom(adapter->active_conn, &dst,
8604e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz				active_conn_find_by_bdaddr))
8614e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		boolean = TRUE;
8624e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	else
8634e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz		boolean = FALSE;
8644e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
8654e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Connected",
8664e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz			DBUS_TYPE_BOOLEAN, &boolean);
8674e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
868ba93fb91ea81a35be0834ac395650e020a6b3fd3Claudio Takahasi	/* UUIDs */
869769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
870769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	for (i = 0, l = device->uuids; l; l = l->next, i++)
871769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz		uuids[i] = l->data;
8728afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "UUIDs",
873769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz			DBUS_TYPE_ARRAY, &uuids);
874769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz	g_free(uuids);
8754e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
87674fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz	/* Adapter */
87774fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz	snprintf(path, sizeof(path), "/hci%d", adapter->dev_id);
87874fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz	ppath = path;
87974fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz	dbus_message_iter_append_dict_entry(&dict, "Adapter",
880fa7d18bdf518a3ea6cb379a1b765547c58155166Luiz Augusto von Dentz			DBUS_TYPE_OBJECT_PATH, &ppath);
88174fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz
8824e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	dbus_message_iter_close_container(&iter, &dict);
8834e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz
884e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return reply;
8852c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}
8862c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
887e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
8887fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					const char *alias, void *data)
8897fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{
8907fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	struct device *device = data;
8917fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
8927fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	bdaddr_t bdaddr;
8937fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	int ecode;
894cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz	char *str, filename[PATH_MAX + 1], path[MAX_PATH_LENGTH];
8957fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
8967fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	str2ba(device->address, &bdaddr);
8977fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
8988afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	/* Remove alias if empty string */
8998afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	if (g_str_equal(alias, "")) {
9008afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
9018afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz				"names");
9028afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		str = textfile_caseget(filename, device->address);
9038afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		ecode = remove_device_alias(adapter->dev_id, &bdaddr);
9048afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	} else {
9058afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		str = g_strdup(alias);
9068afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz		ecode = set_device_alias(adapter->dev_id, &bdaddr, alias);
9078afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz	}
9088afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
9097fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (ecode < 0)
910e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return g_dbus_create_error(msg,
911e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				ERROR_INTERFACE ".Failed",
912e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				strerror(-ecode));
9137fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
914cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id);
915cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz
916cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz	dbus_connection_emit_signal(conn, path,
917cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz					ADAPTER_INTERFACE, "RemoteAliasChanged",
918cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz					DBUS_TYPE_STRING, &device->address,
919cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz					DBUS_TYPE_STRING, &str,
920cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz					DBUS_TYPE_INVALID);
921cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz
9227fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg),
9237fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					DEVICE_INTERFACE, "Alias",
9248afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz					DBUS_TYPE_STRING, &str);
9258afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz
926cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz	g_free(str);
9277fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
928e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return dbus_message_new_method_return(msg);
9297fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz}
9307fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
931e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
9327fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					dbus_bool_t value, void *data)
9337fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{
9347fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	struct device *device = data;
9357fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
9367fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	bdaddr_t local;
937cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz	char path[MAX_PATH_LENGTH];
9387fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9397fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	str2ba(adapter->address, &local);
9407fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9417fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	write_trust(&local, device->address, GLOBAL_TRUST, value);
9427fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
943cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id);
944cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz
945cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz	dbus_connection_emit_signal(conn, path,
94640d6167dd9cec68fc24b331692a8f7f3ec63f95aVinicius Costa Gomes					ADAPTER_INTERFACE,
94740d6167dd9cec68fc24b331692a8f7f3ec63f95aVinicius Costa Gomes					value ? "TrustAdded" : "TrustRemoved",
948cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz					DBUS_TYPE_STRING, &device->address,
949cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz					DBUS_TYPE_INVALID);
950cbace5633e81298844f4223ca1ca1c5d767dde5bLuiz Augusto von Dentz
9517fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg),
9527fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					DEVICE_INTERFACE, "Trusted",
9537fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz					DBUS_TYPE_BOOLEAN, &value);
9547fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
955e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return dbus_message_new_method_return(msg);
9567fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz}
9577fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
958e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic inline DBusMessage *invalid_args(DBusMessage *msg)
959e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi{
960e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return g_dbus_create_error(msg,
961e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			ERROR_INTERFACE ".InvalidArguments",
962e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			"Invalid arguments in method call");
963e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi}
964e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi
965e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_property(DBusConnection *conn,
966e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				DBusMessage *msg, void *data)
9672c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{
9687fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	DBusMessageIter iter;
9697fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	DBusMessageIter sub;
9707fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	const char *property;
9717fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9727fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (!dbus_message_iter_init(msg, &iter))
973e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return invalid_args(msg);
9747fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9757fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
976e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return invalid_args(msg);
9777fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9787fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_message_iter_get_basic(&iter, &property);
9797fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_message_iter_next(&iter);
9807fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9817fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
982e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi		return invalid_args(msg);
9837fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	dbus_message_iter_recurse(&iter, &sub);
9847fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9857fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	if (g_str_equal("Trusted", property)) {
9867fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		dbus_bool_t value;
9877fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9887fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
989e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			return invalid_args(msg);
9907fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &value);
9917fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9927fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		return set_trust(conn, msg, value, data);
9937fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	} else if (g_str_equal("Alias", property)) {
9947fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		char *alias;
9957fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
9967fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
997e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi			return invalid_args(msg);
9987fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		dbus_message_iter_get_basic(&sub, &alias);
9997fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
10007fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz		return set_alias(conn, msg, alias, data);
10017fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz	}
10027fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz
1003e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	return invalid_args(msg);
10042c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}
10052c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
1006e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusMethodTable device_methods[] = {
1007e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	{ "GetProperties",	"",	"a{sv}",	get_properties	},
1008e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	{ "SetProperty",	"sv",	"",		set_property	},
1009e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	{ "Disconnect",		"",	"",		disconnect	},
10102c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes	{ NULL, NULL, NULL, NULL }
10112c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes};
10122c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
1013e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusSignalTable device_signals[] = {
10142c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes	{ "PropertyChanged",			"sv"	},
10152c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes	{ "DisconnectRequested",		""	},
10162c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes	{ NULL, NULL }
10172c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes};
10182c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes
101981cfb0fc353b88658aec4c1ee0eb6cc5f851df41Claudio Takahasistruct device *device_create(DBusConnection *conn, struct adapter *adapter,
102081cfb0fc353b88658aec4c1ee0eb6cc5f851df41Claudio Takahasi					const gchar *address, GSList *uuids)
102186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{
1022ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite	gchar *address_up;
10232c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes	struct device *device;
102486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
10252c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes	device = g_try_malloc0(sizeof(struct device));
102686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	if (device == NULL)
102786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann		return NULL;
102886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
1029ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite	address_up = g_ascii_strup(address, -1);
10304bab9b442ec3e2e06157014c5d27641c79434e2aClaudio Takahasi	device->path = g_strdup_printf("/hci%d/dev_%s",
1031ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite				adapter->dev_id, address_up);
103286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	g_strdelimit(device->path, ":", '_');
1033ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite	g_free(address_up);
103486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
103586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	debug("Creating device %s", device->path);
103686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
1037e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi	if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE,
1038e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				device_methods, device_signals, NULL,
1039e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi				device, device_free) == FALSE) {
104086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann		device_free(device);
104186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann		return NULL;
104286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann	}
1043da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi
10444e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz	device->address = g_strdup(address);
1045da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi	device->adapter = adapter;
10465d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi	device->uuids = uuids;
1047da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi
10486bfa88d706cc57a0c975c980dabec5d8ed67dcc0Claudio Takahasi	return device;
104986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann}
105086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann
10513d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentzvoid device_remove(struct device *device, DBusConnection *conn)
105275add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi{
1053b29381cae56e509c87cfc6ce12ea34d19dec6f55Luiz Augusto von Dentz	debug("Removing device %s", device->path);
105475add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi
105581cfb0fc353b88658aec4c1ee0eb6cc5f851df41Claudio Takahasi	dbus_connection_destroy_object_path(conn, device->path);
105686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann}
1057ff296428a08dee619db1cc702146faefa91087faCidorvan Leite
1058ff296428a08dee619db1cc702146faefa91087faCidorvan Leitegint device_address_cmp(struct device *device, const gchar *address)
1059ff296428a08dee619db1cc702146faefa91087faCidorvan Leite{
1060ff296428a08dee619db1cc702146faefa91087faCidorvan Leite	return strcasecmp(device->address, address);
1061ff296428a08dee619db1cc702146faefa91087faCidorvan Leite}
10623d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
1063601e16bf2f6677cf1a7d3fd12dcb127923e216b4Luiz Augusto von Dentzstatic void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
10643d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{
10653d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	sdp_list_t *seq, *next, *svcclass;
10663d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	struct browse_req *req = user_data;
10673d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	struct device *device = req->device;
10683d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
10693d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	bdaddr_t src, dst;
10703d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	char **uuids;
10713d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	int i;
10723d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	GSList *l;
10733d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	DBusMessage *reply;
10743d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
10753d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	if (err < 0)
10767b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentz		goto proceed;
10773d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
10783d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	for (seq = recs; seq; seq = next) {
10793d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		sdp_record_t *rec = (sdp_record_t *) seq->data;
10803d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
10813d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		if (!rec)
10823d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz			break;
10833d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
10843d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		svcclass = NULL;
10853d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		if (sdp_get_service_classes(rec, &svcclass) == 0) {
10863d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz			/* Extract the first element and skip the remainning */
10873d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz			gchar *uuid_str = bt_uuid2string(svcclass->data);
10883d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz			if (uuid_str) {
10893d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz				if (!g_slist_find_custom(device->uuids, uuid_str,
10903d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz							(GCompareFunc) strcmp))
10913d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz					device->uuids = g_slist_insert_sorted(device->uuids,
10923d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz						uuid_str, (GCompareFunc) strcmp);
10933d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz				else
10943d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz					g_free(uuid_str);
10953d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz			}
10963d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz			sdp_list_free(svcclass, free);
10973d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		}
10983d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
10993d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		next = seq->next;
11003d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	}
11013d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11023d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	sdp_list_free(recs, (sdp_free_func_t) sdp_record_free);
11033d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11043d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	/* Store the device's profiles in the filesystem */
11053d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	str2ba(adapter->address, &src);
11063d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	str2ba(device->address, &dst);
11073d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	if (device->uuids) {
11083d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		gchar *str = bt_list2string(device->uuids);
11093d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		write_device_profiles(&src, &dst, str);
11103d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		g_free(str);
11113d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	} else
11123d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		write_device_profiles(&src, &dst, "");
11133d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11143d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
11153d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	for (i = 0, l = device->uuids; l; l = l->next, i++)
11163d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz		uuids[i] = l->data;
11173d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11183d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	dbus_connection_emit_property_changed(req->conn, device->path,
11193d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz					DEVICE_INTERFACE, "UUIDs",
11203d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz					DBUS_TYPE_ARRAY, &uuids);
11213d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	g_free(uuids);
11223d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11237b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentzproceed:
11248d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz	dbus_connection_emit_signal(req->conn, dbus_message_get_path(req->msg),
11258d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz				ADAPTER_INTERFACE, "DeviceCreated",
11268d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz				DBUS_TYPE_OBJECT_PATH, &device->path,
11278d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz				DBUS_TYPE_INVALID);
11288d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz
11293d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	/* Reply create device request */
11303d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	reply = dbus_message_new_method_return(req->msg);
11313d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	if (!reply)
11327b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentz		goto fail;
11333d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11343d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
11353d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz					DBUS_TYPE_INVALID);
11363d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11373d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	send_message_and_unref(req->conn, reply);
11383d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11397b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentzfail:
11403d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	dbus_message_unref(req->msg);
11413d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	dbus_connection_unref(req->conn);
11423d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	g_free(req);
11433d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}
11443d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11453d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentzint device_browse(struct device *device, DBusConnection *conn,
11463d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz			DBusMessage *msg)
11473d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{
11483d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	struct adapter *adapter = device->adapter;
11493d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	struct browse_req *req;
11503d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	bdaddr_t src, dst;
11513d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11523d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req = g_new0(struct browse_req, 1);
11533d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req->conn = dbus_connection_ref(conn);
11543d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req->msg = dbus_message_ref(msg);
11553d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	req->device = device;
11563d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz
11573d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	str2ba(adapter->address, &src);
11583d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	str2ba(device->address, &dst);
11593d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz	return bt_discover_services(&src, &dst, browse_cb, req, NULL);
11603d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}
116124cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
116224cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmannstatic GSList *drivers = NULL;
116324cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
116424cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmannint btd_register_device_driver(struct btd_device_driver *driver)
116524cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann{
116624cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	const char **uuid;
116724cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
116824cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	drivers = g_slist_append(drivers, driver);
116924cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
117024cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	for (uuid = driver->uuids; *uuid; uuid++) {
117124cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann		debug("name %s uuid %s", driver->name, *uuid);
117224cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	}
117324cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
1174de29b2ff1d8531fd0583e49e4b8840198681ffe8Marcel Holtmann	register_service(driver->name, driver->uuids);
1175de29b2ff1d8531fd0583e49e4b8840198681ffe8Marcel Holtmann
117624cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	return 0;
117724cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann}
117824cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann
117924cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmannvoid btd_unregister_device_driver(struct btd_device_driver *driver)
118024cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann{
1181de29b2ff1d8531fd0583e49e4b8840198681ffe8Marcel Holtmann	unregister_service(driver->name);
1182de29b2ff1d8531fd0583e49e4b8840198681ffe8Marcel Holtmann
118324cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann	drivers = g_slist_remove(drivers, driver);
118424cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann}
1185