hciops.c revision fdb266b6797638b89b9ba9fe0d89670bf71d47c5
194e91856179a268805256055ffd5155d1468b99cAlok Barsode/* 294e91856179a268805256055ffd5155d1468b99cAlok Barsode * 394e91856179a268805256055ffd5155d1468b99cAlok Barsode * BlueZ - Bluetooth protocol stack for Linux 494e91856179a268805256055ffd5155d1468b99cAlok Barsode * 59184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> 694e91856179a268805256055ffd5155d1468b99cAlok Barsode * 794e91856179a268805256055ffd5155d1468b99cAlok Barsode * This program is free software; you can redistribute it and/or modify 894e91856179a268805256055ffd5155d1468b99cAlok Barsode * it under the terms of the GNU General Public License as published by 994e91856179a268805256055ffd5155d1468b99cAlok Barsode * the Free Software Foundation; either version 2 of the License, or 1094e91856179a268805256055ffd5155d1468b99cAlok Barsode * (at your option) any later version. 1194e91856179a268805256055ffd5155d1468b99cAlok Barsode * 1294e91856179a268805256055ffd5155d1468b99cAlok Barsode * This program is distributed in the hope that it will be useful, 1394e91856179a268805256055ffd5155d1468b99cAlok Barsode * but WITHOUT ANY WARRANTY; without even the implied warranty of 1494e91856179a268805256055ffd5155d1468b99cAlok Barsode * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1594e91856179a268805256055ffd5155d1468b99cAlok Barsode * GNU General Public License for more details. 1694e91856179a268805256055ffd5155d1468b99cAlok Barsode * 1794e91856179a268805256055ffd5155d1468b99cAlok Barsode * You should have received a copy of the GNU General Public License 1894e91856179a268805256055ffd5155d1468b99cAlok Barsode * along with this program; if not, write to the Free Software 1994e91856179a268805256055ffd5155d1468b99cAlok Barsode * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2094e91856179a268805256055ffd5155d1468b99cAlok Barsode * 2194e91856179a268805256055ffd5155d1468b99cAlok Barsode */ 2294e91856179a268805256055ffd5155d1468b99cAlok Barsode 2394e91856179a268805256055ffd5155d1468b99cAlok Barsode#ifdef HAVE_CONFIG_H 2494e91856179a268805256055ffd5155d1468b99cAlok Barsode#include <config.h> 2594e91856179a268805256055ffd5155d1468b99cAlok Barsode#endif 26a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 27a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include <stdio.h> 28cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <errno.h> 29a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include <unistd.h> 30a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include <stdlib.h> 31cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <sys/types.h> 32cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <sys/ioctl.h> 33a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include <sys/wait.h> 3494e91856179a268805256055ffd5155d1468b99cAlok Barsode 3594e91856179a268805256055ffd5155d1468b99cAlok Barsode#include <bluetooth/bluetooth.h> 36cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <bluetooth/hci.h> 37cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <bluetooth/hci_lib.h> 3894e91856179a268805256055ffd5155d1468b99cAlok Barsode 39cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <glib.h> 40cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 41cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include "hcid.h" 42a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include "sdpd.h" 43a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include "adapter.h" 4494e91856179a268805256055ffd5155d1468b99cAlok Barsode#include "plugin.h" 45e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h" 465288199788ecb17183d6517da3062cd94692a900Johan Hedberg#include "storage.h" 475288199788ecb17183d6517da3062cd94692a900Johan Hedberg#include "event.h" 485288199788ecb17183d6517da3062cd94692a900Johan Hedberg#include "device.h" 49a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include "manager.h" 50a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 5118e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedbergstatic int child_pipe[2] = { -1, -1 }; 5294e91856179a268805256055ffd5155d1468b99cAlok Barsode 538b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedbergstatic guint child_io_id = 0; 548b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedbergstatic guint ctl_io_id = 0; 558b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 56be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg/* Commands sent by kernel on starting an adapter */ 57be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergenum { 58be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING_BDADDR, 59be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING_VERSION, 60be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING_FEATURES, 61fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg PENDING_NAME, 62be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg}; 63be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 646844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedbergstatic int max_dev = -1; 65ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedbergstatic struct dev_info { 66ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg int sk; 67a352058752e541539b09e55124d411a534cc14afJohan Hedberg bdaddr_t bdaddr; 6800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg char name[249]; 6900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t eir[240]; 70be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg uint8_t features[8]; 7100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t ssp_mode; 7200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 7300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int8_t tx_power; 7400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 7500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint32_t current_cod; 7600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint32_t wanted_cod; 7700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint32_t pending_cod; 7800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg gboolean cache_enable; 795c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg gboolean already_up; 805c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg gboolean registered; 8100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 82be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg struct hci_version ver; 83be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 8400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t did_vendor; 8500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t did_product; 8600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t did_version; 8700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 885a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg gboolean up; 89be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg unsigned long pending; 9055694454017b04a416931a81964bb695f48b3d93Johan Hedberg 91fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg GIOChannel *io; 9255694454017b04a416931a81964bb695f48b3d93Johan Hedberg guint watch_id; 9355694454017b04a416931a81964bb695f48b3d93Johan Hedberg int pin_length; 94ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg} *devs = NULL; 95ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg 96db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedbergstatic int ignore_device(struct hci_dev_info *di) 97db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg{ 98db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR; 99db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg} 100db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg 1015c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic void init_dev_info(int index, int sk, gboolean registered) 102ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg{ 103fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 104fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 105fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memset(dev, 0, sizeof(*dev)); 106fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 107fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->sk = sk; 108fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = -1; 109fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->cache_enable = TRUE; 110fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->registered = registered; 111ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg} 1126844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 113abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg/* Async HCI command handling with callback support */ 114abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 115abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstruct hci_cmd_data { 116abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg bt_hci_result_t cb; 117abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t handle; 118abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t ocf; 119abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg gpointer caller_data; 120abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg}; 121abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 122abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstatic gboolean hci_event_watch(GIOChannel *io, 123abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg GIOCondition cond, gpointer user_data) 124abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg{ 125abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg unsigned char buf[HCI_MAX_EVENT_SIZE], *body; 126abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_cmd_data *cmd = user_data; 127abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_cmd_status *evt_status; 128abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_auth_complete *evt_auth; 129abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_encrypt_change *evt_enc; 130abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_event_hdr *hdr; 131abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg set_conn_encrypt_cp cp; 132abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg int dd; 133abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t ocf; 134abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint8_t status = HCI_OE_POWER_OFF; 135abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 136abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (cond & G_IO_NVAL) { 137abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb(status, cmd->caller_data); 138abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return FALSE; 139abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 140abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 141abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (cond & (G_IO_ERR | G_IO_HUP)) 142abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 143abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 144abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg dd = g_io_channel_unix_get_fd(io); 145abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 146abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (read(dd, buf, sizeof(buf)) < 0) 147abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 148abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 149abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hdr = (hci_event_hdr *) (buf + 1); 150abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg body = buf + (1 + HCI_EVENT_HDR_SIZE); 151abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 152abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg switch (hdr->evt) { 153abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_CMD_STATUS: 154abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_status = (evt_cmd_status *) body; 155abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg ocf = cmd_opcode_ocf(evt_status->opcode); 156abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (ocf != cmd->ocf) 157abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 158abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg switch (ocf) { 159abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case OCF_AUTH_REQUESTED: 160abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case OCF_SET_CONN_ENCRYPT: 161abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_status->status != 0) { 162abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Baseband rejected command */ 163abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_status->status; 164abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 165abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 166abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg break; 167abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg default: 168abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 169abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 170abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Wait for the next event */ 171abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 172abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_AUTH_COMPLETE: 173abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_auth = (evt_auth_complete *) body; 174abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_auth->handle != cmd->handle) { 175abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Skipping */ 176abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 177abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 178abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 179abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_auth->status != 0x00) { 180abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_auth->status; 181abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Abort encryption */ 182abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 183abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 184abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 185abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg memset(&cp, 0, sizeof(cp)); 186abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.handle = cmd->handle; 187abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.encrypt = 1; 188abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 189abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->ocf = OCF_SET_CONN_ENCRYPT; 190abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 191abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, 192abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg SET_CONN_ENCRYPT_CP_SIZE, &cp) < 0) { 193abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = HCI_COMMAND_DISALLOWED; 194abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 195abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 196abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Wait for encrypt change event */ 197abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 198abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_ENCRYPT_CHANGE: 199abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_enc = (evt_encrypt_change *) body; 200abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_enc->handle != cmd->handle) 201abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 202abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 203abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Procedure finished: reporting status */ 204abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_enc->status; 205abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg break; 206abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg default: 207abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Skipping */ 208abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 209abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 210abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 211abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergfailed: 212abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb(status, cmd->caller_data); 213abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_shutdown(io, TRUE, NULL); 214abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 215abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return FALSE; 216abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg} 217abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 218b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic int write_inq_mode(int index, uint8_t mode) 219b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 220fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 221b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg write_inquiry_mode_cp cp; 222b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 223b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg memset(&cp, 0, sizeof(cp)); 224b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg cp.mode = mode; 225b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 226fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, 227b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg WRITE_INQUIRY_MODE_CP_SIZE, &cp) < 0) 228b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return -errno; 229b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 230b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 0; 231b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 232b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 233b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic uint8_t get_inquiry_mode(int index) 234b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 235fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 236fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 237fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_EXT_INQ) 238b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 2; 239b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 240fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[3] & LMP_RSSI_INQ) 241b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 242b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 243fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.manufacturer == 11 && dev->ver.hci_rev == 0x00 && 244fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x0757) 245b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 246b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 247fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.manufacturer == 15) { 248fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.hci_rev == 0x03 && 249fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x6963) 250b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 251fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.hci_rev == 0x09 && 252fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x6963) 253b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 254fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.hci_rev == 0x00 && 255fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x6965) 256b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 257b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 258b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 259fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.manufacturer == 31 && dev->ver.hci_rev == 0x2005 && 260fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x1805) 261b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 262b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 263b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 0; 264b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 265b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 266be49c2621d577da4fafd462265b611289547f183Johan Hedbergstatic int init_ssp_mode(int index) 267be49c2621d577da4fafd462265b611289547f183Johan Hedberg{ 268fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 269be49c2621d577da4fafd462265b611289547f183Johan Hedberg write_simple_pairing_mode_cp cp; 270be49c2621d577da4fafd462265b611289547f183Johan Hedberg 271fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETAUTHINFO, NULL) < 0 && errno == EINVAL) 272be49c2621d577da4fafd462265b611289547f183Johan Hedberg return 0; 273be49c2621d577da4fafd462265b611289547f183Johan Hedberg 274be49c2621d577da4fafd462265b611289547f183Johan Hedberg memset(&cp, 0, sizeof(cp)); 275be49c2621d577da4fafd462265b611289547f183Johan Hedberg cp.mode = 0x01; 276be49c2621d577da4fafd462265b611289547f183Johan Hedberg 277fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 278be49c2621d577da4fafd462265b611289547f183Johan Hedberg OCF_WRITE_SIMPLE_PAIRING_MODE, 279be49c2621d577da4fafd462265b611289547f183Johan Hedberg WRITE_SIMPLE_PAIRING_MODE_CP_SIZE, &cp) < 0) 280be49c2621d577da4fafd462265b611289547f183Johan Hedberg return -errno; 281be49c2621d577da4fafd462265b611289547f183Johan Hedberg 282be49c2621d577da4fafd462265b611289547f183Johan Hedberg return 0; 283be49c2621d577da4fafd462265b611289547f183Johan Hedberg} 284be49c2621d577da4fafd462265b611289547f183Johan Hedberg 2855c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_set_discoverable(int index, gboolean discoverable) 2865c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 287fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2885c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg uint8_t mode; 2895c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2905c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (discoverable) 2915c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = (SCAN_PAGE | SCAN_INQUIRY); 2925c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg else 2935c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = SCAN_PAGE; 2945c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2955c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d discoverable %d", index, discoverable); 2965c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 297fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 2985c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 1, &mode) < 0) 2995c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return -errno; 3005c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3015c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return 0; 3025c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 3035c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3045c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_stop(int index) 3055c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 306fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3075c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg int err = 0; 3085c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3095c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d", index); 3105c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 311fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIDEVDOWN, index) == 0) 3125c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg goto done; /* on success */ 3135c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3145c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (errno != EALREADY) { 3155c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg err = -errno; 3165c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg error("Can't stop device hci%d: %s (%d)", 3175c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg index, strerror(-err), -err); 3185c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } 3195c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3205c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergdone: 3215c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return err; 3225c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 3235c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3245c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_set_pairable(int index, gboolean pairable) 3255c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 3265c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d pairable %d", index, pairable); 3275c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return -ENOSYS; 3285c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 3295c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 330b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic void start_adapter(int index) 331b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 332fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 333b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 }; 334b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg uint8_t inqmode; 335ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg uint16_t link_policy; 336b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 337fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.lmp_ver > 1) { 338fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[5] & LMP_SNIFF_SUBR) 339b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[5] |= 0x20; 340b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 341fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[5] & LMP_PAUSE_ENC) 342b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[5] |= 0x80; 343b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 344fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_EXT_INQ) 345b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[5] |= 0x40; 346b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 347fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_NFLUSH_PKTS) 348b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x01; 349b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 350fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[7] & LMP_LSTO) 351b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x80; 352b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 353fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_SIMPLE_PAIR) { 354b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 355b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 356b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 357b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 358b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 359b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 360b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 361b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 362b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 363b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg * Features Notification */ 364b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 365b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 366fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[4] & LMP_LE) 367b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 368b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 369fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_SET_EVENT_MASK, 370b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg sizeof(events), events); 371b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 372b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 373fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_SIMPLE_PAIR) 374be49c2621d577da4fafd462265b611289547f183Johan Hedberg init_ssp_mode(index); 375be49c2621d577da4fafd462265b611289547f183Johan Hedberg 376b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg inqmode = get_inquiry_mode(index); 377b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (inqmode) 378b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg write_inq_mode(index, inqmode); 379b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 380fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[7] & LMP_INQ_TX_PWR) 381fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, 382b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL, 0, NULL); 383b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 384b59dabdd2515aa111ebc56d946259e4bbdf20c61Pawel Wieczorkiewicz /* Set default link policy */ 385ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy = main_opts.link_policy; 386ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg 387fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[0] & LMP_RSWITCH)) 388ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_RSWITCH; 389fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[0] & LMP_HOLD)) 390ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_HOLD; 391fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[0] & LMP_SNIFF)) 392ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_SNIFF; 393fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[1] & LMP_PARK)) 394ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_PARK; 395b59dabdd2515aa111ebc56d946259e4bbdf20c61Pawel Wieczorkiewicz 396ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy = htobs(link_policy); 397fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_POLICY, OCF_WRITE_DEFAULT_LINK_POLICY, 398ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg sizeof(link_policy), &link_policy); 399b59dabdd2515aa111ebc56d946259e4bbdf20c61Pawel Wieczorkiewicz 400fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->current_cod = 0; 401fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memset(dev->eir, 0, sizeof(dev->eir)); 4025c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 40300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 4045c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic gboolean init_adapter(int index) 4055c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 406fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 4075c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg struct btd_adapter *adapter = NULL; 408fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg gboolean existing_adapter = dev->registered; 4095c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg uint8_t mode, on_mode; 4105c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg gboolean pairable, discoverable; 4115c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 412fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->registered) { 4135c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg adapter = btd_manager_register_adapter(index); 4145c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (adapter) 415fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->registered = TRUE; 4165c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } else { 417fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 4185c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg /* FIXME: manager_find_adapter should return a new ref */ 4195c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_ref(adapter); 4205c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } 4215c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4225c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (adapter == NULL) 4235c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return FALSE; 4245c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4255c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_get_state(adapter, &mode, &on_mode, &pairable); 4265c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4275c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (existing_adapter) 4285c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = on_mode; 4295c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4305c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (mode == MODE_OFF) { 4315c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg hciops_stop(index); 4325c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg goto done; 4335c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } 4345c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4355c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg start_adapter(index); 4365c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_start(adapter); 4375c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4385c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg discoverable = (mode == MODE_DISCOVERABLE); 4395c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4405c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg hciops_set_discoverable(index, discoverable); 4415c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg hciops_set_pairable(index, pairable); 4425c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4435c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergdone: 4445c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_unref(adapter); 4455c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return TRUE; 446b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 447b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 448abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstatic int hciops_encrypt_link(int index, bdaddr_t *dst, bt_hci_result_t cb, 449abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg gpointer user_data) 450abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg{ 451abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg GIOChannel *io; 452abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_cmd_data *cmd; 453abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_conn_info_req *cr; 454abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg auth_requested_cp cp; 455abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_filter nf; 456abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg int dd, err; 457abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint32_t link_mode; 458abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t handle; 459abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 460684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg dd = hci_open_dev(index); 461684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (dd < 0) 462684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg return -errno; 463684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg 464abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); 465abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cr->type = ACL_LINK; 466abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg bacpy(&cr->bdaddr, dst); 467abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 468684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = ioctl(dd, HCIGETCONNINFO, cr); 469abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg link_mode = cr->conn_info->link_mode; 470abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg handle = cr->conn_info->handle; 471abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_free(cr); 472abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 473684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (err < 0) { 474684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = -errno; 475684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 476684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg } 477abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 478684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (link_mode & HCI_LM_ENCRYPT) { 479684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = -EALREADY; 480684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 481684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg } 482abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 483abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg memset(&cp, 0, sizeof(cp)); 484abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.handle = htobs(handle); 485abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 486684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_AUTH_REQUESTED, 487684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg AUTH_REQUESTED_CP_SIZE, &cp) < 0) { 488684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = -errno; 489684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 490684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg } 491abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 492abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd = g_new0(struct hci_cmd_data, 1); 493abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->handle = handle; 494abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->ocf = OCF_AUTH_REQUESTED; 495abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb = cb; 496abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->caller_data = user_data; 497abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 498abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_clear(&nf); 499abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_ptype(HCI_EVENT_PKT, &nf); 500abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_CMD_STATUS, &nf); 501abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_AUTH_COMPLETE, &nf); 502abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_ENCRYPT_CHANGE, &nf); 503abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 504abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) { 505abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg err = -errno; 506abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_free(cmd); 507684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 508abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 509abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 510684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg io = g_io_channel_unix_new(dd); 511abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_set_close_on_unref(io, FALSE); 512abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_add_watch_full(io, G_PRIORITY_DEFAULT, 513abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg G_IO_HUP | G_IO_ERR | G_IO_NVAL | G_IO_IN, 514abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_event_watch, cmd, g_free); 515abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_unref(io); 516abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 517abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return 0; 518684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg 519684b1d3be105b64f3994e621335f69b45e34125fJohan Hedbergfail: 520684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg close(dd); 521684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg return err; 522abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg} 523abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 52400c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_set_did(int index, uint16_t vendor, uint16_t product, 52500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t version) 52600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 527fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 528fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 529fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->did_vendor = vendor; 530fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->did_product = product; 531fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->did_version = version; 53200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 53300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 53400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 53500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 536abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg/* End async HCI command handling */ 537abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 5385288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Start of HCI event callbacks */ 5395288199788ecb17183d6517da3062cd94692a900Johan Hedberg 54042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic int get_handle(int index, bdaddr_t *dba, uint16_t *handle) 5415288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 542fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 5435288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_list_req *cl; 5445288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_info *ci; 5455288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 5465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5475288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); 5485288199788ecb17183d6517da3062cd94692a900Johan Hedberg 54942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cl->dev_id = index; 5505288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl->conn_num = 10; 5515288199788ecb17183d6517da3062cd94692a900Johan Hedberg ci = cl->conn_info; 5525288199788ecb17183d6517da3062cd94692a900Johan Hedberg 553fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETCONNLIST, (void *) cl) < 0) { 5545288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 5555288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -EIO; 5565288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5575288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5585288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < cl->conn_num; i++, ci++) { 5595288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (bacmp(&ci->bdaddr, dba) == 0) { 5605288199788ecb17183d6517da3062cd94692a900Johan Hedberg *handle = ci->handle; 5615288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 5625288199788ecb17183d6517da3062cd94692a900Johan Hedberg return 0; 5635288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5645288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5655288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5665288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 5675288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5685288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -ENOENT; 5695288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 5705288199788ecb17183d6517da3062cd94692a900Johan Hedberg 57142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline int get_bdaddr(int index, uint16_t handle, bdaddr_t *dba) 5725288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 573fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 5745288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_list_req *cl; 5755288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_info *ci; 5765288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 5775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5785288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); 5795288199788ecb17183d6517da3062cd94692a900Johan Hedberg 58042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cl->dev_id = index; 5815288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl->conn_num = 10; 5825288199788ecb17183d6517da3062cd94692a900Johan Hedberg ci = cl->conn_info; 5835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 584fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETCONNLIST, (void *) cl) < 0) { 5855288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 5865288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -EIO; 5875288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5895288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < cl->conn_num; i++, ci++) 5905288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (ci->handle == handle) { 5915288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(dba, &ci->bdaddr); 5925288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 5935288199788ecb17183d6517da3062cd94692a900Johan Hedberg return 0; 5945288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5955288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5965288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 5975288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5985288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -ENOENT; 5995288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6005288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6015288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic inline void update_lastseen(bdaddr_t *sba, bdaddr_t *dba) 6025288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 6035288199788ecb17183d6517da3062cd94692a900Johan Hedberg time_t t; 6045288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct tm *tm; 6055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6065288199788ecb17183d6517da3062cd94692a900Johan Hedberg t = time(NULL); 6075288199788ecb17183d6517da3062cd94692a900Johan Hedberg tm = gmtime(&t); 6085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6095288199788ecb17183d6517da3062cd94692a900Johan Hedberg write_lastseen_info(sba, dba, tm); 6105288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6125288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic inline void update_lastused(bdaddr_t *sba, bdaddr_t *dba) 6135288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 6145288199788ecb17183d6517da3062cd94692a900Johan Hedberg time_t t; 6155288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct tm *tm; 6165288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6175288199788ecb17183d6517da3062cd94692a900Johan Hedberg t = time(NULL); 6185288199788ecb17183d6517da3062cd94692a900Johan Hedberg tm = gmtime(&t); 6195288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6205288199788ecb17183d6517da3062cd94692a900Johan Hedberg write_lastused_info(sba, dba, tm); 6215288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6235288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Link Key handling */ 6245288199788ecb17183d6517da3062cd94692a900Johan Hedberg 62542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void link_key_request(int index, bdaddr_t *dba) 6265288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 627fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 6285288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 6295288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_device *device; 6305288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_auth_info_req req; 6315288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char key[16]; 6320e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 6335288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t type; 6345288199788ecb17183d6517da3062cd94692a900Johan Hedberg int err; 6355288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6360e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 6370e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, da); 6385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 639fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 6405288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (adapter) 6415288199788ecb17183d6517da3062cd94692a900Johan Hedberg device = adapter_find_device(adapter, da); 6425288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 6435288199788ecb17183d6517da3062cd94692a900Johan Hedberg device = NULL; 6445288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6455288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&req, 0, sizeof(req)); 6465288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&req.bdaddr, dba); 6475288199788ecb17183d6517da3062cd94692a900Johan Hedberg 648fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = ioctl(dev->sk, HCIGETAUTHINFO, (unsigned long) &req); 6495288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err < 0) { 6505288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (errno != EINVAL) 6515288199788ecb17183d6517da3062cd94692a900Johan Hedberg DBG("HCIGETAUTHINFO failed %s (%d)", 6525288199788ecb17183d6517da3062cd94692a900Johan Hedberg strerror(errno), errno); 6535288199788ecb17183d6517da3062cd94692a900Johan Hedberg req.type = 0x00; 6545288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6565288199788ecb17183d6517da3062cd94692a900Johan Hedberg DBG("kernel auth requirements = 0x%02x", req.type); 6575288199788ecb17183d6517da3062cd94692a900Johan Hedberg 658e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg if (main_opts.debug_keys && device && 659e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg device_get_debug_key(device, key)) 6605288199788ecb17183d6517da3062cd94692a900Johan Hedberg type = 0x03; 661fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg else if (read_link_key(&dev->bdaddr, dba, key, &type) < 0 || 66242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg type == 0x03) { 6635288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Link key not found */ 664fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 66542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 6, dba); 6665288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 6675288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6695288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Link key found */ 6705288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6710e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("link key type 0x%02x", type); 6725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6735288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't use unauthenticated combination keys if MITM is 6745288199788ecb17183d6517da3062cd94692a900Johan Hedberg * required */ 6755288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (type == 0x04 && req.type != 0xff && (req.type & 0x01)) 676fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6, dba); 6785288199788ecb17183d6517da3062cd94692a900Johan Hedberg else { 6795288199788ecb17183d6517da3062cd94692a900Johan Hedberg link_key_reply_cp lr; 6805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6815288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(lr.link_key, key, 16); 6825288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&lr.bdaddr, dba); 6835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 684fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, 6855288199788ecb17183d6517da3062cd94692a900Johan Hedberg LINK_KEY_REPLY_CP_SIZE, &lr); 6865288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6875288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 68942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void link_key_notify(int index, void *ptr) 6905288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 691fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 6925288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_link_key_notify *evt = ptr; 6935288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t *dba = &evt->bdaddr; 6940e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 69542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg int err; 6965288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char old_key[16]; 6975288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t old_key_type; 6985288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6990e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 7000e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s type %d", index, da, evt->key_type); 7015288199788ecb17183d6517da3062cd94692a900Johan Hedberg 702fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = read_link_key(&dev->bdaddr, dba, old_key, &old_key_type); 7035288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err < 0) 7045288199788ecb17183d6517da3062cd94692a900Johan Hedberg old_key_type = 0xff; 7055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 706fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = btd_event_link_key_notify(&dev->bdaddr, dba, evt->link_key, 707fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg evt->key_type, dev->pin_length, 70842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg old_key_type); 709fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = -1; 7105288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7115288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err < 0) { 7125288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t handle; 7135288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7145288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err == -ENODEV) 715fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_bonding_process_complete(&dev->bdaddr, dba, 7165288199788ecb17183d6517da3062cd94692a900Johan Hedberg HCI_OE_LOW_RESOURCES); 7175288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 718fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_bonding_process_complete(&dev->bdaddr, dba, 7195288199788ecb17183d6517da3062cd94692a900Johan Hedberg HCI_MEMORY_FULL); 7205288199788ecb17183d6517da3062cd94692a900Johan Hedberg 72142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_handle(index, dba, &handle) == 0) { 7225288199788ecb17183d6517da3062cd94692a900Johan Hedberg disconnect_cp cp; 7235288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7245288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 7255288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.handle = htobs(handle); 7265288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.reason = HCI_OE_LOW_RESOURCES; 7275288199788ecb17183d6517da3062cd94692a900Johan Hedberg 728fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_DISCONNECT, 7295288199788ecb17183d6517da3062cd94692a900Johan Hedberg DISCONNECT_CP_SIZE, &cp); 7305288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7315288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7325288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7335288199788ecb17183d6517da3062cd94692a900Johan Hedberg 73442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void return_link_keys(int index, void *ptr) 7355288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 736fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 7375288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_return_link_keys *evt = ptr; 7385288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = evt->num_keys; 7395288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char key[16]; 7400e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 7415288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 7425288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 7435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7440e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d num_keys %u", index, num); 7450e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 7465288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr++; 7475288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7485288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 7495288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&dba, ptr); ba2str(&dba, da); 7505288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(key, ptr + 6, 16); 7515288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7520e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d returned key for %s", index, da); 7535288199788ecb17183d6517da3062cd94692a900Johan Hedberg 754fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_returned_link_key(&dev->bdaddr, &dba); 7555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7565288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += 22; 7575288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7585288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7595288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7605288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Simple Pairing handling */ 7615288199788ecb17183d6517da3062cd94692a900Johan Hedberg 76242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_confirm_request(int index, void *ptr) 7635288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 764fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 7655288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_confirm_request *req = ptr; 7665288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7670e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 7680e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 769fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (btd_event_user_confirm(&dev->bdaddr, &req->bdaddr, 7705288199788ecb17183d6517da3062cd94692a900Johan Hedberg btohl(req->passkey)) < 0) 771fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 7725288199788ecb17183d6517da3062cd94692a900Johan Hedberg OCF_USER_CONFIRM_NEG_REPLY, 6, ptr); 7735288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7745288199788ecb17183d6517da3062cd94692a900Johan Hedberg 77542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_passkey_request(int index, void *ptr) 7765288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 777fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 7785288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_passkey_request *req = ptr; 7795288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7800e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 7810e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 782fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (btd_event_user_passkey(&dev->bdaddr, &req->bdaddr) < 0) 783fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 7845288199788ecb17183d6517da3062cd94692a900Johan Hedberg OCF_USER_PASSKEY_NEG_REPLY, 6, ptr); 7855288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7865288199788ecb17183d6517da3062cd94692a900Johan Hedberg 78742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_passkey_notify(int index, void *ptr) 7885288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 789fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 7905288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_passkey_notify *req = ptr; 7915288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7920e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 7930e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 794fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_user_notify(&dev->bdaddr, &req->bdaddr, 79542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btohl(req->passkey)); 7965288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7975288199788ecb17183d6517da3062cd94692a900Johan Hedberg 79842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void remote_oob_data_request(int index, void *ptr) 7995288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 800fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 801fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 8020e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 803fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 804fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 80542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr); 8065288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8075288199788ecb17183d6517da3062cd94692a900Johan Hedberg 80842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void io_capa_request(int index, void *ptr) 8095288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 810fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 81142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg bdaddr_t *dba = ptr; 8120e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 8135288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t cap, auth; 8145288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8150e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 8160e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d IO capability request for %s", index, da); 8175288199788ecb17183d6517da3062cd94692a900Johan Hedberg 818fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (btd_event_get_io_cap(&dev->bdaddr, dba, &cap, &auth) < 0) { 8195288199788ecb17183d6517da3062cd94692a900Johan Hedberg io_capability_neg_reply_cp cp; 8205288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 8215288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cp.bdaddr, dba); 8225288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.reason = HCI_PAIRING_NOT_ALLOWED; 823fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 82442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg OCF_IO_CAPABILITY_NEG_REPLY, 8255288199788ecb17183d6517da3062cd94692a900Johan Hedberg IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp); 8265288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 8275288199788ecb17183d6517da3062cd94692a900Johan Hedberg io_capability_reply_cp cp; 8285288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 8295288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cp.bdaddr, dba); 8305288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.capability = cap; 8315288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.oob_data = 0x00; 8325288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.authentication = auth; 833fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY, 8345288199788ecb17183d6517da3062cd94692a900Johan Hedberg IO_CAPABILITY_REPLY_CP_SIZE, &cp); 8355288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 8365288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8375288199788ecb17183d6517da3062cd94692a900Johan Hedberg 83842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void io_capa_response(int index, void *ptr) 8395288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 840fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 8415288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_io_capability_response *evt = ptr; 8420e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 8435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8440e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(&evt->bdaddr, da); 8450e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d IO capability response from %s", index, da); 8465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 847fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_set_io_cap(&dev->bdaddr, &evt->bdaddr, 8485288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt->capability, evt->authentication); 8495288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8505288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8515288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* PIN code handling */ 8525288199788ecb17183d6517da3062cd94692a900Johan Hedberg 85342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void pin_code_request(int index, bdaddr_t *dba) 8545288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 855fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 8565288199788ecb17183d6517da3062cd94692a900Johan Hedberg pin_code_reply_cp pr; 8575288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_info_req *cr; 8585288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_info *ci; 8590e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18], pin[17]; 8605288199788ecb17183d6517da3062cd94692a900Johan Hedberg int pinlen; 8615288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8625288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&pr, 0, sizeof(pr)); 8635288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&pr.bdaddr, dba); 8645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8650e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 8660e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d PIN request for %s", index, da); 8675288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8685288199788ecb17183d6517da3062cd94692a900Johan Hedberg cr = g_malloc0(sizeof(*cr) + sizeof(*ci)); 8695288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8705288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cr->bdaddr, dba); 8715288199788ecb17183d6517da3062cd94692a900Johan Hedberg cr->type = ACL_LINK; 872fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETCONNINFO, (unsigned long) cr) < 0) { 8735288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Can't get conn info: %s (%d)", strerror(errno), errno); 8745288199788ecb17183d6517da3062cd94692a900Johan Hedberg goto reject; 8755288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 8765288199788ecb17183d6517da3062cd94692a900Johan Hedberg ci = cr->conn_info; 8775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8785288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(pin, 0, sizeof(pin)); 879fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg pinlen = read_pin_code(&dev->bdaddr, dba, pin); 8805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8815288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (pinlen > 0) { 882fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = pinlen; 8835288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(pr.pin_code, pin, pinlen); 8845288199788ecb17183d6517da3062cd94692a900Johan Hedberg pr.pin_len = pinlen; 885fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, 88642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg PIN_CODE_REPLY_CP_SIZE, &pr); 8875288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 8885288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Request PIN from passkey agent */ 889fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (btd_event_request_pin(&dev->bdaddr, ci) < 0) 8905288199788ecb17183d6517da3062cd94692a900Johan Hedberg goto reject; 8915288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 8925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8935288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cr); 8945288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8955288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 8965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8975288199788ecb17183d6517da3062cd94692a900Johan Hedbergreject: 8985288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cr); 8995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 900fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); 9015288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9035288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic void start_inquiry(bdaddr_t *local, uint8_t status, gboolean periodic) 9045288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 9055288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 9065288199788ecb17183d6517da3062cd94692a900Johan Hedberg int state; 9075288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9085288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't send the signal if the cmd failed */ 9095288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) { 9105288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Inquiry Failed with status 0x%02x", status); 9115288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9125288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 9135288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9145288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(local); 9155288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 9165288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 9175288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9185288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 9195288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9205288199788ecb17183d6517da3062cd94692a900Johan Hedberg state = adapter_get_state(adapter); 9215288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9225288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (periodic) 9235288199788ecb17183d6517da3062cd94692a900Johan Hedberg state |= STATE_PINQ; 9245288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 9255288199788ecb17183d6517da3062cd94692a900Johan Hedberg state |= STATE_STDINQ; 9265288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9275288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_set_state(adapter, state); 9285288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9295288199788ecb17183d6517da3062cd94692a900Johan Hedberg 930e5828c7e30453232e930dbead0e359175dc1decfJohan Hedbergstatic void inquiry_complete(bdaddr_t *local, uint8_t status, 931e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg gboolean periodic) 9325288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 9335288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 9345288199788ecb17183d6517da3062cd94692a900Johan Hedberg int state; 9355288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9365288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't send the signal if the cmd failed */ 9375288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) { 9385288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Inquiry Failed with status 0x%02x", status); 9395288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9405288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 9415288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9425288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(local); 9435288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 9445288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 9455288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9465288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 9475288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9485288199788ecb17183d6517da3062cd94692a900Johan Hedberg state = adapter_get_state(adapter); 9495288199788ecb17183d6517da3062cd94692a900Johan Hedberg state &= ~(STATE_STDINQ | STATE_PINQ); 9505288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_set_state(adapter, state); 9515288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9525288199788ecb17183d6517da3062cd94692a900Johan Hedberg 95342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_features_notify(int index, void *ptr) 9545288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 955fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 9565288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_remote_host_features_notify *evt = ptr; 9575288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9585288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->features[0] & 0x01) 959fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_set_legacy_pairing(&dev->bdaddr, &evt->bdaddr, 96042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg FALSE); 9615288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 962fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_set_legacy_pairing(&dev->bdaddr, &evt->bdaddr, 96342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg TRUE); 9645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 965fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_features_info(&dev->bdaddr, &evt->bdaddr, NULL, evt->features); 9665288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9675288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9682db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedbergstatic void write_le_host_complete(int index, uint8_t status) 9695288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 970fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 9712db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg uint8_t page_num = 0x01; 9725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9735288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) 9745288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9755288199788ecb17183d6517da3062cd94692a900Johan Hedberg 976fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_INFO_PARAM, 9772db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg OCF_READ_LOCAL_EXT_FEATURES, 1, &page_num) < 0) 9782db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg error("Unable to read extended local features: %s (%d)", 9792db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg strerror(errno), errno); 9805288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9815288199788ecb17183d6517da3062cd94692a900Johan Hedberg 982be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void read_local_version_complete(int index, 983be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg const read_local_version_rp *rp) 984be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 985fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 986fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 987be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (rp->status) 988be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 989be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 990fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.manufacturer = btohs(bt_get_unaligned(&rp->manufacturer)); 991fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.hci_ver = rp->hci_ver; 992fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.hci_rev = btohs(bt_get_unaligned(&rp->hci_rev)); 993fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_ver = rp->lmp_ver; 994fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver = btohs(bt_get_unaligned(&rp->lmp_subver)); 995be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 996fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 997be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 998be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 999fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_VERSION, &dev->pending); 1000be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1001be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg DBG("Got version for hci%d", index); 1002be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1003fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending && dev->up) 10045c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 1005be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 1006be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1007be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void read_local_features_complete(int index, 1008be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg const read_local_features_rp *rp) 1009be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 1010fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1011fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 1012be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (rp->status) 1013be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 1014be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1015fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->features, rp->features, 8); 1016be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1017fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 1018be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 1019be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1020fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_FEATURES, &dev->pending); 1021be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1022be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg DBG("Got features for hci%d", index); 1023be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1024fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending && dev->up) 10255c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 1026be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 1027be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 102800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg#define SIZEOF_UUID128 16 102900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 103000c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void eir_generate_uuid128(sdp_list_t *list, 103100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *ptr, uint16_t *eir_len) 103200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 103300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int i, k, uuid_count = 0; 103400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t len = *eir_len; 103500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *uuid128; 103600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg gboolean truncated = FALSE; 103700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 103800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Store UUIDs in place, skip 2 bytes to write type and length later */ 103900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128 = ptr + 2; 104000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 104100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (; list; list = list->next) { 104200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_record_t *rec = list->data; 104300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *uuid128_data = rec->svclass.value.uuid128.data; 104400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 104500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.type != SDP_UUID128) 104600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 104700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 104800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Stop if not enough space to put next UUID128 */ 104900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) { 105000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg truncated = TRUE; 105100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 105200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 105300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 105400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Check for duplicates, EIR data is Little Endian */ 105500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (i = 0; i < uuid_count; i++) { 105600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (k = 0; k < SIZEOF_UUID128; k++) { 105700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid128[i * SIZEOF_UUID128 + k] != 105800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128_data[SIZEOF_UUID128 - 1 - k]) 105900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 106000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 106100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (k == SIZEOF_UUID128) 106200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 106300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 106400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 106500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (i < uuid_count) 106600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 106700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 106800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR data is Little Endian */ 106900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (k = 0; k < SIZEOF_UUID128; k++) 107000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128[uuid_count * SIZEOF_UUID128 + k] = 107100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128_data[SIZEOF_UUID128 - 1 - k]; 107200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 107300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg len += SIZEOF_UUID128; 107400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid_count++; 107500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 107600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 107700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid_count > 0 || truncated) { 107800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data length */ 107900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[0] = (uuid_count * SIZEOF_UUID128) + 1; 108000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data type */ 108100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL; 108200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg len += 2; 108300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *eir_len = len; 108400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 108500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 108600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 108700c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void create_ext_inquiry_response(int index, uint8_t *data) 108800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1089fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 109000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_list_t *services; 109100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_list_t *list; 109200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *ptr = data; 109300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t eir_len = 0; 109400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t uuid16[EIR_DATA_LENGTH / 2]; 109500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int i, uuid_count = 0; 109600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg gboolean truncated = FALSE; 109700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg struct btd_adapter *adapter; 109800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg size_t name_len; 109900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1100fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg name_len = strlen(dev->name); 110100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 110200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (name_len > 0) { 110300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data type */ 110400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (name_len > 48) { 110500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg name_len = 48; 110600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = EIR_NAME_SHORT; 110700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } else 110800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = EIR_NAME_COMPLETE; 110900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 111000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data length */ 111100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[0] = name_len + 1; 111200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1113fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(ptr + 2, dev->name, name_len); 111400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 111500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += (name_len + 2); 111600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr += (name_len + 2); 111700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 111800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1119fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->tx_power != 0) { 112000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = 2; 112100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = EIR_TX_POWER; 1122fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (uint8_t) dev->tx_power; 112300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += 3; 112400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 112500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1126fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->did_vendor != 0x0000) { 112700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t source = 0x0002; 112800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = 9; 112900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = EIR_DEVICE_ID; 113000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (source & 0x00ff); 113100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (source & 0xff00) >> 8; 1132fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_vendor & 0x00ff); 1133fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_vendor & 0xff00) >> 8; 1134fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_product & 0x00ff); 1135fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_product & 0xff00) >> 8; 1136fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_version & 0x00ff); 1137fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_version & 0xff00) >> 8; 113800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += 10; 113900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 114000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1141fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 114200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (adapter == NULL) 114300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 114400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 114500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg services = adapter_get_services(adapter); 114600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 114700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Group all UUID16 types */ 114800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (list = services; list; list = list->next) { 114900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_record_t *rec = list->data; 115000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 115100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.type != SDP_UUID16) 115200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 115300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 115400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.value.uuid16 < 0x1100) 115500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 115600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 115700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.value.uuid16 == PNP_INFO_SVCLASS_ID) 115800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 115900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 116000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Stop if not enough space to put next UUID16 */ 116100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) { 116200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg truncated = TRUE; 116300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 116400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 116500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 116600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Check for duplicates */ 116700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (i = 0; i < uuid_count; i++) 116800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid16[i] == rec->svclass.value.uuid16) 116900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 117000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 117100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (i < uuid_count) 117200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 117300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 117400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid16[uuid_count++] = rec->svclass.value.uuid16; 117500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += sizeof(uint16_t); 117600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 117700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 117800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid_count > 0) { 117900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data length */ 118000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[0] = (uuid_count * sizeof(uint16_t)) + 1; 118100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data type */ 118200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; 118300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 118400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr += 2; 118500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += 2; 118600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 118700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (i = 0; i < uuid_count; i++) { 118800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (uuid16[i] & 0x00ff); 118900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (uuid16[i] & 0xff00) >> 8; 119000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 119100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 119200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 119300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Group all UUID128 types */ 119400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (eir_len <= EIR_DATA_LENGTH - 2) 119500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_generate_uuid128(services, ptr, &eir_len); 119600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 119700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 119800c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void update_ext_inquiry_response(int index) 119900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1200fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 120100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_ext_inquiry_response_cp cp; 120200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 120300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d", index); 120400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1205fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[6] & LMP_EXT_INQ)) 120600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 120700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1208fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ssp_mode == 0) 120900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 121000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1211fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->cache_enable) 121200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 121300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 121400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memset(&cp, 0, sizeof(cp)); 121500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 121600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg create_ext_inquiry_response(index, cp.data); 121700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1218fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0) 121900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 122000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1221fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->eir, cp.data, sizeof(cp.data)); 122200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1223fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 122400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg OCF_WRITE_EXT_INQUIRY_RESPONSE, 122500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &cp) < 0) 122600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg error("Unable to write EIR data: %s (%d)", 122700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg strerror(errno), errno); 122800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 122900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 123019084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedbergstatic void update_name(int index, const char *name) 123119084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg{ 1232fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 123319084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg struct btd_adapter *adapter; 123419084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg 1235fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 123619084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg if (adapter) 123719084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg adapter_update_local_name(adapter, name); 123800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 123900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 124019084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg} 124119084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg 1242fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedbergstatic void read_local_name_complete(int index, read_local_name_rp *rp) 1243fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg{ 1244fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1245fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 12460e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 12470e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1248fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg if (rp->status) 1249fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg return; 1250fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1251fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->name, rp->name, 248); 125200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1253fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) { 125419084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg update_name(index, (char *) rp->name); 1255fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg return; 1256fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg } 1257fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1258fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_NAME, &dev->pending); 1259fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1260fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg DBG("Got name for hci%d", index); 1261fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1262fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->up) 12639f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg return; 12649f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 12659f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg /* Even though it shouldn't happen (assuming the kernel behaves 12669f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * properly) it seems like we might miss the very first 12679f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * initialization commands that the kernel sends. So check for 12689f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * it here (since read_local_name is one of the last init 12699f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * commands) and resend the first ones if we haven't seen 12709f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * their results yet */ 12719f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 1272fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_test_bit(PENDING_FEATURES, &dev->pending)) 1273fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_INFO_PARAM, 12749f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg OCF_READ_LOCAL_FEATURES, 0, NULL); 12759f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 1276fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_test_bit(PENDING_VERSION, &dev->pending)) 1277fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_INFO_PARAM, 12789f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg OCF_READ_LOCAL_VERSION, 0, NULL); 12799f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 1280fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 12815c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 1282fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg} 1283fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1284e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedbergstatic void read_tx_power_complete(int index, void *ptr) 1285e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg{ 1286fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1287fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 1288e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg read_inq_response_tx_power_level_rp *rp = ptr; 1289e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg 12900e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 12910e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1292e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg if (rp->status) 1293e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg return; 1294e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg 1295fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->tx_power = rp->level; 129600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 1297e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg} 1298e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg 1299af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedbergstatic void read_simple_pairing_mode_complete(int index, void *ptr) 1300af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg{ 1301fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1302af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg read_simple_pairing_mode_rp *rp = ptr; 1303af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg struct btd_adapter *adapter; 1304af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 13050e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 13060e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1307af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg if (rp->status) 1308af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg return; 1309af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 1310fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ssp_mode = rp->mode; 131100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 131200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1313fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 1314af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg if (!adapter) { 1315af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg error("No matching adapter found"); 1316af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg return; 1317af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg } 1318af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 1319af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg adapter_update_ssp_mode(adapter, rp->mode); 1320af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg} 1321af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 13220e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedbergstatic void read_local_ext_features_complete(int index, 13235288199788ecb17183d6517da3062cd94692a900Johan Hedberg const read_local_ext_features_rp *rp) 13245288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1325fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 13265288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 13275288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13280e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 13290e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 13305288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (rp->status) 13315288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 13325288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1333fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 13345288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 13355288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("No matching adapter found"); 13365288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 13375288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 13385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13395288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Local Extended feature page number is 1 */ 13405288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (rp->page_num != 1) 13415288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 13425288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13435288199788ecb17183d6517da3062cd94692a900Johan Hedberg btd_adapter_update_local_ext_features(adapter, rp->features); 13445288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 13455288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13465a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedbergstatic void read_bd_addr_complete(int index, read_bd_addr_rp *rp) 13475a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg{ 1348fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1349fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 13500e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 13510e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 13525a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg if (rp->status) 13535a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg return; 13545a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1355fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(&dev->bdaddr, &rp->bdaddr); 13565a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1357fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 13585a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg return; 13595a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1360fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_BDADDR, &dev->pending); 13615a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 136228c405b17a3131494c11599705885ae630c52ee2Johan Hedberg DBG("Got bdaddr for hci%d", index); 13635a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1364fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending && dev->up) 13655c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 13665a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg} 13675a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 136842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void cmd_status(int index, void *ptr) 13695288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1370fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 13715288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_status *evt = ptr; 13725288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t opcode = btohs(evt->opcode); 13735288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13745288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) 1375fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg start_inquiry(&dev->bdaddr, evt->status, FALSE); 13765288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 13775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 137842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void read_scan_complete(int index, uint8_t status, void *ptr) 13795288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1380fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 13815288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 13825288199788ecb17183d6517da3062cd94692a900Johan Hedberg read_scan_enable_rp *rp = ptr; 13835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13840e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, status); 13850e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1386fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 13875288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13885288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 13895288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 13905288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 13915288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 13925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13935288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_mode_changed(adapter, rp->enable); 13945288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 13955288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1396914a9093c108cf67a1ef08bffc7db2e4c9a5b1b9Johan Hedbergstatic int write_class(int index, uint32_t class) 139700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1398fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 139900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_class_of_dev_cp cp; 140000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 140100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d class 0x%06x", index, class); 140200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 140300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memcpy(cp.dev_class, &class, 3); 140400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1405fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, 140600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg WRITE_CLASS_OF_DEV_CP_SIZE, &cp) < 0) 140700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return -errno; 140800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1409fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pending_cod = class; 141000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 141100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 141200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 141300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 141400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg/* Limited Discoverable bit mask in CoD */ 141500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg#define LIMITED_BIT 0x002000 141600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 141700c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_set_limited_discoverable(int index, gboolean limited) 141800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1419fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 142000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int num = (limited ? 2 : 1); 142100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t lap[] = { 0x33, 0x8b, 0x9e, 0x00, 0x8b, 0x9e }; 142200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_current_iac_lap_cp cp; 142300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 142400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d limited %d", index, limited); 142500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 142600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Check if limited bit needs to be set/reset */ 142700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (limited) 1428fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod |= LIMITED_BIT; 142900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg else 1430fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod &= ~LIMITED_BIT; 143100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 143200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* If we dont need the toggling, save an unnecessary CoD write */ 1433fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->pending_cod || dev->wanted_cod == dev->current_cod) 143400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 143500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 143600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* 143700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * 1: giac 143800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * 2: giac + liac 143900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg */ 144000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memset(&cp, 0, sizeof(cp)); 144100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg cp.num_current_iac = num; 144200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memcpy(&cp.lap, lap, num * 3); 144300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1444fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CURRENT_IAC_LAP, 144500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg (num * 3 + 1), &cp) < 0) 144600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return -errno; 144700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1448fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg return write_class(index, dev->wanted_cod); 144900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 145000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 145100c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void write_class_complete(int index, uint8_t status) 145200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1453fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 145400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg struct btd_adapter *adapter; 145500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 145600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (status) 145700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 145800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1459fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->pending_cod == 0) 146000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 146100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1462fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->current_cod = dev->pending_cod; 1463fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pending_cod = 0; 146400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1465fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 146600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (adapter) 1467fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_adapter_class_changed(adapter, dev->current_cod); 146800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 146900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 147000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1471fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->wanted_cod == dev->current_cod) 147200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 147300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1474fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->wanted_cod & LIMITED_BIT && 1475fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg !(dev->current_cod & LIMITED_BIT)) 147600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg hciops_set_limited_discoverable(index, TRUE); 1477fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg else if (!(dev->wanted_cod & LIMITED_BIT) && 1478fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg (dev->current_cod & LIMITED_BIT)) 147900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg hciops_set_limited_discoverable(index, FALSE); 148000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg else 1481fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_class(index, dev->wanted_cod); 148200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 148300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 148442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void cmd_complete(int index, void *ptr) 14855288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1486fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 14875288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_complete *evt = ptr; 14885288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t opcode = btohs(evt->opcode); 14895288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t status = *((uint8_t *) ptr + EVT_CMD_COMPLETE_SIZE); 14905288199788ecb17183d6517da3062cd94692a900Johan Hedberg 14915288199788ecb17183d6517da3062cd94692a900Johan Hedberg switch (opcode) { 1492be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION): 1493be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg ptr += sizeof(evt_cmd_complete); 1494be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg read_local_version_complete(index, ptr); 1495be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg break; 1496be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES): 1497be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg ptr += sizeof(evt_cmd_complete); 1498be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg read_local_features_complete(index, ptr); 1499be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg break; 15005288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_EXT_FEATURES): 15015288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 15020e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg read_local_ext_features_complete(index, ptr); 15035288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15045a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BD_ADDR): 15055a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg ptr += sizeof(evt_cmd_complete); 15065a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg read_bd_addr_complete(index, ptr); 15075a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg break; 15085288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_PERIODIC_INQUIRY): 1509fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg start_inquiry(&dev->bdaddr, status, TRUE); 15105288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15115288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY): 1512fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg inquiry_complete(&dev->bdaddr, status, TRUE); 15135288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15145288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL): 1515fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg inquiry_complete(&dev->bdaddr, status, FALSE); 15165288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15175288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_LE_HOST_SUPPORTED): 15182db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg write_le_host_complete(index, status); 15195288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15205288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE): 1521fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_le_set_scan_enable_complete(&dev->bdaddr, status); 15225288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15235288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME): 1524bd7f8939b50a12418476245f9b5117801f858b02Johan Hedberg if (!status) 1525fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, 1526bd7f8939b50a12418476245f9b5117801f858b02Johan Hedberg OCF_READ_LOCAL_NAME, 0, 0); 15275288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15285288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE): 1529fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_setscan_enable_complete(&dev->bdaddr); 15305288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15315288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SCAN_ENABLE): 15325288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 153342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg read_scan_complete(index, status, ptr); 15345288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15355288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV): 153600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_class_complete(index, status); 15375288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15385288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SIMPLE_PAIRING_MODE): 15397afa48dcf311926269dcfb8ec1a2a12c94eb2d5bJohan Hedberg if (!status) 1540fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, 15417afa48dcf311926269dcfb8ec1a2a12c94eb2d5bJohan Hedberg OCF_READ_SIMPLE_PAIRING_MODE, 0, NULL); 15425288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15435288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SIMPLE_PAIRING_MODE): 15445288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1545af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg read_simple_pairing_mode_complete(index, ptr); 15465288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15475288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_NAME): 15485288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1549fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg read_local_name_complete(index, ptr); 15505288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 1551e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, 1552e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL): 15535288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1554e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg read_tx_power_complete(index, ptr); 15555288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15565288199788ecb17183d6517da3062cd94692a900Johan Hedberg }; 15575288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 15585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 155942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_name_information(int index, void *ptr) 15605288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1561fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 15625288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_remote_name_req_complete *evt = ptr; 15635288199788ecb17183d6517da3062cd94692a900Johan Hedberg char name[MAX_NAME_LENGTH + 1]; 15645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 15650e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 15660e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 15675288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(name, 0, sizeof(name)); 15685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 15695288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!evt->status) 15705288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(name, evt->name, MAX_NAME_LENGTH); 15715288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1572fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_remote_name(&dev->bdaddr, &evt->bdaddr, evt->status, name); 15735288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 15745288199788ecb17183d6517da3062cd94692a900Johan Hedberg 157542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_version_information(int index, void *ptr) 15765288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1577fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 15785288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_read_remote_version_complete *evt = ptr; 15795288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 15805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 15810e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 15820e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 15835288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 15845288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 15855288199788ecb17183d6517da3062cd94692a900Johan Hedberg 158642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) 15875288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 15885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1589fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_version_info(&dev->bdaddr, &dba, btohs(evt->manufacturer), 15905288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt->lmp_ver, btohs(evt->lmp_subver)); 15915288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 15925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 159342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void inquiry_result(int index, int plen, void *ptr) 15945288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1595fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 15965288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 15975288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 15985288199788ecb17183d6517da3062cd94692a900Johan Hedberg 15995288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 16005288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info *info = ptr; 160142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg uint32_t class = info->dev_class[0] | 160242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg (info->dev_class[1] << 8) | 160342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg (info->dev_class[2] << 16); 16045288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1605fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_inquiry_result(&dev->bdaddr, &info->bdaddr, class, 160642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 0, NULL); 16075288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1608fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg update_lastseen(&dev->bdaddr, &info->bdaddr); 16095288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16105288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_SIZE; 16115288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16125288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16135288199788ecb17183d6517da3062cd94692a900Johan Hedberg 161442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void inquiry_result_with_rssi(int index, int plen, void *ptr) 16155288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1616fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 16175288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 16185288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 16195288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16205288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!num) 16215288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16235288199788ecb17183d6517da3062cd94692a900Johan Hedberg if ((plen - 1) / num == INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE) { 16245288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 16255288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info_with_rssi_and_pscan_mode *info = ptr; 16265288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 162742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 162842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 16295288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1630fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_inquiry_result(&dev->bdaddr, &info->bdaddr, 16315288199788ecb17183d6517da3062cd94692a900Johan Hedberg class, info->rssi, NULL); 16325288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1633fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg update_lastseen(&dev->bdaddr, &info->bdaddr); 16345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16355288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; 16365288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16375288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 16385288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 16395288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info_with_rssi *info = ptr; 16405288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 164142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 164242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 16435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1644fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_inquiry_result(&dev->bdaddr, &info->bdaddr, 16455288199788ecb17183d6517da3062cd94692a900Johan Hedberg class, info->rssi, NULL); 16465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1647fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg update_lastseen(&dev->bdaddr, &info->bdaddr); 16485288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16495288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_WITH_RSSI_SIZE; 16505288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16515288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16525288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16535288199788ecb17183d6517da3062cd94692a900Johan Hedberg 165442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void extended_inquiry_result(int index, int plen, void *ptr) 16555288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1656fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 16575288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 16585288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 16595288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16605288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 16615288199788ecb17183d6517da3062cd94692a900Johan Hedberg extended_inquiry_info *info = ptr; 16625288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 166342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 166442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 16655288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1666fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_inquiry_result(&dev->bdaddr, &info->bdaddr, class, 16675288199788ecb17183d6517da3062cd94692a900Johan Hedberg info->rssi, info->data); 16685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1669fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg update_lastseen(&dev->bdaddr, &info->bdaddr); 16705288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16715288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += EXTENDED_INQUIRY_INFO_SIZE; 16725288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16735288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16745288199788ecb17183d6517da3062cd94692a900Johan Hedberg 167542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_features_information(int index, void *ptr) 16765288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1677fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 16785288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_read_remote_features_complete *evt = ptr; 16795288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 16805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16810e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 16820e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 16835288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 16845288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16855288199788ecb17183d6517da3062cd94692a900Johan Hedberg 168642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) 16875288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1689fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_features_info(&dev->bdaddr, &dba, evt->features, NULL); 16905288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16915288199788ecb17183d6517da3062cd94692a900Johan Hedberg 169242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void conn_complete(int index, void *ptr) 16935288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1694fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 16955288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_conn_complete *evt = ptr; 16965288199788ecb17183d6517da3062cd94692a900Johan Hedberg char filename[PATH_MAX]; 16975288199788ecb17183d6517da3062cd94692a900Johan Hedberg char local_addr[18], peer_addr[18], *str; 16985288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 16995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1700fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 17015288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 17025288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 17035288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 17045288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 17055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17065288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->link_type != ACL_LINK) 17075288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 17085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1709fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_conn_complete(&dev->bdaddr, evt->status, 171042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btohs(evt->handle), &evt->bdaddr); 17115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17125288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 17135288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 17145288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1715fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg update_lastused(&dev->bdaddr, &evt->bdaddr); 17165288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17175288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* check if the remote version needs be requested */ 1718fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg ba2str(&dev->bdaddr, local_addr); 17195288199788ecb17183d6517da3062cd94692a900Johan Hedberg ba2str(&evt->bdaddr, peer_addr); 17205288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17215288199788ecb17183d6517da3062cd94692a900Johan Hedberg create_name(filename, sizeof(filename), STORAGEDIR, local_addr, 17225288199788ecb17183d6517da3062cd94692a900Johan Hedberg "manufacturers"); 17235288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17245288199788ecb17183d6517da3062cd94692a900Johan Hedberg str = textfile_get(filename, peer_addr); 17255288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!str) 17265288199788ecb17183d6517da3062cd94692a900Johan Hedberg btd_adapter_get_remote_version(adapter, btohs(evt->handle), 17275288199788ecb17183d6517da3062cd94692a900Johan Hedberg TRUE); 17285288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 17295288199788ecb17183d6517da3062cd94692a900Johan Hedberg free(str); 17305288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 17315288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17325f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demariostatic inline void le_conn_complete(int index, void *ptr) 17335f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario{ 1734fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17355f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario evt_le_connection_complete *evt = ptr; 17365f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario char filename[PATH_MAX]; 17375f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario char local_addr[18], peer_addr[18], *str; 17385f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario struct btd_adapter *adapter; 17395f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 1740fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 17415f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario if (!adapter) { 17425f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario error("Unable to find matching adapter"); 17435f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario return; 17445f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario } 17455f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 1746fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_conn_complete(&dev->bdaddr, evt->status, 17475f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario btohs(evt->handle), &evt->peer_bdaddr); 17485f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 17495f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario if (evt->status) 17505f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario return; 17515f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 1752fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg update_lastused(&dev->bdaddr, &evt->peer_bdaddr); 17535f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 17545f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario /* check if the remote version needs be requested */ 1755fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg ba2str(&dev->bdaddr, local_addr); 17565f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario ba2str(&evt->peer_bdaddr, peer_addr); 17575f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 17585f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario create_name(filename, sizeof(filename), STORAGEDIR, local_addr, 17595f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario "manufacturers"); 17605f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 17615f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario str = textfile_get(filename, peer_addr); 17625f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario if (!str) 17635f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario btd_adapter_get_remote_version(adapter, btohs(evt->handle), 17645f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario TRUE); 17655f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario else 17665f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario free(str); 17675f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario} 17685f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 176942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void disconn_complete(int index, void *ptr) 17705288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1771fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17725288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_disconn_complete *evt = ptr; 17735288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1774fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_disconn_complete(&dev->bdaddr, evt->status, 177542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btohs(evt->handle), evt->reason); 17765288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 17775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 177842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void auth_complete(int index, void *ptr) 17795288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1780fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17815288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_auth_complete *evt = ptr; 17825288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 17835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17840e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 17850e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 178642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) 17875288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 17885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1789fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_bonding_process_complete(&dev->bdaddr, &dba, evt->status); 17905288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 17915288199788ecb17183d6517da3062cd94692a900Johan Hedberg 179242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void simple_pairing_complete(int index, void *ptr) 17935288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1794fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17955288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_simple_pairing_complete *evt = ptr; 17965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17970e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 17980e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1799fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_simple_pairing_complete(&dev->bdaddr, &evt->bdaddr, 180042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg evt->status); 18015288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 18025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 180342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void conn_request(int index, void *ptr) 18045288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1805fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 18065288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_conn_request *evt = ptr; 18075288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = evt->dev_class[0] | (evt->dev_class[1] << 8) 18085288199788ecb17183d6517da3062cd94692a900Johan Hedberg | (evt->dev_class[2] << 16); 18095288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1810fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_remote_class(&dev->bdaddr, &evt->bdaddr, class); 18115288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 18125288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18135f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demariostatic inline void le_advertising_report(int index, evt_le_meta_event *meta) 18145288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1815fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 18165288199788ecb17183d6517da3062cd94692a900Johan Hedberg le_advertising_info *info; 1817e430998efb9da9c89f1d94e3b6786a14aed834ebBruna Moreira uint8_t num, i; 18185288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18195288199788ecb17183d6517da3062cd94692a900Johan Hedberg num = meta->data[0]; 18205288199788ecb17183d6517da3062cd94692a900Johan Hedberg info = (le_advertising_info *) (meta->data + 1); 18215288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18225288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 1823fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_advertising_report(&dev->bdaddr, info); 1824e430998efb9da9c89f1d94e3b6786a14aed834ebBruna Moreira info = (le_advertising_info *) (info->data + info->length + 1); 18255288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 18265288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 18275288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18285f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demariostatic inline void le_metaevent(int index, void *ptr) 18295f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario{ 18305f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario evt_le_meta_event *meta = ptr; 18315f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 18325f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario DBG("hci%d LE Meta Event %u", index, meta->subevent); 18335f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 18345f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario switch (meta->subevent) { 18355f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario case EVT_LE_ADVERTISING_REPORT: 18365f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario le_advertising_report(index, meta); 18375f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario break; 18385f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 18395f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario case EVT_LE_CONN_COMPLETE: 18405f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario le_conn_complete(index, meta->data); 18415f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario break; 18425f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario } 18435f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario} 18445f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 184555694454017b04a416931a81964bb695f48b3d93Johan Hedbergstatic void stop_hci_dev(int index) 18465288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1847fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1848fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg GIOChannel *chan = dev->io; 18495288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18505288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!chan) 18515288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 18525288199788ecb17183d6517da3062cd94692a900Johan Hedberg 185355694454017b04a416931a81964bb695f48b3d93Johan Hedberg info("Stopping hci%d event socket", index); 18545288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1855fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg g_source_remove(dev->watch_id); 1856fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg g_io_channel_unref(dev->io); 1857fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_close_dev(dev->sk); 1858fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg init_dev_info(index, -1, dev->registered); 18595288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 18605288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18615288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic gboolean io_security_event(GIOChannel *chan, GIOCondition cond, 18625288199788ecb17183d6517da3062cd94692a900Johan Hedberg gpointer data) 18635288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 18645288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; 186542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg int type, index = GPOINTER_TO_INT(data); 1866fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 186742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg struct hci_dev_info di; 18685288199788ecb17183d6517da3062cd94692a900Johan Hedberg size_t len; 18695288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_event_hdr *eh; 18705288199788ecb17183d6517da3062cd94692a900Johan Hedberg GIOError err; 18715288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_status *evt; 18725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18735288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { 187455694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 18755288199788ecb17183d6517da3062cd94692a900Johan Hedberg return FALSE; 18765288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 18775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18785288199788ecb17183d6517da3062cd94692a900Johan Hedberg if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { 18795288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err == G_IO_ERROR_AGAIN) 18805288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 188155694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 18825288199788ecb17183d6517da3062cd94692a900Johan Hedberg return FALSE; 18835288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 18845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18855288199788ecb17183d6517da3062cd94692a900Johan Hedberg type = *ptr++; 18865288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18875288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (type != HCI_EVENT_PKT) 18885288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 18895288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18905288199788ecb17183d6517da3062cd94692a900Johan Hedberg eh = (hci_event_hdr *) ptr; 18915288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += HCI_EVENT_HDR_SIZE; 18925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 189342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg memset(&di, 0, sizeof(di)); 189442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (hci_devinfo(index, &di) == 0) { 1895fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(&dev->bdaddr, &di.bdaddr); 18965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 189742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (ignore_device(&di)) 189842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg return TRUE; 189942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg } 190055694454017b04a416931a81964bb695f48b3d93Johan Hedberg 19015288199788ecb17183d6517da3062cd94692a900Johan Hedberg switch (eh->evt) { 19025288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CMD_STATUS: 190342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cmd_status(index, ptr); 19045288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19065288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CMD_COMPLETE: 190742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cmd_complete(index, ptr); 19085288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19095288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19105288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_NAME_REQ_COMPLETE: 191142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_name_information(index, ptr); 19125288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19135288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19145288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_READ_REMOTE_VERSION_COMPLETE: 191542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_version_information(index, ptr); 19165288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19175288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19185288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_READ_REMOTE_FEATURES_COMPLETE: 191942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_features_information(index, ptr); 19205288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19215288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19225288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_HOST_FEATURES_NOTIFY: 192342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_features_notify(index, ptr); 19245288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19255288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19265288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_COMPLETE: 19275288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt = (evt_cmd_status *) ptr; 1928fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg inquiry_complete(&dev->bdaddr, evt->status, FALSE); 19295288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19305288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19315288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_RESULT: 193242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_result(index, eh->plen, ptr); 19335288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19355288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_RESULT_WITH_RSSI: 193642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_result_with_rssi(index, eh->plen, ptr); 19375288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19395288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_EXTENDED_INQUIRY_RESULT: 194042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg extended_inquiry_result(index, eh->plen, ptr); 19415288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19425288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19435288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CONN_COMPLETE: 194442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg conn_complete(index, ptr); 19455288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19475288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_DISCONN_COMPLETE: 194842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg disconn_complete(index, ptr); 19495288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19505288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19515288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_AUTH_COMPLETE: 195242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg auth_complete(index, ptr); 19535288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19545288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19555288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_SIMPLE_PAIRING_COMPLETE: 195642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg simple_pairing_complete(index, ptr); 19575288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19595288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CONN_REQUEST: 196042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg conn_request(index, ptr); 19615288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19625288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LE_META_EVENT: 196342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg le_metaevent(index, ptr); 19645288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19655288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_PIN_CODE_REQ: 196642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg pin_code_request(index, (bdaddr_t *) ptr); 19675288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19695288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LINK_KEY_REQ: 197042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg link_key_request(index, (bdaddr_t *) ptr); 19715288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19735288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LINK_KEY_NOTIFY: 197442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg link_key_notify(index, ptr); 19755288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19765288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19775288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_RETURN_LINK_KEYS: 197842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg return_link_keys(index, ptr); 19795288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19815288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_IO_CAPABILITY_REQUEST: 198242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg io_capa_request(index, ptr); 19835288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19855288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_IO_CAPABILITY_RESPONSE: 198642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg io_capa_response(index, ptr); 19875288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19895288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_CONFIRM_REQUEST: 199042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_confirm_request(index, ptr); 19915288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19935288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_PASSKEY_REQUEST: 199442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_passkey_request(index, ptr); 19955288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19975288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_PASSKEY_NOTIFY: 199842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_passkey_notify(index, ptr); 19995288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 20005288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20015288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_OOB_DATA_REQUEST: 200242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_oob_data_request(index, ptr); 20035288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 20045288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 20055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20065288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 20075288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 20085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20095a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedbergstatic void start_hci_dev(int index) 20105288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2011fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2012fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg GIOChannel *chan = dev->io; 2013e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg GIOCondition cond; 20145288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_filter flt; 20155288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20165288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (chan) 20175288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 20185288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20195a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg info("Listening for HCI events on hci%d", index); 20205288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20215288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Set filter */ 20225288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_clear(&flt); 20235288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 20245288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CMD_STATUS, &flt); 20255288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CMD_COMPLETE, &flt); 20265288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); 20275288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); 20285288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); 20295288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_RETURN_LINK_KEYS, &flt); 20305288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_IO_CAPABILITY_REQUEST, &flt); 20315288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_IO_CAPABILITY_RESPONSE, &flt); 20325288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_CONFIRM_REQUEST, &flt); 20335288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_PASSKEY_REQUEST, &flt); 20345288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_OOB_DATA_REQUEST, &flt); 20355288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_PASSKEY_NOTIFY, &flt); 20365288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_KEYPRESS_NOTIFY, &flt); 20375288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_SIMPLE_PAIRING_COMPLETE, &flt); 20385288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_AUTH_COMPLETE, &flt); 20395288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); 20405288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt); 20415288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); 20425288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_HOST_FEATURES_NOTIFY, &flt); 20435288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); 20445288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); 20455288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); 20465288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); 20475288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CONN_REQUEST, &flt); 20485288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CONN_COMPLETE, &flt); 20495288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt); 20505288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LE_META_EVENT, &flt); 2051fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (setsockopt(dev->sk, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { 20525288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Can't set filter on hci%d: %s (%d)", 20535a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg index, strerror(errno), errno); 20545288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 20555288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 20565288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2057fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg chan = g_io_channel_unix_new(dev->sk); 2058e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg cond = G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR; 2059fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->watch_id = g_io_add_watch_full(chan, G_PRIORITY_LOW, cond, 2060e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg io_security_event, 2061e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg GINT_TO_POINTER(index), NULL); 2062fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->io = chan; 2063fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = -1; 20645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20655288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 20665288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20675288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* End of HCI event callbacks */ 20685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2069a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodestatic gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data) 2070a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2071a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode int status, fd = g_io_channel_unix_get_fd(io); 2072a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid_t child_pid; 2073a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2074a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) { 2075a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("child_exit: unable to read child pid from pipe"); 2076a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return TRUE; 2077a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2078a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2079a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (waitpid(child_pid, &status, 0) != child_pid) 2080a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("waitpid(%d) failed", child_pid); 2081a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode else 20828e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("child %d exited", child_pid); 2083a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2084a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return TRUE; 2085a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2086a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2087a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodestatic void at_child_exit(void) 2088a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2089a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid_t pid = getpid(); 2090a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2091a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid)) 2092a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("unable to write to child pipe"); 2093a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2094a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2095fccdf4a50765ef5a2dbde00d95f65e94ce0a543bJohan Hedbergstatic void device_devup_setup(int index) 2096a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2097fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2098a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_info di; 20995a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg read_stored_link_key_cp cp; 2100a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 21010e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 21020e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2103ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (hci_devinfo(index, &di) < 0) 2104a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2105a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 210665bf1321203b55b11167ac8b869da28a86ce49d2David Scherba if (ignore_device(&di)) 2107a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2108a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2109fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(&dev->bdaddr, &di.bdaddr); 2110fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->features, di.features, 8); 2111a352058752e541539b09e55124d411a534cc14afJohan Hedberg 2112a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Set page timeout */ 2113a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if ((main_opts.flags & (1 << HCID_SET_PAGETO))) { 2114a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode write_page_timeout_cp cp; 2115a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2116a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode cp.timeout = htobs(main_opts.pageto); 2117fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, 2118a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode WRITE_PAGE_TIMEOUT_CP_SIZE, &cp); 2119a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2120a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 21215a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 21225a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg cp.read_all = 1; 2123fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY, 21245a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg READ_STORED_LINK_KEY_CP_SIZE, (void *) &cp); 2125fccdf4a50765ef5a2dbde00d95f65e94ce0a543bJohan Hedberg 2126fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 21275c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 2128a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2129a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2130be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void init_pending(int index) 2131be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 2132fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2133fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2134fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_BDADDR, &dev->pending); 2135fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_VERSION, &dev->pending); 2136fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_FEATURES, &dev->pending); 2137fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_NAME, &dev->pending); 2138be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 2139be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 2140ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void init_device(int index) 2141a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2142a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_req dr; 2143c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg int dd; 21446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg pid_t pid; 21456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 21460e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 21470e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 21486844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg dd = hci_open_dev(index); 21496844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (dd < 0) { 21506844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Unable to open hci%d: %s (%d)", index, 21516844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg strerror(errno), errno); 21526844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return; 21536844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 21546844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 21556844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (index > max_dev) { 21566844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg max_dev = index; 2157ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg devs = g_realloc(devs, sizeof(devs[0]) * (max_dev + 1)); 21586844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 21596844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 21605c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_dev_info(index, dd, FALSE); 2161be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg init_pending(index); 21625a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg start_hci_dev(index); 2163a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2164a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Do initialization in the separate process */ 2165a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid = fork(); 2166a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode switch (pid) { 2167a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case 0: 2168a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode atexit(at_child_exit); 2169a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2170a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case -1: 2171a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Fork failed. Can't init device hci%d: %s (%d)", 2172c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg index, strerror(errno), errno); 2173a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode default: 21748e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("child %d forked", pid); 2175a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2176a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2177a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2178a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode memset(&dr, 0, sizeof(dr)); 2179ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode dr.dev_id = index; 2180a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2181a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Set link mode */ 2182a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode dr.dev_opt = main_opts.link_mode; 2183c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) 2184a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Can't set link mode on hci%d: %s (%d)", 2185ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg index, strerror(errno), errno); 2186a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2187a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Start HCI device */ 2188ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (ioctl(dd, HCIDEVUP, index) < 0 && errno != EALREADY) { 2189a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Can't init device hci%d: %s (%d)", 2190ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode index, strerror(errno), errno); 2191a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode goto fail; 2192a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2193a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2194a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode hci_close_dev(dd); 2195a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode exit(0); 2196a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2197a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodefail: 2198a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode hci_close_dev(dd); 2199a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode exit(1); 2200a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2201a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2202ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void device_devreg_setup(int index) 2203a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2204a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_info di; 2205a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 22060e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 22070e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2208ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode init_device(index); 2209a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2210a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode memset(&di, 0, sizeof(di)); 2211a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2212ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (hci_devinfo(index, &di) < 0) 2213a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2214a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 22155c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (ignore_device(&di)) 22165c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return; 2217a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2218fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].already_up = hci_test_bit(HCI_UP, &di.flags); 2219a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2220a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2221ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void device_event(int event, int index) 2222a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2223a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode switch (event) { 2224a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_REG: 2225ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d registered", index); 2226ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode device_devreg_setup(index); 2227fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (devs[index].already_up) 22285c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg device_event(HCI_DEV_UP, index); 2229a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2230a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2231a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_UNREG: 2232ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d unregistered", index); 223355694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 2234fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (devs[index].registered) 22355c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_manager_unregister_adapter(index); 2236a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2237a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2238a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_UP: 2239ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d up", index); 2240fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].up = TRUE; 2241ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode device_devup_setup(index); 2242a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2243a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2244a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_DOWN: 2245ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d down", index); 2246fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].up = FALSE; 2247fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].pending_cod = 0; 2248fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].cache_enable = TRUE; 2249fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!devs[index].pending) { 22505a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg manager_stop_adapter(index); 2251be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg init_pending(index); 22525a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg } 2253a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2254a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2255a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2256cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 22575c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_stop_inquiry(int index) 22585c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 2259fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 22605c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg struct hci_dev_info di; 22615c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg int err; 22625c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 22635c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d", index); 22645c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 22655c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (hci_devinfo(index, &di) < 0) 22665c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return -errno; 22675c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 22685c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (hci_test_bit(HCI_INQUIRY, &di.flags)) 2269fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 22705c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg OCF_INQUIRY_CANCEL, 0, 0); 22715c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg else 2272fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 22735c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg OCF_EXIT_PERIODIC_INQUIRY, 0, 0); 22745c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (err < 0) 22755c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg err = -errno; 22765c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 22775c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return err; 22785c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 22795c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2280f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedbergstatic gboolean init_known_adapters(gpointer user_data) 228194e91856179a268805256055ffd5155d1468b99cAlok Barsode{ 2282cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_dev_list_req *dl; 2283cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_dev_req *dr; 2284f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg int i, err, ctl = GPOINTER_TO_INT(user_data); 2285ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg size_t req_size; 2286cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 22870e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 22880e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2289ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg req_size = HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t); 2290ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg 2291ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg dl = g_try_malloc0(req_size); 2292cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (!dl) { 2293ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg error("Can't allocate devlist buffer"); 2294f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 2295cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2296cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2297cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode dl->dev_num = HCI_MAX_DEV; 2298cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode dr = dl->dev_req; 2299cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2300ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg if (ioctl(ctl, HCIGETDEVLIST, dl) < 0) { 2301c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2302ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg error("Can't get device list: %s (%d)", strerror(-err), -err); 230383003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi g_free(dl); 2304f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 2305cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2306cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2307cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode for (i = 0; i < dl->dev_num; i++, dr++) { 2308fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev; 2309fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2310cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode device_event(HCI_DEV_REG, dr->dev_id); 2311cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2312fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev = &devs[dr->dev_id]; 2313fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2314fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->already_up = hci_test_bit(HCI_UP, &dr->dev_opt); 23155c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2316fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->already_up) 2317be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg continue; 2318be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 23195c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg hciops_stop_inquiry(dr->dev_id); 23205c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2321fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pending = 0; 2322fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_VERSION, &dev->pending); 2323fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_INFO_PARAM, 2324be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg OCF_READ_LOCAL_VERSION, 0, NULL); 2325be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg device_event(HCI_DEV_UP, dr->dev_id); 2326cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2327cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2328cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_free(dl); 2329f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg 2330f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 233194e91856179a268805256055ffd5155d1468b99cAlok Barsode} 233294e91856179a268805256055ffd5155d1468b99cAlok Barsode 2333cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsodestatic gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, 2334cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode gpointer data) 2335cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode{ 2336cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; 2337cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode evt_stack_internal *si; 2338cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode evt_si_device *sd; 2339cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_event_hdr *eh; 2340cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode int type; 2341cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode size_t len; 2342cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode GIOError err; 2343cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2344cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ptr = buf; 2345cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2346cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len); 2347cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (err) { 2348cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (err == G_IO_ERROR_AGAIN) 2349cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2350cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2351cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode error("Read from control socket failed: %s (%d)", 2352ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg strerror(errno), errno); 2353cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return FALSE; 2354cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2355cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2356cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode type = *ptr++; 2357cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2358cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (type != HCI_EVENT_PKT) 2359cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2360cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2361cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode eh = (hci_event_hdr *) ptr; 2362cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (eh->evt != EVT_STACK_INTERNAL) 2363cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2364cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2365cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ptr += HCI_EVENT_HDR_SIZE; 2366cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2367cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode si = (evt_stack_internal *) ptr; 2368cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode switch (si->type) { 2369cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode case EVT_SI_DEVICE: 2370cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode sd = (void *) &si->data; 2371cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode device_event(sd->event, sd->dev_id); 2372cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode break; 2373cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2374cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2375cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2376cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode} 2377cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 237834c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic int hciops_setup(void) 2379cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode{ 2380cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct sockaddr_hci addr; 2381cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_filter flt; 2382a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode GIOChannel *ctl_io, *child_io; 238318e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg int sock, err; 238418e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg 23850e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 23860e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 238718e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg if (child_pipe[0] != -1) 238818e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg return -EALREADY; 2389cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2390a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (pipe(child_pipe) < 0) { 2391c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2392c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("pipe(): %s (%d)", strerror(-err), -err); 2393c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2394a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2395a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2396a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode child_io = g_io_channel_unix_new(child_pipe[0]); 2397a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode g_io_channel_set_close_on_unref(child_io, TRUE); 23988b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_io_id = g_io_add_watch(child_io, 23998b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, 24008b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_exit, NULL); 2401a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode g_io_channel_unref(child_io); 2402a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2403cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode /* Create and bind HCI socket */ 2404cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); 2405cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (sock < 0) { 2406c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2407c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("Can't open HCI socket: %s (%d)", strerror(-err), 2408c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg -err); 2409c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2410cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2411cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2412cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode /* Set filter */ 2413cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_clear(&flt); 2414cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 2415cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_set_event(EVT_STACK_INTERNAL, &flt); 24166844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { 2417c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2418c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("Can't set filter: %s (%d)", strerror(-err), -err); 2419c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2420cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2421cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2422cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode memset(&addr, 0, sizeof(addr)); 2423cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode addr.hci_family = AF_BLUETOOTH; 2424cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode addr.hci_dev = HCI_DEV_NONE; 24256844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 2426c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 24276844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Can't bind HCI socket: %s (%d)", strerror(-err), -err); 2428c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2429cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2430cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2431cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ctl_io = g_io_channel_unix_new(sock); 2432cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_io_channel_set_close_on_unref(ctl_io, TRUE); 2433cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 24348b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL); 2435cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2436cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_io_channel_unref(ctl_io); 2437cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2438f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg g_idle_add(init_known_adapters, GINT_TO_POINTER(sock)); 2439f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg 2440f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return 0; 2441cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode} 2442cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 244334c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic void hciops_cleanup(void) 244434c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode{ 24456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int i; 24466844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 24470e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 24480e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 24496844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg for (i = 0; i <= max_dev; i++) { 2450fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[i]; 2451fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2452fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->sk >= 0) 2453fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_close_dev(dev->sk); 24546844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 24556844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 24566844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg g_free(devs); 24576844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg devs = NULL; 24586844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg max_dev = -1; 24596844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 24608b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_io_id) { 24618b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg g_source_remove(child_io_id); 24628b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_io_id = 0; 24638b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 24648b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 24658b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (ctl_io_id) { 24668b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg g_source_remove(ctl_io_id); 24678b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg ctl_io_id = 0; 24688b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 24698b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 24708b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_pipe[0] >= 0) { 24718b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg close(child_pipe[0]); 24728b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_pipe[0] = -1; 24738b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 24748b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 24758b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_pipe[1] >= 0) { 24768b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg close(child_pipe[1]); 24778b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_pipe[1] = -1; 24788b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 247934c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode} 248034c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode 2481076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsodestatic int hciops_start(int index) 2482076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode{ 2483fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 24846844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2485076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 24860e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 24870e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2488fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIDEVUP, index) == 0) 24896844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2490076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 24916844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (errno == EALREADY) 24926844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2493076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 24946844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 24956844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Can't init device hci%d: %s (%d)", 24966844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg index, strerror(-err), -err); 2497076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 2498c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2499076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode} 2500076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 25016a63c312559ef5d83c32db9ea57435786cdebadaJohan Hedbergstatic int hciops_set_powered(int index, gboolean powered) 2502030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode{ 2503fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2504030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode uint8_t mode = SCAN_DISABLED; 2505030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode 25060e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d powered %d", index, powered); 25070e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2508030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode if (powered) 2509030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode return hciops_start(index); 2510030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode 2511fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 25126844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_SCAN_ENABLE, 1, &mode) < 0) 25136844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2514030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode 2515030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode return hciops_stop(index); 2516030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode} 2517030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode 25185c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_set_connectable(int index, gboolean connectable) 25198b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode{ 2520fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 25215c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg uint8_t mode; 25228b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode 25235c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (connectable) 25245c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = SCAN_PAGE; 25255c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg else 25265c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = 0x00; 25275c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 25285c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d connectable %d", index, connectable); 25290e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2530fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 25316844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_SCAN_ENABLE, 1, &mode) < 0) 25326844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 25338b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode 25346844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 25358b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode} 25368b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode 253700c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_set_dev_class(int index, uint8_t major, uint8_t minor) 2538d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode{ 2539fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 254000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int err; 2541d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 25425c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d major %u minor %u", index, major, minor); 25435c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 254400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Update only the major and minor class bits keeping remaining bits 254500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * intact*/ 2546fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod &= 0xffe000; 2547fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod |= ((major & 0x1f) << 8) | minor; 2548d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 2549fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->wanted_cod == dev->current_cod || 2550fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->cache_enable || dev->pending_cod) 255100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 25520e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2553fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg DBG("Changing Major/Minor class to 0x%06x", dev->wanted_cod); 2554eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode 2555fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = write_class(index, dev->wanted_cod); 255600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (err < 0) 255700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg error("Adapter class update failed: %s (%d)", 255800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg strerror(-err), -err); 2559d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 256000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return err; 2561eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode} 2562eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode 25633af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasistatic int hciops_start_inquiry(int index, uint8_t length, gboolean periodic) 2564a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode{ 2565fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2566a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; 25676844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2568a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 25690e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d length %u periodic %d", index, length, periodic); 25700e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2571a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode if (periodic) { 2572a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode periodic_inquiry_cp cp; 2573a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2574a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memset(&cp, 0, sizeof(cp)); 2575a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memcpy(&cp.lap, lap, 3); 2576a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.max_period = htobs(24); 2577a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.min_period = htobs(16); 2578388cdea43870fe5c5163cfbe96d3218111ba39b5Claudio Takahasi cp.length = length; 2579a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.num_rsp = 0x00; 2580a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2581fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 25826844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_PERIODIC_INQUIRY, 25836844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg PERIODIC_INQUIRY_CP_SIZE, &cp); 2584a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode } else { 2585a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode inquiry_cp inq_cp; 2586a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2587a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memset(&inq_cp, 0, sizeof(inq_cp)); 2588a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memcpy(&inq_cp.lap, lap, 3); 2589388cdea43870fe5c5163cfbe96d3218111ba39b5Claudio Takahasi inq_cp.length = length; 2590a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode inq_cp.num_rsp = 0x00; 2591a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2592fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 25936844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_INQUIRY, INQUIRY_CP_SIZE, &inq_cp); 2594a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode } 2595a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2596a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode if (err < 0) 2597a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode err = -errno; 2598a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2599a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode return err; 2600a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode} 2601a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 26023ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int le_set_scan_enable(int index, uint8_t enable) 260370cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi{ 2604fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 26053ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi le_set_scan_enable_cp cp; 26063ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 26070e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d enable %u", index, enable); 26080e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 26093ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi memset(&cp, 0, sizeof(cp)); 26103ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.enable = enable; 26113ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.filter_dup = 0; 261270cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 2613fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE, 26143ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi LE_SET_SCAN_ENABLE_CP_SIZE, &cp) < 0) 26156844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 261670cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 26176844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 261870cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi} 261970cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 26203ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int hciops_start_scanning(int index) 262170cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi{ 2622fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 26233ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi le_set_scan_parameters_cp cp; 26243ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 26250e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 26260e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 26273ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi memset(&cp, 0, sizeof(cp)); 26283ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.type = 0x01; /* Active scanning */ 26293ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.interval = htobs(0x0010); 26303ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.window = htobs(0x0010); 26313ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.own_bdaddr_type = 0; /* Public address */ 26323ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.filter = 0; /* Accept all adv packets */ 26333ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 2634fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LE_CTL, OCF_LE_SET_SCAN_PARAMETERS, 26353ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi LE_SET_SCAN_PARAMETERS_CP_SIZE, &cp) < 0) 263670cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi return -errno; 263770cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 26383ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi return le_set_scan_enable(index, 1); 26393ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi} 26403ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 26413ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int hciops_stop_scanning(int index) 26423ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi{ 26430e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 26440e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 26453ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi return le_set_scan_enable(index, 0); 264670cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi} 264770cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 2648ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsodestatic int hciops_resolve_name(int index, bdaddr_t *bdaddr) 2649ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode{ 2650fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2651ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode remote_name_req_cp cp; 26520e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 26530e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 26540e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 26550e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 2656ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 2657ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode memset(&cp, 0, sizeof(cp)); 2658ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode bacpy(&cp.bdaddr, bdaddr); 2659ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode cp.pscan_rep_mode = 0x02; 2660ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 2661fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ, 26626844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg REMOTE_NAME_REQ_CP_SIZE, &cp) < 0) 26636844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2664ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 26656844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2666ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode} 2667ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 2668164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsodestatic int hciops_set_name(int index, const char *name) 2669164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode{ 2670fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2671164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode change_local_name_cp cp; 2672164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 26730e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d, name %s", index, name); 26740e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2675164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode memset(&cp, 0, sizeof(cp)); 2676164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode strncpy((char *) cp.name, name, sizeof(cp.name)); 2677164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 2678fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, 26796844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg CHANGE_LOCAL_NAME_CP_SIZE, &cp) < 0) 26806844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2681164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 2682fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->name, cp.name, 248); 268300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 268400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 26856844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2686164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode} 2687164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 2688b96f44db8e91325968a0149595b2522d4a22481aAlok Barsodestatic int hciops_cancel_resolve_name(int index, bdaddr_t *bdaddr) 2689b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode{ 2690fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2691b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode remote_name_req_cancel_cp cp; 26920e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 26930e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 26940e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 26950e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 2696b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 2697b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode memset(&cp, 0, sizeof(cp)); 2698b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode bacpy(&cp.bdaddr, bdaddr); 2699b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 2700fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL, 27016844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg REMOTE_NAME_REQ_CANCEL_CP_SIZE, &cp) < 0) 27026844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2703b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 27046844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2705b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode} 2706b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 270761f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliystatic int hciops_fast_connectable(int index, gboolean enable) 270861f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy{ 2709fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 271061f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy write_page_activity_cp cp; 271161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy uint8_t type; 271261f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 27130e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d enable %d", index, enable); 27140e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 271561f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy if (enable) { 271661f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy type = PAGE_SCAN_TYPE_INTERLACED; 271761f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.interval = 0x0024; /* 22.5 msec page scan interval */ 271861f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy } else { 271961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy type = PAGE_SCAN_TYPE_STANDARD; /* default */ 272061f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.interval = 0x0800; /* default 1.28 sec page scan */ 272161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy } 272261f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 272361f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.window = 0x0012; /* default 11.25 msec page scan window */ 272461f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 2725fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_PAGE_ACTIVITY, 272661f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy WRITE_PAGE_ACTIVITY_CP_SIZE, &cp) < 0) 27276844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2728fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg else if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 27296844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_PAGE_SCAN_TYPE, 1, &type) < 0) 27306844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 273161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 27326844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 273361f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy} 273461f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 27355bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuterstatic int hciops_read_clock(int index, int handle, int which, int timeout, 2736ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg uint32_t *clock, uint16_t *accuracy) 27375bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter{ 2738fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2739fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 27400e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d handle %d which %d timeout %d", index, handle, which, 27410e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg timeout); 27420e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2743fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_read_clock(dev->sk, handle, which, clock, accuracy, 27446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg timeout) < 0) 27456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 27465bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 27476844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 27485bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter} 27495bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 27505bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuterstatic int hciops_conn_handle(int index, const bdaddr_t *bdaddr, int *handle) 27515bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter{ 2752fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 27535bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter struct hci_conn_info_req *cr; 27540e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 2755fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg int err; 27560e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 27570e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 27580e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 27595bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 27605bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); 27615bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter bacpy(&cr->bdaddr, bdaddr); 27625bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter cr->type = ACL_LINK; 27635bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 2764fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETCONNINFO, (unsigned long) cr) < 0) { 2765c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2766c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg goto fail; 2767c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg } 27685bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 27696844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = 0; 2770c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg *handle = htobs(cr->conn_info->handle); 27715bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 2772c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedbergfail: 27735bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter g_free(cr); 27745bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter return err; 27755bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter} 27765bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 2777b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedbergstatic int hciops_read_bdaddr(int index, bdaddr_t *bdaddr) 2778b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg{ 2779fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2780fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 27810e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 2782fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2783fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(bdaddr, &dev->bdaddr); 2784fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 27856844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2786b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg} 2787b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg 2788885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedbergstatic int hciops_block_device(int index, bdaddr_t *bdaddr) 2789885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg{ 2790fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 27910e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 27920e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 27930e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 27940e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 27950e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2796fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIBLOCKADDR, bdaddr) < 0) 2797885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg return -errno; 2798885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 27996844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2800885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg} 2801885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 2802885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedbergstatic int hciops_unblock_device(int index, bdaddr_t *bdaddr) 2803885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg{ 2804fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 28050e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 28060e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 28070e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 28080e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 28090e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2810fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIUNBLOCKADDR, bdaddr) < 0) 2811885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg return -errno; 2812885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 28136844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2814885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg} 2815885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 2816f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedbergstatic int hciops_get_conn_list(int index, GSList **conns) 2817f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg{ 2818fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2819f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg struct hci_conn_list_req *cl; 2820f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg struct hci_conn_info *ci; 28216844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err, i; 2822f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 28230e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 28240e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2825f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); 2826f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2827f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg cl->dev_id = index; 2828f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg cl->conn_num = 10; 2829f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg ci = cl->conn_info; 2830f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2831fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETCONNLIST, cl) < 0) { 2832f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg err = -errno; 2833f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg goto fail; 2834f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg } 2835f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2836f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg err = 0; 2837f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg *conns = NULL; 2838f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2839f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg for (i = 0; i < cl->conn_num; i++, ci++) 2840f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg *conns = g_slist_append(*conns, g_memdup(ci, sizeof(*ci))); 2841f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2842f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedbergfail: 2843f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg g_free(cl); 2844f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg return err; 2845f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg} 2846f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2847e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedbergstatic int hciops_read_local_version(int index, struct hci_version *ver) 2848e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg{ 2849fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2850fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 28510e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 2852fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2853fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(ver, &dev->ver, sizeof(*ver)); 2854fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 28556844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2856e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg} 2857e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg 285848e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedbergstatic int hciops_read_local_features(int index, uint8_t *features) 285948e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg{ 2860fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2861fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 28620e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 2863fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2864fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(features, dev->features, 8); 2865fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 28666844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 286748e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg} 286848e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg 286906dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedbergstatic int hciops_disconnect(int index, uint16_t handle) 287006dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg{ 2871fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 287206dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg disconnect_cp cp; 287306dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 28740e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d handle %u", index, handle); 28750e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 287606dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg memset(&cp, 0, sizeof(cp)); 287706dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg cp.handle = htobs(handle); 287806dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg cp.reason = HCI_OE_USER_ENDED_CONNECTION; 287906dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 2880fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_DISCONNECT, 288106dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg DISCONNECT_CP_SIZE, &cp) < 0) 28826844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 288306dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 28846844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 288506dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg} 288606dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 28871bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedbergstatic int hciops_remove_bonding(int index, bdaddr_t *bdaddr) 28881bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg{ 2889fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 289073c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg delete_stored_link_key_cp cp; 28910e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 28920e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 28930e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 28940e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 28951bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 289673c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg memset(&cp, 0, sizeof(cp)); 289773c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg bacpy(&cp.bdaddr, bdaddr); 289873c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg 28991bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg /* Delete the link key from the Bluetooth chip */ 2900fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_DELETE_STORED_LINK_KEY, 290173c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg DELETE_STORED_LINK_KEY_CP_SIZE, &cp) < 0) 29026844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 29031bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 29046844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 29051bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg} 29061bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 2907c3ebed5a7d7e6146e7dfb97f6597222f1f9f0e71Johan Hedbergstatic int hciops_request_authentication(int index, uint16_t handle) 2908424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg{ 2909fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2910424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg auth_requested_cp cp; 2911424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 29120e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d handle %u", index, handle); 2913424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2914424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg memset(&cp, 0, sizeof(cp)); 2915424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg cp.handle = htobs(handle); 2916424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2917fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_AUTH_REQUESTED, 2918c3ebed5a7d7e6146e7dfb97f6597222f1f9f0e71Johan Hedberg AUTH_REQUESTED_CP_SIZE, &cp) < 0) 29196844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2920424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 29216844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2922424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg} 2923424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2924e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedbergstatic int hciops_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin) 2925e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg{ 2926fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 29270e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 29286844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2929e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 29300e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 29310e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 29320e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2933e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg if (pin) { 2934e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg pin_code_reply_cp pr; 2935e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg size_t len = strlen(pin); 2936e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 2937fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = len; 293842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 2939e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg memset(&pr, 0, sizeof(pr)); 2940e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg bacpy(&pr.bdaddr, bdaddr); 2941e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg memcpy(pr.pin_code, pin, len); 2942e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg pr.pin_len = len; 2943fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 29446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_PIN_CODE_REPLY, 2945e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg PIN_CODE_REPLY_CP_SIZE, &pr); 2946e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg } else 2947fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 2948e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg OCF_PIN_CODE_NEG_REPLY, 6, bdaddr); 2949e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 29506844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 29516844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 2952e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 2953e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg return err; 2954e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg} 2955e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 2956df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedbergstatic int hciops_confirm_reply(int index, bdaddr_t *bdaddr, gboolean success) 2957df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg{ 2958fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2959df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg user_confirm_reply_cp cp; 29600e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 29610e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg int err; 29620e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 29630e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 29640e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s success %d", index, addr, success); 2965df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2966df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg memset(&cp, 0, sizeof(cp)); 2967df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 2968df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2969df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg if (success) 2970fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 29716844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_USER_CONFIRM_REPLY, 2972df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg USER_CONFIRM_REPLY_CP_SIZE, &cp); 2973df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg else 2974fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 2975df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg OCF_USER_CONFIRM_NEG_REPLY, 2976df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg USER_CONFIRM_REPLY_CP_SIZE, &cp); 2977df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 29786844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 29796844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 2980df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2981df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg return err; 2982df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg} 2983df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2984889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedbergstatic int hciops_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey) 2985889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg{ 2986fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 29870e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 29886844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2989889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 29900e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 29910e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 29920e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2993889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg if (passkey != INVALID_PASSKEY) { 2994889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg user_passkey_reply_cp cp; 2995889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 2996889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg memset(&cp, 0, sizeof(cp)); 2997889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg bacpy(&cp.bdaddr, bdaddr); 2998889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg cp.passkey = passkey; 2999889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 3000fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 30016844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_USER_PASSKEY_REPLY, 3002889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg USER_PASSKEY_REPLY_CP_SIZE, &cp); 3003889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg } else 3004fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 3005889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg OCF_USER_PASSKEY_NEG_REPLY, 6, bdaddr); 3006889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 30076844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 30086844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 3009889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 3010889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg return err; 3011889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg} 3012889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 30134b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedbergstatic int hciops_get_auth_info(int index, bdaddr_t *bdaddr, uint8_t *auth) 30144b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg{ 3015fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 30164b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg struct hci_auth_info_req req; 30170e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 30180e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 30190e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 30200e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 30214b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 30224b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg memset(&req, 0, sizeof(req)); 30234b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg bacpy(&req.bdaddr, bdaddr); 30244b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 3025fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETAUTHINFO, (unsigned long) &req) < 0) 30266844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 30274b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 30284b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg if (auth) 30294b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg *auth = req.type; 30304b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 30316844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 30324b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg} 30334b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 3034f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedbergstatic int hciops_read_scan_enable(int index) 3035f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg{ 3036fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3037fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 30380e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 30390e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3040fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_READ_SCAN_ENABLE, 30416844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 0, NULL) < 0) 3042f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg return -errno; 3043f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg 30446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 3045f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg} 3046f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg 30475c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_enable_le(int index) 30487ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi{ 3049fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 30507ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi write_le_host_supported_cp cp; 30517ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 30525c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d", index); 30535c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3054fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[4] & LMP_LE)) 30555c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return -ENOTSUP; 30560e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 30575c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg cp.le = 0x01; 3058fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg cp.simul = (dev->features[6] & LMP_LE_BREDR) ? 0x01 : 0x00; 30597ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 3060fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 30616844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_LE_HOST_SUPPORTED, 30626844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg WRITE_LE_HOST_SUPPORTED_CP_SIZE, &cp) < 0) 30636844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 30647ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 30656844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 30667ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi} 30677ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 3068646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedbergstruct remote_version_req { 3069646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg int index; 3070646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg uint16_t handle; 3071646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg}; 3072646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 3073646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedbergstatic gboolean get_remote_version(gpointer user_data) 3074646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg{ 3075646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg struct remote_version_req *req = user_data; 3076fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[req->index]; 3077646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg read_remote_version_cp cp; 3078646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 30790e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d handle %u", req->index, req->handle); 30800e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3081646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg memset(&cp, 0, sizeof(cp)); 3082646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg cp.handle = htobs(req->handle); 3083646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 3084fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_READ_REMOTE_VERSION, 3085646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg READ_REMOTE_VERSION_CP_SIZE, &cp); 3086646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 3087646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg return FALSE; 3088646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg} 3089646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 3090646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedbergstatic int hciops_get_remote_version(int index, uint16_t handle, 3091646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg gboolean delayed) 3092646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg{ 3093646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg struct remote_version_req *req; 3094646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 30950e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d handle %u delayed %d", index, handle, delayed); 30960e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3097646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg req = g_new0(struct remote_version_req, 1); 3098646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg req->handle = handle; 3099646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg req->index = index; 3100646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 3101646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg if (!delayed) { 3102646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg get_remote_version(req); 3103646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg g_free(req); 3104646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg return 0; 3105646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg } 3106646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 3107646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1, get_remote_version, 3108646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg req, g_free); 3109646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 3110646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg return 0; 3111646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg} 3112646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 311300c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int set_service_classes(int index, uint8_t value) 311400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 3115fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 311600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int err; 311700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 31185c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d value %u", index, value); 31195c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 312000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Update only the service class, keep the limited bit, 312100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * major/minor class bits intact */ 3122fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod &= 0x00ffff; 3123fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod |= (value << 16); 312400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 312500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* If the cache is enabled or an existing CoD write is in progress 312600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * just bail out */ 3127fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->cache_enable || dev->pending_cod) 312800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 312900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 313000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* If we already have the CoD we want, update EIR and return */ 3131fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->current_cod == dev->wanted_cod) { 313200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 313300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 313400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 313500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3136fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg DBG("Changing service classes to 0x%06x", dev->wanted_cod); 313700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3138fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = write_class(index, dev->wanted_cod); 313900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (err < 0) 314000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg error("Adapter class update failed: %s (%d)", 314100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg strerror(-err), -err); 314200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 314300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return err; 314400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 314500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 314600c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_services_updated(int index) 314700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 3148fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 314900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg struct btd_adapter *adapter; 315000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_list_t *list; 315100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t val = 0; 315200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 315300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d", index); 315400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3155fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 315600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (adapter == NULL) 315700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return -ENODEV; 315800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 315900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (list = adapter_get_services(adapter); list; list = list->next) { 31605c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg sdp_record_t *rec = list->data; 316100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 316200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.type != SDP_UUID16) 316300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 316400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 316500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg switch (rec->svclass.value.uuid16) { 316600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case DIALUP_NET_SVCLASS_ID: 316700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case CIP_SVCLASS_ID: 316800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x42; /* Telephony & Networking */ 316900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 317000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case IRMC_SYNC_SVCLASS_ID: 317100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case OBEX_OBJPUSH_SVCLASS_ID: 317200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case OBEX_FILETRANS_SVCLASS_ID: 317300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case IRMC_SYNC_CMD_SVCLASS_ID: 317400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case PBAP_PSE_SVCLASS_ID: 317500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x10; /* Object Transfer */ 317600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 317700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case HEADSET_SVCLASS_ID: 317800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case HANDSFREE_SVCLASS_ID: 317900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x20; /* Audio */ 318000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 318100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case CORDLESS_TELEPHONY_SVCLASS_ID: 318200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case INTERCOM_SVCLASS_ID: 318300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case FAX_SVCLASS_ID: 318400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case SAP_SVCLASS_ID: 318500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* 318600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * Setting the telephony bit for the handsfree audio gateway 318700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * role is not required by the HFP specification, but the 318800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * Nokia 616 carkit is just plain broken! It will refuse 318900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * pairing without this bit set. 319000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg */ 319100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case HANDSFREE_AGW_SVCLASS_ID: 319200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x40; /* Telephony */ 319300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 319400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case AUDIO_SOURCE_SVCLASS_ID: 319500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case VIDEO_SOURCE_SVCLASS_ID: 319600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x08; /* Capturing */ 319700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 319800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case AUDIO_SINK_SVCLASS_ID: 319900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case VIDEO_SINK_SVCLASS_ID: 320000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x04; /* Rendering */ 320100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 320200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case PANU_SVCLASS_ID: 320300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case NAP_SVCLASS_ID: 320400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case GN_SVCLASS_ID: 320500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x02; /* Networking */ 320600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 320700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 320800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 320900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 321000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return set_service_classes(index, val); 321100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 321200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 321300c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_disable_cod_cache(int index) 321400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 3215fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 321600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3217fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg DBG("hci%d cache_enable %d", index, dev->cache_enable); 3218fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 3219fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->cache_enable) 322000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 322100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 322200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d current_cod 0x%06x wanted_cod 0x%06x", index, 3223fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->current_cod, dev->wanted_cod); 322400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 322500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Disable and flush svc cache. All successive service class 322600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * updates * will be written to the device */ 3227fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->cache_enable = FALSE; 322800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3229fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->current_cod == dev->wanted_cod) { 323000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 323100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 323200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 323300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3234fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg return write_class(index, dev->wanted_cod); 323500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 323600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 32375c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_restore_powered(int index) 32385c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 3239fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3240fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 3241fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->already_up && dev->up) 32425c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return hciops_stop(index); 32435c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 32445c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return 0; 32455c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 32465c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 324734c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic struct btd_adapter_ops hci_ops = { 324834c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode .setup = hciops_setup, 324934c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode .cleanup = hciops_cleanup, 3250076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode .start = hciops_start, 32514e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode .stop = hciops_stop, 32526a63c312559ef5d83c32db9ea57435786cdebadaJohan Hedberg .set_powered = hciops_set_powered, 32535c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .set_connectable = hciops_set_connectable, 32545c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .set_discoverable = hciops_set_discoverable, 32555c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .set_pairable = hciops_set_pairable, 3256eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode .set_limited_discoverable = hciops_set_limited_discoverable, 32573af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasi .start_inquiry = hciops_start_inquiry, 32583af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasi .stop_inquiry = hciops_stop_inquiry, 325970cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi .start_scanning = hciops_start_scanning, 326070cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi .stop_scanning = hciops_stop_scanning, 3261ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode .resolve_name = hciops_resolve_name, 3262b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode .cancel_resolve_name = hciops_cancel_resolve_name, 3263164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode .set_name = hciops_set_name, 326400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .set_dev_class = hciops_set_dev_class, 326561f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy .set_fast_connectable = hciops_fast_connectable, 32665bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter .read_clock = hciops_read_clock, 32675bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter .get_conn_handle = hciops_conn_handle, 3268b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg .read_bdaddr = hciops_read_bdaddr, 3269885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg .block_device = hciops_block_device, 3270885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg .unblock_device = hciops_unblock_device, 3271f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg .get_conn_list = hciops_get_conn_list, 3272e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg .read_local_version = hciops_read_local_version, 327348e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg .read_local_features = hciops_read_local_features, 327406dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg .disconnect = hciops_disconnect, 32751bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg .remove_bonding = hciops_remove_bonding, 3276424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg .request_authentication = hciops_request_authentication, 3277e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg .pincode_reply = hciops_pincode_reply, 3278df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg .confirm_reply = hciops_confirm_reply, 3279889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg .passkey_reply = hciops_passkey_reply, 32804b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg .get_auth_info = hciops_get_auth_info, 3281f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg .read_scan_enable = hciops_read_scan_enable, 32825c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .enable_le = hciops_enable_le, 3283646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg .get_remote_version = hciops_get_remote_version, 3284abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg .encrypt_link = hciops_encrypt_link, 328500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .set_did = hciops_set_did, 328600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .services_updated = hciops_services_updated, 328700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .disable_cod_cache = hciops_disable_cod_cache, 32885c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .restore_powered = hciops_restore_powered, 328934c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode}; 329034c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode 329134c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic int hciops_init(void) 329234c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode{ 32930e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 3294d30044157466e7f34e7f2d5d7ce70215ea013338Johan Hedberg return btd_register_adapter_ops(&hci_ops, FALSE); 329534c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode} 3296d57934d1d09c34d1b136c572cad1dff6306c8c48Johan Hedberg 329794e91856179a268805256055ffd5155d1468b99cAlok Barsodestatic void hciops_exit(void) 329894e91856179a268805256055ffd5155d1468b99cAlok Barsode{ 32990e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 3300929393b82db06368ff5fa4074bc209d1d4d03a48Marcel Holtmann btd_adapter_cleanup_ops(&hci_ops); 330194e91856179a268805256055ffd5155d1468b99cAlok Barsode} 330294e91856179a268805256055ffd5155d1468b99cAlok Barsode 330394e91856179a268805256055ffd5155d1468b99cAlok BarsodeBLUETOOTH_PLUGIN_DEFINE(hciops, VERSION, 33041ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann BLUETOOTH_PLUGIN_PRIORITY_LOW, hciops_init, hciops_exit) 3305