hciops.c revision 65edd4d5397d00d204123432fd83326486860783
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; 93b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 94b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg GSList *keys; 9555694454017b04a416931a81964bb695f48b3d93Johan Hedberg int pin_length; 96ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg} *devs = NULL; 97ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg 98db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedbergstatic int ignore_device(struct hci_dev_info *di) 99db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg{ 100db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR; 101db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg} 102db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg 1035c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic void init_dev_info(int index, int sk, gboolean registered) 104ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg{ 105fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 106fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 107fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memset(dev, 0, sizeof(*dev)); 108fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 109fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->sk = sk; 110fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = -1; 111fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->cache_enable = TRUE; 112fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->registered = registered; 113ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg} 1146844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 115abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg/* Async HCI command handling with callback support */ 116abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 117abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstruct hci_cmd_data { 118abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg bt_hci_result_t cb; 119abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t handle; 120abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t ocf; 121abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg gpointer caller_data; 122abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg}; 123abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 124abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstatic gboolean hci_event_watch(GIOChannel *io, 125abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg GIOCondition cond, gpointer user_data) 126abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg{ 127abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg unsigned char buf[HCI_MAX_EVENT_SIZE], *body; 128abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_cmd_data *cmd = user_data; 129abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_cmd_status *evt_status; 130abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_auth_complete *evt_auth; 131abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_encrypt_change *evt_enc; 132abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_event_hdr *hdr; 133abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg set_conn_encrypt_cp cp; 134abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg int dd; 135abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t ocf; 136abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint8_t status = HCI_OE_POWER_OFF; 137abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 138abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (cond & G_IO_NVAL) { 139abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb(status, cmd->caller_data); 140abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return FALSE; 141abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 142abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 143abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (cond & (G_IO_ERR | G_IO_HUP)) 144abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 145abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 146abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg dd = g_io_channel_unix_get_fd(io); 147abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 148abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (read(dd, buf, sizeof(buf)) < 0) 149abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 150abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 151abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hdr = (hci_event_hdr *) (buf + 1); 152abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg body = buf + (1 + HCI_EVENT_HDR_SIZE); 153abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 154abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg switch (hdr->evt) { 155abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_CMD_STATUS: 156abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_status = (evt_cmd_status *) body; 157abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg ocf = cmd_opcode_ocf(evt_status->opcode); 158abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (ocf != cmd->ocf) 159abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 160abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg switch (ocf) { 161abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case OCF_AUTH_REQUESTED: 162abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case OCF_SET_CONN_ENCRYPT: 163abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_status->status != 0) { 164abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Baseband rejected command */ 165abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_status->status; 166abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 167abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 168abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg break; 169abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg default: 170abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 171abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 172abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Wait for the next event */ 173abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 174abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_AUTH_COMPLETE: 175abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_auth = (evt_auth_complete *) body; 176abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_auth->handle != cmd->handle) { 177abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Skipping */ 178abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 179abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 180abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 181abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_auth->status != 0x00) { 182abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_auth->status; 183abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Abort encryption */ 184abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 185abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 186abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 187abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg memset(&cp, 0, sizeof(cp)); 188abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.handle = cmd->handle; 189abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.encrypt = 1; 190abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 191abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->ocf = OCF_SET_CONN_ENCRYPT; 192abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 193abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, 194abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg SET_CONN_ENCRYPT_CP_SIZE, &cp) < 0) { 195abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = HCI_COMMAND_DISALLOWED; 196abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 197abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 198abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Wait for encrypt change event */ 199abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 200abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_ENCRYPT_CHANGE: 201abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_enc = (evt_encrypt_change *) body; 202abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_enc->handle != cmd->handle) 203abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 204abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 205abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Procedure finished: reporting status */ 206abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_enc->status; 207abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg break; 208abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg default: 209abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Skipping */ 210abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 211abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 212abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 213abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergfailed: 214abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb(status, cmd->caller_data); 215abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_shutdown(io, TRUE, NULL); 216abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 217abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return FALSE; 218abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg} 219abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 220b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic int write_inq_mode(int index, uint8_t mode) 221b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 222fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 223b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg write_inquiry_mode_cp cp; 224b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 225b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg memset(&cp, 0, sizeof(cp)); 226b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg cp.mode = mode; 227b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 228fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, 229b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg WRITE_INQUIRY_MODE_CP_SIZE, &cp) < 0) 230b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return -errno; 231b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 232b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 0; 233b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 234b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 235b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic uint8_t get_inquiry_mode(int index) 236b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 237fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 238fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 239fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_EXT_INQ) 240b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 2; 241b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 242fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[3] & LMP_RSSI_INQ) 243b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 244b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 245fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.manufacturer == 11 && dev->ver.hci_rev == 0x00 && 246fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x0757) 247b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 248b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 249fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.manufacturer == 15) { 250fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.hci_rev == 0x03 && 251fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x6963) 252b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 253fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.hci_rev == 0x09 && 254fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x6963) 255b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 256fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.hci_rev == 0x00 && 257fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x6965) 258b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 259b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 260b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 261fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.manufacturer == 31 && dev->ver.hci_rev == 0x2005 && 262fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x1805) 263b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 264b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 265b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 0; 266b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 267b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 268be49c2621d577da4fafd462265b611289547f183Johan Hedbergstatic int init_ssp_mode(int index) 269be49c2621d577da4fafd462265b611289547f183Johan Hedberg{ 270fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 271be49c2621d577da4fafd462265b611289547f183Johan Hedberg write_simple_pairing_mode_cp cp; 272be49c2621d577da4fafd462265b611289547f183Johan Hedberg 273fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETAUTHINFO, NULL) < 0 && errno == EINVAL) 274be49c2621d577da4fafd462265b611289547f183Johan Hedberg return 0; 275be49c2621d577da4fafd462265b611289547f183Johan Hedberg 276be49c2621d577da4fafd462265b611289547f183Johan Hedberg memset(&cp, 0, sizeof(cp)); 277be49c2621d577da4fafd462265b611289547f183Johan Hedberg cp.mode = 0x01; 278be49c2621d577da4fafd462265b611289547f183Johan Hedberg 279fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 280be49c2621d577da4fafd462265b611289547f183Johan Hedberg OCF_WRITE_SIMPLE_PAIRING_MODE, 281be49c2621d577da4fafd462265b611289547f183Johan Hedberg WRITE_SIMPLE_PAIRING_MODE_CP_SIZE, &cp) < 0) 282be49c2621d577da4fafd462265b611289547f183Johan Hedberg return -errno; 283be49c2621d577da4fafd462265b611289547f183Johan Hedberg 284be49c2621d577da4fafd462265b611289547f183Johan Hedberg return 0; 285be49c2621d577da4fafd462265b611289547f183Johan Hedberg} 286be49c2621d577da4fafd462265b611289547f183Johan Hedberg 2875c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_set_discoverable(int index, gboolean discoverable) 2885c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 289fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2905c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg uint8_t mode; 2915c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2925c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (discoverable) 2935c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = (SCAN_PAGE | SCAN_INQUIRY); 2945c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg else 2955c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = SCAN_PAGE; 2965c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2975c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d discoverable %d", index, discoverable); 2985c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 299fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 3005c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 1, &mode) < 0) 3015c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return -errno; 3025c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3035c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return 0; 3045c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 3055c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 30663ff6738abc6bf21becbbfde583062502e7728a6Johan Hedbergstatic int hciops_set_pairable(int index, gboolean pairable) 30763ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg{ 30863ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg DBG("hci%d pairable %d", index, pairable); 30963ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg return -ENOSYS; 31063ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg} 31163ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg 31263ff6738abc6bf21becbbfde583062502e7728a6Johan Hedbergstatic int hciops_power_off(int index) 3135c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 314fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 31563ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg uint8_t mode = SCAN_DISABLED; 3165c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3175c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d", index); 3185c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 31963ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 32063ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg OCF_WRITE_SCAN_ENABLE, 1, &mode) < 0) 32163ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg return -errno; 3225c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 32363ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg if (ioctl(dev->sk, HCIDEVDOWN, index) < 0 && errno != EALREADY) 32463ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg return -errno; 3255c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 32663ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg return 0; 3275c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 3285c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 329b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic void start_adapter(int index) 330b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 331fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 332b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 }; 333b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg uint8_t inqmode; 334ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg uint16_t link_policy; 335b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 336fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.lmp_ver > 1) { 337fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[5] & LMP_SNIFF_SUBR) 338b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[5] |= 0x20; 339b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 340fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[5] & LMP_PAUSE_ENC) 341b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[5] |= 0x80; 342b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 343fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_EXT_INQ) 344b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[5] |= 0x40; 345b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 346fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_NFLUSH_PKTS) 347b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x01; 348b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 349fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[7] & LMP_LSTO) 350b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x80; 351b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 352fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_SIMPLE_PAIR) { 353b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 354b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 355b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 356b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 357b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 358b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 359b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 360b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 361b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 362b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg * Features Notification */ 363b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 364b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 365fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[4] & LMP_LE) 366b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 367b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 368fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_SET_EVENT_MASK, 369b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg sizeof(events), events); 370b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 371b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 372fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_SIMPLE_PAIR) 373be49c2621d577da4fafd462265b611289547f183Johan Hedberg init_ssp_mode(index); 374be49c2621d577da4fafd462265b611289547f183Johan Hedberg 375b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg inqmode = get_inquiry_mode(index); 376b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (inqmode) 377b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg write_inq_mode(index, inqmode); 378b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 379fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[7] & LMP_INQ_TX_PWR) 380fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, 381b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL, 0, NULL); 382b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 383b59dabdd2515aa111ebc56d946259e4bbdf20c61Pawel Wieczorkiewicz /* Set default link policy */ 384ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy = main_opts.link_policy; 385ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg 386fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[0] & LMP_RSWITCH)) 387ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_RSWITCH; 388fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[0] & LMP_HOLD)) 389ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_HOLD; 390fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[0] & LMP_SNIFF)) 391ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_SNIFF; 392fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[1] & LMP_PARK)) 393ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_PARK; 394b59dabdd2515aa111ebc56d946259e4bbdf20c61Pawel Wieczorkiewicz 395ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy = htobs(link_policy); 396fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_POLICY, OCF_WRITE_DEFAULT_LINK_POLICY, 397ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg sizeof(link_policy), &link_policy); 398b59dabdd2515aa111ebc56d946259e4bbdf20c61Pawel Wieczorkiewicz 399fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->current_cod = 0; 400fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memset(dev->eir, 0, sizeof(dev->eir)); 4015c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 40200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 4035c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic gboolean init_adapter(int index) 4045c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 405fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 4065c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg struct btd_adapter *adapter = NULL; 407fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg gboolean existing_adapter = dev->registered; 4085c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg uint8_t mode, on_mode; 4095c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg gboolean pairable, discoverable; 4105c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 411fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->registered) { 4125c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg adapter = btd_manager_register_adapter(index); 4135c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (adapter) 414fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->registered = TRUE; 4155c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } else { 416fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 4175c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg /* FIXME: manager_find_adapter should return a new ref */ 4185c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_ref(adapter); 4195c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } 4205c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4215c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (adapter == NULL) 4225c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return FALSE; 4235c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4245c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_get_state(adapter, &mode, &on_mode, &pairable); 4255c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4265c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (existing_adapter) 4275c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = on_mode; 4285c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4295c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (mode == MODE_OFF) { 43063ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg hciops_power_off(index); 4315c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg goto done; 4325c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } 4335c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4345c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg start_adapter(index); 4355c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_start(adapter); 4365c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4375c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg discoverable = (mode == MODE_DISCOVERABLE); 4385c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4395c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg hciops_set_discoverable(index, discoverable); 4405c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg hciops_set_pairable(index, pairable); 4415c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 4425c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergdone: 4435c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_unref(adapter); 4445c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return TRUE; 445b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 446b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 447abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstatic int hciops_encrypt_link(int index, bdaddr_t *dst, bt_hci_result_t cb, 448abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg gpointer user_data) 449abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg{ 450abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg GIOChannel *io; 451abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_cmd_data *cmd; 452abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_conn_info_req *cr; 453abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg auth_requested_cp cp; 454abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_filter nf; 455abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg int dd, err; 456abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint32_t link_mode; 457abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t handle; 458abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 459684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg dd = hci_open_dev(index); 460684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (dd < 0) 461684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg return -errno; 462684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg 463abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); 464abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cr->type = ACL_LINK; 465abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg bacpy(&cr->bdaddr, dst); 466abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 467684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = ioctl(dd, HCIGETCONNINFO, cr); 468abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg link_mode = cr->conn_info->link_mode; 469abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg handle = cr->conn_info->handle; 470abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_free(cr); 471abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 472684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (err < 0) { 473684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = -errno; 474684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 475684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg } 476abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 477684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (link_mode & HCI_LM_ENCRYPT) { 478684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = -EALREADY; 479684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 480684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg } 481abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 482abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg memset(&cp, 0, sizeof(cp)); 483abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.handle = htobs(handle); 484abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 485684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_AUTH_REQUESTED, 486684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg AUTH_REQUESTED_CP_SIZE, &cp) < 0) { 487684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = -errno; 488684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 489684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg } 490abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 491abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd = g_new0(struct hci_cmd_data, 1); 492abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->handle = handle; 493abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->ocf = OCF_AUTH_REQUESTED; 494abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb = cb; 495abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->caller_data = user_data; 496abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 497abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_clear(&nf); 498abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_ptype(HCI_EVENT_PKT, &nf); 499abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_CMD_STATUS, &nf); 500abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_AUTH_COMPLETE, &nf); 501abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_ENCRYPT_CHANGE, &nf); 502abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 503abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) { 504abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg err = -errno; 505abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_free(cmd); 506684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 507abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 508abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 509684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg io = g_io_channel_unix_new(dd); 510abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_set_close_on_unref(io, FALSE); 511abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_add_watch_full(io, G_PRIORITY_DEFAULT, 512abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg G_IO_HUP | G_IO_ERR | G_IO_NVAL | G_IO_IN, 513abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_event_watch, cmd, g_free); 514abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_unref(io); 515abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 516abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return 0; 517684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg 518684b1d3be105b64f3994e621335f69b45e34125fJohan Hedbergfail: 519684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg close(dd); 520684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg return err; 521abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg} 522abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 52300c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_set_did(int index, uint16_t vendor, uint16_t product, 52400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t version) 52500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 526fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 527fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 528fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->did_vendor = vendor; 529fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->did_product = product; 530fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->did_version = version; 53100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 53200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 53300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 53400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 535abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg/* End async HCI command handling */ 536abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 5375288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Start of HCI event callbacks */ 5385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5395a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedbergstatic int get_handle(int index, const bdaddr_t *bdaddr, uint16_t *handle) 540b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg{ 541b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg struct dev_info *dev = &devs[index]; 5425a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg struct hci_conn_info_req *cr; 5435a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg char addr[18]; 5445a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg int err; 545b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 5465a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg ba2str(bdaddr, addr); 5475a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg DBG("hci%d dba %s", index, addr); 548b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 5495a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); 5505a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg bacpy(&cr->bdaddr, bdaddr); 5515a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg cr->type = ACL_LINK; 552b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 5535a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg if (ioctl(dev->sk, HCIGETCONNINFO, (unsigned long) cr) < 0) { 5545a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg err = -errno; 5555a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg goto fail; 5565a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg } 5575a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg 5585a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg err = 0; 5595a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg *handle = cr->conn_info->handle; 5605a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg 5615a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedbergfail: 5625a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg g_free(cr); 5635a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg return err; 564b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg} 565b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 566b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedbergstatic int disconnect_addr(int index, bdaddr_t *dba, uint8_t reason) 5675288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 5685a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg disconnect_cp cp; 5695a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg uint16_t handle; 5705a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg int err; 5715288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5725a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg err = get_handle(index, dba, &handle); 5735a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg if (err < 0) 5745a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg return err; 5755288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5765a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg memset(&cp, 0, sizeof(cp)); 5775a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg cp.handle = htobs(handle); 5785a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg cp.reason = reason; 579b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 5805a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg if (hci_send_cmd(devs[index].sk, OGF_LINK_CTL, OCF_DISCONNECT, 5815a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg DISCONNECT_CP_SIZE, &cp) < 0) 5825a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg return -errno; 5835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5845a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg return 0; 5855288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 5865288199788ecb17183d6517da3062cd94692a900Johan Hedberg 58742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline int get_bdaddr(int index, uint16_t handle, bdaddr_t *dba) 5885288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 589fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 5905288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_list_req *cl; 5915288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_info *ci; 5925288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 5935288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5945288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); 5955288199788ecb17183d6517da3062cd94692a900Johan Hedberg 59642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cl->dev_id = index; 5975288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl->conn_num = 10; 5985288199788ecb17183d6517da3062cd94692a900Johan Hedberg ci = cl->conn_info; 5995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 600fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETCONNLIST, (void *) cl) < 0) { 6015288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 6025288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -EIO; 6035288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6045288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6055288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < cl->conn_num; i++, ci++) 6065288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (ci->handle == handle) { 6075288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(dba, &ci->bdaddr); 6085288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 6095288199788ecb17183d6517da3062cd94692a900Johan Hedberg return 0; 6105288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6125288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 6135288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6145288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -ENOENT; 6155288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6165288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6175288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Link Key handling */ 6185288199788ecb17183d6517da3062cd94692a900Johan Hedberg 61942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void link_key_request(int index, bdaddr_t *dba) 6205288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 621fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 6225288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 6235288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_device *device; 6245288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_auth_info_req req; 625b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg GSList *match; 626b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg struct link_key_info *key_info; 6275288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char key[16]; 6280e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 6295288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t type; 6305288199788ecb17183d6517da3062cd94692a900Johan Hedberg int err; 6315288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6320e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 6330e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, da); 6345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 635fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 6365288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (adapter) 6375288199788ecb17183d6517da3062cd94692a900Johan Hedberg device = adapter_find_device(adapter, da); 6385288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 6395288199788ecb17183d6517da3062cd94692a900Johan Hedberg device = NULL; 6405288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6415288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&req, 0, sizeof(req)); 6425288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&req.bdaddr, dba); 6435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 644fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = ioctl(dev->sk, HCIGETAUTHINFO, (unsigned long) &req); 6455288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err < 0) { 6465288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (errno != EINVAL) 6475288199788ecb17183d6517da3062cd94692a900Johan Hedberg DBG("HCIGETAUTHINFO failed %s (%d)", 6485288199788ecb17183d6517da3062cd94692a900Johan Hedberg strerror(errno), errno); 6495288199788ecb17183d6517da3062cd94692a900Johan Hedberg req.type = 0x00; 6505288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6515288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6525288199788ecb17183d6517da3062cd94692a900Johan Hedberg DBG("kernel auth requirements = 0x%02x", req.type); 6535288199788ecb17183d6517da3062cd94692a900Johan Hedberg 654b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg match = g_slist_find_custom(dev->keys, dba, (GCompareFunc) bacmp); 655b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (match) 656b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = match->data; 657b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg else 658b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = NULL; 659b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 660b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg DBG("Matching key %s", key_info ? "found" : "not found"); 661b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 662b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (key_info) { 663b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg memcpy(key, key_info->key, sizeof(key)); 664b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg type = key_info->type; 665b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg } else 666b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg type = 0xff; 667b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 668b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (device && device_get_debug_key(device, key)) 6695288199788ecb17183d6517da3062cd94692a900Johan Hedberg type = 0x03; 670b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg else if (key_info == NULL || key_info->type == 0x03) { 6715288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Link key not found */ 672fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 67342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 6, dba); 6745288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 6755288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6765288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6775288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Link key found */ 6785288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6790e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("link key type 0x%02x", type); 6805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6815288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't use unauthenticated combination keys if MITM is 6825288199788ecb17183d6517da3062cd94692a900Johan Hedberg * required */ 6835288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (type == 0x04 && req.type != 0xff && (req.type & 0x01)) 684fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6855288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6, dba); 6865288199788ecb17183d6517da3062cd94692a900Johan Hedberg else { 6875288199788ecb17183d6517da3062cd94692a900Johan Hedberg link_key_reply_cp lr; 6885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6895288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(lr.link_key, key, 16); 6905288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&lr.bdaddr, dba); 6915288199788ecb17183d6517da3062cd94692a900Johan Hedberg 692fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, 6935288199788ecb17183d6517da3062cd94692a900Johan Hedberg LINK_KEY_REPLY_CP_SIZE, &lr); 6945288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6955288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 69742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void link_key_notify(int index, void *ptr) 6985288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 699fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 7005288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_link_key_notify *evt = ptr; 7015288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t *dba = &evt->bdaddr; 702b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg struct link_key_info *key_info; 703b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg GSList *match; 704b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg uint8_t old_key_type, reason; 7050e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 70642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg int err; 7075288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7080e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 7090e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s type %d", index, da, evt->key_type); 7105288199788ecb17183d6517da3062cd94692a900Johan Hedberg 711b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg match = g_slist_find_custom(dev->keys, dba, (GCompareFunc) bacmp); 712b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (match) 713b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = match->data; 714b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg else 715b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = NULL; 716b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 717b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (key_info == NULL) { 718b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = g_new0(struct link_key_info, 1); 719b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg bacpy(&key_info->bdaddr, &evt->bdaddr); 7205288199788ecb17183d6517da3062cd94692a900Johan Hedberg old_key_type = 0xff; 721b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg } else { 722b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg dev->keys = g_slist_remove(dev->keys, key_info); 723b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg old_key_type = key_info->type; 724b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg } 725b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 726b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg memcpy(key_info->key, evt->link_key, sizeof(evt->link_key)); 727b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info->type = evt->key_type; 728b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info->pin_len = dev->pin_length; 7295288199788ecb17183d6517da3062cd94692a900Johan Hedberg 730fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = btd_event_link_key_notify(&dev->bdaddr, dba, evt->link_key, 731fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg evt->key_type, dev->pin_length, 73242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg old_key_type); 733fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = -1; 7345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 735b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (err == 0) { 736b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg dev->keys = g_slist_append(dev->keys, key_info); 737b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg return; 738b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg } 7395288199788ecb17183d6517da3062cd94692a900Johan Hedberg 740b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_free(key_info); 7415288199788ecb17183d6517da3062cd94692a900Johan Hedberg 742b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (err == -ENODEV) 743b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg reason = HCI_OE_LOW_RESOURCES; 744b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg else 745b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg reason = HCI_MEMORY_FULL; 7465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 747b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg btd_event_bonding_process_complete(&dev->bdaddr, dba, reason); 7485288199788ecb17183d6517da3062cd94692a900Johan Hedberg 749b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg disconnect_addr(index, dba, reason); 7505288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7515288199788ecb17183d6517da3062cd94692a900Johan Hedberg 75242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void return_link_keys(int index, void *ptr) 7535288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 754fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 7555288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_return_link_keys *evt = ptr; 7565288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = evt->num_keys; 7575288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char key[16]; 7580e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 7595288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 7605288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 7615288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7620e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d num_keys %u", index, num); 7630e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 7645288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr++; 7655288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7665288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 7675288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&dba, ptr); ba2str(&dba, da); 7685288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(key, ptr + 6, 16); 7695288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7700e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d returned key for %s", index, da); 7715288199788ecb17183d6517da3062cd94692a900Johan Hedberg 772fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_returned_link_key(&dev->bdaddr, &dba); 7735288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7745288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += 22; 7755288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7765288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7785288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Simple Pairing handling */ 7795288199788ecb17183d6517da3062cd94692a900Johan Hedberg 78042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_confirm_request(int index, void *ptr) 7815288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 782fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 7835288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_confirm_request *req = ptr; 7845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7850e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 7860e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 787fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (btd_event_user_confirm(&dev->bdaddr, &req->bdaddr, 7885288199788ecb17183d6517da3062cd94692a900Johan Hedberg btohl(req->passkey)) < 0) 789fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 7905288199788ecb17183d6517da3062cd94692a900Johan Hedberg OCF_USER_CONFIRM_NEG_REPLY, 6, ptr); 7915288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 79342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_passkey_request(int index, void *ptr) 7945288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 795fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 7965288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_passkey_request *req = ptr; 7975288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7980e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 7990e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 800fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (btd_event_user_passkey(&dev->bdaddr, &req->bdaddr) < 0) 801fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 8025288199788ecb17183d6517da3062cd94692a900Johan Hedberg OCF_USER_PASSKEY_NEG_REPLY, 6, ptr); 8035288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8045288199788ecb17183d6517da3062cd94692a900Johan Hedberg 80542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_passkey_notify(int index, void *ptr) 8065288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 807fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 8085288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_passkey_notify *req = ptr; 8095288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8100e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 8110e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 812fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_user_notify(&dev->bdaddr, &req->bdaddr, 81342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btohl(req->passkey)); 8145288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8155288199788ecb17183d6517da3062cd94692a900Johan Hedberg 81642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void remote_oob_data_request(int index, void *ptr) 8175288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 818fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 819fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 8200e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 821fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 822fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 82342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr); 8245288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8255288199788ecb17183d6517da3062cd94692a900Johan Hedberg 82642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void io_capa_request(int index, void *ptr) 8275288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 828fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 82942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg bdaddr_t *dba = ptr; 8300e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 8315288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t cap, auth; 8325288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8330e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 8340e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d IO capability request for %s", index, da); 8355288199788ecb17183d6517da3062cd94692a900Johan Hedberg 836fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (btd_event_get_io_cap(&dev->bdaddr, dba, &cap, &auth) < 0) { 8375288199788ecb17183d6517da3062cd94692a900Johan Hedberg io_capability_neg_reply_cp cp; 8385288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 8395288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cp.bdaddr, dba); 8405288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.reason = HCI_PAIRING_NOT_ALLOWED; 841fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 84242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg OCF_IO_CAPABILITY_NEG_REPLY, 8435288199788ecb17183d6517da3062cd94692a900Johan Hedberg IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp); 8445288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 8455288199788ecb17183d6517da3062cd94692a900Johan Hedberg io_capability_reply_cp cp; 8465288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 8475288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cp.bdaddr, dba); 8485288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.capability = cap; 8495288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.oob_data = 0x00; 8505288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.authentication = auth; 851fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY, 8525288199788ecb17183d6517da3062cd94692a900Johan Hedberg IO_CAPABILITY_REPLY_CP_SIZE, &cp); 8535288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 8545288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 85642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void io_capa_response(int index, void *ptr) 8575288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 858fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 8595288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_io_capability_response *evt = ptr; 8600e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 8615288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8620e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(&evt->bdaddr, da); 8630e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d IO capability response from %s", index, da); 8645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 865fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_set_io_cap(&dev->bdaddr, &evt->bdaddr, 8665288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt->capability, evt->authentication); 8675288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8695288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* PIN code handling */ 8705288199788ecb17183d6517da3062cd94692a900Johan Hedberg 87142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void pin_code_request(int index, bdaddr_t *dba) 8725288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 873fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 87453a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg char addr[18]; 87553a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg int err; 8765288199788ecb17183d6517da3062cd94692a900Johan Hedberg 87753a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg ba2str(dba, addr); 87853a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg DBG("hci%d PIN request for %s", index, addr); 8795288199788ecb17183d6517da3062cd94692a900Johan Hedberg 88053a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg err = btd_event_request_pin(&dev->bdaddr, dba); 88153a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg if (err < 0) { 88253a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg error("PIN code negative reply: %s", strerror(-err)); 88353a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 88453a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg 6, dba); 8855288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 8865288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8875288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8885288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic void start_inquiry(bdaddr_t *local, uint8_t status, gboolean periodic) 8895288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 8905288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 8915288199788ecb17183d6517da3062cd94692a900Johan Hedberg int state; 8925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8935288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't send the signal if the cmd failed */ 8945288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) { 8955288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Inquiry Failed with status 0x%02x", status); 8965288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 8975288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 8985288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8995288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(local); 9005288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 9015288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 9025288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9035288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 9045288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9055288199788ecb17183d6517da3062cd94692a900Johan Hedberg state = adapter_get_state(adapter); 9065288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9075288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (periodic) 9085288199788ecb17183d6517da3062cd94692a900Johan Hedberg state |= STATE_PINQ; 9095288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 9105288199788ecb17183d6517da3062cd94692a900Johan Hedberg state |= STATE_STDINQ; 9115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9125288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_set_state(adapter, state); 9135288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9145288199788ecb17183d6517da3062cd94692a900Johan Hedberg 915e5828c7e30453232e930dbead0e359175dc1decfJohan Hedbergstatic void inquiry_complete(bdaddr_t *local, uint8_t status, 916e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg gboolean periodic) 9175288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 9185288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 9195288199788ecb17183d6517da3062cd94692a900Johan Hedberg int state; 9205288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9215288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't send the signal if the cmd failed */ 9225288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) { 9235288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Inquiry Failed with status 0x%02x", status); 9245288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9255288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 9265288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9275288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(local); 9285288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 9295288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 9305288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9315288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 9325288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9335288199788ecb17183d6517da3062cd94692a900Johan Hedberg state = adapter_get_state(adapter); 9345288199788ecb17183d6517da3062cd94692a900Johan Hedberg state &= ~(STATE_STDINQ | STATE_PINQ); 9355288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_set_state(adapter, state); 9365288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9375288199788ecb17183d6517da3062cd94692a900Johan Hedberg 93842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_features_notify(int index, void *ptr) 9395288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 940fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 9415288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_remote_host_features_notify *evt = ptr; 9425288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9435288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->features[0] & 0x01) 944fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_set_legacy_pairing(&dev->bdaddr, &evt->bdaddr, 94542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg FALSE); 9465288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 947fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_set_legacy_pairing(&dev->bdaddr, &evt->bdaddr, 94842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg TRUE); 9495288199788ecb17183d6517da3062cd94692a900Johan Hedberg 950fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_features_info(&dev->bdaddr, &evt->bdaddr, NULL, evt->features); 9515288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9525288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9532db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedbergstatic void write_le_host_complete(int index, uint8_t status) 9545288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 955fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 9562db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg uint8_t page_num = 0x01; 9575288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9585288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) 9595288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9605288199788ecb17183d6517da3062cd94692a900Johan Hedberg 961fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_INFO_PARAM, 9622db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg OCF_READ_LOCAL_EXT_FEATURES, 1, &page_num) < 0) 9632db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg error("Unable to read extended local features: %s (%d)", 9642db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg strerror(errno), errno); 9655288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9665288199788ecb17183d6517da3062cd94692a900Johan Hedberg 967be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void read_local_version_complete(int index, 968be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg const read_local_version_rp *rp) 969be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 970fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 971fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 972be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (rp->status) 973be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 974be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 975fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.manufacturer = btohs(bt_get_unaligned(&rp->manufacturer)); 976fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.hci_ver = rp->hci_ver; 977fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.hci_rev = btohs(bt_get_unaligned(&rp->hci_rev)); 978fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_ver = rp->lmp_ver; 979fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver = btohs(bt_get_unaligned(&rp->lmp_subver)); 980be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 981fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 982be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 983be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 984fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_VERSION, &dev->pending); 985be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 986be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg DBG("Got version for hci%d", index); 987be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 988fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending && dev->up) 9895c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 990be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 991be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 992be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void read_local_features_complete(int index, 993be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg const read_local_features_rp *rp) 994be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 995fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 996fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 997be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (rp->status) 998be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 999be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1000fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->features, rp->features, 8); 1001be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1002fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 1003be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 1004be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1005fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_FEATURES, &dev->pending); 1006be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1007be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg DBG("Got features for hci%d", index); 1008be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1009fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending && dev->up) 10105c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 1011be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 1012be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 101300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg#define SIZEOF_UUID128 16 101400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 101500c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void eir_generate_uuid128(sdp_list_t *list, 101600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *ptr, uint16_t *eir_len) 101700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 101800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int i, k, uuid_count = 0; 101900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t len = *eir_len; 102000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *uuid128; 102100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg gboolean truncated = FALSE; 102200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 102300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Store UUIDs in place, skip 2 bytes to write type and length later */ 102400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128 = ptr + 2; 102500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 102600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (; list; list = list->next) { 102700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_record_t *rec = list->data; 102800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *uuid128_data = rec->svclass.value.uuid128.data; 102900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 103000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.type != SDP_UUID128) 103100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 103200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 103300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Stop if not enough space to put next UUID128 */ 103400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) { 103500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg truncated = TRUE; 103600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 103700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 103800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 103900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Check for duplicates, EIR data is Little Endian */ 104000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (i = 0; i < uuid_count; i++) { 104100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (k = 0; k < SIZEOF_UUID128; k++) { 104200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid128[i * SIZEOF_UUID128 + k] != 104300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128_data[SIZEOF_UUID128 - 1 - k]) 104400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 104500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 104600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (k == SIZEOF_UUID128) 104700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 104800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 104900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 105000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (i < uuid_count) 105100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 105200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 105300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR data is Little Endian */ 105400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (k = 0; k < SIZEOF_UUID128; k++) 105500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128[uuid_count * SIZEOF_UUID128 + k] = 105600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128_data[SIZEOF_UUID128 - 1 - k]; 105700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 105800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg len += SIZEOF_UUID128; 105900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid_count++; 106000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 106100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 106200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid_count > 0 || truncated) { 106300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data length */ 106400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[0] = (uuid_count * SIZEOF_UUID128) + 1; 106500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data type */ 106600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL; 106700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg len += 2; 106800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *eir_len = len; 106900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 107000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 107100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 107200c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void create_ext_inquiry_response(int index, uint8_t *data) 107300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1074fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 107500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_list_t *services; 107600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_list_t *list; 107700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *ptr = data; 107800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t eir_len = 0; 107900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t uuid16[EIR_DATA_LENGTH / 2]; 108000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int i, uuid_count = 0; 108100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg gboolean truncated = FALSE; 108200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg struct btd_adapter *adapter; 108300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg size_t name_len; 108400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1085fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg name_len = strlen(dev->name); 108600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 108700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (name_len > 0) { 108800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data type */ 108900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (name_len > 48) { 109000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg name_len = 48; 109100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = EIR_NAME_SHORT; 109200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } else 109300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = EIR_NAME_COMPLETE; 109400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 109500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data length */ 109600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[0] = name_len + 1; 109700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1098fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(ptr + 2, dev->name, name_len); 109900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 110000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += (name_len + 2); 110100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr += (name_len + 2); 110200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 110300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1104fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->tx_power != 0) { 110500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = 2; 110600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = EIR_TX_POWER; 1107fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (uint8_t) dev->tx_power; 110800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += 3; 110900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 111000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1111fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->did_vendor != 0x0000) { 111200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t source = 0x0002; 111300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = 9; 111400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = EIR_DEVICE_ID; 111500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (source & 0x00ff); 111600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (source & 0xff00) >> 8; 1117fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_vendor & 0x00ff); 1118fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_vendor & 0xff00) >> 8; 1119fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_product & 0x00ff); 1120fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_product & 0xff00) >> 8; 1121fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_version & 0x00ff); 1122fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_version & 0xff00) >> 8; 112300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += 10; 112400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 112500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1126fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 112700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (adapter == NULL) 112800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 112900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 113000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg services = adapter_get_services(adapter); 113100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 113200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Group all UUID16 types */ 113300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (list = services; list; list = list->next) { 113400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_record_t *rec = list->data; 113500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 113600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.type != SDP_UUID16) 113700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 113800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 113900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.value.uuid16 < 0x1100) 114000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 114100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 114200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.value.uuid16 == PNP_INFO_SVCLASS_ID) 114300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 114400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 114500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Stop if not enough space to put next UUID16 */ 114600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) { 114700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg truncated = TRUE; 114800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 114900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 115000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 115100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Check for duplicates */ 115200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (i = 0; i < uuid_count; i++) 115300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid16[i] == rec->svclass.value.uuid16) 115400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 115500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 115600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (i < uuid_count) 115700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 115800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 115900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid16[uuid_count++] = rec->svclass.value.uuid16; 116000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += sizeof(uint16_t); 116100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 116200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 116300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid_count > 0) { 116400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data length */ 116500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[0] = (uuid_count * sizeof(uint16_t)) + 1; 116600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data type */ 116700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; 116800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 116900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr += 2; 117000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += 2; 117100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 117200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (i = 0; i < uuid_count; i++) { 117300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (uuid16[i] & 0x00ff); 117400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (uuid16[i] & 0xff00) >> 8; 117500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 117600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 117700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 117800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Group all UUID128 types */ 117900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (eir_len <= EIR_DATA_LENGTH - 2) 118000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_generate_uuid128(services, ptr, &eir_len); 118100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 118200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 118300c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void update_ext_inquiry_response(int index) 118400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1185fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 118600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_ext_inquiry_response_cp cp; 118700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 118800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d", index); 118900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1190fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[6] & LMP_EXT_INQ)) 119100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 119200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1193fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ssp_mode == 0) 119400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 119500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1196fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->cache_enable) 119700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 119800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 119900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memset(&cp, 0, sizeof(cp)); 120000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 120100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg create_ext_inquiry_response(index, cp.data); 120200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1203fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0) 120400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 120500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1206fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->eir, cp.data, sizeof(cp.data)); 120700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1208fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 120900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg OCF_WRITE_EXT_INQUIRY_RESPONSE, 121000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &cp) < 0) 121100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg error("Unable to write EIR data: %s (%d)", 121200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg strerror(errno), errno); 121300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 121400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 121519084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedbergstatic void update_name(int index, const char *name) 121619084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg{ 1217fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 121819084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg struct btd_adapter *adapter; 121919084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg 1220fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 122119084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg if (adapter) 122219084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg adapter_update_local_name(adapter, name); 122300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 122400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 122519084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg} 122619084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg 1227fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedbergstatic void read_local_name_complete(int index, read_local_name_rp *rp) 1228fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg{ 1229fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1230fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 12310e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 12320e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1233fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg if (rp->status) 1234fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg return; 1235fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1236fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->name, rp->name, 248); 123700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1238fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) { 123919084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg update_name(index, (char *) rp->name); 1240fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg return; 1241fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg } 1242fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1243fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_NAME, &dev->pending); 1244fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1245fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg DBG("Got name for hci%d", index); 1246fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1247fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->up) 12489f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg return; 12499f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 12509f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg /* Even though it shouldn't happen (assuming the kernel behaves 12519f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * properly) it seems like we might miss the very first 12529f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * initialization commands that the kernel sends. So check for 12539f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * it here (since read_local_name is one of the last init 12549f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * commands) and resend the first ones if we haven't seen 12559f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * their results yet */ 12569f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 1257fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_test_bit(PENDING_FEATURES, &dev->pending)) 1258fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_INFO_PARAM, 12599f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg OCF_READ_LOCAL_FEATURES, 0, NULL); 12609f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 1261fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_test_bit(PENDING_VERSION, &dev->pending)) 1262fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_INFO_PARAM, 12639f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg OCF_READ_LOCAL_VERSION, 0, NULL); 12649f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 1265fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 12665c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 1267fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg} 1268fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1269e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedbergstatic void read_tx_power_complete(int index, void *ptr) 1270e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg{ 1271fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1272fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 1273e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg read_inq_response_tx_power_level_rp *rp = ptr; 1274e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg 12750e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 12760e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1277e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg if (rp->status) 1278e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg return; 1279e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg 1280fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->tx_power = rp->level; 128100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 1282e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg} 1283e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg 1284af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedbergstatic void read_simple_pairing_mode_complete(int index, void *ptr) 1285af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg{ 1286fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1287af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg read_simple_pairing_mode_rp *rp = ptr; 1288af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg struct btd_adapter *adapter; 1289af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 12900e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 12910e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1292af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg if (rp->status) 1293af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg return; 1294af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 1295fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ssp_mode = rp->mode; 129600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 129700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1298fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 1299af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg if (!adapter) { 1300af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg error("No matching adapter found"); 1301af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg return; 1302af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg } 1303af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 1304af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg adapter_update_ssp_mode(adapter, rp->mode); 1305af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg} 1306af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 13070e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedbergstatic void read_local_ext_features_complete(int index, 13085288199788ecb17183d6517da3062cd94692a900Johan Hedberg const read_local_ext_features_rp *rp) 13095288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1310fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 13115288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 13125288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13130e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 13140e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 13155288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (rp->status) 13165288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 13175288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1318fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 13195288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 13205288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("No matching adapter found"); 13215288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 13225288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 13235288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13245288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Local Extended feature page number is 1 */ 13255288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (rp->page_num != 1) 13265288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 13275288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13285288199788ecb17183d6517da3062cd94692a900Johan Hedberg btd_adapter_update_local_ext_features(adapter, rp->features); 13295288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 13305288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13315a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedbergstatic void read_bd_addr_complete(int index, read_bd_addr_rp *rp) 13325a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg{ 1333fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1334fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 13350e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 13360e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 13375a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg if (rp->status) 13385a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg return; 13395a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1340fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(&dev->bdaddr, &rp->bdaddr); 13415a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1342fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 13435a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg return; 13445a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1345fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_BDADDR, &dev->pending); 13465a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 134728c405b17a3131494c11599705885ae630c52ee2Johan Hedberg DBG("Got bdaddr for hci%d", index); 13485a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1349fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending && dev->up) 13505c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 13515a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg} 13525a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 135342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void cmd_status(int index, void *ptr) 13545288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1355fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 13565288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_status *evt = ptr; 13575288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t opcode = btohs(evt->opcode); 13585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13595288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) 1360fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg start_inquiry(&dev->bdaddr, evt->status, FALSE); 13615288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 13625288199788ecb17183d6517da3062cd94692a900Johan Hedberg 136342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void read_scan_complete(int index, uint8_t status, void *ptr) 13645288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1365fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 13665288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 13675288199788ecb17183d6517da3062cd94692a900Johan Hedberg read_scan_enable_rp *rp = ptr; 13685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13690e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, status); 13700e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1371fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 13725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13735288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 13745288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 13755288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 13765288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 13775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13785288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_mode_changed(adapter, rp->enable); 13795288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 13805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1381914a9093c108cf67a1ef08bffc7db2e4c9a5b1b9Johan Hedbergstatic int write_class(int index, uint32_t class) 138200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1383fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 138400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_class_of_dev_cp cp; 138500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 138600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d class 0x%06x", index, class); 138700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 138800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memcpy(cp.dev_class, &class, 3); 138900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1390fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, 139100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg WRITE_CLASS_OF_DEV_CP_SIZE, &cp) < 0) 139200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return -errno; 139300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1394fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pending_cod = class; 139500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 139600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 139700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 139800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 139900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg/* Limited Discoverable bit mask in CoD */ 140000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg#define LIMITED_BIT 0x002000 140100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 140200c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_set_limited_discoverable(int index, gboolean limited) 140300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1404fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 140500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int num = (limited ? 2 : 1); 140600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t lap[] = { 0x33, 0x8b, 0x9e, 0x00, 0x8b, 0x9e }; 140700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_current_iac_lap_cp cp; 140800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 140900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d limited %d", index, limited); 141000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 141100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Check if limited bit needs to be set/reset */ 141200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (limited) 1413fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod |= LIMITED_BIT; 141400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg else 1415fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod &= ~LIMITED_BIT; 141600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 141700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* If we dont need the toggling, save an unnecessary CoD write */ 1418fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->pending_cod || dev->wanted_cod == dev->current_cod) 141900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 142000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 142100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* 142200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * 1: giac 142300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * 2: giac + liac 142400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg */ 142500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memset(&cp, 0, sizeof(cp)); 142600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg cp.num_current_iac = num; 142700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memcpy(&cp.lap, lap, num * 3); 142800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1429fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CURRENT_IAC_LAP, 143000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg (num * 3 + 1), &cp) < 0) 143100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return -errno; 143200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1433fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg return write_class(index, dev->wanted_cod); 143400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 143500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 143600c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void write_class_complete(int index, uint8_t status) 143700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1438fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 143900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg struct btd_adapter *adapter; 144000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 144100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (status) 144200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 144300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1444fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->pending_cod == 0) 144500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 144600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1447fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->current_cod = dev->pending_cod; 1448fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pending_cod = 0; 144900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1450fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 145100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (adapter) 1452fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_adapter_class_changed(adapter, dev->current_cod); 145300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 145400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 145500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1456fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->wanted_cod == dev->current_cod) 145700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 145800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1459fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->wanted_cod & LIMITED_BIT && 1460fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg !(dev->current_cod & LIMITED_BIT)) 146100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg hciops_set_limited_discoverable(index, TRUE); 1462fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg else if (!(dev->wanted_cod & LIMITED_BIT) && 1463fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg (dev->current_cod & LIMITED_BIT)) 146400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg hciops_set_limited_discoverable(index, FALSE); 146500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg else 1466fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_class(index, dev->wanted_cod); 146700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 146800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 146942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void cmd_complete(int index, void *ptr) 14705288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1471fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 14725288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_complete *evt = ptr; 14735288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t opcode = btohs(evt->opcode); 14745288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t status = *((uint8_t *) ptr + EVT_CMD_COMPLETE_SIZE); 14755288199788ecb17183d6517da3062cd94692a900Johan Hedberg 14765288199788ecb17183d6517da3062cd94692a900Johan Hedberg switch (opcode) { 1477be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION): 1478be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg ptr += sizeof(evt_cmd_complete); 1479be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg read_local_version_complete(index, ptr); 1480be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg break; 1481be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES): 1482be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg ptr += sizeof(evt_cmd_complete); 1483be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg read_local_features_complete(index, ptr); 1484be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg break; 14855288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_EXT_FEATURES): 14865288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 14870e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg read_local_ext_features_complete(index, ptr); 14885288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 14895a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BD_ADDR): 14905a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg ptr += sizeof(evt_cmd_complete); 14915a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg read_bd_addr_complete(index, ptr); 14925a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg break; 14935288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_PERIODIC_INQUIRY): 1494fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg start_inquiry(&dev->bdaddr, status, TRUE); 14955288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 14965288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY): 1497fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg inquiry_complete(&dev->bdaddr, status, TRUE); 14985288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 14995288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL): 1500fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg inquiry_complete(&dev->bdaddr, status, FALSE); 15015288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15025288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_LE_HOST_SUPPORTED): 15032db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg write_le_host_complete(index, status); 15045288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15055288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE): 1506fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_le_set_scan_enable_complete(&dev->bdaddr, status); 15075288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15085288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME): 1509bd7f8939b50a12418476245f9b5117801f858b02Johan Hedberg if (!status) 1510fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, 1511bd7f8939b50a12418476245f9b5117801f858b02Johan Hedberg OCF_READ_LOCAL_NAME, 0, 0); 15125288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15135288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE): 1514fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_setscan_enable_complete(&dev->bdaddr); 15155288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15165288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SCAN_ENABLE): 15175288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 151842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg read_scan_complete(index, status, ptr); 15195288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15205288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV): 152100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_class_complete(index, status); 15225288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15235288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SIMPLE_PAIRING_MODE): 15247afa48dcf311926269dcfb8ec1a2a12c94eb2d5bJohan Hedberg if (!status) 1525fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, 15267afa48dcf311926269dcfb8ec1a2a12c94eb2d5bJohan Hedberg OCF_READ_SIMPLE_PAIRING_MODE, 0, NULL); 15275288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15285288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SIMPLE_PAIRING_MODE): 15295288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1530af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg read_simple_pairing_mode_complete(index, ptr); 15315288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15325288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_NAME): 15335288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1534fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg read_local_name_complete(index, ptr); 15355288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 1536e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, 1537e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL): 15385288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1539e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg read_tx_power_complete(index, ptr); 15405288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 15415288199788ecb17183d6517da3062cd94692a900Johan Hedberg }; 15425288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 15435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 154442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_name_information(int index, void *ptr) 15455288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1546fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 15475288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_remote_name_req_complete *evt = ptr; 15485288199788ecb17183d6517da3062cd94692a900Johan Hedberg char name[MAX_NAME_LENGTH + 1]; 15495288199788ecb17183d6517da3062cd94692a900Johan Hedberg 15500e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 15510e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 15525288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(name, 0, sizeof(name)); 15535288199788ecb17183d6517da3062cd94692a900Johan Hedberg 15545288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!evt->status) 15555288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(name, evt->name, MAX_NAME_LENGTH); 15565288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1557fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_remote_name(&dev->bdaddr, &evt->bdaddr, evt->status, name); 15585288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 15595288199788ecb17183d6517da3062cd94692a900Johan Hedberg 156042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_version_information(int index, void *ptr) 15615288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1562fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 15635288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_read_remote_version_complete *evt = ptr; 15645288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 15655288199788ecb17183d6517da3062cd94692a900Johan Hedberg 15660e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 15670e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 15685288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 15695288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 15705288199788ecb17183d6517da3062cd94692a900Johan Hedberg 157142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) 15725288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 15735288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1574fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_version_info(&dev->bdaddr, &dba, btohs(evt->manufacturer), 15755288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt->lmp_ver, btohs(evt->lmp_subver)); 15765288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 15775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 157842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void inquiry_result(int index, int plen, void *ptr) 15795288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1580fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 15815288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 15825288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 15835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 15845288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 15855288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info *info = ptr; 158642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg uint32_t class = info->dev_class[0] | 158742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg (info->dev_class[1] << 8) | 158842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg (info->dev_class[2] << 16); 15895288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1590b98312395e628aa8e7c25b963dad7d21c714fcc7Johan Hedberg btd_event_device_found(&dev->bdaddr, &info->bdaddr, class, 159142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 0, NULL); 15925288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_SIZE; 15935288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 15945288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 15955288199788ecb17183d6517da3062cd94692a900Johan Hedberg 159642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void inquiry_result_with_rssi(int index, int plen, void *ptr) 15975288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1598fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 15995288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 16005288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 16015288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16025288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!num) 16035288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16045288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16055288199788ecb17183d6517da3062cd94692a900Johan Hedberg if ((plen - 1) / num == INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE) { 16065288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 16075288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info_with_rssi_and_pscan_mode *info = ptr; 16085288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 160942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 161042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 16115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1612b98312395e628aa8e7c25b963dad7d21c714fcc7Johan Hedberg btd_event_device_found(&dev->bdaddr, &info->bdaddr, 16135288199788ecb17183d6517da3062cd94692a900Johan Hedberg class, info->rssi, NULL); 16145288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; 16155288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16165288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 16175288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 16185288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info_with_rssi *info = ptr; 16195288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 162042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 162142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 16225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1623b98312395e628aa8e7c25b963dad7d21c714fcc7Johan Hedberg btd_event_device_found(&dev->bdaddr, &info->bdaddr, 16245288199788ecb17183d6517da3062cd94692a900Johan Hedberg class, info->rssi, NULL); 16255288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_WITH_RSSI_SIZE; 16265288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16275288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16285288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16295288199788ecb17183d6517da3062cd94692a900Johan Hedberg 163042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void extended_inquiry_result(int index, int plen, void *ptr) 16315288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1632fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 16335288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 16345288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 16355288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16365288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 16375288199788ecb17183d6517da3062cd94692a900Johan Hedberg extended_inquiry_info *info = ptr; 16385288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 163942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 164042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 16415288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1642b98312395e628aa8e7c25b963dad7d21c714fcc7Johan Hedberg btd_event_device_found(&dev->bdaddr, &info->bdaddr, class, 16435288199788ecb17183d6517da3062cd94692a900Johan Hedberg info->rssi, info->data); 16445288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += EXTENDED_INQUIRY_INFO_SIZE; 16455288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16465288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16475288199788ecb17183d6517da3062cd94692a900Johan Hedberg 164842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_features_information(int index, void *ptr) 16495288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1650fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 16515288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_read_remote_features_complete *evt = ptr; 16525288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 16535288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16540e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 16550e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 16565288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 16575288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 165942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) 16605288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16615288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1662fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_features_info(&dev->bdaddr, &dba, evt->features, NULL); 16635288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16658e17ca3a784294aec947866071c38d934e21940dJohan Hedbergstruct remote_version_req { 16668e17ca3a784294aec947866071c38d934e21940dJohan Hedberg int index; 16678e17ca3a784294aec947866071c38d934e21940dJohan Hedberg uint16_t handle; 16688e17ca3a784294aec947866071c38d934e21940dJohan Hedberg}; 16698e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 16708e17ca3a784294aec947866071c38d934e21940dJohan Hedbergstatic gboolean __get_remote_version(gpointer user_data) 16718e17ca3a784294aec947866071c38d934e21940dJohan Hedberg{ 16728e17ca3a784294aec947866071c38d934e21940dJohan Hedberg struct remote_version_req *req = user_data; 16738e17ca3a784294aec947866071c38d934e21940dJohan Hedberg struct dev_info *dev = &devs[req->index]; 16748e17ca3a784294aec947866071c38d934e21940dJohan Hedberg read_remote_version_cp cp; 16758e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 16768e17ca3a784294aec947866071c38d934e21940dJohan Hedberg DBG("hci%d handle %u", req->index, req->handle); 16778e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 16788e17ca3a784294aec947866071c38d934e21940dJohan Hedberg memset(&cp, 0, sizeof(cp)); 16798e17ca3a784294aec947866071c38d934e21940dJohan Hedberg cp.handle = htobs(req->handle); 16808e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 16818e17ca3a784294aec947866071c38d934e21940dJohan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_READ_REMOTE_VERSION, 16828e17ca3a784294aec947866071c38d934e21940dJohan Hedberg READ_REMOTE_VERSION_CP_SIZE, &cp); 16838e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 16848e17ca3a784294aec947866071c38d934e21940dJohan Hedberg return FALSE; 16858e17ca3a784294aec947866071c38d934e21940dJohan Hedberg} 16868e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 16878e17ca3a784294aec947866071c38d934e21940dJohan Hedbergstatic void get_remote_version(int index, uint16_t handle) 16888e17ca3a784294aec947866071c38d934e21940dJohan Hedberg{ 16898e17ca3a784294aec947866071c38d934e21940dJohan Hedberg struct remote_version_req *req; 16908e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 16918e17ca3a784294aec947866071c38d934e21940dJohan Hedberg req = g_new0(struct remote_version_req, 1); 16928e17ca3a784294aec947866071c38d934e21940dJohan Hedberg req->handle = handle; 16938e17ca3a784294aec947866071c38d934e21940dJohan Hedberg req->index = index; 16948e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 16958e17ca3a784294aec947866071c38d934e21940dJohan Hedberg g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1, __get_remote_version, 16968e17ca3a784294aec947866071c38d934e21940dJohan Hedberg req, g_free); 16978e17ca3a784294aec947866071c38d934e21940dJohan Hedberg} 16988e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 169942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void conn_complete(int index, void *ptr) 17005288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1701fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17025288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_conn_complete *evt = ptr; 17035288199788ecb17183d6517da3062cd94692a900Johan Hedberg char filename[PATH_MAX]; 17045288199788ecb17183d6517da3062cd94692a900Johan Hedberg char local_addr[18], peer_addr[18], *str; 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 17155288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* check if the remote version needs be requested */ 1716fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg ba2str(&dev->bdaddr, local_addr); 17175288199788ecb17183d6517da3062cd94692a900Johan Hedberg ba2str(&evt->bdaddr, peer_addr); 17185288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17195288199788ecb17183d6517da3062cd94692a900Johan Hedberg create_name(filename, sizeof(filename), STORAGEDIR, local_addr, 17205288199788ecb17183d6517da3062cd94692a900Johan Hedberg "manufacturers"); 17215288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17225288199788ecb17183d6517da3062cd94692a900Johan Hedberg str = textfile_get(filename, peer_addr); 17235288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!str) 17248e17ca3a784294aec947866071c38d934e21940dJohan Hedberg get_remote_version(index, btohs(evt->handle)); 17255288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 17265288199788ecb17183d6517da3062cd94692a900Johan Hedberg free(str); 17275288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 17285288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17295f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demariostatic inline void le_conn_complete(int index, void *ptr) 17305f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario{ 1731fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17325f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario evt_le_connection_complete *evt = ptr; 17335f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario char filename[PATH_MAX]; 17345f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario char local_addr[18], peer_addr[18], *str; 17355f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 1736fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_conn_complete(&dev->bdaddr, evt->status, 17375f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario btohs(evt->handle), &evt->peer_bdaddr); 17385f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 17395f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario if (evt->status) 17405f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario return; 17415f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 17425f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario /* check if the remote version needs be requested */ 1743fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg ba2str(&dev->bdaddr, local_addr); 17445f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario ba2str(&evt->peer_bdaddr, peer_addr); 17455f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 17465f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario create_name(filename, sizeof(filename), STORAGEDIR, local_addr, 17475f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario "manufacturers"); 17485f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 17495f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario str = textfile_get(filename, peer_addr); 17505f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario if (!str) 17518e17ca3a784294aec947866071c38d934e21940dJohan Hedberg get_remote_version(index, btohs(evt->handle)); 17525f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario else 17535f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario free(str); 17545f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario} 17555f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 175642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void disconn_complete(int index, void *ptr) 17575288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1758fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17595288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_disconn_complete *evt = ptr; 17605288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1761fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_disconn_complete(&dev->bdaddr, evt->status, 176242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btohs(evt->handle), evt->reason); 17635288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 17645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 176542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void auth_complete(int index, void *ptr) 17665288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1767fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17685288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_auth_complete *evt = ptr; 17695288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 17705288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17710e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 17720e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 177342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) 17745288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 17755288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1776fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_bonding_process_complete(&dev->bdaddr, &dba, evt->status); 17775288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 17785288199788ecb17183d6517da3062cd94692a900Johan Hedberg 177942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void simple_pairing_complete(int index, void *ptr) 17805288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1781fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17825288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_simple_pairing_complete *evt = ptr; 17835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17840e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 17850e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1786fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_simple_pairing_complete(&dev->bdaddr, &evt->bdaddr, 178742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg evt->status); 17885288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 17895288199788ecb17183d6517da3062cd94692a900Johan Hedberg 179042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void conn_request(int index, void *ptr) 17915288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1792fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17935288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_conn_request *evt = ptr; 17945288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = evt->dev_class[0] | (evt->dev_class[1] << 8) 17955288199788ecb17183d6517da3062cd94692a900Johan Hedberg | (evt->dev_class[2] << 16); 17965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1797fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_remote_class(&dev->bdaddr, &evt->bdaddr, class); 17985288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 17995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18005f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demariostatic inline void le_advertising_report(int index, evt_le_meta_event *meta) 18015288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1802fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 18035288199788ecb17183d6517da3062cd94692a900Johan Hedberg le_advertising_info *info; 1804e430998efb9da9c89f1d94e3b6786a14aed834ebBruna Moreira uint8_t num, i; 18055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18065288199788ecb17183d6517da3062cd94692a900Johan Hedberg num = meta->data[0]; 18075288199788ecb17183d6517da3062cd94692a900Johan Hedberg info = (le_advertising_info *) (meta->data + 1); 18085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18095288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 1810fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_advertising_report(&dev->bdaddr, info); 1811e430998efb9da9c89f1d94e3b6786a14aed834ebBruna Moreira info = (le_advertising_info *) (info->data + info->length + 1); 18125288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 18135288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 18145288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18155f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demariostatic inline void le_metaevent(int index, void *ptr) 18165f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario{ 18175f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario evt_le_meta_event *meta = ptr; 18185f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 18195f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario DBG("hci%d LE Meta Event %u", index, meta->subevent); 18205f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 18215f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario switch (meta->subevent) { 18225f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario case EVT_LE_ADVERTISING_REPORT: 18235f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario le_advertising_report(index, meta); 18245f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario break; 18255f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 18265f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario case EVT_LE_CONN_COMPLETE: 18275f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario le_conn_complete(index, meta->data); 18285f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario break; 18295f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario } 18305f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario} 18315f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 183255694454017b04a416931a81964bb695f48b3d93Johan Hedbergstatic void stop_hci_dev(int index) 18335288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1834fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 18355288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1836b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (dev->sk < 0) 18375288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 18385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 183955694454017b04a416931a81964bb695f48b3d93Johan Hedberg info("Stopping hci%d event socket", index); 18405288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1841b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (dev->watch_id > 0) 1842b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_source_remove(dev->watch_id); 1843b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 1844b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (dev->io != NULL) 1845b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_io_channel_unref(dev->io); 1846b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 1847fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_close_dev(dev->sk); 1848b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 1849b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_slist_foreach(dev->keys, (GFunc) g_free, NULL); 1850b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_slist_free(dev->keys); 1851b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 1852fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg init_dev_info(index, -1, dev->registered); 18535288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 18545288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18555288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic gboolean io_security_event(GIOChannel *chan, GIOCondition cond, 18565288199788ecb17183d6517da3062cd94692a900Johan Hedberg gpointer data) 18575288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 18585288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; 185942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg int type, index = GPOINTER_TO_INT(data); 1860fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 186142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg struct hci_dev_info di; 18625288199788ecb17183d6517da3062cd94692a900Johan Hedberg size_t len; 18635288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_event_hdr *eh; 18645288199788ecb17183d6517da3062cd94692a900Johan Hedberg GIOError err; 18655288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_status *evt; 18665288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18675288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { 186855694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 18695288199788ecb17183d6517da3062cd94692a900Johan Hedberg return FALSE; 18705288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 18715288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18725288199788ecb17183d6517da3062cd94692a900Johan Hedberg if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { 18735288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err == G_IO_ERROR_AGAIN) 18745288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 187555694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 18765288199788ecb17183d6517da3062cd94692a900Johan Hedberg return FALSE; 18775288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 18785288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18795288199788ecb17183d6517da3062cd94692a900Johan Hedberg type = *ptr++; 18805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18815288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (type != HCI_EVENT_PKT) 18825288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 18835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18845288199788ecb17183d6517da3062cd94692a900Johan Hedberg eh = (hci_event_hdr *) ptr; 18855288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += HCI_EVENT_HDR_SIZE; 18865288199788ecb17183d6517da3062cd94692a900Johan Hedberg 188742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg memset(&di, 0, sizeof(di)); 188842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (hci_devinfo(index, &di) == 0) { 1889fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(&dev->bdaddr, &di.bdaddr); 18905288199788ecb17183d6517da3062cd94692a900Johan Hedberg 189142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (ignore_device(&di)) 189242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg return TRUE; 189342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg } 189455694454017b04a416931a81964bb695f48b3d93Johan Hedberg 18955288199788ecb17183d6517da3062cd94692a900Johan Hedberg switch (eh->evt) { 18965288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CMD_STATUS: 189742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cmd_status(index, ptr); 18985288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19005288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CMD_COMPLETE: 190142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cmd_complete(index, ptr); 19025288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19035288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19045288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_NAME_REQ_COMPLETE: 190542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_name_information(index, ptr); 19065288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19075288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19085288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_READ_REMOTE_VERSION_COMPLETE: 190942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_version_information(index, ptr); 19105288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19125288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_READ_REMOTE_FEATURES_COMPLETE: 191342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_features_information(index, ptr); 19145288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19155288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19165288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_HOST_FEATURES_NOTIFY: 191742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_features_notify(index, ptr); 19185288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19195288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19205288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_COMPLETE: 19215288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt = (evt_cmd_status *) ptr; 1922fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg inquiry_complete(&dev->bdaddr, evt->status, FALSE); 19235288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19245288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19255288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_RESULT: 192642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_result(index, eh->plen, ptr); 19275288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19285288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19295288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_RESULT_WITH_RSSI: 193042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_result_with_rssi(index, eh->plen, ptr); 19315288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19325288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19335288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_EXTENDED_INQUIRY_RESULT: 193442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg extended_inquiry_result(index, eh->plen, ptr); 19355288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19365288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19375288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CONN_COMPLETE: 193842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg conn_complete(index, ptr); 19395288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19405288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19415288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_DISCONN_COMPLETE: 194242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg disconn_complete(index, ptr); 19435288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19445288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19455288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_AUTH_COMPLETE: 194642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg auth_complete(index, ptr); 19475288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19485288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19495288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_SIMPLE_PAIRING_COMPLETE: 195042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg simple_pairing_complete(index, ptr); 19515288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19525288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19535288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CONN_REQUEST: 195442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg conn_request(index, ptr); 19555288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19565288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LE_META_EVENT: 195742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg le_metaevent(index, ptr); 19585288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19595288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_PIN_CODE_REQ: 196042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg pin_code_request(index, (bdaddr_t *) ptr); 19615288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19625288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19635288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LINK_KEY_REQ: 196442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg link_key_request(index, (bdaddr_t *) ptr); 19655288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19665288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19675288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LINK_KEY_NOTIFY: 196842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg link_key_notify(index, ptr); 19695288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19705288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19715288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_RETURN_LINK_KEYS: 197242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg return_link_keys(index, ptr); 19735288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19745288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19755288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_IO_CAPABILITY_REQUEST: 197642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg io_capa_request(index, ptr); 19775288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19785288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19795288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_IO_CAPABILITY_RESPONSE: 198042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg io_capa_response(index, ptr); 19815288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19825288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19835288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_CONFIRM_REQUEST: 198442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_confirm_request(index, ptr); 19855288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19865288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19875288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_PASSKEY_REQUEST: 198842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_passkey_request(index, ptr); 19895288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19905288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19915288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_PASSKEY_NOTIFY: 199242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_passkey_notify(index, ptr); 19935288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19945288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19955288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_OOB_DATA_REQUEST: 199642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_oob_data_request(index, ptr); 19975288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 19985288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 19995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20005288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 20015288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 20025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20035a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedbergstatic void start_hci_dev(int index) 20045288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2005fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2006fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg GIOChannel *chan = dev->io; 2007e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg GIOCondition cond; 20085288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_filter flt; 20095288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20105288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (chan) 20115288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 20125288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20135a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg info("Listening for HCI events on hci%d", index); 20145288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20155288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Set filter */ 20165288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_clear(&flt); 20175288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 20185288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CMD_STATUS, &flt); 20195288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CMD_COMPLETE, &flt); 20205288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); 20215288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); 20225288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); 20235288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_RETURN_LINK_KEYS, &flt); 20245288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_IO_CAPABILITY_REQUEST, &flt); 20255288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_IO_CAPABILITY_RESPONSE, &flt); 20265288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_CONFIRM_REQUEST, &flt); 20275288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_PASSKEY_REQUEST, &flt); 20285288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_OOB_DATA_REQUEST, &flt); 20295288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_PASSKEY_NOTIFY, &flt); 20305288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_KEYPRESS_NOTIFY, &flt); 20315288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_SIMPLE_PAIRING_COMPLETE, &flt); 20325288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_AUTH_COMPLETE, &flt); 20335288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); 20345288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt); 20355288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); 20365288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_HOST_FEATURES_NOTIFY, &flt); 20375288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); 20385288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); 20395288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); 20405288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); 20415288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CONN_REQUEST, &flt); 20425288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CONN_COMPLETE, &flt); 20435288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt); 20445288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LE_META_EVENT, &flt); 2045fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (setsockopt(dev->sk, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { 20465288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Can't set filter on hci%d: %s (%d)", 20475a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg index, strerror(errno), errno); 20485288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 20495288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 20505288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2051fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg chan = g_io_channel_unix_new(dev->sk); 2052e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg cond = G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR; 2053fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->watch_id = g_io_add_watch_full(chan, G_PRIORITY_LOW, cond, 2054e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg io_security_event, 2055e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg GINT_TO_POINTER(index), NULL); 2056fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->io = chan; 2057fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = -1; 20585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20595288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 20605288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20615288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* End of HCI event callbacks */ 20625288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2063a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodestatic gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data) 2064a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2065a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode int status, fd = g_io_channel_unix_get_fd(io); 2066a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid_t child_pid; 2067a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2068a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) { 2069a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("child_exit: unable to read child pid from pipe"); 2070a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return TRUE; 2071a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2072a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2073a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (waitpid(child_pid, &status, 0) != child_pid) 2074a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("waitpid(%d) failed", child_pid); 2075a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode else 20768e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("child %d exited", child_pid); 2077a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2078a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return TRUE; 2079a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2080a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2081a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodestatic void at_child_exit(void) 2082a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2083a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid_t pid = getpid(); 2084a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2085a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid)) 2086a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("unable to write to child pipe"); 2087a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2088a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2089fccdf4a50765ef5a2dbde00d95f65e94ce0a543bJohan Hedbergstatic void device_devup_setup(int index) 2090a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2091fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2092a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_info di; 20935a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg read_stored_link_key_cp cp; 2094a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 20950e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 20960e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2097ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (hci_devinfo(index, &di) < 0) 2098a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2099a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 210065bf1321203b55b11167ac8b869da28a86ce49d2David Scherba if (ignore_device(&di)) 2101a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2102a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2103fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(&dev->bdaddr, &di.bdaddr); 2104fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->features, di.features, 8); 2105a352058752e541539b09e55124d411a534cc14afJohan Hedberg 2106a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Set page timeout */ 2107a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if ((main_opts.flags & (1 << HCID_SET_PAGETO))) { 2108a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode write_page_timeout_cp cp; 2109a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2110a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode cp.timeout = htobs(main_opts.pageto); 2111fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, 2112a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode WRITE_PAGE_TIMEOUT_CP_SIZE, &cp); 2113a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2114a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 21155a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 21165a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg cp.read_all = 1; 2117fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY, 21185a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg READ_STORED_LINK_KEY_CP_SIZE, (void *) &cp); 2119fccdf4a50765ef5a2dbde00d95f65e94ce0a543bJohan Hedberg 2120fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 21215c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 2122a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2123a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2124be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void init_pending(int index) 2125be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 2126fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2127fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2128fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_BDADDR, &dev->pending); 2129fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_VERSION, &dev->pending); 2130fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_FEATURES, &dev->pending); 2131fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_NAME, &dev->pending); 2132be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 2133be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 2134ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void init_device(int index) 2135a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2136a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_req dr; 2137c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg int dd; 21386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg pid_t pid; 21396844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 21400e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 21410e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 21426844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg dd = hci_open_dev(index); 21436844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (dd < 0) { 21446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Unable to open hci%d: %s (%d)", index, 21456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg strerror(errno), errno); 21466844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return; 21476844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 21486844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 21496844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (index > max_dev) { 21506844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg max_dev = index; 2151ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg devs = g_realloc(devs, sizeof(devs[0]) * (max_dev + 1)); 21526844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 21536844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 21545c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_dev_info(index, dd, FALSE); 2155be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg init_pending(index); 21565a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg start_hci_dev(index); 2157a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2158a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Do initialization in the separate process */ 2159a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid = fork(); 2160a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode switch (pid) { 2161a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case 0: 2162a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode atexit(at_child_exit); 2163a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2164a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case -1: 2165a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Fork failed. Can't init device hci%d: %s (%d)", 2166c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg index, strerror(errno), errno); 2167a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode default: 21688e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("child %d forked", pid); 2169a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2170a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2171a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2172a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode memset(&dr, 0, sizeof(dr)); 2173ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode dr.dev_id = index; 2174a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2175a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Set link mode */ 2176a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode dr.dev_opt = main_opts.link_mode; 2177c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) 2178a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Can't set link mode on hci%d: %s (%d)", 2179ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg index, strerror(errno), errno); 2180a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2181a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Start HCI device */ 2182ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (ioctl(dd, HCIDEVUP, index) < 0 && errno != EALREADY) { 2183a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Can't init device hci%d: %s (%d)", 2184ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode index, strerror(errno), errno); 2185a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode goto fail; 2186a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2187a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2188a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode hci_close_dev(dd); 2189a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode exit(0); 2190a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2191a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodefail: 2192a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode hci_close_dev(dd); 2193a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode exit(1); 2194a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2195a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2196ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void device_devreg_setup(int index) 2197a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2198a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_info di; 2199a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 22000e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 22010e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2202ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode init_device(index); 2203a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2204a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode memset(&di, 0, sizeof(di)); 2205a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2206ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (hci_devinfo(index, &di) < 0) 2207a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2208a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 22095c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (ignore_device(&di)) 22105c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return; 2211a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2212fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].already_up = hci_test_bit(HCI_UP, &di.flags); 2213a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2214a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2215ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void device_event(int event, int index) 2216a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2217a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode switch (event) { 2218a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_REG: 2219ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d registered", index); 2220ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode device_devreg_setup(index); 2221fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (devs[index].already_up) 22225c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg device_event(HCI_DEV_UP, index); 2223a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2224a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2225a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_UNREG: 2226ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d unregistered", index); 222755694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 2228fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (devs[index].registered) 22295c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_manager_unregister_adapter(index); 2230a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2231a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2232a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_UP: 2233ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d up", index); 2234fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].up = TRUE; 2235ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode device_devup_setup(index); 2236a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2237a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2238a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_DOWN: 2239ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d down", index); 2240fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].up = FALSE; 2241fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].pending_cod = 0; 2242fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].cache_enable = TRUE; 2243fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!devs[index].pending) { 224465edd4d5397d00d204123432fd83326486860783Johan Hedberg struct btd_adapter *adapter; 224565edd4d5397d00d204123432fd83326486860783Johan Hedberg 224665edd4d5397d00d204123432fd83326486860783Johan Hedberg adapter = manager_find_adapter(&devs[index].bdaddr); 224765edd4d5397d00d204123432fd83326486860783Johan Hedberg if (adapter) 224865edd4d5397d00d204123432fd83326486860783Johan Hedberg btd_adapter_stop(index); 224965edd4d5397d00d204123432fd83326486860783Johan Hedberg 2250be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg init_pending(index); 22515a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg } 2252a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2253a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2254a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2255cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 22565c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_stop_inquiry(int index) 22575c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 2258fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 22595c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg struct hci_dev_info di; 22605c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg int err; 22615c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 22625c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d", index); 22635c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 22645c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (hci_devinfo(index, &di) < 0) 22655c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return -errno; 22665c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 22675c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (hci_test_bit(HCI_INQUIRY, &di.flags)) 2268fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 22695c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg OCF_INQUIRY_CANCEL, 0, 0); 22705c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg else 2271fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 22725c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg OCF_EXIT_PERIODIC_INQUIRY, 0, 0); 22735c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (err < 0) 22745c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg err = -errno; 22755c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 22765c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return err; 22775c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 22785c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2279f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedbergstatic gboolean init_known_adapters(gpointer user_data) 228094e91856179a268805256055ffd5155d1468b99cAlok Barsode{ 2281cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_dev_list_req *dl; 2282cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_dev_req *dr; 2283f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg int i, err, ctl = GPOINTER_TO_INT(user_data); 2284ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg size_t req_size; 2285cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 22860e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 22870e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2288ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg req_size = HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t); 2289ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg 2290ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg dl = g_try_malloc0(req_size); 2291cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (!dl) { 2292ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg error("Can't allocate devlist buffer"); 2293f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 2294cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2295cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2296cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode dl->dev_num = HCI_MAX_DEV; 2297cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode dr = dl->dev_req; 2298cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2299ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg if (ioctl(ctl, HCIGETDEVLIST, dl) < 0) { 2300c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2301ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg error("Can't get device list: %s (%d)", strerror(-err), -err); 230283003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi g_free(dl); 2303f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 2304cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2305cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2306cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode for (i = 0; i < dl->dev_num; i++, dr++) { 2307fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev; 2308fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2309cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode device_event(HCI_DEV_REG, dr->dev_id); 2310cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2311fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev = &devs[dr->dev_id]; 2312fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2313fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->already_up = hci_test_bit(HCI_UP, &dr->dev_opt); 23145c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2315fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->already_up) 2316be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg continue; 2317be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 23185c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg hciops_stop_inquiry(dr->dev_id); 23195c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2320fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pending = 0; 2321fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_VERSION, &dev->pending); 2322fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_INFO_PARAM, 2323be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg OCF_READ_LOCAL_VERSION, 0, NULL); 2324be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg device_event(HCI_DEV_UP, dr->dev_id); 2325cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2326cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2327cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_free(dl); 2328f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg 2329f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 233094e91856179a268805256055ffd5155d1468b99cAlok Barsode} 233194e91856179a268805256055ffd5155d1468b99cAlok Barsode 2332cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsodestatic gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, 2333cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode gpointer data) 2334cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode{ 2335cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; 2336cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode evt_stack_internal *si; 2337cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode evt_si_device *sd; 2338cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_event_hdr *eh; 2339cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode int type; 2340cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode size_t len; 2341cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode GIOError err; 2342cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2343cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ptr = buf; 2344cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2345cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len); 2346cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (err) { 2347cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (err == G_IO_ERROR_AGAIN) 2348cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2349cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2350cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode error("Read from control socket failed: %s (%d)", 2351ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg strerror(errno), errno); 2352cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return FALSE; 2353cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2354cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2355cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode type = *ptr++; 2356cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2357cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (type != HCI_EVENT_PKT) 2358cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2359cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2360cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode eh = (hci_event_hdr *) ptr; 2361cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (eh->evt != EVT_STACK_INTERNAL) 2362cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2363cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2364cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ptr += HCI_EVENT_HDR_SIZE; 2365cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2366cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode si = (evt_stack_internal *) ptr; 2367cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode switch (si->type) { 2368cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode case EVT_SI_DEVICE: 2369cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode sd = (void *) &si->data; 2370cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode device_event(sd->event, sd->dev_id); 2371cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode break; 2372cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2373cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2374cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2375cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode} 2376cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 237734c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic int hciops_setup(void) 2378cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode{ 2379cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct sockaddr_hci addr; 2380cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_filter flt; 2381a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode GIOChannel *ctl_io, *child_io; 238218e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg int sock, err; 238318e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg 23840e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 23850e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 238618e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg if (child_pipe[0] != -1) 238718e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg return -EALREADY; 2388cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2389a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (pipe(child_pipe) < 0) { 2390c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2391c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("pipe(): %s (%d)", strerror(-err), -err); 2392c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2393a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2394a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2395a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode child_io = g_io_channel_unix_new(child_pipe[0]); 2396a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode g_io_channel_set_close_on_unref(child_io, TRUE); 23978b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_io_id = g_io_add_watch(child_io, 23988b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, 23998b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_exit, NULL); 2400a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode g_io_channel_unref(child_io); 2401a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2402cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode /* Create and bind HCI socket */ 2403cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); 2404cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (sock < 0) { 2405c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2406c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("Can't open HCI socket: %s (%d)", strerror(-err), 2407c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg -err); 2408c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2409cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2410cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2411cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode /* Set filter */ 2412cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_clear(&flt); 2413cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 2414cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_set_event(EVT_STACK_INTERNAL, &flt); 24156844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { 2416c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2417c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("Can't set filter: %s (%d)", strerror(-err), -err); 2418c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2419cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2420cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2421cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode memset(&addr, 0, sizeof(addr)); 2422cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode addr.hci_family = AF_BLUETOOTH; 2423cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode addr.hci_dev = HCI_DEV_NONE; 24246844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 2425c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 24266844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Can't bind HCI socket: %s (%d)", strerror(-err), -err); 2427c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2428cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2429cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2430cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ctl_io = g_io_channel_unix_new(sock); 2431cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_io_channel_set_close_on_unref(ctl_io, TRUE); 2432cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 24338b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL); 2434cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2435cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_io_channel_unref(ctl_io); 2436cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2437f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg g_idle_add(init_known_adapters, GINT_TO_POINTER(sock)); 2438f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg 2439f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return 0; 2440cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode} 2441cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 244234c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic void hciops_cleanup(void) 244334c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode{ 24446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int i; 24456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 24460e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 24470e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2448b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg for (i = 0; i <= max_dev; i++) 2449b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg stop_hci_dev(i); 24506844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 24516844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg g_free(devs); 24526844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg devs = NULL; 24536844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg max_dev = -1; 24546844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 24558b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_io_id) { 24568b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg g_source_remove(child_io_id); 24578b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_io_id = 0; 24588b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 24598b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 24608b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (ctl_io_id) { 24618b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg g_source_remove(ctl_io_id); 24628b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg ctl_io_id = 0; 24638b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 24648b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 24658b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_pipe[0] >= 0) { 24668b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg close(child_pipe[0]); 24678b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_pipe[0] = -1; 24688b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 24698b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 24708b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_pipe[1] >= 0) { 24718b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg close(child_pipe[1]); 24728b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_pipe[1] = -1; 24738b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 247434c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode} 247534c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode 247663ff6738abc6bf21becbbfde583062502e7728a6Johan Hedbergstatic int hciops_power_on(int index, gboolean discoverable) 2477076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode{ 2478fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 24796844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2480076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 24810e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 24820e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2483fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIDEVUP, index) == 0) 24846844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2485076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 24866844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (errno == EALREADY) 24876844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2488076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 24896844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 24906844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Can't init device hci%d: %s (%d)", 24916844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg index, strerror(-err), -err); 2492076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 2493c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2494076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode} 2495076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 24965c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_set_connectable(int index, gboolean connectable) 24978b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode{ 2498fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 24995c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg uint8_t mode; 25008b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode 25015c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (connectable) 25025c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = SCAN_PAGE; 25035c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg else 25045c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = 0x00; 25055c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 25065c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d connectable %d", index, connectable); 25070e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2508fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 25096844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_SCAN_ENABLE, 1, &mode) < 0) 25106844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 25118b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode 25126844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 25138b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode} 25148b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode 251500c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_set_dev_class(int index, uint8_t major, uint8_t minor) 2516d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode{ 2517fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 251800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int err; 2519d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 25205c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d major %u minor %u", index, major, minor); 25215c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 252200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Update only the major and minor class bits keeping remaining bits 252300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * intact*/ 2524fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod &= 0xffe000; 2525fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod |= ((major & 0x1f) << 8) | minor; 2526d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 2527fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->wanted_cod == dev->current_cod || 2528fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->cache_enable || dev->pending_cod) 252900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 25300e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2531fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg DBG("Changing Major/Minor class to 0x%06x", dev->wanted_cod); 2532eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode 2533fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = write_class(index, dev->wanted_cod); 253400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (err < 0) 253500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg error("Adapter class update failed: %s (%d)", 253600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg strerror(-err), -err); 2537d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 253800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return err; 2539eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode} 2540eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode 25413af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasistatic int hciops_start_inquiry(int index, uint8_t length, gboolean periodic) 2542a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode{ 2543fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2544a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; 25456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2546a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 25470e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d length %u periodic %d", index, length, periodic); 25480e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2549a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode if (periodic) { 2550a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode periodic_inquiry_cp cp; 2551a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2552a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memset(&cp, 0, sizeof(cp)); 2553a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memcpy(&cp.lap, lap, 3); 2554a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.max_period = htobs(24); 2555a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.min_period = htobs(16); 2556388cdea43870fe5c5163cfbe96d3218111ba39b5Claudio Takahasi cp.length = length; 2557a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.num_rsp = 0x00; 2558a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2559fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 25606844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_PERIODIC_INQUIRY, 25616844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg PERIODIC_INQUIRY_CP_SIZE, &cp); 2562a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode } else { 2563a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode inquiry_cp inq_cp; 2564a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2565a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memset(&inq_cp, 0, sizeof(inq_cp)); 2566a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memcpy(&inq_cp.lap, lap, 3); 2567388cdea43870fe5c5163cfbe96d3218111ba39b5Claudio Takahasi inq_cp.length = length; 2568a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode inq_cp.num_rsp = 0x00; 2569a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2570fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 25716844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_INQUIRY, INQUIRY_CP_SIZE, &inq_cp); 2572a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode } 2573a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2574a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode if (err < 0) 2575a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode err = -errno; 2576a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2577a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode return err; 2578a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode} 2579a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 25803ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int le_set_scan_enable(int index, uint8_t enable) 258170cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi{ 2582fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 25833ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi le_set_scan_enable_cp cp; 25843ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 25850e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d enable %u", index, enable); 25860e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 25873ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi memset(&cp, 0, sizeof(cp)); 25883ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.enable = enable; 25893ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.filter_dup = 0; 259070cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 2591fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE, 25923ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi LE_SET_SCAN_ENABLE_CP_SIZE, &cp) < 0) 25936844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 259470cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 25956844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 259670cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi} 259770cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 25983ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int hciops_start_scanning(int index) 259970cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi{ 2600fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 26013ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi le_set_scan_parameters_cp cp; 26023ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 26030e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 26040e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 26053ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi memset(&cp, 0, sizeof(cp)); 26063ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.type = 0x01; /* Active scanning */ 26073ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.interval = htobs(0x0010); 26083ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.window = htobs(0x0010); 26093ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.own_bdaddr_type = 0; /* Public address */ 26103ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.filter = 0; /* Accept all adv packets */ 26113ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 2612fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LE_CTL, OCF_LE_SET_SCAN_PARAMETERS, 26133ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi LE_SET_SCAN_PARAMETERS_CP_SIZE, &cp) < 0) 261470cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi return -errno; 261570cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 26163ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi return le_set_scan_enable(index, 1); 26173ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi} 26183ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 26193ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int hciops_stop_scanning(int index) 26203ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi{ 26210e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 26220e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 26233ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi return le_set_scan_enable(index, 0); 262470cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi} 262570cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 2626ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsodestatic int hciops_resolve_name(int index, bdaddr_t *bdaddr) 2627ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode{ 2628fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2629ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode remote_name_req_cp cp; 26300e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 26310e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 26320e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 26330e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 2634ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 2635ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode memset(&cp, 0, sizeof(cp)); 2636ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode bacpy(&cp.bdaddr, bdaddr); 2637ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode cp.pscan_rep_mode = 0x02; 2638ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 2639fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ, 26406844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg REMOTE_NAME_REQ_CP_SIZE, &cp) < 0) 26416844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2642ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 26436844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2644ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode} 2645ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 2646164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsodestatic int hciops_set_name(int index, const char *name) 2647164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode{ 2648fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2649164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode change_local_name_cp cp; 2650164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 26510e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d, name %s", index, name); 26520e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2653164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode memset(&cp, 0, sizeof(cp)); 2654164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode strncpy((char *) cp.name, name, sizeof(cp.name)); 2655164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 2656fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, 26576844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg CHANGE_LOCAL_NAME_CP_SIZE, &cp) < 0) 26586844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2659164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 2660fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->name, cp.name, 248); 266100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 266200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 26636844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2664164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode} 2665164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 2666b96f44db8e91325968a0149595b2522d4a22481aAlok Barsodestatic int hciops_cancel_resolve_name(int index, bdaddr_t *bdaddr) 2667b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode{ 2668fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2669b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode remote_name_req_cancel_cp cp; 26700e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 26710e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 26720e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 26730e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 2674b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 2675b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode memset(&cp, 0, sizeof(cp)); 2676b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode bacpy(&cp.bdaddr, bdaddr); 2677b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 2678fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL, 26796844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg REMOTE_NAME_REQ_CANCEL_CP_SIZE, &cp) < 0) 26806844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2681b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 26826844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2683b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode} 2684b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 268561f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliystatic int hciops_fast_connectable(int index, gboolean enable) 268661f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy{ 2687fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 268861f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy write_page_activity_cp cp; 268961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy uint8_t type; 269061f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 26910e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d enable %d", index, enable); 26920e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 269361f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy if (enable) { 269461f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy type = PAGE_SCAN_TYPE_INTERLACED; 269561f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.interval = 0x0024; /* 22.5 msec page scan interval */ 269661f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy } else { 269761f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy type = PAGE_SCAN_TYPE_STANDARD; /* default */ 269861f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.interval = 0x0800; /* default 1.28 sec page scan */ 269961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy } 270061f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 270161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.window = 0x0012; /* default 11.25 msec page scan window */ 270261f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 2703fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_PAGE_ACTIVITY, 270461f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy WRITE_PAGE_ACTIVITY_CP_SIZE, &cp) < 0) 27056844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2706fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg else if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 27076844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_PAGE_SCAN_TYPE, 1, &type) < 0) 27086844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 270961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 27106844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 271161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy} 271261f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 27136b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedbergstatic int hciops_read_clock(int index, bdaddr_t *bdaddr, int which, 271458b68d33c5fad024f2b235555be0234e97721920Johan Hedberg int timeout, uint32_t *clock, 271558b68d33c5fad024f2b235555be0234e97721920Johan Hedberg uint16_t *accuracy) 27165bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter{ 2717fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 27186b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg uint16_t handle = 0; 27196b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg char addr[18]; 27206b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg int ret; 2721fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 27226b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg ba2str(bdaddr, addr); 27236b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg DBG("hci%d addr %s which %d timeout %d", index, addr, which, timeout); 27246b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg 27256b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg ret = get_handle(index, bdaddr, &handle); 27266b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg if (ret < 0) 27276b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg return ret; 27280e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 272958b68d33c5fad024f2b235555be0234e97721920Johan Hedberg if (hci_read_clock(dev->sk, htobs(handle), which, clock, accuracy, 27306844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg timeout) < 0) 27316844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 27325bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 27336844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 27345bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter} 27355bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 2736b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedbergstatic int hciops_read_bdaddr(int index, bdaddr_t *bdaddr) 2737b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg{ 2738fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2739fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 27400e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 2741fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2742fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(bdaddr, &dev->bdaddr); 2743fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 27446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2745b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg} 2746b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg 2747885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedbergstatic int hciops_block_device(int index, bdaddr_t *bdaddr) 2748885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg{ 2749fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 27500e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 27510e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 27520e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 27530e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 27540e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2755fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIBLOCKADDR, bdaddr) < 0) 2756885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg return -errno; 2757885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 27586844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2759885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg} 2760885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 2761885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedbergstatic int hciops_unblock_device(int index, bdaddr_t *bdaddr) 2762885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg{ 2763fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 27640e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 27650e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 27660e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 27670e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 27680e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2769fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIUNBLOCKADDR, bdaddr) < 0) 2770885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg return -errno; 2771885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 27726844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2773885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg} 2774885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 2775f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedbergstatic int hciops_get_conn_list(int index, GSList **conns) 2776f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg{ 2777fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2778f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg struct hci_conn_list_req *cl; 2779f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg struct hci_conn_info *ci; 27806844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err, i; 2781f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 27820e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 27830e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2784f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); 2785f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2786f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg cl->dev_id = index; 2787f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg cl->conn_num = 10; 2788f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg ci = cl->conn_info; 2789f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2790fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETCONNLIST, cl) < 0) { 2791f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg err = -errno; 2792f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg goto fail; 2793f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg } 2794f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2795f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg err = 0; 2796f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg *conns = NULL; 2797f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2798f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg for (i = 0; i < cl->conn_num; i++, ci++) 2799f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg *conns = g_slist_append(*conns, g_memdup(ci, sizeof(*ci))); 2800f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2801f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedbergfail: 2802f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg g_free(cl); 2803f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg return err; 2804f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg} 2805f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2806e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedbergstatic int hciops_read_local_version(int index, struct hci_version *ver) 2807e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg{ 2808fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2809fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 28100e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 2811fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2812fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(ver, &dev->ver, sizeof(*ver)); 2813fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 28146844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2815e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg} 2816e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg 281748e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedbergstatic int hciops_read_local_features(int index, uint8_t *features) 281848e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg{ 2819fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2820fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 28210e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 2822fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2823fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(features, dev->features, 8); 2824fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 28256844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 282648e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg} 282748e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg 282806dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedbergstatic int hciops_disconnect(int index, uint16_t handle) 282906dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg{ 2830fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 283106dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg disconnect_cp cp; 283206dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 28330e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d handle %u", index, handle); 28340e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 283506dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg memset(&cp, 0, sizeof(cp)); 283606dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg cp.handle = htobs(handle); 283706dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg cp.reason = HCI_OE_USER_ENDED_CONNECTION; 283806dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 2839fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_DISCONNECT, 284006dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg DISCONNECT_CP_SIZE, &cp) < 0) 28416844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 284206dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 28436844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 284406dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg} 284506dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 28461bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedbergstatic int hciops_remove_bonding(int index, bdaddr_t *bdaddr) 28471bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg{ 2848fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 284973c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg delete_stored_link_key_cp cp; 2850b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg GSList *match; 28510e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 28520e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 28530e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 28540e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 28551bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 2856b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg match = g_slist_find_custom(dev->keys, bdaddr, (GCompareFunc) bacmp); 2857b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (match) { 2858b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_free(match->data); 2859b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg dev->keys = g_slist_delete_link(dev->keys, match); 2860b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg } 2861b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 286273c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg memset(&cp, 0, sizeof(cp)); 286373c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg bacpy(&cp.bdaddr, bdaddr); 286473c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg 28651bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg /* Delete the link key from the Bluetooth chip */ 2866fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_DELETE_STORED_LINK_KEY, 286773c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg DELETE_STORED_LINK_KEY_CP_SIZE, &cp) < 0) 28686844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 28691bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 28706844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 28711bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg} 28721bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 2873c3ebed5a7d7e6146e7dfb97f6597222f1f9f0e71Johan Hedbergstatic int hciops_request_authentication(int index, uint16_t handle) 2874424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg{ 2875fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2876424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg auth_requested_cp cp; 2877424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 28780e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d handle %u", index, handle); 2879424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2880424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg memset(&cp, 0, sizeof(cp)); 2881424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg cp.handle = htobs(handle); 2882424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2883fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_AUTH_REQUESTED, 2884c3ebed5a7d7e6146e7dfb97f6597222f1f9f0e71Johan Hedberg AUTH_REQUESTED_CP_SIZE, &cp) < 0) 28856844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2886424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 28876844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2888424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg} 2889424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2890e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedbergstatic int hciops_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin) 2891e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg{ 2892fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 28930e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 28946844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2895e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 28960e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 28970e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 28980e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2899e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg if (pin) { 2900e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg pin_code_reply_cp pr; 2901e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg size_t len = strlen(pin); 2902e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 2903fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = len; 290442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 2905e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg memset(&pr, 0, sizeof(pr)); 2906e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg bacpy(&pr.bdaddr, bdaddr); 2907e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg memcpy(pr.pin_code, pin, len); 2908e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg pr.pin_len = len; 2909fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 29106844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_PIN_CODE_REPLY, 2911e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg PIN_CODE_REPLY_CP_SIZE, &pr); 2912e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg } else 2913fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 2914e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg OCF_PIN_CODE_NEG_REPLY, 6, bdaddr); 2915e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 29166844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 29176844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 2918e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 2919e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg return err; 2920e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg} 2921e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 2922df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedbergstatic int hciops_confirm_reply(int index, bdaddr_t *bdaddr, gboolean success) 2923df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg{ 2924fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2925df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg user_confirm_reply_cp cp; 29260e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 29270e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg int err; 29280e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 29290e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 29300e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s success %d", index, addr, success); 2931df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2932df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg memset(&cp, 0, sizeof(cp)); 2933df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 2934df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2935df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg if (success) 2936fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 29376844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_USER_CONFIRM_REPLY, 2938df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg USER_CONFIRM_REPLY_CP_SIZE, &cp); 2939df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg else 2940fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 2941df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg OCF_USER_CONFIRM_NEG_REPLY, 2942df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg USER_CONFIRM_REPLY_CP_SIZE, &cp); 2943df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 29446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 29456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 2946df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2947df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg return err; 2948df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg} 2949df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2950889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedbergstatic int hciops_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey) 2951889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg{ 2952fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 29530e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 29546844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2955889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 29560e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 29570e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 29580e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2959889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg if (passkey != INVALID_PASSKEY) { 2960889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg user_passkey_reply_cp cp; 2961889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 2962889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg memset(&cp, 0, sizeof(cp)); 2963889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg bacpy(&cp.bdaddr, bdaddr); 2964889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg cp.passkey = passkey; 2965889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 2966fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 29676844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_USER_PASSKEY_REPLY, 2968889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg USER_PASSKEY_REPLY_CP_SIZE, &cp); 2969889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg } else 2970fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 2971889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg OCF_USER_PASSKEY_NEG_REPLY, 6, bdaddr); 2972889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 29736844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 29746844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 2975889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 2976889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg return err; 2977889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg} 2978889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 29794b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedbergstatic int hciops_get_auth_info(int index, bdaddr_t *bdaddr, uint8_t *auth) 29804b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg{ 2981fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 29824b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg struct hci_auth_info_req req; 29830e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 29840e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 29850e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 29860e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 29874b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 29884b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg memset(&req, 0, sizeof(req)); 29894b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg bacpy(&req.bdaddr, bdaddr); 29904b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 2991fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETAUTHINFO, (unsigned long) &req) < 0) 29926844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 29934b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 29944b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg if (auth) 29954b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg *auth = req.type; 29964b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 29976844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 29984b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg} 29994b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 3000f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedbergstatic int hciops_read_scan_enable(int index) 3001f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg{ 3002fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3003fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 30040e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 30050e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3006fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_READ_SCAN_ENABLE, 30076844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 0, NULL) < 0) 3008f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg return -errno; 3009f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg 30106844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 3011f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg} 3012f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg 30135c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_enable_le(int index) 30147ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi{ 3015fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 30167ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi write_le_host_supported_cp cp; 30177ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 30185c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d", index); 30195c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3020fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[4] & LMP_LE)) 30215c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return -ENOTSUP; 30220e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 30235c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg cp.le = 0x01; 3024fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg cp.simul = (dev->features[6] & LMP_LE_BREDR) ? 0x01 : 0x00; 30257ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 3026fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 30276844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_LE_HOST_SUPPORTED, 30286844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg WRITE_LE_HOST_SUPPORTED_CP_SIZE, &cp) < 0) 30296844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 30307ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 30316844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 30327ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi} 30337ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 303400c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int set_service_classes(int index, uint8_t value) 303500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 3036fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 303700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int err; 303800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 30395c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d value %u", index, value); 30405c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 304100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Update only the service class, keep the limited bit, 304200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * major/minor class bits intact */ 3043fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod &= 0x00ffff; 3044fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod |= (value << 16); 304500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 304600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* If the cache is enabled or an existing CoD write is in progress 304700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * just bail out */ 3048fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->cache_enable || dev->pending_cod) 304900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 305000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 305100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* If we already have the CoD we want, update EIR and return */ 3052fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->current_cod == dev->wanted_cod) { 305300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 305400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 305500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 305600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3057fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg DBG("Changing service classes to 0x%06x", dev->wanted_cod); 305800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3059fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = write_class(index, dev->wanted_cod); 306000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (err < 0) 306100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg error("Adapter class update failed: %s (%d)", 306200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg strerror(-err), -err); 306300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 306400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return err; 306500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 306600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 306700c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_services_updated(int index) 306800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 3069fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 307000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg struct btd_adapter *adapter; 307100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg sdp_list_t *list; 307200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t val = 0; 307300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 307400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d", index); 307500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3076fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 307700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (adapter == NULL) 307800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return -ENODEV; 307900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 308000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (list = adapter_get_services(adapter); list; list = list->next) { 30815c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg sdp_record_t *rec = list->data; 308200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 308300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (rec->svclass.type != SDP_UUID16) 308400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 308500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 308600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg switch (rec->svclass.value.uuid16) { 308700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case DIALUP_NET_SVCLASS_ID: 308800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case CIP_SVCLASS_ID: 308900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x42; /* Telephony & Networking */ 309000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 309100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case IRMC_SYNC_SVCLASS_ID: 309200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case OBEX_OBJPUSH_SVCLASS_ID: 309300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case OBEX_FILETRANS_SVCLASS_ID: 309400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case IRMC_SYNC_CMD_SVCLASS_ID: 309500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case PBAP_PSE_SVCLASS_ID: 309600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x10; /* Object Transfer */ 309700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 309800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case HEADSET_SVCLASS_ID: 309900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case HANDSFREE_SVCLASS_ID: 310000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x20; /* Audio */ 310100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 310200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case CORDLESS_TELEPHONY_SVCLASS_ID: 310300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case INTERCOM_SVCLASS_ID: 310400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case FAX_SVCLASS_ID: 310500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case SAP_SVCLASS_ID: 310600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* 310700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * Setting the telephony bit for the handsfree audio gateway 310800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * role is not required by the HFP specification, but the 310900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * Nokia 616 carkit is just plain broken! It will refuse 311000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * pairing without this bit set. 311100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg */ 311200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case HANDSFREE_AGW_SVCLASS_ID: 311300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x40; /* Telephony */ 311400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 311500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case AUDIO_SOURCE_SVCLASS_ID: 311600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case VIDEO_SOURCE_SVCLASS_ID: 311700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x08; /* Capturing */ 311800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 311900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case AUDIO_SINK_SVCLASS_ID: 312000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case VIDEO_SINK_SVCLASS_ID: 312100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x04; /* Rendering */ 312200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 312300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case PANU_SVCLASS_ID: 312400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case NAP_SVCLASS_ID: 312500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg case GN_SVCLASS_ID: 312600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg val |= 0x02; /* Networking */ 312700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 312800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 312900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 313000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 313100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return set_service_classes(index, val); 313200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 313300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 313400c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_disable_cod_cache(int index) 313500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 3136fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 313700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3138fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg DBG("hci%d cache_enable %d", index, dev->cache_enable); 3139fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 3140fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->cache_enable) 314100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 314200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 314300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d current_cod 0x%06x wanted_cod 0x%06x", index, 3144fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->current_cod, dev->wanted_cod); 314500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 314600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Disable and flush svc cache. All successive service class 314700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * updates * will be written to the device */ 3148fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->cache_enable = FALSE; 314900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3150fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->current_cod == dev->wanted_cod) { 315100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 315200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 315300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 315400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3155fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg return write_class(index, dev->wanted_cod); 315600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 315700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 31585c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_restore_powered(int index) 31595c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 3160fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3161fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 3162fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->already_up && dev->up) 316363ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg return hciops_power_off(index); 31645c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 31655c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return 0; 31665c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 31675c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3168b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedbergstatic int hciops_load_keys(int index, GSList *keys) 3169b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg{ 3170b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg struct dev_info *dev = &devs[index]; 3171b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 3172b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg DBG("hci%d keys %d", index, g_slist_length(keys)); 3173b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 3174b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (dev->keys != NULL) 3175b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg return -EEXIST; 3176b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 3177b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg dev->keys = keys; 3178b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 3179b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg return 0; 3180b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg} 3181b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 318234c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic struct btd_adapter_ops hci_ops = { 318334c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode .setup = hciops_setup, 318434c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode .cleanup = hciops_cleanup, 318563ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg .power_on = hciops_power_on, 318663ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg .power_off = hciops_power_off, 31875c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .set_connectable = hciops_set_connectable, 31885c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .set_discoverable = hciops_set_discoverable, 31895c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .set_pairable = hciops_set_pairable, 3190eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode .set_limited_discoverable = hciops_set_limited_discoverable, 31913af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasi .start_inquiry = hciops_start_inquiry, 31923af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasi .stop_inquiry = hciops_stop_inquiry, 319370cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi .start_scanning = hciops_start_scanning, 319470cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi .stop_scanning = hciops_stop_scanning, 3195ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode .resolve_name = hciops_resolve_name, 3196b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode .cancel_resolve_name = hciops_cancel_resolve_name, 3197164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode .set_name = hciops_set_name, 319800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .set_dev_class = hciops_set_dev_class, 319961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy .set_fast_connectable = hciops_fast_connectable, 32005bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter .read_clock = hciops_read_clock, 3201b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg .read_bdaddr = hciops_read_bdaddr, 3202885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg .block_device = hciops_block_device, 3203885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg .unblock_device = hciops_unblock_device, 3204f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg .get_conn_list = hciops_get_conn_list, 3205e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg .read_local_version = hciops_read_local_version, 320648e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg .read_local_features = hciops_read_local_features, 320706dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg .disconnect = hciops_disconnect, 32081bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg .remove_bonding = hciops_remove_bonding, 3209424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg .request_authentication = hciops_request_authentication, 3210e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg .pincode_reply = hciops_pincode_reply, 3211df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg .confirm_reply = hciops_confirm_reply, 3212889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg .passkey_reply = hciops_passkey_reply, 32134b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg .get_auth_info = hciops_get_auth_info, 3214f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg .read_scan_enable = hciops_read_scan_enable, 32155c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .enable_le = hciops_enable_le, 3216abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg .encrypt_link = hciops_encrypt_link, 321700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .set_did = hciops_set_did, 321800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .services_updated = hciops_services_updated, 321900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .disable_cod_cache = hciops_disable_cod_cache, 32205c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .restore_powered = hciops_restore_powered, 3221b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg .load_keys = hciops_load_keys, 322234c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode}; 322334c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode 322434c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic int hciops_init(void) 322534c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode{ 32260e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 3227d30044157466e7f34e7f2d5d7ce70215ea013338Johan Hedberg return btd_register_adapter_ops(&hci_ops, FALSE); 322834c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode} 3229d57934d1d09c34d1b136c572cad1dff6306c8c48Johan Hedberg 323094e91856179a268805256055ffd5155d1468b99cAlok Barsodestatic void hciops_exit(void) 323194e91856179a268805256055ffd5155d1468b99cAlok Barsode{ 32320e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 3233929393b82db06368ff5fa4074bc209d1d4d03a48Marcel Holtmann btd_adapter_cleanup_ops(&hci_ops); 323494e91856179a268805256055ffd5155d1468b99cAlok Barsode} 323594e91856179a268805256055ffd5155d1468b99cAlok Barsode 323694e91856179a268805256055ffd5155d1468b99cAlok BarsodeBLUETOOTH_PLUGIN_DEFINE(hciops, VERSION, 32371ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann BLUETOOTH_PLUGIN_PRIORITY_LOW, hciops_init, hciops_exit) 3238