device.c revision 2c1effee41e974f97b21aec1bdd1a232ba48056a
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> 41dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 4286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <glib.h> 4386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 4486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <dbus/dbus.h> 4586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 4686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "dbus-helper.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" 5786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 58dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#define MAX_DEVICES 16 59dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 602c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#define DEVICE_INTERFACE "org.bluez.Device" 612c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 62dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstruct hci_peer { 63dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct timeval lastseen; 64dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct timeval lastused; 65dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 66dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann bdaddr_t bdaddr; 67dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint32_t class; 68dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann int8_t rssi; 69dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t data[240]; 70dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t name[248]; 71dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 72dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t pscan_rep_mode; 73dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t pscan_period_mode; 74dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t pscan_mode; 75dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint16_t clock_offset; 76dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 77dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_peer *next; 78dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}; 79dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 80dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstruct hci_conn { 81dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann bdaddr_t bdaddr; 82dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint16_t handle; 83dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 84dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_conn *next; 85dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}; 86dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 87dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstruct hci_dev { 8857eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann int ignore; 8957eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann 90dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann bdaddr_t bdaddr; 91dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t features[8]; 92dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint8_t lmp_ver; 93dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint16_t lmp_subver; 940d7408aa899f84210d0e6418ee528636292276bcMarcel Holtmann uint16_t hci_rev; 95dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann uint16_t manufacturer; 96dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 970b727924102df07d609be955800793c1f33d6952Marcel Holtmann uint8_t ssp_mode; 986a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann uint8_t name[248]; 99277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi uint8_t class[3]; 1006a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 101dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_peer *peers; 102dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_conn *conns; 103dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann}; 104dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 105dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannstatic struct hci_dev devices[MAX_DEVICES]; 106dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 107dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#define ASSERT_DEV_ID { if (dev_id >= MAX_DEVICES) return -ERANGE; } 108dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 10952a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannvoid init_adapters(void) 110dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 111dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann int i; 112dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 113dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann for (i = 0; i < MAX_DEVICES; i++) 114dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann memset(devices + i, 0, sizeof(struct hci_dev)); 115dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 116dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 117ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedbergstatic int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr) 118ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg{ 119ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg int dd; 120ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 121ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg dd = hci_open_dev(dev_id); 122ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg if (dd < 0) { 123ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg error("Can't open device hci%d", 1240b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(errno), errno); 125ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg return -errno; 126ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg } 127ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 128ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg if (hci_read_bd_addr(dd, bdaddr, 2000) < 0) { 129fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim int err = errno; 130ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg error("Can't read address for hci%d: %s (%d)", 1310b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(errno), errno); 132ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg hci_close_dev(dd); 133fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim return -err; 134ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg } 135ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 136ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg hci_close_dev(dd); 137ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 138ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg return 0; 139ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg} 140ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg 14152a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint add_adapter(uint16_t dev_id) 142dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 143dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev *dev; 144dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev_info di; 145dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 146dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 147dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 148dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev = &devices[dev_id]; 149dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 15057eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann if (hci_devinfo(dev_id, &di) < 0) { 15157eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann dev->ignore = 1; 152dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return -errno; 15357eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann } 15457eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann 15557eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann if (hci_test_bit(HCI_RAW, &di.flags)) { 15657eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann info("Device hci%d is using raw mode", dev_id); 15757eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann dev->ignore = 1; 15857eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann } 159dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 160ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg if (bacmp(&di.bdaddr, BDADDR_ANY)) 161ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg bacpy(&dev->bdaddr, &di.bdaddr); 162ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg else { 1630b727924102df07d609be955800793c1f33d6952Marcel Holtmann int err = device_read_bdaddr(dev_id, &dev->bdaddr); 1640b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (err < 0) 1650b727924102df07d609be955800793c1f33d6952Marcel Holtmann return err; 166ca6e6c5a32dda535b9f76f9b0f8433f71f977efaJohan Hedberg } 167dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann memcpy(dev->features, di.features, 8); 168dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 169dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann info("Device hci%d has been added", dev_id); 170dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 171dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return 0; 172dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 173dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 17452a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint remove_adapter(uint16_t dev_id) 175dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 176dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev *dev; 177dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 178dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 179dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 180dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev = &devices[dev_id]; 181dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 182dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann memset(dev, 0, sizeof(struct hci_dev)); 183dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 184dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann info("Device hci%d has been removed", dev_id); 185dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 186dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return 0; 187dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 188dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 189b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmannstatic inline uint8_t get_inquiry_mode(struct hci_dev *dev) 190b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann{ 191b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann if (dev->features[6] & LMP_EXT_INQ) 192b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann return 2; 193b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 194b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann if (dev->features[3] & LMP_RSSI_INQ) 195b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann return 1; 196b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 197e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann if (dev->manufacturer == 11 && 198e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann dev->hci_rev == 0x00 && dev->lmp_subver == 0x0757) 199e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann return 1; 200e833fda08627147d42a251d76308408e5ac6c5fdMarcel Holtmann 201431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann if (dev->manufacturer == 15) { 202431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann if (dev->hci_rev == 0x03 && dev->lmp_subver == 0x6963) 203431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann return 1; 204431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann if (dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963) 205431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann return 1; 206b98c93ed852d29557fe71de5262357b704f85592Marcel Holtmann if (dev->hci_rev == 0x00 && dev->lmp_subver == 0x6965) 207b98c93ed852d29557fe71de5262357b704f85592Marcel Holtmann return 1; 208431ac89881eaed4c44f2204736ba5debe2d29a33Marcel Holtmann } 20919fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann 21019fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann if (dev->manufacturer == 31 && 21119fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann dev->hci_rev == 0x2005 && dev->lmp_subver == 0x1805) 21219fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann return 1; 21319fb70a42ac27051f8fe1adc2502943dd56c5f0dMarcel Holtmann 214b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann return 0; 215b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann} 216b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 2170b727924102df07d609be955800793c1f33d6952Marcel Holtmannstatic void update_ext_inquiry_response(int dd, struct hci_dev *dev) 2180b727924102df07d609be955800793c1f33d6952Marcel Holtmann{ 2190b727924102df07d609be955800793c1f33d6952Marcel Holtmann uint8_t fec = 0, data[240]; 2200b727924102df07d609be955800793c1f33d6952Marcel Holtmann 2210b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (!(dev->features[6] & LMP_EXT_INQ)) 2220b727924102df07d609be955800793c1f33d6952Marcel Holtmann return; 2230b727924102df07d609be955800793c1f33d6952Marcel Holtmann 2240b727924102df07d609be955800793c1f33d6952Marcel Holtmann memset(data, 0, sizeof(data)); 2250b727924102df07d609be955800793c1f33d6952Marcel Holtmann 226eb4d49890ca8a4d8f567e81fdf82b6903d30f326Marcel Holtmann if (dev->ssp_mode > 0) 227eb4d49890ca8a4d8f567e81fdf82b6903d30f326Marcel Holtmann create_ext_inquiry_response((char *) dev->name, data); 2280b727924102df07d609be955800793c1f33d6952Marcel Holtmann 2290b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) 2300b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't write extended inquiry response: %s (%d)", 2310b727924102df07d609be955800793c1f33d6952Marcel Holtmann strerror(errno), errno); 2320b727924102df07d609be955800793c1f33d6952Marcel Holtmann} 2330b727924102df07d609be955800793c1f33d6952Marcel Holtmann 23452a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint start_adapter(uint16_t dev_id) 235dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 236dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev *dev; 237dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_version ver; 238b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann uint8_t features[8], inqmode; 2393dfe93f27c455e07be72a38239f4f8335ba6a860Marcel Holtmann uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 }; 2400b727924102df07d609be955800793c1f33d6952Marcel Holtmann char name[249]; 241277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi int dd, err; 242dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 243dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 244dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 245dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev = &devices[dev_id]; 246dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 24757eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann if (dev->ignore) 24857eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann return 0; 24957eb59510dc89b134cc35bdac9949bceab7da1d6Marcel Holtmann 250dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dd = hci_open_dev(dev_id); 251dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (dd < 0) { 25226e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't open device hci%d", 253dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev_id, strerror(errno), errno); 254dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return -errno; 255dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann } 256dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 257dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (hci_read_local_version(dd, &ver, 1000) < 0) { 258fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim int err = errno; 25926e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't read version info for hci%d: %s (%d)", 260dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev_id, strerror(errno), errno); 261276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmann hci_close_dev(dd); 262fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim return -err; 263dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann } 264dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 2650fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann dev->hci_rev = ver.hci_rev; 266dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev->lmp_ver = ver.lmp_ver; 267dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev->lmp_subver = ver.lmp_subver; 268dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev->manufacturer = ver.manufacturer; 269dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 270b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann if (hci_read_local_features(dd, features, 1000) < 0) { 271277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi err = errno; 272b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann error("Can't read features for hci%d: %s (%d)", 273277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi dev_id, strerror(err), err); 274276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmann hci_close_dev(dd); 275fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim return -err; 276b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann } 277b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 278b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann memcpy(dev->features, features, 8); 279b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 280277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi if (hci_read_class_of_dev(dd, dev->class, 1000) < 0) { 281277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi err = errno; 2820b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't read class of device on hci%d: %s (%d)", 2830b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(err), err); 284277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi hci_close_dev(dd); 285277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi return -err; 286277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi } 287277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 2880b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (hci_read_local_name(dd, sizeof(name), name, 2000) < 0) { 2890b727924102df07d609be955800793c1f33d6952Marcel Holtmann err = errno; 2900b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't read local name on hci%d: %s (%d)", 2910b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(err), err); 2920b727924102df07d609be955800793c1f33d6952Marcel Holtmann hci_close_dev(dd); 2930b727924102df07d609be955800793c1f33d6952Marcel Holtmann return -err; 2940b727924102df07d609be955800793c1f33d6952Marcel Holtmann } 295b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 2960b727924102df07d609be955800793c1f33d6952Marcel Holtmann memcpy(dev->name, name, 248); 2970b727924102df07d609be955800793c1f33d6952Marcel Holtmann 2980b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (!(features[6] & LMP_SIMPLE_PAIR)) 2990b727924102df07d609be955800793c1f33d6952Marcel Holtmann goto setup; 3000b727924102df07d609be955800793c1f33d6952Marcel Holtmann 3010b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (hci_read_simple_pairing_mode(dd, &dev->ssp_mode, 1000) < 0) { 3020b727924102df07d609be955800793c1f33d6952Marcel Holtmann err = errno; 3030b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't read simple pairing mode on hci%d: %s (%d)", 3040b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(err), err); 305276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmann hci_close_dev(dd); 306fdba3b26687425c6523f728f7e79d5f7a76af367Ulisses Furquim return -err; 307b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann } 308b1609cb6ebaa241102257152e8eb8f248726035fMarcel Holtmann 3090b727924102df07d609be955800793c1f33d6952Marcel Holtmannsetup: 31057290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann if (ver.hci_rev > 1) { 31157290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann if (features[5] & LMP_SNIFF_SUBR) 31257290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann events[5] |= 0x20; 31357290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann 314a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann if (features[5] & LMP_PAUSE_ENC) 315a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann events[5] |= 0x80; 316a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann 31757290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann if (features[6] & LMP_EXT_INQ) 31857290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann events[5] |= 0x40; 31957290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann 320a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann if (features[6] & LMP_NFLUSH_PKTS) 321a47211b0097fe3612b96246f08bf37dccd15fd61Marcel Holtmann events[7] |= 0x01; 322f4051e4e1bc3a5a00fc74b5b5eb7eb3794f67310Johan Hedberg 32357290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann if (features[7] & LMP_LSTO) 32457290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann events[6] |= 0x80; 32557290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann 3260b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (features[6] & LMP_SIMPLE_PAIR) { 3270b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x01; /* IO Capability Request */ 3280b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x02; /* IO Capability Response */ 3290b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x04; /* User Confirmation Request */ 3300b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x08; /* User Passkey Request */ 3310b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x10; /* Remote OOB Data Request */ 3320b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[6] |= 0x20; /* Simple Pairing Complete */ 3330b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[7] |= 0x04; /* User Passkey Notification */ 3340b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[7] |= 0x08; /* Keypress Notification */ 3350b727924102df07d609be955800793c1f33d6952Marcel Holtmann events[7] |= 0x10; /* Remote Host Supported Features Notification */ 3360b727924102df07d609be955800793c1f33d6952Marcel Holtmann } 3370b727924102df07d609be955800793c1f33d6952Marcel Holtmann 33857290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann hci_send_cmd(dd, OGF_HOST_CTL, OCF_SET_EVENT_MASK, 33957290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann sizeof(events), events); 34057290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann } 34157290a1e2c13f79d353a21f7c67388ee8c142897Marcel Holtmann 342c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann if (read_local_name(&dev->bdaddr, name) == 0) { 343c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann memcpy(dev->name, name, 248); 344c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann hci_write_local_name(dd, name, 5000); 345c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann } 346c3cd59ae39ebb53e27ddd99ee48f1875bd480c1dMarcel Holtmann 3470b727924102df07d609be955800793c1f33d6952Marcel Holtmann update_ext_inquiry_response(dd, dev); 3480b727924102df07d609be955800793c1f33d6952Marcel Holtmann 3490b727924102df07d609be955800793c1f33d6952Marcel Holtmann inqmode = get_inquiry_mode(dev); 3500b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (inqmode < 1) 3510b727924102df07d609be955800793c1f33d6952Marcel Holtmann goto done; 3520b727924102df07d609be955800793c1f33d6952Marcel Holtmann 3530b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (hci_write_inquiry_mode(dd, inqmode, 1000) < 0) { 3540b727924102df07d609be955800793c1f33d6952Marcel Holtmann int err = errno; 3550b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't write inquiry mode for hci%d: %s (%d)", 3560b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(errno), err); 3570b727924102df07d609be955800793c1f33d6952Marcel Holtmann hci_close_dev(dd); 3580b727924102df07d609be955800793c1f33d6952Marcel Holtmann return -err; 3590b727924102df07d609be955800793c1f33d6952Marcel Holtmann } 3600b727924102df07d609be955800793c1f33d6952Marcel Holtmann 361276a7aeaed518f61b0ec85f9658c62829d99a925Marcel Holtmanndone: 362dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann hci_close_dev(dd); 363dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 364dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann info("Device hci%d has been activated", dev_id); 365dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 366dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return 0; 367dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 368dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 36952a124ee19a84ca68171dbe88057d8b01b9d16d8Marcel Holtmannint stop_adapter(uint16_t dev_id) 370dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 371dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 372dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 373dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann info("Device hci%d has been disabled", dev_id); 374dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 375dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return 0; 376dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 377dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 3780e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmannint update_adapter(uint16_t dev_id) 3790e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann{ 3800e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann struct hci_dev *dev; 3810e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann int dd; 3820e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3830e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann ASSERT_DEV_ID; 3840e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3850e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann dev = &devices[dev_id]; 3860e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3870e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann if (dev->ignore) 3880e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann return 0; 3890e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3900e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann dd = hci_open_dev(dev_id); 3910e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann if (dd < 0) { 3920e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann error("Can't open device hci%d", 3930e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann dev_id, strerror(errno), errno); 3940e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann return -errno; 3950e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann } 3960e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3970e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann update_ext_inquiry_response(dd, dev); 3980e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 3990e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann hci_close_dev(dd); 4000e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 4010e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann return 0; 4020e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann} 4030e8c93725dbdc6ce76ca48da92f9d15b2a706111Marcel Holtmann 404dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_address(uint16_t dev_id, char *address, size_t size) 405dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 4068586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann struct hci_dev *dev; 4078586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 408dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 409dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 410dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (size < 18) 411dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return -ENOBUFS; 412dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 4138586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dev = &devices[dev_id]; 4148586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 4158586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann return ba2str(&dev->bdaddr, address); 416dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 417dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 418277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasiint get_device_class(uint16_t dev_id, uint8_t *cls) 419277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi{ 420277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi struct hci_dev *dev; 421277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 422277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi ASSERT_DEV_ID; 423277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 424277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi dev = &devices[dev_id]; 425277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi memcpy(cls, dev->class, 3); 426277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 427277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi return 0; 428277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi} 429277e0363f2839a05b80c1bc4263cfeaf9909be8cClaudio Takahasi 430f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmannint set_device_class(uint16_t dev_id, uint8_t *cls) 431f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann{ 432f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann struct hci_dev *dev; 433f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann 434f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann ASSERT_DEV_ID; 435f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann dev = &devices[dev_id]; 436f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann memcpy(dev->class, cls, 3); 437f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann 438f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann return 0; 439f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann} 440f205cd06dc4e9da2c1d5109e570008d7d80b8380Marcel Holtmann 441dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_version(uint16_t dev_id, char *version, size_t size) 442dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 443dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann struct hci_dev *dev; 444dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann char edr[7], *tmp; 445dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann int err; 446dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 447dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 448dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 449dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (size < 14) 450dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return -ENOBUFS; 451dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 452dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann dev = &devices[dev_id]; 453dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 45498329bfce1a1ce33cf2f46007196ecc63441465aMarcel Holtmann if ((dev->lmp_ver == 0x03 || dev->lmp_ver == 0x04) && 455dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann (dev->features[3] & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M))) 456dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann sprintf(edr, " + EDR"); 457dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann else 458dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann edr[0] = '\0'; 459dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 460dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann tmp = lmp_vertostr(dev->lmp_ver); 461dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 462dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann if (strlen(tmp) == 0) 463dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann err = snprintf(version, size, "not assigned"); 464dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann else 465dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann err = snprintf(version, size, "Bluetooth %s%s", tmp, edr); 466dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 467dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann bt_free(tmp); 468dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 469dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return err; 470dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 471dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 4728586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmannstatic int digi_revision(uint16_t dev_id, char *revision, size_t size) 4738586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann{ 4748586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann struct hci_request rq; 4758586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann unsigned char req[] = { 0x07 }; 4768586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann unsigned char buf[102]; 4778586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann int dd; 4788586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 4798586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dd = hci_open_dev(dev_id); 4808586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann if (dd < 0) { 48126e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't open device hci%d", 4828586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dev_id, strerror(errno), errno); 4838586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann return -errno; 4848586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann } 4858586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 4868586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann memset(&rq, 0, sizeof(rq)); 4878586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.ogf = OGF_VENDOR_CMD; 4888586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.ocf = 0x000e; 4898586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.cparam = req; 4908586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.clen = sizeof(req); 4918586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.rparam = &buf; 4928586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann rq.rlen = sizeof(buf); 4938586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 4948586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann if (hci_send_req(dd, &rq, 2000) < 0) { 4954c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi int err = errno; 49626e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't read revision for hci%d: %s (%d)", 4978586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dev_id, strerror(errno), errno); 4984c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi hci_close_dev(dd); 4994c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi return -err; 5008586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann } 5018586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 5028586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann hci_close_dev(dd); 5038586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 5048586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann return snprintf(revision, size, "%s", buf + 1); 5058586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann} 5068586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 507dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_revision(uint16_t dev_id, char *revision, size_t size) 508dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 5098586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann struct hci_dev *dev; 5108586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann int err; 5118586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 512dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 513dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 5148586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann dev = &devices[dev_id]; 5158586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 5168586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann switch (dev->manufacturer) { 5178586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann case 10: 5188586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann err = snprintf(revision, size, "Build %d", dev->lmp_subver); 5198586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann break; 5208586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann case 12: 5218586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann err = digi_revision(dev_id, revision, size); 5228586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann break; 5230fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann case 15: 5240fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann err = snprintf(revision, size, "%d.%d / %d", 5250fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann dev->hci_rev & 0xff, 5260fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann dev->lmp_subver >> 8, dev->lmp_subver & 0xff); 5270fe4da23f22cf74624a4576fb879d6dd500dfc5cMarcel Holtmann break; 5288586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann default: 5298586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann err = snprintf(revision, size, "0x%02x", dev->lmp_subver); 5308586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann break; 5318586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann } 5328586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann 5338586fc0c0dc8d6fe219f7eb7a697f359827b39a0Marcel Holtmann return err; 534dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 535dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 536dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_manufacturer(uint16_t dev_id, char *manufacturer, size_t size) 537dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 538dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann char *tmp; 539dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 540dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 541dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 542dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann tmp = bt_compidtostr(devices[dev_id].manufacturer); 543dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 544dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return snprintf(manufacturer, size, "%s", tmp); 545dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 546dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 547dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmannint get_device_company(uint16_t dev_id, char *company, size_t size) 548dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann{ 549dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann char *tmp, oui[9]; 550dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann int err; 551dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 552dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ASSERT_DEV_ID; 553dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 554dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann ba2oui(&devices[dev_id].bdaddr, oui); 555dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann tmp = ouitocomp(oui); 556dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 557dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann err = snprintf(company, size, "%s", tmp); 558dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 559dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann free(tmp); 560dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 561dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann return err; 562dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann} 5636a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 5640b727924102df07d609be955800793c1f33d6952Marcel Holtmannint set_simple_pairing_mode(uint16_t dev_id, uint8_t mode) 5650b727924102df07d609be955800793c1f33d6952Marcel Holtmann{ 5660b727924102df07d609be955800793c1f33d6952Marcel Holtmann struct hci_dev *dev; 5670b727924102df07d609be955800793c1f33d6952Marcel Holtmann int dd; 5680b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5690b727924102df07d609be955800793c1f33d6952Marcel Holtmann ASSERT_DEV_ID; 5700b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5710b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev = &devices[dev_id]; 5720b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5730b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev->ssp_mode = mode; 5740b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5750b727924102df07d609be955800793c1f33d6952Marcel Holtmann dd = hci_open_dev(dev_id); 5760b727924102df07d609be955800793c1f33d6952Marcel Holtmann if (dd < 0) { 5770b727924102df07d609be955800793c1f33d6952Marcel Holtmann error("Can't open device hci%d", 5780b727924102df07d609be955800793c1f33d6952Marcel Holtmann dev_id, strerror(errno), errno); 5790b727924102df07d609be955800793c1f33d6952Marcel Holtmann return -errno; 5800b727924102df07d609be955800793c1f33d6952Marcel Holtmann } 5810b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5820b727924102df07d609be955800793c1f33d6952Marcel Holtmann update_ext_inquiry_response(dd, dev); 5830b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5840b727924102df07d609be955800793c1f33d6952Marcel Holtmann hci_close_dev(dd); 5850b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5860b727924102df07d609be955800793c1f33d6952Marcel Holtmann return 0; 5870b727924102df07d609be955800793c1f33d6952Marcel Holtmann} 5880b727924102df07d609be955800793c1f33d6952Marcel Holtmann 5896a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint get_device_name(uint16_t dev_id, char *name, size_t size) 5906a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{ 5916a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann char tmp[249]; 5926a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann int dd; 5936a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 5946a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ASSERT_DEV_ID; 5956a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 5966a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann memset(tmp, 0, sizeof(tmp)); 5976a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 5986a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dd = hci_open_dev(dev_id); 5996a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (dd < 0) { 60026e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't open device hci%d", 6016a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dev_id, strerror(errno), errno); 6026a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return -errno; 6036a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann } 6046a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6056a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (hci_read_local_name(dd, sizeof(tmp), tmp, 2000) < 0) { 6064c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi int err = errno; 60726e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't read name for hci%d: %s (%d)", 6086a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dev_id, strerror(errno), errno); 6094c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi hci_close_dev(dd); 6104c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi return -err; 6116a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann } 6126a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6136a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann hci_close_dev(dd); 6146a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6156a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann memcpy(devices[dev_id].name, tmp, 248); 6166a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6176a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return snprintf(name, size, "%s", tmp); 6186a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann} 6196a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6206a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint set_device_name(uint16_t dev_id, const char *name) 6216a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{ 622abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann struct hci_dev *dev; 6236a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann int dd; 6246a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6256a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ASSERT_DEV_ID; 6266a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 627abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann dev = &devices[dev_id]; 628abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann 6296a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dd = hci_open_dev(dev_id); 6306a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (dd < 0) { 63126e7f9195005deda91eea83f368c0d53ec95856cMarcel Holtmann error("Can't open device hci%d", 6326a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dev_id, strerror(errno), errno); 6336a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return -errno; 6346a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann } 6356a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6366a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (hci_write_local_name(dd, name, 5000) < 0) { 6374c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi int err = errno; 6383dec6f11d625a351bae0aada4160f3d2de429cddClaudio Takahasi error("Can't write name for hci%d: %s (%d)", 6396a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann dev_id, strerror(errno), errno); 6404c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi hci_close_dev(dd); 6414c172501d839e5d7c3f46510432b731ea2768dbfClaudio Takahasi return -err; 6426a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann } 6436a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6440b727924102df07d609be955800793c1f33d6952Marcel Holtmann memcpy(dev->name, name, 248); 645abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann 6460b727924102df07d609be955800793c1f33d6952Marcel Holtmann update_ext_inquiry_response(dd, dev); 647abe03b24985eef4659c9d058c354f9b7df0a41f0Marcel Holtmann 6486a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann hci_close_dev(dd); 6496a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6506a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return 0; 6516a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann} 6526a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6536a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint get_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, char *alias, size_t size) 6546a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{ 6556a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann char filename[PATH_MAX + 1], addr[18], *tmp; 6566a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann int err; 6576a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6586a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ASSERT_DEV_ID; 6596a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6606a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ba2str(&devices[dev_id].bdaddr, addr); 66117152022a5844275a6f3e3e71ef5b32dc2c0ec04Marcel Holtmann create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases"); 6626a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6636a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ba2str(bdaddr, addr); 6646a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6656a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann tmp = textfile_get(filename, addr); 6666a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann if (!tmp) 6676a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return -ENXIO; 6686a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6696a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann err = snprintf(alias, size, "%s", tmp); 6706a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6716a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann free(tmp); 6726a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6736a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return err; 6746a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann} 6756a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6766a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmannint set_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, const char *alias) 6776a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann{ 6786a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann char filename[PATH_MAX + 1], addr[18]; 6796a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6806a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ASSERT_DEV_ID; 6816a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6826a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ba2str(&devices[dev_id].bdaddr, addr); 68317152022a5844275a6f3e3e71ef5b32dc2c0ec04Marcel Holtmann create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases"); 6846a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6856a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 6866a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6876a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann ba2str(bdaddr, addr); 6886a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann 6896a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann return textfile_put(filename, addr, alias); 6906a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann} 691129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 692129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmannint get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr) 693129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann{ 694129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann struct hci_dev *dev; 695129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann int size; 696129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 697129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann ASSERT_DEV_ID; 698129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 699129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann dev = &devices[dev_id]; 700129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 701129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann switch (dev->manufacturer) { 702129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann default: 703129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann size = -ENOENT; 704129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann break; 705129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann } 706129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann 707129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann return size; 708129147b47b9df4895888c6a674f8d15dc35e9a16Marcel Holtmann} 70986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 71086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannstatic DBusConnection *connection = NULL; 71186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 71286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannstatic GSList *device_list = NULL; 71386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 71486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmanngboolean device_init(DBusConnection *conn) 71586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 71686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann connection = dbus_connection_ref(conn); 71786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (connection == NULL) 71886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return FALSE; 71986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 72086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return TRUE; 72186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 72286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 7232c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic void device_destroy(struct device *device) 72486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 72586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann debug("Removing device %s", device->path); 72686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 72786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann dbus_connection_destroy_object_path(connection, device->path); 72886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 72986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 73086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannvoid device_cleanup(void) 73186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 73286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_slist_foreach(device_list, (GFunc) device_destroy, NULL); 73386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_slist_free(device_list); 73486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 73586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (connection == NULL) 73686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return; 73786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 73886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann dbus_connection_unref(connection); 73986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 74086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 74186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannvoid device_foreach(GFunc func, gpointer user_data) 74286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 74386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_slist_foreach(device_list, func, user_data); 74486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 74586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 7462c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic void device_free(struct device *device) 74786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 74886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device->path); 74986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device); 75086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 75186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 75286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannstatic void device_unregister(DBusConnection *conn, void *user_data) 75386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 7542c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes struct device *device = user_data; 75586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 75686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_list = g_slist_remove(device_list, device); 75786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 75886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_free(device); 75986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 76086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 7612c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusHandlerResult disconnect(DBusConnection *conn, 7622c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes DBusMessage *msg, void *user_data) 7632c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 7642c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 7652c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 7662c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 7672c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusHandlerResult get_properties(DBusConnection *conn, 7682c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes DBusMessage *msg, void *user_data) 7692c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 7702c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 7712c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 7722c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 7732c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusHandlerResult set_property(DBusConnection *conn, 7742c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes DBusMessage *msg, void *user_data) 7752c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 7762c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 7772c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 7782c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 7792c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusMethodVTable device_methods[] = { 7802c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "GetProperties", get_properties, "", "a{sv}" }, 7812c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "SetProperty", set_property, "sv", "" }, 7822c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "Disconnect", disconnect, "", "" }, 7832c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { NULL, NULL, NULL, NULL } 7842c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 7852c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 7862c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstatic DBusSignalVTable device_signals[] = { 7872c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "PropertyChanged", "sv" }, 7882c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { "DisconnectRequested", "" }, 7892c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes { NULL, NULL } 7902c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 7912c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 7922c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomesstruct device *device_create(struct adapter *adapter, const char *address) 79386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 7942c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes struct device *device; 79586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 7962c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes device = g_try_malloc0(sizeof(struct device)); 79786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (device == NULL) 79886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 79986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 8002c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes device->path = g_strdup_printf("%s/dev_%s", adapter->address, address); 80186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_strdelimit(device->path, ":", '_'); 80286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 80386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann debug("Creating device %s", device->path); 80486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 80586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (dbus_connection_create_object_path(connection, device->path, 80686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device, device_unregister) == FALSE) { 80786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_free(device); 80886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 80986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann } 8102c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes dbus_connection_register_interface(connection, device->path, 8112c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes DEVICE_INTERFACE, device_methods, device_signals, NULL); 81286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 81386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_list = g_slist_append(device_list, device); 81486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 81586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return device; 81686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 81786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 81886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmannvoid device_remove(const char *path) 81986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 82086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 821