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