device.c revision 5d5d89bb2dbc295443900d59d8a7172dc2f279c7
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 4686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <dbus/dbus.h> 4786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 4886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "dbus-helper.h" 4986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 5026e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann#include "hcid.h" 51eb4d49890ca8a4d8f567e81fdf82b6903d30f326Marcel Holtmann#include "sdpd.h" 5226e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann 5386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "logging.h" 546a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include "textfile.h" 55dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include "oui.h" 56dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 572c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#include "adapter.h" 5886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "device.h" 59da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi#include "dbus-common.h" 6086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 61dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#define MAX_DEVICES 16 62dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 632c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#define DEVICE_INTERFACE "org.bluez.Device" 642c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 65dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstruct hci_peer { 66dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct timeval lastseen; 67dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct timeval lastused; 68dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 69dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann bdaddr_t bdaddr; 70dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint32_t class; 71dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann int8_t rssi; 72dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t data[240]; 73dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t name[248]; 74dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 75dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t pscan_rep_mode; 76dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t pscan_period_mode; 77dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t pscan_mode; 78dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint16_t clock_offset; 79dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 80dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_peer *next; 81dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}; 82dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 83dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstruct hci_conn { 84dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann bdaddr_t bdaddr; 85dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint16_t handle; 86dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 87dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_conn *next; 88dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}; 89dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 90dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstruct hci_dev { 9157eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann int ignore; 9257eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann 93dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann bdaddr_t bdaddr; 94dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t features[8]; 95dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t lmp_ver; 96dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint16_t lmp_subver; 970d7408aa899f84210d0e6418ee528636292276bcMarcel Holtmann uint16_t hci_rev; 98dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint16_t manufacturer; 99dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 1000b727924102df07d609be955800793c1f33d6952Marcel Holtmann uint8_t ssp_mode; 1016a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann uint8_t name[248]; 102277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi uint8_t class[3]; 1036a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 104dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_peer *peers; 105dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_conn *conns; 106dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}; 107dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 108dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstatic struct hci_dev devices[MAX_DEVICES]; 109dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 110dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#define ASSERT_DEV_ID { if (dev_id >= MAX_DEVICES) return -ERANGE; } 111dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 11252a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannvoid init_adapters(void) 113dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 114dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann int i; 115dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 116dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann for (i = 0; i < MAX_DEVICES; i++) 117dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann memset(devices + i, 0, sizeof(struct hci_dev)); 118dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 119dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 120ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedbergstatic int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr) 121ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg{ 122ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg int dd; 123ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 124ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg dd = hci_open_dev(dev_id); 125ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg if (dd < 0) { 126ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg error("Can't open device hci%d", 1270b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(errno), errno); 128ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg return -errno; 129ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg } 130ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 131ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg if (hci_read_bd_addr(dd, bdaddr, 2000) < 0) { 132fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim int err = errno; 133ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg error("Can't read address for hci%d: %s (%d)", 1340b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(errno), errno); 135ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg hci_close_dev(dd); 136fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim return -err; 137ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg } 138ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 139ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg hci_close_dev(dd); 140ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 141ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg return 0; 142ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg} 143ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 14452a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint add_adapter(uint16_t dev_id) 145dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 146dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev *dev; 147dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev_info di; 148dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 149dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 150dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 151dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev = &devices[dev_id]; 152dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 15357eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann if (hci_devinfo(dev_id, &di) < 0) { 15457eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann dev->ignore = 1; 155dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return -errno; 15657eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann } 15757eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann 15857eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann if (hci_test_bit(HCI_RAW, &di.flags)) { 15957eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann info("Device hci%d is using raw mode", dev_id); 16057eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann dev->ignore = 1; 16157eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann } 162dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 163ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg if (bacmp(&di.bdaddr, BDADDR_ANY)) 164ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg bacpy(&dev->bdaddr, &di.bdaddr); 165ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg else { 1660b727924102df07d609be955800793c1f33d6952Marcel Holtmann int err = device_read_bdaddr(dev_id, &dev->bdaddr); 1670b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (err < 0) 1680b727924102df07d609be955800793c1f33d6952Marcel Holtmann return err; 169ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg } 170dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann memcpy(dev->features, di.features, 8); 171dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 172dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann info("Device hci%d has been added", dev_id); 173dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 174dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return 0; 175dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 176dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 17752a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint remove_adapter(uint16_t dev_id) 178dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 179dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev *dev; 180dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 181dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 182dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 183dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev = &devices[dev_id]; 184dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 185dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann memset(dev, 0, sizeof(struct hci_dev)); 186dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 187dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann info("Device hci%d has been removed", dev_id); 188dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 189dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return 0; 190dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 191dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 192b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmannstatic inline uint8_t get_inquiry_mode(struct hci_dev *dev) 193b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann{ 194b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann if (dev->features[6] & LMP_EXT_INQ) 195b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann return 2; 196b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 197b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann if (dev->features[3] & LMP_RSSI_INQ) 198b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann return 1; 199b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 200e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann if (dev->manufacturer == 11 && 201e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann dev->hci_rev == 0x00 && dev->lmp_subver == 0x0757) 202e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann return 1; 203e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann 204431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann if (dev->manufacturer == 15) { 205431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann if (dev->hci_rev == 0x03 && dev->lmp_subver == 0x6963) 206431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann return 1; 207431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann if (dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963) 208431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann return 1; 209b98c93ed852d29557fe71de5262357b704f85592Marcel Holtmann if (dev->hci_rev == 0x00 && dev->lmp_subver == 0x6965) 210b98c93ed852d29557fe71de5262357b704f85592Marcel Holtmann return 1; 211431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann } 21219fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann 21319fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann if (dev->manufacturer == 31 && 21419fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann dev->hci_rev == 0x2005 && dev->lmp_subver == 0x1805) 21519fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann return 1; 21619fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann 217b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann return 0; 218b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann} 219b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 2200b727924102df07d609be955800793c1f33d6952Marcel Holtmannstatic void update_ext_inquiry_response(int dd, struct hci_dev *dev) 2210b727924102df07d609be955800793c1f33d6952Marcel Holtmann{ 2220b727924102df07d609be955800793c1f33d6952Marcel Holtmann uint8_t fec = 0, data[240]; 2230b727924102df07d609be955800793c1f33d6952Marcel Holtmann 2240b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (!(dev->features[6] & LMP_EXT_INQ)) 2250b727924102df07d609be955800793c1f33d6952Marcel Holtmann return; 2260b727924102df07d609be955800793c1f33d6952Marcel Holtmann 2270b727924102df07d609be955800793c1f33d6952Marcel Holtmann memset(data, 0, sizeof(data)); 2280b727924102df07d609be955800793c1f33d6952Marcel Holtmann 229eb4d49890ca8a4d8f567e81fdf82b6903d30f326Marcel Holtmann if (dev->ssp_mode > 0) 230eb4d49890ca8a4d8f567e81fdf82b6903d30f326Marcel Holtmann create_ext_inquiry_response((char *) dev->name, data); 2310b727924102df07d609be955800793c1f33d6952Marcel Holtmann 2320b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) 2330b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't write extended inquiry response: %s (%d)", 2340b727924102df07d609be955800793c1f33d6952Marcel Holtmann strerror(errno), errno); 2350b727924102df07d609be955800793c1f33d6952Marcel Holtmann} 2360b727924102df07d609be955800793c1f33d6952Marcel Holtmann 23752a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint start_adapter(uint16_t dev_id) 238dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 239dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev *dev; 240dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_version ver; 241b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann uint8_t features[8], inqmode; 2423dfe93f27c455e07be72a38239f4f8335ba6a860Marcel Holtmann uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 }; 2430b727924102df07d609be955800793c1f33d6952Marcel Holtmann char name[249]; 244277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi int dd, err; 245dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 246dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 247dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 248dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev = &devices[dev_id]; 249dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 25057eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann if (dev->ignore) 25157eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann return 0; 25257eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann 253dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dd = hci_open_dev(dev_id); 254dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (dd < 0) { 25526e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't open device hci%d", 256dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev_id, strerror(errno), errno); 257dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return -errno; 258dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann } 259dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 260dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (hci_read_local_version(dd, &ver, 1000) < 0) { 261fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim int err = errno; 26226e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't read version info for hci%d: %s (%d)", 263dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev_id, strerror(errno), errno); 264276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmann hci_close_dev(dd); 265fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim return -err; 266dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann } 267dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 2680fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann dev->hci_rev = ver.hci_rev; 269dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev->lmp_ver = ver.lmp_ver; 270dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev->lmp_subver = ver.lmp_subver; 271dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev->manufacturer = ver.manufacturer; 272dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 273b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann if (hci_read_local_features(dd, features, 1000) < 0) { 274277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi err = errno; 275b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann error("Can't read features for hci%d: %s (%d)", 276277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi dev_id, strerror(err), err); 277276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmann hci_close_dev(dd); 278fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim return -err; 279b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann } 280b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 281b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann memcpy(dev->features, features, 8); 282b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 283277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi if (hci_read_class_of_dev(dd, dev->class, 1000) < 0) { 284277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi err = errno; 2850b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't read class of device on hci%d: %s (%d)", 2860b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(err), err); 287277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi hci_close_dev(dd); 288277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi return -err; 289277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi } 290277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 2910b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (hci_read_local_name(dd, sizeof(name), name, 2000) < 0) { 2920b727924102df07d609be955800793c1f33d6952Marcel Holtmann err = errno; 2930b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't read local name on hci%d: %s (%d)", 2940b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(err), err); 2950b727924102df07d609be955800793c1f33d6952Marcel Holtmann hci_close_dev(dd); 2960b727924102df07d609be955800793c1f33d6952Marcel Holtmann return -err; 2970b727924102df07d609be955800793c1f33d6952Marcel Holtmann } 298b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 2990b727924102df07d609be955800793c1f33d6952Marcel Holtmann memcpy(dev->name, name, 248); 3000b727924102df07d609be955800793c1f33d6952Marcel Holtmann 3010b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (!(features[6] & LMP_SIMPLE_PAIR)) 3020b727924102df07d609be955800793c1f33d6952Marcel Holtmann goto setup; 3030b727924102df07d609be955800793c1f33d6952Marcel Holtmann 3040b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (hci_read_simple_pairing_mode(dd, &dev->ssp_mode, 1000) < 0) { 3050b727924102df07d609be955800793c1f33d6952Marcel Holtmann err = errno; 3060b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't read simple pairing mode on hci%d: %s (%d)", 3070b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(err), err); 308276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmann hci_close_dev(dd); 309fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim return -err; 310b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann } 311b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 3120b727924102df07d609be955800793c1f33d6952Marcel Holtmannsetup: 31357290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann if (ver.hci_rev > 1) { 31457290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann if (features[5] & LMP_SNIFF_SUBR) 31557290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann events[5] |= 0x20; 31657290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann 317a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann if (features[5] & LMP_PAUSE_ENC) 318a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann events[5] |= 0x80; 319a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann 32057290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann if (features[6] & LMP_EXT_INQ) 32157290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann events[5] |= 0x40; 32257290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann 323a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann if (features[6] & LMP_NFLUSH_PKTS) 324a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann events[7] |= 0x01; 325f4051e4e1bc3a5a00fc74b5b5eb7eb3794f67310Johan Hedberg 32657290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann if (features[7] & LMP_LSTO) 32757290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann events[6] |= 0x80; 32857290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann 3290b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (features[6] & LMP_SIMPLE_PAIR) { 3300b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x01; /* IO Capability Request */ 3310b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x02; /* IO Capability Response */ 3320b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x04; /* User Confirmation Request */ 3330b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x08; /* User Passkey Request */ 3340b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x10; /* Remote OOB Data Request */ 3350b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x20; /* Simple Pairing Complete */ 3360b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[7] |= 0x04; /* User Passkey Notification */ 3370b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[7] |= 0x08; /* Keypress Notification */ 3380b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[7] |= 0x10; /* Remote Host Supported Features Notification */ 3390b727924102df07d609be955800793c1f33d6952Marcel Holtmann } 3400b727924102df07d609be955800793c1f33d6952Marcel Holtmann 34157290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann hci_send_cmd(dd, OGF_HOST_CTL, OCF_SET_EVENT_MASK, 34257290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann sizeof(events), events); 34357290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann } 34457290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann 345c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann if (read_local_name(&dev->bdaddr, name) == 0) { 346c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann memcpy(dev->name, name, 248); 347c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann hci_write_local_name(dd, name, 5000); 348c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann } 349c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann 3500b727924102df07d609be955800793c1f33d6952Marcel Holtmann update_ext_inquiry_response(dd, dev); 3510b727924102df07d609be955800793c1f33d6952Marcel Holtmann 3520b727924102df07d609be955800793c1f33d6952Marcel Holtmann inqmode = get_inquiry_mode(dev); 3530b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (inqmode < 1) 3540b727924102df07d609be955800793c1f33d6952Marcel Holtmann goto done; 3550b727924102df07d609be955800793c1f33d6952Marcel Holtmann 3560b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (hci_write_inquiry_mode(dd, inqmode, 1000) < 0) { 3570b727924102df07d609be955800793c1f33d6952Marcel Holtmann int err = errno; 3580b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't write inquiry mode for hci%d: %s (%d)", 3590b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(errno), err); 3600b727924102df07d609be955800793c1f33d6952Marcel Holtmann hci_close_dev(dd); 3610b727924102df07d609be955800793c1f33d6952Marcel Holtmann return -err; 3620b727924102df07d609be955800793c1f33d6952Marcel Holtmann } 3630b727924102df07d609be955800793c1f33d6952Marcel Holtmann 364276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmanndone: 365dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann hci_close_dev(dd); 366dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 367dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann info("Device hci%d has been activated", dev_id); 368dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 369dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return 0; 370dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 371dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 37252a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint stop_adapter(uint16_t dev_id) 373dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 374dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 375dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 376dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann info("Device hci%d has been disabled", dev_id); 377dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 378dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return 0; 379dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 380dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 3810e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmannint update_adapter(uint16_t dev_id) 3820e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann{ 3830e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann struct hci_dev *dev; 3840e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann int dd; 3850e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3860e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann ASSERT_DEV_ID; 3870e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3880e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann dev = &devices[dev_id]; 3890e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3900e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann if (dev->ignore) 3910e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann return 0; 3920e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3930e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann dd = hci_open_dev(dev_id); 3940e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann if (dd < 0) { 3950e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann error("Can't open device hci%d", 3960e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann dev_id, strerror(errno), errno); 3970e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann return -errno; 3980e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann } 3990e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 4000e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann update_ext_inquiry_response(dd, dev); 4010e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 4020e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann hci_close_dev(dd); 4030e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 4040e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann return 0; 4050e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann} 4060e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 407dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_address(uint16_t dev_id, char *address, size_t size) 408dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 4098586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann struct hci_dev *dev; 4108586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 411dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 412dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 413dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (size < 18) 414dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return -ENOBUFS; 415dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 4168586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dev = &devices[dev_id]; 4178586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 4188586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann return ba2str(&dev->bdaddr, address); 419dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 420dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 421277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasiint get_device_class(uint16_t dev_id, uint8_t *cls) 422277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi{ 423277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi struct hci_dev *dev; 424277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 425277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi ASSERT_DEV_ID; 426277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 427277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi dev = &devices[dev_id]; 428277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi memcpy(cls, dev->class, 3); 429277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 430277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi return 0; 431277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi} 432277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 433f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmannint set_device_class(uint16_t dev_id, uint8_t *cls) 434f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann{ 435f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann struct hci_dev *dev; 436f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann 437f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann ASSERT_DEV_ID; 438f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann dev = &devices[dev_id]; 439f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann memcpy(dev->class, cls, 3); 440f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann 441f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann return 0; 442f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann} 443f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann 444dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_version(uint16_t dev_id, char *version, size_t size) 445dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 446dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev *dev; 447dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann char edr[7], *tmp; 448dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann int err; 449dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 450dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 451dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 452dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (size < 14) 453dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return -ENOBUFS; 454dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 455dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev = &devices[dev_id]; 456dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 45798329bfce1a1ce33cf2f46007196ecc63441465aMarcel Holtmann if ((dev->lmp_ver == 0x03 || dev->lmp_ver == 0x04) && 458dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann (dev->features[3] & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M))) 459dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann sprintf(edr, " + EDR"); 460dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann else 461dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann edr[0] = '\0'; 462dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 463dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann tmp = lmp_vertostr(dev->lmp_ver); 464dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 465dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (strlen(tmp) == 0) 466dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann err = snprintf(version, size, "not assigned"); 467dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann else 468dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann err = snprintf(version, size, "Bluetooth %s%s", tmp, edr); 469dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 470dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann bt_free(tmp); 471dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 472dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return err; 473dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 474dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 4758586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmannstatic int digi_revision(uint16_t dev_id, char *revision, size_t size) 4768586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann{ 4778586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann struct hci_request rq; 4788586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann unsigned char req[] = { 0x07 }; 4798586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann unsigned char buf[102]; 4808586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann int dd; 4818586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 4828586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dd = hci_open_dev(dev_id); 4838586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann if (dd < 0) { 48426e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't open device hci%d", 4858586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dev_id, strerror(errno), errno); 4868586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann return -errno; 4878586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann } 4888586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 4898586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann memset(&rq, 0, sizeof(rq)); 4908586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.ogf = OGF_VENDOR_CMD; 4918586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.ocf = 0x000e; 4928586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.cparam = req; 4938586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.clen = sizeof(req); 4948586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.rparam = &buf; 4958586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.rlen = sizeof(buf); 4968586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 4978586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann if (hci_send_req(dd, &rq, 2000) < 0) { 4984c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi int err = errno; 49926e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't read revision for hci%d: %s (%d)", 5008586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dev_id, strerror(errno), errno); 5014c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi hci_close_dev(dd); 5024c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi return -err; 5038586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann } 5048586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 5058586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann hci_close_dev(dd); 5068586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 5078586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann return snprintf(revision, size, "%s", buf + 1); 5088586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann} 5098586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 510dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_revision(uint16_t dev_id, char *revision, size_t size) 511dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 5128586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann struct hci_dev *dev; 5138586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann int err; 5148586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 515dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 516dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 5178586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dev = &devices[dev_id]; 5188586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 5198586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann switch (dev->manufacturer) { 5208586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann case 10: 5218586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann err = snprintf(revision, size, "Build %d", dev->lmp_subver); 5228586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann break; 5238586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann case 12: 5248586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann err = digi_revision(dev_id, revision, size); 5258586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann break; 5260fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann case 15: 5270fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann err = snprintf(revision, size, "%d.%d / %d", 5280fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann dev->hci_rev & 0xff, 5290fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann dev->lmp_subver >> 8, dev->lmp_subver & 0xff); 5300fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann break; 5318586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann default: 5328586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann err = snprintf(revision, size, "0x%02x", dev->lmp_subver); 5338586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann break; 5348586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann } 5358586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 5368586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann return err; 537dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 538dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 539dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_manufacturer(uint16_t dev_id, char *manufacturer, size_t size) 540dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 541dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann char *tmp; 542dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 543dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 544dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 545dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann tmp = bt_compidtostr(devices[dev_id].manufacturer); 546dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 547dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return snprintf(manufacturer, size, "%s", tmp); 548dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 549dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 550dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_company(uint16_t dev_id, char *company, size_t size) 551dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 552dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann char *tmp, oui[9]; 553dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann int err; 554dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 555dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 556dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 557dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ba2oui(&devices[dev_id].bdaddr, oui); 558dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann tmp = ouitocomp(oui); 559dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 560dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann err = snprintf(company, size, "%s", tmp); 561dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 562dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann free(tmp); 563dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 564dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return err; 565dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 5666a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 5670b727924102df07d609be955800793c1f33d6952Marcel Holtmannint set_simple_pairing_mode(uint16_t dev_id, uint8_t mode) 5680b727924102df07d609be955800793c1f33d6952Marcel Holtmann{ 5690b727924102df07d609be955800793c1f33d6952Marcel Holtmann struct hci_dev *dev; 5700b727924102df07d609be955800793c1f33d6952Marcel Holtmann int dd; 5710b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5720b727924102df07d609be955800793c1f33d6952Marcel Holtmann ASSERT_DEV_ID; 5730b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5740b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev = &devices[dev_id]; 5750b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5760b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev->ssp_mode = mode; 5770b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5780b727924102df07d609be955800793c1f33d6952Marcel Holtmann dd = hci_open_dev(dev_id); 5790b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (dd < 0) { 5800b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't open device hci%d", 5810b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(errno), errno); 5820b727924102df07d609be955800793c1f33d6952Marcel Holtmann return -errno; 5830b727924102df07d609be955800793c1f33d6952Marcel Holtmann } 5840b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5850b727924102df07d609be955800793c1f33d6952Marcel Holtmann update_ext_inquiry_response(dd, dev); 5860b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5870b727924102df07d609be955800793c1f33d6952Marcel Holtmann hci_close_dev(dd); 5880b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5890b727924102df07d609be955800793c1f33d6952Marcel Holtmann return 0; 5900b727924102df07d609be955800793c1f33d6952Marcel Holtmann} 5910b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5926a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint get_device_name(uint16_t dev_id, char *name, size_t size) 5936a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{ 5946a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann char tmp[249]; 5956a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann int dd; 5966a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 5976a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ASSERT_DEV_ID; 5986a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 5996a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann memset(tmp, 0, sizeof(tmp)); 6006a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6016a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dd = hci_open_dev(dev_id); 6026a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (dd < 0) { 60326e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't open device hci%d", 6046a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dev_id, strerror(errno), errno); 6056a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return -errno; 6066a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann } 6076a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6086a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (hci_read_local_name(dd, sizeof(tmp), tmp, 2000) < 0) { 6094c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi int err = errno; 61026e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't read name for hci%d: %s (%d)", 6116a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dev_id, strerror(errno), errno); 6124c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi hci_close_dev(dd); 6134c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi return -err; 6146a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann } 6156a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6166a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann hci_close_dev(dd); 6176a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6186a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann memcpy(devices[dev_id].name, tmp, 248); 6196a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6206a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return snprintf(name, size, "%s", tmp); 6216a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann} 6226a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6236a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint set_device_name(uint16_t dev_id, const char *name) 6246a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{ 625abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann struct hci_dev *dev; 6266a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann int dd; 6276a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6286a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ASSERT_DEV_ID; 6296a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 630abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann dev = &devices[dev_id]; 631abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann 6326a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dd = hci_open_dev(dev_id); 6336a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (dd < 0) { 63426e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't open device hci%d", 6356a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dev_id, strerror(errno), errno); 6366a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return -errno; 6376a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann } 6386a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6396a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (hci_write_local_name(dd, name, 5000) < 0) { 6404c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi int err = errno; 6413dec6f11d625a351bae0aada4160f3d2de429cddClaudio Takahasi error("Can't write name for hci%d: %s (%d)", 6426a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dev_id, strerror(errno), errno); 6434c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi hci_close_dev(dd); 6444c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi return -err; 6456a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann } 6466a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6470b727924102df07d609be955800793c1f33d6952Marcel Holtmann memcpy(dev->name, name, 248); 648abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann 6490b727924102df07d609be955800793c1f33d6952Marcel Holtmann update_ext_inquiry_response(dd, dev); 650abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann 6516a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann hci_close_dev(dd); 6526a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6536a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return 0; 6546a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann} 6556a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6566a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint get_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, char *alias, size_t size) 6576a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{ 6586a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann char filename[PATH_MAX + 1], addr[18], *tmp; 6596a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann int err; 6606a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6616a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ASSERT_DEV_ID; 6626a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6636a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ba2str(&devices[dev_id].bdaddr, addr); 66417152022a5844275a6f3e3e71ef5b32dc2c0ec04Marcel Holtmann create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases"); 6656a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6666a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ba2str(bdaddr, addr); 6676a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6686a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann tmp = textfile_get(filename, addr); 6696a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (!tmp) 6706a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return -ENXIO; 6716a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6726a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann err = snprintf(alias, size, "%s", tmp); 6736a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6746a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann free(tmp); 6756a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6766a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return err; 6776a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann} 6786a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6796a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint set_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, const char *alias) 6806a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{ 6816a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann char filename[PATH_MAX + 1], addr[18]; 6826a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6836a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ASSERT_DEV_ID; 6846a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6856a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ba2str(&devices[dev_id].bdaddr, addr); 68617152022a5844275a6f3e3e71ef5b32dc2c0ec04Marcel Holtmann create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases"); 6876a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6886a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 6896a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6906a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ba2str(bdaddr, addr); 6916a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6926a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return textfile_put(filename, addr, alias); 6936a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann} 694129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 695129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmannint get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr) 696129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann{ 697129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann struct hci_dev *dev; 698129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann int size; 699129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 700129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann ASSERT_DEV_ID; 701129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 702129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann dev = &devices[dev_id]; 703129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 704129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann switch (dev->manufacturer) { 705129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann default: 706129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann size = -ENOENT; 707129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann break; 708129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann } 709129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 710129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann return size; 711129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann} 71286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 71386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannstatic DBusConnection *connection = NULL; 71486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 71586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannstatic GSList *device_list = NULL; 71686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 71786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmanngboolean device_init(DBusConnection *conn) 71886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 71986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann connection = dbus_connection_ref(conn); 72086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (connection == NULL) 72186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return FALSE; 72286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 72386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return TRUE; 72486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 72586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 7262c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic void device_destroy(struct device *device) 72786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 72886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann debug("Removing device %s", device->path); 72986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 73086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann dbus_connection_destroy_object_path(connection, device->path); 73186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 73286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 73386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannvoid device_cleanup(void) 73486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 73586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_slist_foreach(device_list, (GFunc) device_destroy, NULL); 73686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_slist_free(device_list); 73786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 73886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (connection == NULL) 73986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return; 74086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 74186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann dbus_connection_unref(connection); 74286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 74386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 74486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannvoid device_foreach(GFunc func, gpointer user_data) 74586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 74686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_slist_foreach(device_list, func, user_data); 74786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 74886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 7492c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic void device_free(struct device *device) 75086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 7515d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi sdp_list_free(device->uuids, (sdp_free_func_t) free); 75286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device->path); 75386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device); 75486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 75586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 75686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannstatic void device_unregister(DBusConnection *conn, void *user_data) 75786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 7582c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes struct device *device = user_data; 75986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 76086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_list = g_slist_remove(device_list, device); 76186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 76286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_free(device); 76386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 76486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 7652c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusHandlerResult disconnect(DBusConnection *conn, 7662c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes DBusMessage *msg, void *user_data) 7672c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 7682c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 7692c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 7702c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 7712c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusHandlerResult get_properties(DBusConnection *conn, 7722c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes DBusMessage *msg, void *user_data) 7732c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 7742c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 7752c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 7762c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 7772c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusHandlerResult set_property(DBusConnection *conn, 7782c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes DBusMessage *msg, void *user_data) 7792c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 7802c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 7812c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 7822c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 7832c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusMethodVTable device_methods[] = { 7842c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "GetProperties", get_properties, "", "a{sv}" }, 7852c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "SetProperty", set_property, "sv", "" }, 7862c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "Disconnect", disconnect, "", "" }, 7872c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { NULL, NULL, NULL, NULL } 7882c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 7892c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 7902c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusSignalVTable device_signals[] = { 7912c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "PropertyChanged", "sv" }, 7922c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "DisconnectRequested", "" }, 7932c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { NULL, NULL } 7942c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 7952c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 796da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasiconst char *device_create(struct adapter *adapter, 7975d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi const char *address, sdp_list_t *uuids) 79886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 7992c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes struct device *device; 80086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 8012c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes device = g_try_malloc0(sizeof(struct device)); 80286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (device == NULL) 80386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 80486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 805da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi device->path = g_strdup_printf("%s/hci%d/dev_%s", 806da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi BASE_PATH, adapter->dev_id, address); 80786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_strdelimit(device->path, ":", '_'); 80886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 80986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann debug("Creating device %s", device->path); 81086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 81186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (dbus_connection_create_object_path(connection, device->path, 81286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device, device_unregister) == FALSE) { 81386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_free(device); 81486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 81586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann } 816da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 8172c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes dbus_connection_register_interface(connection, device->path, 8182c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes DEVICE_INTERFACE, device_methods, device_signals, NULL); 81986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 82086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_list = g_slist_append(device_list, device); 82186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 822da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi device->adapter = adapter; 8235d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi device->uuids = uuids; 824da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 825da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi return device->path; 82686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 82786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 82886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannvoid device_remove(const char *path) 82986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 83086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 831