hciops.c revision ab8a3b836133345ce2e29f4a079aaff1f5a33b70
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> 383e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg#include <bluetooth/sdp.h> 393e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg#include <bluetooth/sdp_lib.h> 4094e91856179a268805256055ffd5155d1468b99cAlok Barsode 41cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <glib.h> 42cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 43cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include "hcid.h" 44a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include "sdpd.h" 45b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg#include "btio.h" 46a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include "adapter.h" 4750fb53c4a7520e210244d909be9ef1accf5cfdfeVinicius Costa Gomes#include "device.h" 4894e91856179a268805256055ffd5155d1468b99cAlok Barsode#include "plugin.h" 49e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h" 505288199788ecb17183d6517da3062cd94692a900Johan Hedberg#include "storage.h" 515288199788ecb17183d6517da3062cd94692a900Johan Hedberg#include "event.h" 52a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include "manager.h" 53a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 5418e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedbergstatic int child_pipe[2] = { -1, -1 }; 5594e91856179a268805256055ffd5155d1468b99cAlok Barsode 568b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedbergstatic guint child_io_id = 0; 578b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedbergstatic guint ctl_io_id = 0; 588b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 59be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg/* Commands sent by kernel on starting an adapter */ 60be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergenum { 61be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING_BDADDR, 62be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING_VERSION, 63be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING_FEATURES, 64fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg PENDING_NAME, 65be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg}; 66be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 67006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedbergstruct uuid_info { 68006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg uuid_t uuid; 69006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg uint8_t svc_hint; 70006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg}; 71006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg 72b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstruct bt_conn { 73b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct dev_info *dev; 74bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg bdaddr_t bdaddr; 75bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg uint16_t handle; 76b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint8_t loc_cap; 77b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint8_t loc_auth; 78b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint8_t rem_cap; 79b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint8_t rem_auth; 80b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg gboolean bonding_initiator; 81b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg gboolean secmode3; 82b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg GIOChannel *io; /* For raw L2CAP socket (bonding) */ 83bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg}; 84bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 856844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedbergstatic int max_dev = -1; 86ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedbergstatic struct dev_info { 87b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg int id; 88ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg int sk; 89a352058752e541539b09e55124d411a534cc14afJohan Hedberg bdaddr_t bdaddr; 9000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg char name[249]; 9100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t eir[240]; 92be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg uint8_t features[8]; 9300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t ssp_mode; 9400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 9500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int8_t tx_power; 9600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 9700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint32_t current_cod; 9800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint32_t wanted_cod; 9900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint32_t pending_cod; 10000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg gboolean cache_enable; 1015c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg gboolean already_up; 1025c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg gboolean registered; 103b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg gboolean pairable; 104b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 105b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint8_t io_capability; 10600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 107be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg struct hci_version ver; 108be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 10900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t did_vendor; 11000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t did_product; 11100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t did_version; 11200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1135a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg gboolean up; 114ab8a3b836133345ce2e29f4a079aaff1f5a33b70Rafal Michalski uint32_t pending; 11555694454017b04a416931a81964bb695f48b3d93Johan Hedberg 116fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg GIOChannel *io; 11755694454017b04a416931a81964bb695f48b3d93Johan Hedberg guint watch_id; 118b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 119dccef4954d8dcaa4559be66263ea0945cd9be528Johan Hedberg gboolean debug_keys; 120b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg GSList *keys; 1211522d6568002afa27ee7a3280b3166f7ecb02f06Johan Hedberg uint8_t pin_length; 1223e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg 1233e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg GSList *uuids; 124bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 125bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg GSList *connections; 126ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg} *devs = NULL; 127ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg 128db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedbergstatic int ignore_device(struct hci_dev_info *di) 129db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg{ 130db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR; 131db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg} 132db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg 13371ba00415bd2941db24958d1e6e265611945194eJohan Hedbergstatic struct dev_info *init_dev_info(int index, int sk, gboolean registered, 134149f5d0b49d7c52e64e3c63505f689a9f872af8bLuiz Augusto von Dentz gboolean already_up) 135ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg{ 136fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 137fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 138fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memset(dev, 0, sizeof(*dev)); 139fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 140b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg dev->id = index; 141fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->sk = sk; 142fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->cache_enable = TRUE; 143fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->registered = registered; 144149f5d0b49d7c52e64e3c63505f689a9f872af8bLuiz Augusto von Dentz dev->already_up = already_up; 145b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg dev->io_capability = 0x03; /* No Input No Output */ 14671ba00415bd2941db24958d1e6e265611945194eJohan Hedberg 14771ba00415bd2941db24958d1e6e265611945194eJohan Hedberg return dev; 148ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg} 1496844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 150abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg/* Async HCI command handling with callback support */ 151abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 152abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstruct hci_cmd_data { 153abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg bt_hci_result_t cb; 154abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t handle; 155abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t ocf; 156abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg gpointer caller_data; 157abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg}; 158abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 159abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstatic gboolean hci_event_watch(GIOChannel *io, 160abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg GIOCondition cond, gpointer user_data) 161abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg{ 162abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg unsigned char buf[HCI_MAX_EVENT_SIZE], *body; 163abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_cmd_data *cmd = user_data; 164abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_cmd_status *evt_status; 165abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_auth_complete *evt_auth; 166abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_encrypt_change *evt_enc; 167abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_event_hdr *hdr; 168abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg set_conn_encrypt_cp cp; 169abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg int dd; 170abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t ocf; 171abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint8_t status = HCI_OE_POWER_OFF; 172abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 173abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (cond & G_IO_NVAL) { 174abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb(status, cmd->caller_data); 175abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return FALSE; 176abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 177abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 178abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (cond & (G_IO_ERR | G_IO_HUP)) 179abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 180abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 181abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg dd = g_io_channel_unix_get_fd(io); 182abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 183abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (read(dd, buf, sizeof(buf)) < 0) 184abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 185abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 186abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hdr = (hci_event_hdr *) (buf + 1); 187abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg body = buf + (1 + HCI_EVENT_HDR_SIZE); 188abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 189abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg switch (hdr->evt) { 190abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_CMD_STATUS: 191abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_status = (evt_cmd_status *) body; 192abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg ocf = cmd_opcode_ocf(evt_status->opcode); 193abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (ocf != cmd->ocf) 194abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 195abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg switch (ocf) { 196abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case OCF_AUTH_REQUESTED: 197abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case OCF_SET_CONN_ENCRYPT: 198abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_status->status != 0) { 199abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Baseband rejected command */ 200abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_status->status; 201abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 202abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 203abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg break; 204abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg default: 205abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 206abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 207abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Wait for the next event */ 208abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 209abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_AUTH_COMPLETE: 210abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_auth = (evt_auth_complete *) body; 211abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_auth->handle != cmd->handle) { 212abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Skipping */ 213abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 214abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 215abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 216abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_auth->status != 0x00) { 217abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_auth->status; 218abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Abort encryption */ 219abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 220abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 221abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 222abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg memset(&cp, 0, sizeof(cp)); 223abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.handle = cmd->handle; 224abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.encrypt = 1; 225abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 226abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->ocf = OCF_SET_CONN_ENCRYPT; 227abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 228abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, 229abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg SET_CONN_ENCRYPT_CP_SIZE, &cp) < 0) { 230abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = HCI_COMMAND_DISALLOWED; 231abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 232abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 233abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Wait for encrypt change event */ 234abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 235abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_ENCRYPT_CHANGE: 236abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_enc = (evt_encrypt_change *) body; 237abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_enc->handle != cmd->handle) 238abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 239abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 240abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Procedure finished: reporting status */ 241abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_enc->status; 242abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg break; 243abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg default: 244abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Skipping */ 245abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 246abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 247abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 248abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergfailed: 249abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb(status, cmd->caller_data); 250abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_shutdown(io, TRUE, NULL); 251abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 252abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return FALSE; 253abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg} 254abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 255b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic int write_inq_mode(int index, uint8_t mode) 256b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 257fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 258b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg write_inquiry_mode_cp cp; 259b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 260b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg memset(&cp, 0, sizeof(cp)); 261b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg cp.mode = mode; 262b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 263fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, 264b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg WRITE_INQUIRY_MODE_CP_SIZE, &cp) < 0) 265b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return -errno; 266b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 267b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 0; 268b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 269b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 270b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic uint8_t get_inquiry_mode(int index) 271b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 272fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 273fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 274fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_EXT_INQ) 275b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 2; 276b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 277fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[3] & LMP_RSSI_INQ) 278b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 279b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 280fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.manufacturer == 11 && dev->ver.hci_rev == 0x00 && 281fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x0757) 282b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 283b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 284fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.manufacturer == 15) { 285fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.hci_rev == 0x03 && 286fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x6963) 287b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 288fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.hci_rev == 0x09 && 289fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x6963) 290b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 291fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.hci_rev == 0x00 && 292fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x6965) 293b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 294b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 295b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 296fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.manufacturer == 31 && dev->ver.hci_rev == 0x2005 && 297fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver == 0x1805) 298b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 299b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 300b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 0; 301b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 302b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 303be49c2621d577da4fafd462265b611289547f183Johan Hedbergstatic int init_ssp_mode(int index) 304be49c2621d577da4fafd462265b611289547f183Johan Hedberg{ 305fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 306be49c2621d577da4fafd462265b611289547f183Johan Hedberg write_simple_pairing_mode_cp cp; 307be49c2621d577da4fafd462265b611289547f183Johan Hedberg 308fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIGETAUTHINFO, NULL) < 0 && errno == EINVAL) 309be49c2621d577da4fafd462265b611289547f183Johan Hedberg return 0; 310be49c2621d577da4fafd462265b611289547f183Johan Hedberg 311be49c2621d577da4fafd462265b611289547f183Johan Hedberg memset(&cp, 0, sizeof(cp)); 312be49c2621d577da4fafd462265b611289547f183Johan Hedberg cp.mode = 0x01; 313be49c2621d577da4fafd462265b611289547f183Johan Hedberg 314fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 315be49c2621d577da4fafd462265b611289547f183Johan Hedberg OCF_WRITE_SIMPLE_PAIRING_MODE, 316be49c2621d577da4fafd462265b611289547f183Johan Hedberg WRITE_SIMPLE_PAIRING_MODE_CP_SIZE, &cp) < 0) 317be49c2621d577da4fafd462265b611289547f183Johan Hedberg return -errno; 318be49c2621d577da4fafd462265b611289547f183Johan Hedberg 319be49c2621d577da4fafd462265b611289547f183Johan Hedberg return 0; 320be49c2621d577da4fafd462265b611289547f183Johan Hedberg} 321be49c2621d577da4fafd462265b611289547f183Johan Hedberg 3225c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_set_discoverable(int index, gboolean discoverable) 3235c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 324fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3255c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg uint8_t mode; 3265c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3275c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (discoverable) 3285c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = (SCAN_PAGE | SCAN_INQUIRY); 3295c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg else 3305c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = SCAN_PAGE; 3315c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3325c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d discoverable %d", index, discoverable); 3335c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 334fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 3355c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 1, &mode) < 0) 3365c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return -errno; 3375c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3385c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return 0; 3395c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 3405c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 34163ff6738abc6bf21becbbfde583062502e7728a6Johan Hedbergstatic int hciops_set_pairable(int index, gboolean pairable) 34263ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg{ 3436964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9Johan Hedberg struct btd_adapter *adapter; 3446964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9Johan Hedberg 34563ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg DBG("hci%d pairable %d", index, pairable); 3466964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9Johan Hedberg 3476964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9Johan Hedberg adapter = manager_find_adapter(&devs[index].bdaddr); 3486964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9Johan Hedberg if (adapter) 3496964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9Johan Hedberg btd_adapter_pairable_changed(adapter, pairable); 3506964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9Johan Hedberg 351b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg devs[index].pairable = pairable; 352b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3536964bd2dd54d5cce7ce2588b0dcd0a3530e6fba9Johan Hedberg return 0; 35463ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg} 35563ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg 35663ff6738abc6bf21becbbfde583062502e7728a6Johan Hedbergstatic int hciops_power_off(int index) 3575c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 358fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3595c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3605c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d", index); 3615c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 36263ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg if (ioctl(dev->sk, HCIDEVDOWN, index) < 0 && errno != EALREADY) 36363ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg return -errno; 3645c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 36563ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg return 0; 3665c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 3675c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3685b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedbergstatic void set_event_mask(int index) 369b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 370fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 371bca43a4edb640ecf56ada1166f7d83fad8a2ce0dJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 372bca43a4edb640ecf56ada1166f7d83fad8a2ce0dJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 373bca43a4edb640ecf56ada1166f7d83fad8a2ce0dJohan Hedberg * command otherwise */ 374bca43a4edb640ecf56ada1166f7d83fad8a2ce0dJohan Hedberg uint8_t events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 375b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 3765b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg /* Events for 1.2 and newer controllers */ 377fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ver.lmp_ver > 1) { 3785b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 3795b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 3805b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 3815b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 3825b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 3835b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg } 384b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 3855b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg if (dev->features[3] & LMP_RSSI_INQ) 3865b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[4] |= 0x04; /* Inquiry Result with RSSI */ 387b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 3885b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg if (dev->features[5] & LMP_SNIFF_SUBR) 3895b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 3905b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg 3915b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg if (dev->features[5] & LMP_PAUSE_ENC) 3925b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 3935b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg 3945b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg if (dev->features[6] & LMP_EXT_INQ) 3955b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 3965b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg 3975b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg if (dev->features[6] & LMP_NFLUSH_PKTS) 3985b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 3995b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg 4005b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg if (dev->features[7] & LMP_LSTO) 4015b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 4025b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg 4035b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg if (dev->features[6] & LMP_SIMPLE_PAIR) { 4045b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 4055b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 4065b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 4075b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 4085b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 4095b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 4105b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 4115b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 4125b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 4135b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg * Features Notification */ 414b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 415b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 4165b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg if (dev->features[4] & LMP_LE) 4175b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 4185b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg 4195b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_SET_EVENT_MASK, 4205b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg sizeof(events), events); 4215b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg} 4225b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg 4235b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedbergstatic void start_adapter(int index) 4245b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg{ 4255b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg struct dev_info *dev = &devs[index]; 4265b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg uint8_t inqmode; 4275b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg uint16_t link_policy; 4285b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg 4295b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg set_event_mask(index); 4305b1a2a39dc7710f5a58e4f676389fea06764800bJohan Hedberg 431fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[6] & LMP_SIMPLE_PAIR) 432be49c2621d577da4fafd462265b611289547f183Johan Hedberg init_ssp_mode(index); 433be49c2621d577da4fafd462265b611289547f183Johan Hedberg 434b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg inqmode = get_inquiry_mode(index); 435b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (inqmode) 436b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg write_inq_mode(index, inqmode); 437b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 438fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->features[7] & LMP_INQ_TX_PWR) 439fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, 440b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL, 0, NULL); 441b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 442b59dabdd2515aa111ebc56d946259e4bbdf20c61Pawel Wieczorkiewicz /* Set default link policy */ 443ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy = main_opts.link_policy; 444ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg 445fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[0] & LMP_RSWITCH)) 446ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_RSWITCH; 447fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[0] & LMP_HOLD)) 448ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_HOLD; 449fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[0] & LMP_SNIFF)) 450ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_SNIFF; 451fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[1] & LMP_PARK)) 452ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy &= ~HCI_LP_PARK; 453b59dabdd2515aa111ebc56d946259e4bbdf20c61Pawel Wieczorkiewicz 454ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg link_policy = htobs(link_policy); 455fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_POLICY, OCF_WRITE_DEFAULT_LINK_POLICY, 456ea30b84b2349c01175ed8700e206bca1e019a635Johan Hedberg sizeof(link_policy), &link_policy); 457b59dabdd2515aa111ebc56d946259e4bbdf20c61Pawel Wieczorkiewicz 458fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->current_cod = 0; 459fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memset(dev->eir, 0, sizeof(dev->eir)); 4605c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 46100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 462dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentzstatic int hciops_stop_inquiry(int index) 463dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz{ 464dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz struct dev_info *dev = &devs[index]; 465dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz struct hci_dev_info di; 466dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz int err; 467dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz 468dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz DBG("hci%d", index); 469dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz 470dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz if (hci_devinfo(index, &di) < 0) 471dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz return -errno; 472dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz 473dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz if (hci_test_bit(HCI_INQUIRY, &di.flags)) 474dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 475dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz OCF_INQUIRY_CANCEL, 0, 0); 476dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz else 477dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 478dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz OCF_EXIT_PERIODIC_INQUIRY, 0, 0); 479dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz if (err < 0) 480dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz err = -errno; 481dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz 482dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz return err; 483dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz} 484dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz 4855c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic gboolean init_adapter(int index) 4865c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 487fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 4885c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg struct btd_adapter *adapter = NULL; 489fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg gboolean existing_adapter = dev->registered; 4905c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg uint8_t mode, on_mode; 4915c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg gboolean pairable, discoverable; 4925c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 493fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->registered) { 4945c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg adapter = btd_manager_register_adapter(index); 4955c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (adapter) 496fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->registered = TRUE; 4975c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } else { 498fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 4995c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg /* FIXME: manager_find_adapter should return a new ref */ 5005c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_ref(adapter); 5015c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } 5025c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 5035c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (adapter == NULL) 5045c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return FALSE; 5055c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 5068440ce6ac89fdb290e566ab01edc4dcb6935a682Johan Hedberg btd_adapter_get_mode(adapter, &mode, &on_mode, &pairable); 5075c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 5085c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (existing_adapter) 5095c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg mode = on_mode; 5105c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 5115c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg if (mode == MODE_OFF) { 51263ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg hciops_power_off(index); 5135c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg goto done; 5145c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg } 5155c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 5165c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg start_adapter(index); 5175c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_start(adapter); 5185c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 5195c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg discoverable = (mode == MODE_DISCOVERABLE); 5205c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 5215c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg hciops_set_discoverable(index, discoverable); 5225c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg hciops_set_pairable(index, pairable); 5235c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 524dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz if (dev->already_up) 525dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz hciops_stop_inquiry(index); 526dc2860e16a2860a8c17af8dab1fd5e8b73dd38f7Luiz Augusto von Dentz 5275c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergdone: 5285c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_adapter_unref(adapter); 5295c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return TRUE; 530b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 531b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 532abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstatic int hciops_encrypt_link(int index, bdaddr_t *dst, bt_hci_result_t cb, 533abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg gpointer user_data) 534abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg{ 535abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg GIOChannel *io; 536abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_cmd_data *cmd; 537abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_conn_info_req *cr; 538abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg auth_requested_cp cp; 539abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_filter nf; 540abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg int dd, err; 541abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint32_t link_mode; 542abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t handle; 543abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 544684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg dd = hci_open_dev(index); 545684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (dd < 0) 546684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg return -errno; 547684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg 548abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); 549abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cr->type = ACL_LINK; 550abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg bacpy(&cr->bdaddr, dst); 551abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 552684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = ioctl(dd, HCIGETCONNINFO, cr); 553abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg link_mode = cr->conn_info->link_mode; 554abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg handle = cr->conn_info->handle; 555abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_free(cr); 556abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 557684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (err < 0) { 558684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = -errno; 559684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 560684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg } 561abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 562684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (link_mode & HCI_LM_ENCRYPT) { 563684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = -EALREADY; 564684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 565684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg } 566abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 567abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg memset(&cp, 0, sizeof(cp)); 568abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.handle = htobs(handle); 569abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 570684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_AUTH_REQUESTED, 571684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg AUTH_REQUESTED_CP_SIZE, &cp) < 0) { 572684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg err = -errno; 573684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 574684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg } 575abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 576abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd = g_new0(struct hci_cmd_data, 1); 577abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->handle = handle; 578abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->ocf = OCF_AUTH_REQUESTED; 579abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb = cb; 580abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->caller_data = user_data; 581abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 582abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_clear(&nf); 583abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_ptype(HCI_EVENT_PKT, &nf); 584abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_CMD_STATUS, &nf); 585abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_AUTH_COMPLETE, &nf); 586abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_ENCRYPT_CHANGE, &nf); 587abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 588abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) { 589abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg err = -errno; 590abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_free(cmd); 591684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg goto fail; 592abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 593abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 594684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg io = g_io_channel_unix_new(dd); 595abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_set_close_on_unref(io, FALSE); 596abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_add_watch_full(io, G_PRIORITY_DEFAULT, 597abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg G_IO_HUP | G_IO_ERR | G_IO_NVAL | G_IO_IN, 598abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_event_watch, cmd, g_free); 599abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_unref(io); 600abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 601abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return 0; 602684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg 603684b1d3be105b64f3994e621335f69b45e34125fJohan Hedbergfail: 604684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg close(dd); 605684b1d3be105b64f3994e621335f69b45e34125fJohan Hedberg return err; 606abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg} 607abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 60800c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_set_did(int index, uint16_t vendor, uint16_t product, 60900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t version) 61000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 611fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 612fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 613fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->did_vendor = vendor; 614fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->did_product = product; 615fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->did_version = version; 61600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 61700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 61800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 61900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 620abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg/* End async HCI command handling */ 621abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 6225288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Start of HCI event callbacks */ 6235288199788ecb17183d6517da3062cd94692a900Johan Hedberg 624b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic gint conn_handle_cmp(gconstpointer a, gconstpointer b) 625b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 626b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg const struct bt_conn *conn = a; 627b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint16_t handle = *((const uint16_t *) b); 628b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 629b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return (int) conn->handle - (int) handle; 630b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 631b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 632b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic struct bt_conn *find_conn_by_handle(struct dev_info *dev, 633b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint16_t handle) 634b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 635b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg GSList *match; 636b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 637b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg match = g_slist_find_custom(dev->connections, &handle, 638b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn_handle_cmp); 639b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (match) 640b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return match->data; 641b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 642b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return NULL; 643b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 644b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 645b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic gint conn_bdaddr_cmp(gconstpointer a, gconstpointer b) 646b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 647b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg const struct bt_conn *conn = a; 648b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg const bdaddr_t *bdaddr = b; 649b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 650b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return bacmp(&conn->bdaddr, bdaddr); 651b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 652b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 653b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic struct bt_conn *find_connection(struct dev_info *dev, bdaddr_t *bdaddr) 654b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg{ 655bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg GSList *match; 656b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 657b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg match = g_slist_find_custom(dev->connections, bdaddr, conn_bdaddr_cmp); 658b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (match) 659b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return match->data; 660b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 661b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return NULL; 662b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 663b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 664b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic struct bt_conn *get_connection(struct dev_info *dev, bdaddr_t *bdaddr) 665b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 666b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 667b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 668b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_connection(dev, bdaddr); 669b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn) 670b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return conn; 671b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 672b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = g_new0(struct bt_conn, 1); 673b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 674b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->dev = dev; 675b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_cap = dev->io_capability; 676b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_auth = 0xff; 677b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->rem_auth = 0xff; 678b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg bacpy(&conn->bdaddr, bdaddr); 679b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 680b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg dev->connections = g_slist_append(dev->connections, conn); 681b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 682b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return conn; 683b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 684b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 685b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic int get_handle(int index, bdaddr_t *bdaddr, uint16_t *handle) 686b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 687b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct dev_info *dev = &devs[index]; 688b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 6895a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg char addr[18]; 690b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 6915a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg ba2str(bdaddr, addr); 6925a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg DBG("hci%d dba %s", index, addr); 693b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 694b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_connection(dev, bdaddr); 695b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn == NULL) 696bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg return -ENOENT; 697b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 698bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg *handle = conn->handle; 6995a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg 700bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg return 0; 701b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg} 702b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 703b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedbergstatic int disconnect_addr(int index, bdaddr_t *dba, uint8_t reason) 7045288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 7055a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg disconnect_cp cp; 7065a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg uint16_t handle; 7075a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg int err; 7085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7095a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg err = get_handle(index, dba, &handle); 7105a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg if (err < 0) 7115a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg return err; 7125288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7135a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg memset(&cp, 0, sizeof(cp)); 7145a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg cp.handle = htobs(handle); 7155a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg cp.reason = reason; 716b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 7175a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg if (hci_send_cmd(devs[index].sk, OGF_LINK_CTL, OCF_DISCONNECT, 7185a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg DISCONNECT_CP_SIZE, &cp) < 0) 7195a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg return -errno; 7205288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7215a50e2192ec53c4aeccabbb2a7dcacf7ee456dd4Johan Hedberg return 0; 7225288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7235288199788ecb17183d6517da3062cd94692a900Johan Hedberg 724b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic void bonding_complete(struct dev_info *dev, struct bt_conn *conn, 725b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint8_t status) 7265288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 727b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("status 0x%02x", status); 7285288199788ecb17183d6517da3062cd94692a900Johan Hedberg 729b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->io != NULL) { 7301cd99f445e0a11ae936d9e80b44f504f807ce35aJohan Hedberg /* bonding_connect_cb takes care of the successul case */ 7311cd99f445e0a11ae936d9e80b44f504f807ce35aJohan Hedberg if (status != 0) 7321cd99f445e0a11ae936d9e80b44f504f807ce35aJohan Hedberg g_io_channel_shutdown(conn->io, TRUE, NULL); 733b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_io_channel_unref(conn->io); 734b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->io = NULL; 735b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 7365288199788ecb17183d6517da3062cd94692a900Johan Hedberg 737b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->bonding_initiator = FALSE; 7385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 739fa41c93fe1dd04c1c25d34956d02c54f19ac3130Johan Hedberg btd_event_bonding_complete(&dev->bdaddr, &conn->bdaddr, status); 740b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 7415288199788ecb17183d6517da3062cd94692a900Johan Hedberg 742b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic int get_auth_info(int index, bdaddr_t *bdaddr, uint8_t *auth) 743b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 744b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct dev_info *dev = &devs[index]; 745b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct hci_auth_info_req req; 746b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg char addr[18]; 7475288199788ecb17183d6517da3062cd94692a900Johan Hedberg 748b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg ba2str(bdaddr, addr); 749b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("hci%d dba %s", index, addr); 750b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 751b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg memset(&req, 0, sizeof(req)); 752b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg bacpy(&req.bdaddr, bdaddr); 7535288199788ecb17183d6517da3062cd94692a900Johan Hedberg 754b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (ioctl(dev->sk, HCIGETAUTHINFO, (unsigned long) &req) < 0) 755b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return -errno; 756b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 757b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (auth) 758b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg *auth = req.type; 759b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 760b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return 0; 7615288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7625288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7635288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Link Key handling */ 7645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 76542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void link_key_request(int index, bdaddr_t *dba) 7665288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 767fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 768b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg struct link_key_info *key_info; 769b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 770b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg GSList *match; 7710e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 7725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7730e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 7740e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, da); 7755288199788ecb17183d6517da3062cd94692a900Johan Hedberg 776b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = get_connection(dev, dba); 777b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->handle == 0) 778b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->secmode3 = TRUE; 7795288199788ecb17183d6517da3062cd94692a900Johan Hedberg 780b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg get_auth_info(index, dba, &conn->loc_auth); 7815288199788ecb17183d6517da3062cd94692a900Johan Hedberg 782b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("kernel auth requirements = 0x%02x", conn->loc_auth); 7835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 784b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg match = g_slist_find_custom(dev->keys, dba, (GCompareFunc) bacmp); 785b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (match) 786b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = match->data; 787b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg else 788b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = NULL; 789b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 790b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg DBG("Matching key %s", key_info ? "found" : "not found"); 791b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 792dccef4954d8dcaa4559be66263ea0945cd9be528Johan Hedberg if (key_info == NULL || (!dev->debug_keys && key_info->type == 0x03)) { 7935288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Link key not found */ 794fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 79542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 6, dba); 7965288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 7975288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7985288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7995288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Link key found */ 8005288199788ecb17183d6517da3062cd94692a900Johan Hedberg 801a61d0e8e738e905604c3339309718f3b2eadbdf7Johan Hedberg DBG("link key type 0x%02x", key_info->type); 8025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8035288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't use unauthenticated combination keys if MITM is 8045288199788ecb17183d6517da3062cd94692a900Johan Hedberg * required */ 805b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (key_info->type == 0x04 && conn->loc_auth != 0xff && 806b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg (conn->loc_auth & 0x01)) 807fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 8085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6, dba); 8095288199788ecb17183d6517da3062cd94692a900Johan Hedberg else { 8105288199788ecb17183d6517da3062cd94692a900Johan Hedberg link_key_reply_cp lr; 8115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 812a61d0e8e738e905604c3339309718f3b2eadbdf7Johan Hedberg memcpy(lr.link_key, key_info->key, 16); 8135288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&lr.bdaddr, dba); 8145288199788ecb17183d6517da3062cd94692a900Johan Hedberg 815fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, 8165288199788ecb17183d6517da3062cd94692a900Johan Hedberg LINK_KEY_REPLY_CP_SIZE, &lr); 8175288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 8185288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8195288199788ecb17183d6517da3062cd94692a900Johan Hedberg 82042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void link_key_notify(int index, void *ptr) 8215288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 822fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 8235288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_link_key_notify *evt = ptr; 8245288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t *dba = &evt->bdaddr; 825b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg struct link_key_info *key_info; 826b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint8_t old_key_type, key_type; 827b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 828b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg GSList *match; 8290e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 830b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint8_t status = 0; 8315288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8320e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 8330e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s type %d", index, da, evt->key_type); 8345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 835b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = get_connection(dev, &evt->bdaddr); 836b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 837b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg match = g_slist_find_custom(dev->keys, dba, (GCompareFunc) bacmp); 838b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (match) 839b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = match->data; 840b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg else 841b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = NULL; 842b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 843b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (key_info == NULL) { 844b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info = g_new0(struct link_key_info, 1); 845b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg bacpy(&key_info->bdaddr, &evt->bdaddr); 846c614654d76da74a51a18c7d4474a8046ca6bda01Johan Hedberg old_key_type = 0xff; 847b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg } else { 848b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg dev->keys = g_slist_remove(dev->keys, key_info); 849b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg old_key_type = key_info->type; 850b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg } 851b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 852b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg memcpy(key_info->key, evt->link_key, sizeof(evt->link_key)); 853b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info->type = evt->key_type; 854b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg key_info->pin_len = dev->pin_length; 8555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 856b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg key_type = evt->key_type; 8575288199788ecb17183d6517da3062cd94692a900Johan Hedberg 858b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("key type 0x%02x old key type 0x%02x", key_type, old_key_type); 859b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("local auth 0x%02x and remote auth 0x%02x", 860b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_auth, conn->rem_auth); 861b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 862b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (key_type == 0x06) { 863b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* Some buggy controller combinations generate a changed 864b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * combination key for legacy pairing even when there's no 865b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * previous key */ 866b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if ((!conn || conn->rem_auth == 0xff) && old_key_type == 0xff) 867b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg key_type = 0x00; 868b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg else if (old_key_type != 0xff) 869b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg key_type = old_key_type; 870b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg else 871b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* This is Changed Combination Link Key for 872b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * a temporary link key.*/ 873b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg goto done; 874b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg } 8755288199788ecb17183d6517da3062cd94692a900Johan Hedberg 876b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg key_info->type = key_type; 8775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 878b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* Skip the storage check if this is a debug key */ 879b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (key_type == 0x03) 880b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg goto done; 881b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 882b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* Store the link key persistently if one of the following is true: 883b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * 1. this is a legacy link key 884b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * 2. this is a changed combination key and there was a previously 885b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * stored one 886b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * 3. neither local nor remote side had no-bonding as a requirement 887b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * 4. the local side had dedicated bonding as a requirement 888b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * 5. the remote side is using dedicated bonding since in that case 889b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * also the local requirements are set to dedicated bonding 890b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * If none of the above match only keep the link key around for 891b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * this connection and set the temporary flag for the device. 892b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg */ 893b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (key_type < 0x03 || (key_type == 0x06 && old_key_type != 0xff) || 894b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg (conn->loc_auth > 0x01 && conn->rem_auth > 0x01) || 895b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg (conn->loc_auth == 0x02 || conn->loc_auth == 0x03) || 896b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg (conn->rem_auth == 0x02 || conn->rem_auth == 0x03)) { 897b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg int err; 898b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 899b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg err = btd_event_link_key_notify(&dev->bdaddr, dba, 900b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg evt->link_key, key_type, 901b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg dev->pin_length); 902b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 903b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (err == -ENODEV) 904b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg status = HCI_OE_LOW_RESOURCES; 905b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg else if (err < 0) 906b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg status = HCI_MEMORY_FULL; 907b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 908b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg goto done; 909b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 9105288199788ecb17183d6517da3062cd94692a900Johan Hedberg 911b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergdone: 912b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg dev->pin_length = 0; 913b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 914b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (status != 0) { 915b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_free(key_info); 916b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg bonding_complete(dev, conn, status); 917b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg disconnect_addr(index, dba, status); 918b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return; 919b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 920b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 9215ac0142426d3e286117962cb997c5822633e43d5Johan Hedberg dev->keys = g_slist_prepend(dev->keys, key_info); 9225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 923b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If we're connected and not dedicated bonding initiators we're 924b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * done with the bonding process */ 925b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (!conn->bonding_initiator && conn->handle != 0) 926b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg bonding_complete(dev, conn, 0); 9275288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9285288199788ecb17183d6517da3062cd94692a900Johan Hedberg 92942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void return_link_keys(int index, void *ptr) 9305288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 931fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 9325288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_return_link_keys *evt = ptr; 9335288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = evt->num_keys; 9345288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char key[16]; 9350e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 9365288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 9375288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 9385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9390e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d num_keys %u", index, num); 9400e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 9415288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr++; 9425288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9435288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 9445288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&dba, ptr); ba2str(&dba, da); 9455288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(key, ptr + 6, 16); 9465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9470e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d returned key for %s", index, da); 9485288199788ecb17183d6517da3062cd94692a900Johan Hedberg 949fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_returned_link_key(&dev->bdaddr, &dba); 9505288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9515288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += 22; 9525288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 9535288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9545288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9555288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Simple Pairing handling */ 9565288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9574d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedbergstatic int hciops_confirm_reply(int index, bdaddr_t *bdaddr, gboolean success) 9584d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg{ 9594d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg struct dev_info *dev = &devs[index]; 9604d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg user_confirm_reply_cp cp; 9614d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg char addr[18]; 9624d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg int err; 9634d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg 9644d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg ba2str(bdaddr, addr); 9654d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg DBG("hci%d dba %s success %d", index, addr, success); 9664d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg 9674d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg memset(&cp, 0, sizeof(cp)); 9684d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 9694d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg 9704d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg if (success) 9714d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 9724d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg OCF_USER_CONFIRM_REPLY, 9734d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg USER_CONFIRM_REPLY_CP_SIZE, &cp); 9744d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg else 9754d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 9764d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg OCF_USER_CONFIRM_NEG_REPLY, 9774d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg USER_CONFIRM_REPLY_CP_SIZE, &cp); 9784d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg 9794d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg if (err < 0) 9804d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg err = -errno; 9814d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg 9824d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg return err; 9834d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg} 9844d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg 98542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_confirm_request(int index, void *ptr) 9865288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 987fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 9885288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_confirm_request *req = ptr; 9894d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg gboolean loc_mitm, rem_mitm; 990b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 9915288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9920e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 9930e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 994b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_connection(dev, &req->bdaddr); 995b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn == NULL) 996b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return; 997b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 998b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg loc_mitm = (conn->loc_auth & 0x01) ? TRUE : FALSE; 999b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg rem_mitm = (conn->rem_auth & 0x01) ? TRUE : FALSE; 1000b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1001b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If we require MITM but the remote device can't provide that 1002b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 1003b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * request. The only exception is when we're dedicated bonding 1004b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * initiators since then we always have the MITM bit set. */ 1005b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (!conn->bonding_initiator && loc_mitm && conn->rem_cap == 0x03) { 1006b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg error("Rejecting request: remote device can't provide MITM"); 1007b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg goto fail; 1008b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 1009b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1010b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If no side requires MITM protection; auto-accept */ 1011b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if ((conn->loc_auth == 0xff || !loc_mitm || conn->rem_cap == 0x03) && 1012b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg (!rem_mitm || conn->loc_cap == 0x03)) { 1013b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("auto accept of confirmation"); 10144d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg 10154d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg /* Wait 5 milliseconds before doing auto-accept */ 10164d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg usleep(5000); 10174d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg 10184d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg if (hciops_confirm_reply(index, &req->bdaddr, TRUE) < 0) 10194d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg goto fail; 10204d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg 10214d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg return; 10224d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg } 1023b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1024fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (btd_event_user_confirm(&dev->bdaddr, &req->bdaddr, 10254d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg btohl(req->passkey)) == 0) 1026b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return; 1027b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1028b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergfail: 1029b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY, 1030b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 6, ptr); 10315288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 10325288199788ecb17183d6517da3062cd94692a900Johan Hedberg 103342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_passkey_request(int index, void *ptr) 10345288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1035fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 10365288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_passkey_request *req = ptr; 10375288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10380e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 10390e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1040fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (btd_event_user_passkey(&dev->bdaddr, &req->bdaddr) < 0) 1041fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 10425288199788ecb17183d6517da3062cd94692a900Johan Hedberg OCF_USER_PASSKEY_NEG_REPLY, 6, ptr); 10435288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 10445288199788ecb17183d6517da3062cd94692a900Johan Hedberg 104542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_passkey_notify(int index, void *ptr) 10465288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1047fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 10485288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_passkey_notify *req = ptr; 10495288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10500e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 10510e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1052fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_user_notify(&dev->bdaddr, &req->bdaddr, 105342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btohl(req->passkey)); 10545288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 10555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 105642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void remote_oob_data_request(int index, void *ptr) 10575288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1058fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1059fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 10600e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 1061fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 1062fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 106342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr); 10645288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 10655288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1066b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic int get_io_cap(int index, bdaddr_t *bdaddr, uint8_t *cap, uint8_t *auth) 1067b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 1068b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct dev_info *dev = &devs[index]; 1069b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 1070b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg int err; 1071b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1072b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_connection(dev, bdaddr); 1073b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn == NULL) 1074b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return -ENOENT; 1075b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1076b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg err = get_auth_info(index, bdaddr, &conn->loc_auth); 1077b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (err < 0) 1078b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return err; 1079b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1080b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("initial authentication requirement is 0x%02x", conn->loc_auth); 1081b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1082b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (!dev->pairable && !conn->bonding_initiator) { 1083b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->rem_auth < 0x02) { 1084b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("Allowing no bonding in non-bondable mode"); 1085b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* Kernel defaults to general bonding and so 1086b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * overwrite for this special case. Otherwise 1087b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * non-pairable test cases will fail. */ 1088b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_auth = conn->rem_auth; 1089b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg goto done; 1090b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 1091b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1092b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return -EPERM; 1093b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 1094b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1095b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If the kernel doesn't know the local requirement just mirror 1096b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * the remote one */ 1097b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->loc_auth == 0xff) 1098b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_auth = conn->rem_auth; 1099b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1100b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->loc_auth == 0x00 || conn->loc_auth == 0x04) { 1101b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If remote requests dedicated bonding follow that lead */ 1102b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->rem_auth == 0x02 || conn->rem_auth == 0x03) { 1103b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1104b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If both remote and local IO capabilities allow MITM 1105b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * then require it, otherwise don't */ 1106b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->rem_cap == 0x03 || conn->loc_cap == 0x03) 1107b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_auth = 0x02; 1108b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg else 1109b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_auth = 0x03; 1110b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 1111b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1112b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If remote indicates no bonding then follow that. This 1113b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * is important since the kernel might give general bonding 1114b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * as default. */ 1115b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->rem_auth == 0x00 || conn->rem_auth == 0x01) 1116b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_auth = 0x00; 1117b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1118b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If remote requires MITM then also require it, unless 1119b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * our IO capability is NoInputNoOutput (so some 1120b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * just-works security cases can be tested) */ 1121b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->rem_auth != 0xff && (conn->rem_auth & 0x01) && 1122b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_cap != 0x03) 1123b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_auth |= 0x01; 1124b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 1125b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1126b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergdone: 1127b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg *cap = conn->loc_cap; 1128b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg *auth = conn->loc_auth; 1129b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1130b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("final authentication requirement is 0x%02x", *auth); 1131b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1132b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return 0; 1133b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 1134b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 113542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void io_capa_request(int index, void *ptr) 11365288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1137fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 113842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg bdaddr_t *dba = ptr; 1139b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg uint8_t cap, auth = 0xff; 11400e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 1141b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg int err; 11425288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11430e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(dba, da); 11440e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d IO capability request for %s", index, da); 11455288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1146b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg err = get_io_cap(index, dba, &cap, &auth); 1147b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (err < 0) { 11485288199788ecb17183d6517da3062cd94692a900Johan Hedberg io_capability_neg_reply_cp cp; 1149b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1150b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg error("Getting IO capability failed: %s (%d)", 1151b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg strerror(-err), -err); 1152b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 11535288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 11545288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cp.bdaddr, dba); 11555288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.reason = HCI_PAIRING_NOT_ALLOWED; 1156fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, 115742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg OCF_IO_CAPABILITY_NEG_REPLY, 11585288199788ecb17183d6517da3062cd94692a900Johan Hedberg IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp); 11595288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 11605288199788ecb17183d6517da3062cd94692a900Johan Hedberg io_capability_reply_cp cp; 11615288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 11625288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cp.bdaddr, dba); 11635288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.capability = cap; 11645288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.oob_data = 0x00; 11655288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.authentication = auth; 1166fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY, 11675288199788ecb17183d6517da3062cd94692a900Johan Hedberg IO_CAPABILITY_REPLY_CP_SIZE, &cp); 11685288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 11695288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 11705288199788ecb17183d6517da3062cd94692a900Johan Hedberg 117142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void io_capa_response(int index, void *ptr) 11725288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1173fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 11745288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_io_capability_response *evt = ptr; 1175b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 11760e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char da[18]; 11775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11780e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(&evt->bdaddr, da); 11790e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d IO capability response from %s", index, da); 11805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1181b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_connection(dev, &evt->bdaddr); 1182b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn) { 1183b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->rem_cap = evt->capability; 1184b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->rem_auth = evt->authentication; 1185b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 11865288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 11875288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11885288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* PIN code handling */ 11895288199788ecb17183d6517da3062cd94692a900Johan Hedberg 119042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void pin_code_request(int index, bdaddr_t *dba) 11915288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1192fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1193b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 119453a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg char addr[18]; 119553a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg int err; 11965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 119753a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg ba2str(dba, addr); 119853a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg DBG("hci%d PIN request for %s", index, addr); 11995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1200b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = get_connection(dev, dba); 1201b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->handle == 0) 1202b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->secmode3 = TRUE; 1203b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1204b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* Check if the adapter is not pairable and if there isn't a bonding in 1205b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * progress */ 1206b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (!dev->pairable && !conn->bonding_initiator) { 1207b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("Rejecting PIN request in non-pairable mode"); 1208b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg goto reject; 1209b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 1210b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 121153a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg err = btd_event_request_pin(&dev->bdaddr, dba); 121253a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg if (err < 0) { 121353a4fa31e72841c8db229c75fd9f798c90e29ee5Johan Hedberg error("PIN code negative reply: %s", strerror(-err)); 1214b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg goto reject; 12155288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 1216b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1217b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return; 1218b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 1219b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergreject: 1220b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); 12215288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 12225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12235288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic void start_inquiry(bdaddr_t *local, uint8_t status, gboolean periodic) 12245288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 12255288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 12265288199788ecb17183d6517da3062cd94692a900Johan Hedberg int state; 12275288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12285288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't send the signal if the cmd failed */ 12295288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) { 12305288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Inquiry Failed with status 0x%02x", status); 12315288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 12325288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 12335288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12345288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(local); 12355288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 12365288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 12375288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 12385288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 12395288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12405288199788ecb17183d6517da3062cd94692a900Johan Hedberg state = adapter_get_state(adapter); 12415288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12425288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (periodic) 12435288199788ecb17183d6517da3062cd94692a900Johan Hedberg state |= STATE_PINQ; 12445288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 12455288199788ecb17183d6517da3062cd94692a900Johan Hedberg state |= STATE_STDINQ; 12465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12475288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_set_state(adapter, state); 12485288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 12495288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1250e5828c7e30453232e930dbead0e359175dc1decfJohan Hedbergstatic void inquiry_complete(bdaddr_t *local, uint8_t status, 1251e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg gboolean periodic) 12525288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 12535288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 12545288199788ecb17183d6517da3062cd94692a900Johan Hedberg int state; 12555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12565288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't send the signal if the cmd failed */ 12575288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) { 12585288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Inquiry Failed with status 0x%02x", status); 12595288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 12605288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 12615288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12625288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(local); 12635288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 12645288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 12655288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 12665288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 12675288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12685288199788ecb17183d6517da3062cd94692a900Johan Hedberg state = adapter_get_state(adapter); 12695288199788ecb17183d6517da3062cd94692a900Johan Hedberg state &= ~(STATE_STDINQ | STATE_PINQ); 12705288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_set_state(adapter, state); 12715288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 12725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 127342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_features_notify(int index, void *ptr) 12745288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1275fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 12765288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_remote_host_features_notify *evt = ptr; 12775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12785288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->features[0] & 0x01) 1279fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_set_legacy_pairing(&dev->bdaddr, &evt->bdaddr, 128042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg FALSE); 12815288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 1282fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_set_legacy_pairing(&dev->bdaddr, &evt->bdaddr, 128342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg TRUE); 12845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1285fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_features_info(&dev->bdaddr, &evt->bdaddr, NULL, evt->features); 12865288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 12875288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12882db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedbergstatic void write_le_host_complete(int index, uint8_t status) 12895288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1290fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 12912db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg uint8_t page_num = 0x01; 12925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12935288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) 12945288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 12955288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1296fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_INFO_PARAM, 12972db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg OCF_READ_LOCAL_EXT_FEATURES, 1, &page_num) < 0) 12982db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg error("Unable to read extended local features: %s (%d)", 12992db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg strerror(errno), errno); 13005288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 13015288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1302be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void read_local_version_complete(int index, 1303be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg const read_local_version_rp *rp) 1304be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 1305fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1306fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 1307be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (rp->status) 1308be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 1309be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1310fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.manufacturer = btohs(bt_get_unaligned(&rp->manufacturer)); 1311fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.hci_ver = rp->hci_ver; 1312fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.hci_rev = btohs(bt_get_unaligned(&rp->hci_rev)); 1313fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_ver = rp->lmp_ver; 1314fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ver.lmp_subver = btohs(bt_get_unaligned(&rp->lmp_subver)); 1315be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1316fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 1317be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 1318be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1319fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_VERSION, &dev->pending); 1320be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1321be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg DBG("Got version for hci%d", index); 1322be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1323fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending && dev->up) 13245c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 1325be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 1326be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1327be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void read_local_features_complete(int index, 1328be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg const read_local_features_rp *rp) 1329be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 1330fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1331fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 1332be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (rp->status) 1333be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 1334be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1335fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->features, rp->features, 8); 1336be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1337fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 1338be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 1339be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1340fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_FEATURES, &dev->pending); 1341be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1342be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg DBG("Got features for hci%d", index); 1343be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1344fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending && dev->up) 13455c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 1346be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 1347be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 134800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg#define SIZEOF_UUID128 16 134900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 13503e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedbergstatic void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len) 135100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 135200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int i, k, uuid_count = 0; 135300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t len = *eir_len; 135400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *uuid128; 135500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg gboolean truncated = FALSE; 135600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 135700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Store UUIDs in place, skip 2 bytes to write type and length later */ 135800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128 = ptr + 2; 135900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 136000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (; list; list = list->next) { 1361006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg struct uuid_info *uuid = list->data; 1362006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg uint8_t *uuid128_data = uuid->uuid.value.uuid128.data; 136300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1364006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg if (uuid->uuid.type != SDP_UUID128) 136500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 136600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 136700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Stop if not enough space to put next UUID128 */ 136800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) { 136900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg truncated = TRUE; 137000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 137100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 137200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 137300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Check for duplicates, EIR data is Little Endian */ 137400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (i = 0; i < uuid_count; i++) { 137500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (k = 0; k < SIZEOF_UUID128; k++) { 137600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid128[i * SIZEOF_UUID128 + k] != 137700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128_data[SIZEOF_UUID128 - 1 - k]) 137800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 137900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 138000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (k == SIZEOF_UUID128) 138100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 138200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 138300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 138400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (i < uuid_count) 138500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 138600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 138700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR data is Little Endian */ 138800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (k = 0; k < SIZEOF_UUID128; k++) 138900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128[uuid_count * SIZEOF_UUID128 + k] = 139000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid128_data[SIZEOF_UUID128 - 1 - k]; 139100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 139200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg len += SIZEOF_UUID128; 139300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uuid_count++; 139400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 139500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 139600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid_count > 0 || truncated) { 139700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data length */ 139800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[0] = (uuid_count * SIZEOF_UUID128) + 1; 139900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data type */ 140000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL; 140100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg len += 2; 140200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *eir_len = len; 140300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 140400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 140500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 140600c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void create_ext_inquiry_response(int index, uint8_t *data) 140700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1408fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 14093e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg GSList *l; 141000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t *ptr = data; 141100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t eir_len = 0; 141200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t uuid16[EIR_DATA_LENGTH / 2]; 141300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int i, uuid_count = 0; 141400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg gboolean truncated = FALSE; 141500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg size_t name_len; 141600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1417fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg name_len = strlen(dev->name); 141800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 141900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (name_len > 0) { 142000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data type */ 142100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (name_len > 48) { 142200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg name_len = 48; 142300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = EIR_NAME_SHORT; 142400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } else 142500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = EIR_NAME_COMPLETE; 142600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 142700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data length */ 142800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[0] = name_len + 1; 142900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1430fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(ptr + 2, dev->name, name_len); 143100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 143200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += (name_len + 2); 143300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr += (name_len + 2); 143400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 143500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1436fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->tx_power != 0) { 143700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = 2; 143800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = EIR_TX_POWER; 1439fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (uint8_t) dev->tx_power; 144000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += 3; 144100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 144200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1443fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->did_vendor != 0x0000) { 144400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint16_t source = 0x0002; 144500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = 9; 144600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = EIR_DEVICE_ID; 144700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (source & 0x00ff); 144800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (source & 0xff00) >> 8; 1449fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_vendor & 0x00ff); 1450fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_vendor & 0xff00) >> 8; 1451fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_product & 0x00ff); 1452fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_product & 0xff00) >> 8; 1453fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_version & 0x00ff); 1454fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg *ptr++ = (dev->did_version & 0xff00) >> 8; 145500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += 10; 145600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 145700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 145800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Group all UUID16 types */ 14593e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg for (l = dev->uuids; l != NULL; l = g_slist_next(l)) { 1460006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg struct uuid_info *uuid = l->data; 146100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1462006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg if (uuid->uuid.type != SDP_UUID16) 146300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 146400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1465006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg if (uuid->uuid.value.uuid16 < 0x1100) 146600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 146700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1468006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg if (uuid->uuid.value.uuid16 == PNP_INFO_SVCLASS_ID) 146900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 147000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 147100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Stop if not enough space to put next UUID16 */ 147200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) { 147300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg truncated = TRUE; 147400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 147500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 147600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 147700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Check for duplicates */ 147800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (i = 0; i < uuid_count; i++) 1479006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg if (uuid16[i] == uuid->uuid.value.uuid16) 148000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg break; 148100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 148200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (i < uuid_count) 148300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg continue; 148400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1485006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg uuid16[uuid_count++] = uuid->uuid.value.uuid16; 148600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += sizeof(uint16_t); 148700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 148800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 148900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (uuid_count > 0) { 149000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data length */ 149100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[0] = (uuid_count * sizeof(uint16_t)) + 1; 149200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* EIR Data type */ 149300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; 149400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 149500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg ptr += 2; 149600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg eir_len += 2; 149700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 149800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg for (i = 0; i < uuid_count; i++) { 149900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (uuid16[i] & 0x00ff); 150000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg *ptr++ = (uuid16[i] & 0xff00) >> 8; 150100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 150200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 150300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 150400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Group all UUID128 types */ 150500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (eir_len <= EIR_DATA_LENGTH - 2) 15063e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg eir_generate_uuid128(dev->uuids, ptr, &eir_len); 150700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 150800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 150900c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void update_ext_inquiry_response(int index) 151000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1511fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 151200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_ext_inquiry_response_cp cp; 151300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 151400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d", index); 151500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1516fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[6] & LMP_EXT_INQ)) 151700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 151800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1519fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->ssp_mode == 0) 152000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 152100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1522fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->cache_enable) 152300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 152400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 152500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memset(&cp, 0, sizeof(cp)); 152600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 152700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg create_ext_inquiry_response(index, cp.data); 152800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1529fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0) 153000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 153100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1532fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->eir, cp.data, sizeof(cp.data)); 153300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1534fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 153500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg OCF_WRITE_EXT_INQUIRY_RESPONSE, 153600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &cp) < 0) 153700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg error("Unable to write EIR data: %s (%d)", 153800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg strerror(errno), errno); 153900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 154000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 154119084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedbergstatic void update_name(int index, const char *name) 154219084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg{ 154319084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg struct btd_adapter *adapter; 154419084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg 1545f674830abac4c9e7ee4d96a354e0f7850942d548Johan Hedberg adapter = manager_find_adapter_by_id(index); 154619084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg if (adapter) 154719084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg adapter_update_local_name(adapter, name); 154800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 154900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 155019084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg} 155119084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg 1552fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedbergstatic void read_local_name_complete(int index, read_local_name_rp *rp) 1553fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg{ 1554fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1555fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 15560e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 15570e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1558fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg if (rp->status) 1559fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg return; 1560fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1561fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->name, rp->name, 248); 156200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1563fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) { 156419084de6a65e4dfad006eb0364eb68e7ced3b46cJohan Hedberg update_name(index, (char *) rp->name); 1565fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg return; 1566fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg } 1567fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1568fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_NAME, &dev->pending); 1569fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1570fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg DBG("Got name for hci%d", index); 1571fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 15729f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg /* Even though it shouldn't happen (assuming the kernel behaves 15739f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * properly) it seems like we might miss the very first 15749f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * initialization commands that the kernel sends. So check for 15759f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * it here (since read_local_name is one of the last init 15769f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * commands) and resend the first ones if we haven't seen 15779f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg * their results yet */ 15789f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 1579fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_test_bit(PENDING_FEATURES, &dev->pending)) 1580fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_INFO_PARAM, 15819f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg OCF_READ_LOCAL_FEATURES, 0, NULL); 15829f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 1583fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_test_bit(PENDING_VERSION, &dev->pending)) 1584fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_INFO_PARAM, 15859f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg OCF_READ_LOCAL_VERSION, 0, NULL); 15869f524fe68a075edd9d0cfdbadea181c76cce4ff5Johan Hedberg 15874f8d6ba3531fc2d27d17a54e073e3db529fc1cf5Johan Hedberg if (!dev->pending && dev->up) 15885c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 1589fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg} 1590fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 1591e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedbergstatic void read_tx_power_complete(int index, void *ptr) 1592e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg{ 1593fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1594fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 1595e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg read_inq_response_tx_power_level_rp *rp = ptr; 1596e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg 15970e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 15980e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1599e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg if (rp->status) 1600e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg return; 1601e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg 1602fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->tx_power = rp->level; 160300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 1604e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg} 1605e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg 1606af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedbergstatic void read_simple_pairing_mode_complete(int index, void *ptr) 1607af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg{ 1608700d2ae37c0008e87bc7d3e25027cf80b8ba98e5Johan Hedberg struct dev_info *dev = &devs[index]; 1609af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg read_simple_pairing_mode_rp *rp = ptr; 1610af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg struct btd_adapter *adapter; 1611af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 16120e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 16130e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1614af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg if (rp->status) 1615af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg return; 1616af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 1617fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->ssp_mode = rp->mode; 161800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 161900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1620700d2ae37c0008e87bc7d3e25027cf80b8ba98e5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 1621af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg if (!adapter) { 1622af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg error("No matching adapter found"); 1623af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg return; 1624af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg } 1625af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 1626af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg adapter_update_ssp_mode(adapter, rp->mode); 1627af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg} 1628af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg 16290e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedbergstatic void read_local_ext_features_complete(int index, 16305288199788ecb17183d6517da3062cd94692a900Johan Hedberg const read_local_ext_features_rp *rp) 16315288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 16325288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 16335288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16340e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 16350e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 16365288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (rp->status) 16375288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1639f674830abac4c9e7ee4d96a354e0f7850942d548Johan Hedberg adapter = manager_find_adapter_by_id(index); 16405288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 16415288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("No matching adapter found"); 16425288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16435288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16445288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16455288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Local Extended feature page number is 1 */ 16465288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (rp->page_num != 1) 16475288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16485288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16495288199788ecb17183d6517da3062cd94692a900Johan Hedberg btd_adapter_update_local_ext_features(adapter, rp->features); 16505288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16515288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16525a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedbergstatic void read_bd_addr_complete(int index, read_bd_addr_rp *rp) 16535a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg{ 1654fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 1655fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 16560e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, rp->status); 16570e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 16585a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg if (rp->status) 16595a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg return; 16605a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1661fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(&dev->bdaddr, &rp->bdaddr); 16625a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1663fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 16645a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg return; 16655a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1666fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_clear_bit(PENDING_BDADDR, &dev->pending); 16675a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 166828c405b17a3131494c11599705885ae630c52ee2Johan Hedberg DBG("Got bdaddr for hci%d", index); 16695a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 1670fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending && dev->up) 16715c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 16725a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg} 16735a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 167442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void cmd_status(int index, void *ptr) 16755288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1676fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 16775288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_status *evt = ptr; 16785288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t opcode = btohs(evt->opcode); 16795288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16805288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) 1681fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg start_inquiry(&dev->bdaddr, evt->status, FALSE); 16825288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 168442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void read_scan_complete(int index, uint8_t status, void *ptr) 16855288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 16865288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 16875288199788ecb17183d6517da3062cd94692a900Johan Hedberg read_scan_enable_rp *rp = ptr; 16885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16890e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, status); 16900e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 1691f674830abac4c9e7ee4d96a354e0f7850942d548Johan Hedberg adapter = manager_find_adapter_by_id(index); 16925288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 16935288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 16945288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 16955288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 16965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 16975288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_mode_changed(adapter, rp->enable); 16985288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 16995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1700914a9093c108cf67a1ef08bffc7db2e4c9a5b1b9Johan Hedbergstatic int write_class(int index, uint32_t class) 170100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1702fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 170300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_class_of_dev_cp cp; 170400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 170500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d class 0x%06x", index, class); 170600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 170700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memcpy(cp.dev_class, &class, 3); 170800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1709fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, 171000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg WRITE_CLASS_OF_DEV_CP_SIZE, &cp) < 0) 171100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return -errno; 171200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1713fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pending_cod = class; 171400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 171500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 171600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 171700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 171800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg/* Limited Discoverable bit mask in CoD */ 171900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg#define LIMITED_BIT 0x002000 172000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 172100c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_set_limited_discoverable(int index, gboolean limited) 172200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1723fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 172400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int num = (limited ? 2 : 1); 172500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg uint8_t lap[] = { 0x33, 0x8b, 0x9e, 0x00, 0x8b, 0x9e }; 172600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_current_iac_lap_cp cp; 172700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 172800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d limited %d", index, limited); 172900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 173000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Check if limited bit needs to be set/reset */ 173100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (limited) 1732fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod |= LIMITED_BIT; 173300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg else 1734fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod &= ~LIMITED_BIT; 173500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 173600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* If we dont need the toggling, save an unnecessary CoD write */ 1737fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->pending_cod || dev->wanted_cod == dev->current_cod) 173800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 173900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 174000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* 174100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * 1: giac 174200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * 2: giac + liac 174300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg */ 174400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memset(&cp, 0, sizeof(cp)); 174500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg cp.num_current_iac = num; 174600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg memcpy(&cp.lap, lap, num * 3); 174700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1748fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CURRENT_IAC_LAP, 174900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg (num * 3 + 1), &cp) < 0) 175000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return -errno; 175100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1752fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg return write_class(index, dev->wanted_cod); 175300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 175400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 175500c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic void write_class_complete(int index, uint8_t status) 175600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 1757fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 175800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg struct btd_adapter *adapter; 175900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 176000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (status) 176100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 176200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1763fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->pending_cod == 0) 176400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 176500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1766fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->current_cod = dev->pending_cod; 1767fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pending_cod = 0; 176800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1769fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg adapter = manager_find_adapter(&dev->bdaddr); 177000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (adapter) 1771fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_adapter_class_changed(adapter, dev->current_cod); 177200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 177300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 177400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1775fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->wanted_cod == dev->current_cod) 177600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return; 177700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 1778fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->wanted_cod & LIMITED_BIT && 1779fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg !(dev->current_cod & LIMITED_BIT)) 178000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg hciops_set_limited_discoverable(index, TRUE); 1781fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg else if (!(dev->wanted_cod & LIMITED_BIT) && 1782fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg (dev->current_cod & LIMITED_BIT)) 178300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg hciops_set_limited_discoverable(index, FALSE); 178400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg else 1785fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg write_class(index, dev->wanted_cod); 178600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 178700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 178842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void cmd_complete(int index, void *ptr) 17895288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1790fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 17915288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_complete *evt = ptr; 17925288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t opcode = btohs(evt->opcode); 17935288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t status = *((uint8_t *) ptr + EVT_CMD_COMPLETE_SIZE); 17945288199788ecb17183d6517da3062cd94692a900Johan Hedberg 17955288199788ecb17183d6517da3062cd94692a900Johan Hedberg switch (opcode) { 1796be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION): 1797be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg ptr += sizeof(evt_cmd_complete); 1798be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg read_local_version_complete(index, ptr); 1799be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg break; 1800be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES): 1801be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg ptr += sizeof(evt_cmd_complete); 1802be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg read_local_features_complete(index, ptr); 1803be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg break; 18045288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_EXT_FEATURES): 18055288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 18060e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg read_local_ext_features_complete(index, ptr); 18075288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18085a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BD_ADDR): 18095a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg ptr += sizeof(evt_cmd_complete); 18105a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg read_bd_addr_complete(index, ptr); 18115a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg break; 18125288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_PERIODIC_INQUIRY): 1813fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg start_inquiry(&dev->bdaddr, status, TRUE); 18145288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18155288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY): 1816fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg inquiry_complete(&dev->bdaddr, status, TRUE); 18175288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18185288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL): 1819fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg inquiry_complete(&dev->bdaddr, status, FALSE); 18205288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18215288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_LE_HOST_SUPPORTED): 18222db4f654cb730adffe7b55044327f68808cd1c9dJohan Hedberg write_le_host_complete(index, status); 18235288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18245288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE): 1825fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_le_set_scan_enable_complete(&dev->bdaddr, status); 18265288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18275288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME): 1828bd7f8939b50a12418476245f9b5117801f858b02Johan Hedberg if (!status) 1829fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, 1830bd7f8939b50a12418476245f9b5117801f858b02Johan Hedberg OCF_READ_LOCAL_NAME, 0, 0); 18315288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18325288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE): 1833073c798c8f77c9d63aa4008c2c56cd645f68c7afJohan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_READ_SCAN_ENABLE, 1834073c798c8f77c9d63aa4008c2c56cd645f68c7afJohan Hedberg 0, NULL); 18355288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18365288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SCAN_ENABLE): 18375288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 183842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg read_scan_complete(index, status, ptr); 18395288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18405288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV): 184100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg write_class_complete(index, status); 18425288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18435288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SIMPLE_PAIRING_MODE): 18447afa48dcf311926269dcfb8ec1a2a12c94eb2d5bJohan Hedberg if (!status) 1845fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, 18467afa48dcf311926269dcfb8ec1a2a12c94eb2d5bJohan Hedberg OCF_READ_SIMPLE_PAIRING_MODE, 0, NULL); 18475288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18485288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SIMPLE_PAIRING_MODE): 18495288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1850af56f3b6d5c0261d9faf8c95cf4da5b244a03caeJohan Hedberg read_simple_pairing_mode_complete(index, ptr); 18515288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18525288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_NAME): 18535288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1854fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg read_local_name_complete(index, ptr); 18555288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 1856e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, 1857e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL): 18585288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1859e47f4351bcea802ee23a9db237ecd4802894e97eJohan Hedberg read_tx_power_complete(index, ptr); 18605288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 18615288199788ecb17183d6517da3062cd94692a900Johan Hedberg }; 18625288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 18635288199788ecb17183d6517da3062cd94692a900Johan Hedberg 186442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_name_information(int index, void *ptr) 18655288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1866fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 18675288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_remote_name_req_complete *evt = ptr; 18685288199788ecb17183d6517da3062cd94692a900Johan Hedberg char name[MAX_NAME_LENGTH + 1]; 18695288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18700e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 18710e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 18725288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(name, 0, sizeof(name)); 18735288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18745288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!evt->status) 18755288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(name, evt->name, MAX_NAME_LENGTH); 18765288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1877fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_remote_name(&dev->bdaddr, &evt->bdaddr, evt->status, name); 18785288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 18795288199788ecb17183d6517da3062cd94692a900Johan Hedberg 188042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_version_information(int index, void *ptr) 18815288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1882fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 18835288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_read_remote_version_complete *evt = ptr; 1884b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 18855288199788ecb17183d6517da3062cd94692a900Johan Hedberg 18860e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 18870e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 18885288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 18895288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 18905288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1891b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_conn_by_handle(dev, btohs(evt->handle)); 1892b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn == NULL) 18935288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 18945288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1895b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg write_version_info(&dev->bdaddr, &conn->bdaddr, 1896b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg btohs(evt->manufacturer), evt->lmp_ver, 1897b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg btohs(evt->lmp_subver)); 18985288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 18995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 190042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void inquiry_result(int index, int plen, void *ptr) 19015288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1902fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 19035288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 19045288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 19055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19065288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 19075288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info *info = ptr; 190842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg uint32_t class = info->dev_class[0] | 190942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg (info->dev_class[1] << 8) | 191042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg (info->dev_class[2] << 16); 19115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1912b98312395e628aa8e7c25b963dad7d21c714fcc7Johan Hedberg btd_event_device_found(&dev->bdaddr, &info->bdaddr, class, 191342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 0, NULL); 19145288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_SIZE; 19155288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 19165288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 19175288199788ecb17183d6517da3062cd94692a900Johan Hedberg 191842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void inquiry_result_with_rssi(int index, int plen, void *ptr) 19195288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1920fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 19215288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 19225288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 19235288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19245288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!num) 19255288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 19265288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19275288199788ecb17183d6517da3062cd94692a900Johan Hedberg if ((plen - 1) / num == INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE) { 19285288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 19295288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info_with_rssi_and_pscan_mode *info = ptr; 19305288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 193142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 193242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 19335288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1934b98312395e628aa8e7c25b963dad7d21c714fcc7Johan Hedberg btd_event_device_found(&dev->bdaddr, &info->bdaddr, 19355288199788ecb17183d6517da3062cd94692a900Johan Hedberg class, info->rssi, NULL); 19365288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; 19375288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 19385288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 19395288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 19405288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info_with_rssi *info = ptr; 19415288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 194242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 194342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 19445288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1945b98312395e628aa8e7c25b963dad7d21c714fcc7Johan Hedberg btd_event_device_found(&dev->bdaddr, &info->bdaddr, 19465288199788ecb17183d6517da3062cd94692a900Johan Hedberg class, info->rssi, NULL); 19475288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_WITH_RSSI_SIZE; 19485288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 19495288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 19505288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 19515288199788ecb17183d6517da3062cd94692a900Johan Hedberg 195242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void extended_inquiry_result(int index, int plen, void *ptr) 19535288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1954fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 19555288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 19565288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 19575288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19585288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 19595288199788ecb17183d6517da3062cd94692a900Johan Hedberg extended_inquiry_info *info = ptr; 19605288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 196142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 196242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 19635288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1964b98312395e628aa8e7c25b963dad7d21c714fcc7Johan Hedberg btd_event_device_found(&dev->bdaddr, &info->bdaddr, class, 19655288199788ecb17183d6517da3062cd94692a900Johan Hedberg info->rssi, info->data); 19665288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += EXTENDED_INQUIRY_INFO_SIZE; 19675288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 19685288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 19695288199788ecb17183d6517da3062cd94692a900Johan Hedberg 197042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_features_information(int index, void *ptr) 19715288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 1972fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 19735288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_read_remote_features_complete *evt = ptr; 1974b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 19755288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19760e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 19770e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 19785288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 19795288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 19805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1981b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_conn_by_handle(dev, btohs(evt->handle)); 1982b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn == NULL) 19835288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 19845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1985b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg write_features_info(&dev->bdaddr, &conn->bdaddr, evt->features, NULL); 19865288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 19875288199788ecb17183d6517da3062cd94692a900Johan Hedberg 19888e17ca3a784294aec947866071c38d934e21940dJohan Hedbergstruct remote_version_req { 19898e17ca3a784294aec947866071c38d934e21940dJohan Hedberg int index; 19908e17ca3a784294aec947866071c38d934e21940dJohan Hedberg uint16_t handle; 19918e17ca3a784294aec947866071c38d934e21940dJohan Hedberg}; 19928e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 19938e17ca3a784294aec947866071c38d934e21940dJohan Hedbergstatic gboolean __get_remote_version(gpointer user_data) 19948e17ca3a784294aec947866071c38d934e21940dJohan Hedberg{ 19958e17ca3a784294aec947866071c38d934e21940dJohan Hedberg struct remote_version_req *req = user_data; 19968e17ca3a784294aec947866071c38d934e21940dJohan Hedberg struct dev_info *dev = &devs[req->index]; 19978e17ca3a784294aec947866071c38d934e21940dJohan Hedberg read_remote_version_cp cp; 19988e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 19998e17ca3a784294aec947866071c38d934e21940dJohan Hedberg DBG("hci%d handle %u", req->index, req->handle); 20008e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 20018e17ca3a784294aec947866071c38d934e21940dJohan Hedberg memset(&cp, 0, sizeof(cp)); 20028e17ca3a784294aec947866071c38d934e21940dJohan Hedberg cp.handle = htobs(req->handle); 20038e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 20048e17ca3a784294aec947866071c38d934e21940dJohan Hedberg hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_READ_REMOTE_VERSION, 20058e17ca3a784294aec947866071c38d934e21940dJohan Hedberg READ_REMOTE_VERSION_CP_SIZE, &cp); 20068e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 20078e17ca3a784294aec947866071c38d934e21940dJohan Hedberg return FALSE; 20088e17ca3a784294aec947866071c38d934e21940dJohan Hedberg} 20098e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 20108e17ca3a784294aec947866071c38d934e21940dJohan Hedbergstatic void get_remote_version(int index, uint16_t handle) 20118e17ca3a784294aec947866071c38d934e21940dJohan Hedberg{ 20128e17ca3a784294aec947866071c38d934e21940dJohan Hedberg struct remote_version_req *req; 20138e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 20148e17ca3a784294aec947866071c38d934e21940dJohan Hedberg req = g_new0(struct remote_version_req, 1); 20158e17ca3a784294aec947866071c38d934e21940dJohan Hedberg req->handle = handle; 20168e17ca3a784294aec947866071c38d934e21940dJohan Hedberg req->index = index; 20178e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 20188e17ca3a784294aec947866071c38d934e21940dJohan Hedberg g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1, __get_remote_version, 20198e17ca3a784294aec947866071c38d934e21940dJohan Hedberg req, g_free); 20208e17ca3a784294aec947866071c38d934e21940dJohan Hedberg} 20218e17ca3a784294aec947866071c38d934e21940dJohan Hedberg 2022b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic void conn_free(struct bt_conn *conn) 2023b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 2024b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->io != NULL) { 2025b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_io_channel_shutdown(conn->io, TRUE, NULL); 2026b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_io_channel_unref(conn->io); 2027b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 2028b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 2029b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_free(conn); 2030b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 2031b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 203232c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedbergstatic inline void conn_failed(int index, bdaddr_t *bdaddr, uint8_t status) 203332c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg{ 203432c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg struct dev_info *dev = &devs[index]; 203532c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg struct bt_conn *conn; 203632c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg 2037b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg btd_event_conn_failed(&dev->bdaddr, bdaddr, status); 203832c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg 203932c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg conn = find_connection(dev, bdaddr); 204032c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg if (conn == NULL) 204132c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg return; 204232c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg 2043d4a25e44a88e15da6f523183b30997e6669c481dJohan Hedberg bonding_complete(dev, conn, status); 204432c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg 204532c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg dev->connections = g_slist_remove(dev->connections, conn); 204632c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg conn_free(conn); 204732c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg} 204832c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg 204942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void conn_complete(int index, void *ptr) 20505288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2051fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 20525288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_conn_complete *evt = ptr; 20535288199788ecb17183d6517da3062cd94692a900Johan Hedberg char filename[PATH_MAX]; 20545288199788ecb17183d6517da3062cd94692a900Johan Hedberg char local_addr[18], peer_addr[18], *str; 2055b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 20565288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20575288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->link_type != ACL_LINK) 20585288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 20595288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2060b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("status 0x%02x", evt->status); 2061bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 206232c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg if (evt->status != 0) { 206332c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg conn_failed(index, &evt->bdaddr, evt->status); 206432c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg return; 2065bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg } 2066bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 206732c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg conn = get_connection(dev, &evt->bdaddr); 206832c3d13c1f736c2a500df0b1f497ebcdb9fb27fdJohan Hedberg conn->handle = btohs(evt->handle); 20695288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2070b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg btd_event_conn_complete(&dev->bdaddr, &evt->bdaddr); 20715288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2072b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->secmode3) 2073b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg bonding_complete(dev, conn, 0); 2074b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 20755288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* check if the remote version needs be requested */ 2076fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg ba2str(&dev->bdaddr, local_addr); 20775288199788ecb17183d6517da3062cd94692a900Johan Hedberg ba2str(&evt->bdaddr, peer_addr); 20785288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20795288199788ecb17183d6517da3062cd94692a900Johan Hedberg create_name(filename, sizeof(filename), STORAGEDIR, local_addr, 20805288199788ecb17183d6517da3062cd94692a900Johan Hedberg "manufacturers"); 20815288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20825288199788ecb17183d6517da3062cd94692a900Johan Hedberg str = textfile_get(filename, peer_addr); 20835288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!str) 20848e17ca3a784294aec947866071c38d934e21940dJohan Hedberg get_remote_version(index, btohs(evt->handle)); 20855288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 20865288199788ecb17183d6517da3062cd94692a900Johan Hedberg free(str); 20875288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 20885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 20895f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demariostatic inline void le_conn_complete(int index, void *ptr) 20905f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario{ 2091fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 20925f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario evt_le_connection_complete *evt = ptr; 20935f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario char filename[PATH_MAX]; 20945f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario char local_addr[18], peer_addr[18], *str; 2095b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg struct bt_conn *conn; 20965f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 2097b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg if (evt->status) { 2098b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg btd_event_conn_failed(&dev->bdaddr, &evt->peer_bdaddr, 2099b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg evt->status); 2100b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg return; 2101bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg } 2102bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 2103b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg conn = get_connection(dev, &evt->peer_bdaddr); 2104b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg conn->handle = btohs(evt->handle); 21055f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 2106b18b51e97bddc67c8b4ff10a3f97241ac480596aJohan Hedberg btd_event_conn_complete(&dev->bdaddr, &evt->peer_bdaddr); 21075f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 21085f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario /* check if the remote version needs be requested */ 2109fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg ba2str(&dev->bdaddr, local_addr); 21105f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario ba2str(&evt->peer_bdaddr, peer_addr); 21115f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 21125f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario create_name(filename, sizeof(filename), STORAGEDIR, local_addr, 21135f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario "manufacturers"); 21145f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 21155f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario str = textfile_get(filename, peer_addr); 21165f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario if (!str) 21178e17ca3a784294aec947866071c38d934e21940dJohan Hedberg get_remote_version(index, btohs(evt->handle)); 21185f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario else 21195f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario free(str); 21205f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario} 21215f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 212242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void disconn_complete(int index, void *ptr) 21235288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2124fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 21255288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_disconn_complete *evt = ptr; 2126b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 2127b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 2128b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("handle %u status 0x%02x", btohs(evt->handle), evt->status); 2129bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 2130bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg if (evt->status != 0) 2131bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg return; 21325288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2133b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_conn_by_handle(dev, btohs(evt->handle)); 2134b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn == NULL) 2135bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg return; 2136bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 2137b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg dev->connections = g_slist_remove(dev->connections, conn); 2138bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 2139bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg btd_event_disconn_complete(&dev->bdaddr, &conn->bdaddr); 2140bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 2141b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn_free(conn); 21425288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 21435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 214442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void auth_complete(int index, void *ptr) 21455288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2146fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 21475288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_auth_complete *evt = ptr; 2148b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 21495288199788ecb17183d6517da3062cd94692a900Johan Hedberg 21500e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 21510e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2152b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_conn_by_handle(dev, btohs(evt->handle)); 2153b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn == NULL) 21545288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 21555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2156b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg bonding_complete(dev, conn, evt->status); 21575288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 21585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 215942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void simple_pairing_complete(int index, void *ptr) 21605288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2161fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 21625288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_simple_pairing_complete *evt = ptr; 21635288199788ecb17183d6517da3062cd94692a900Johan Hedberg 21640e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d status %u", index, evt->status); 21650e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2166fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_simple_pairing_complete(&dev->bdaddr, &evt->bdaddr, 216742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg evt->status); 21685288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 21695288199788ecb17183d6517da3062cd94692a900Johan Hedberg 217042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void conn_request(int index, void *ptr) 21715288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2172fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 21735288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_conn_request *evt = ptr; 21745288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = evt->dev_class[0] | (evt->dev_class[1] << 8) 21755288199788ecb17183d6517da3062cd94692a900Johan Hedberg | (evt->dev_class[2] << 16); 21765288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2177fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_remote_class(&dev->bdaddr, &evt->bdaddr, class); 21785288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 21795288199788ecb17183d6517da3062cd94692a900Johan Hedberg 21805f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demariostatic inline void le_advertising_report(int index, evt_le_meta_event *meta) 21815288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2182fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 21835288199788ecb17183d6517da3062cd94692a900Johan Hedberg le_advertising_info *info; 2184e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes uint8_t num_reports; 2185e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes const uint8_t RSSI_SIZE = 1; 21865288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2187e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes num_reports = meta->data[0]; 21885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2189e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes info = (le_advertising_info *) &meta->data[1]; 2190e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes btd_event_advertising_report(&dev->bdaddr, info); 2191e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes num_reports--; 2192e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes 2193e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes while (num_reports--) { 2194e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes info = (le_advertising_info *) (info->data + info->length + 2195e27614655c3c37d1ed82a944e9f34e129a7c1f6cAndre Guedes RSSI_SIZE); 2196fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg btd_event_advertising_report(&dev->bdaddr, info); 21975288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 21985288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 21995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 22005f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demariostatic inline void le_metaevent(int index, void *ptr) 22015f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario{ 22025f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario evt_le_meta_event *meta = ptr; 22035f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 22045f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario DBG("hci%d LE Meta Event %u", index, meta->subevent); 22055f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 22065f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario switch (meta->subevent) { 22075f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario case EVT_LE_ADVERTISING_REPORT: 22085f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario le_advertising_report(index, meta); 22095f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario break; 22105f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 22115f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario case EVT_LE_CONN_COMPLETE: 22125f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario le_conn_complete(index, meta->data); 22135f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario break; 22145f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario } 22155f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario} 22165f9ebfaa84eacb59a47bcdd6c9479d8b94552414Sheldon Demario 221755694454017b04a416931a81964bb695f48b3d93Johan Hedbergstatic void stop_hci_dev(int index) 22185288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2219fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 22205288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2221b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (dev->sk < 0) 22225288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 22235288199788ecb17183d6517da3062cd94692a900Johan Hedberg 222455694454017b04a416931a81964bb695f48b3d93Johan Hedberg info("Stopping hci%d event socket", index); 22255288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2226b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (dev->watch_id > 0) 2227b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_source_remove(dev->watch_id); 2228b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 2229b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (dev->io != NULL) 2230b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_io_channel_unref(dev->io); 2231b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 2232fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_close_dev(dev->sk); 2233b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 2234b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_slist_foreach(dev->keys, (GFunc) g_free, NULL); 2235b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_slist_free(dev->keys); 2236b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 22373e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg g_slist_foreach(dev->uuids, (GFunc) g_free, NULL); 22383e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg g_slist_free(dev->uuids); 22393e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg 2240b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_slist_foreach(dev->connections, (GFunc) conn_free, NULL); 2241bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg g_slist_free(dev->connections); 2242bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg 2243149f5d0b49d7c52e64e3c63505f689a9f872af8bLuiz Augusto von Dentz init_dev_info(index, -1, dev->registered, dev->already_up); 22445288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 22455288199788ecb17183d6517da3062cd94692a900Johan Hedberg 22465288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic gboolean io_security_event(GIOChannel *chan, GIOCondition cond, 22475288199788ecb17183d6517da3062cd94692a900Johan Hedberg gpointer data) 22485288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 22495288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; 225042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg int type, index = GPOINTER_TO_INT(data); 2251fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 225242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg struct hci_dev_info di; 225390e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz ssize_t len; 22545288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_event_hdr *eh; 22555288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_status *evt; 225690e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz int fd; 22575288199788ecb17183d6517da3062cd94692a900Johan Hedberg 22585288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { 225955694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 22605288199788ecb17183d6517da3062cd94692a900Johan Hedberg return FALSE; 22615288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 22625288199788ecb17183d6517da3062cd94692a900Johan Hedberg 226390e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz fd = g_io_channel_unix_get_fd(chan); 226490e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz 226590e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz len = read(fd, buf, sizeof(buf)); 226690e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz if (len < 0) { 226790e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz if (errno == EAGAIN) 22685288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 226955694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 22705288199788ecb17183d6517da3062cd94692a900Johan Hedberg return FALSE; 22715288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 22725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 22735288199788ecb17183d6517da3062cd94692a900Johan Hedberg type = *ptr++; 22745288199788ecb17183d6517da3062cd94692a900Johan Hedberg 22755288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (type != HCI_EVENT_PKT) 22765288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 22775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 22785288199788ecb17183d6517da3062cd94692a900Johan Hedberg eh = (hci_event_hdr *) ptr; 22795288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += HCI_EVENT_HDR_SIZE; 22805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 228142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg memset(&di, 0, sizeof(di)); 228242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (hci_devinfo(index, &di) == 0) { 2283fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(&dev->bdaddr, &di.bdaddr); 22845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 228542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (ignore_device(&di)) 228642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg return TRUE; 228742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg } 228855694454017b04a416931a81964bb695f48b3d93Johan Hedberg 22895288199788ecb17183d6517da3062cd94692a900Johan Hedberg switch (eh->evt) { 22905288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CMD_STATUS: 229142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cmd_status(index, ptr); 22925288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 22935288199788ecb17183d6517da3062cd94692a900Johan Hedberg 22945288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CMD_COMPLETE: 229542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cmd_complete(index, ptr); 22965288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 22975288199788ecb17183d6517da3062cd94692a900Johan Hedberg 22985288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_NAME_REQ_COMPLETE: 229942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_name_information(index, ptr); 23005288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23015288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23025288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_READ_REMOTE_VERSION_COMPLETE: 230342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_version_information(index, ptr); 23045288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23065288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_READ_REMOTE_FEATURES_COMPLETE: 230742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_features_information(index, ptr); 23085288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23095288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23105288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_HOST_FEATURES_NOTIFY: 231142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_features_notify(index, ptr); 23125288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23135288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23145288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_COMPLETE: 23155288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt = (evt_cmd_status *) ptr; 2316fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg inquiry_complete(&dev->bdaddr, evt->status, FALSE); 23175288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23185288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23195288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_RESULT: 232042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_result(index, eh->plen, ptr); 23215288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23235288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_RESULT_WITH_RSSI: 232442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_result_with_rssi(index, eh->plen, ptr); 23255288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23265288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23275288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_EXTENDED_INQUIRY_RESULT: 232842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg extended_inquiry_result(index, eh->plen, ptr); 23295288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23305288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23315288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CONN_COMPLETE: 233242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg conn_complete(index, ptr); 23335288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23355288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_DISCONN_COMPLETE: 233642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg disconn_complete(index, ptr); 23375288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23395288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_AUTH_COMPLETE: 234042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg auth_complete(index, ptr); 23415288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23425288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23435288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_SIMPLE_PAIRING_COMPLETE: 234442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg simple_pairing_complete(index, ptr); 23455288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23475288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CONN_REQUEST: 234842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg conn_request(index, ptr); 23495288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23505288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LE_META_EVENT: 235142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg le_metaevent(index, ptr); 23525288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23535288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_PIN_CODE_REQ: 235442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg pin_code_request(index, (bdaddr_t *) ptr); 23555288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23565288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23575288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LINK_KEY_REQ: 235842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg link_key_request(index, (bdaddr_t *) ptr); 23595288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23605288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23615288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LINK_KEY_NOTIFY: 236242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg link_key_notify(index, ptr); 23635288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23655288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_RETURN_LINK_KEYS: 236642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg return_link_keys(index, ptr); 23675288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23695288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_IO_CAPABILITY_REQUEST: 237042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg io_capa_request(index, ptr); 23715288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23735288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_IO_CAPABILITY_RESPONSE: 237442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg io_capa_response(index, ptr); 23755288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23765288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23775288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_CONFIRM_REQUEST: 237842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_confirm_request(index, ptr); 23795288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23815288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_PASSKEY_REQUEST: 238242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_passkey_request(index, ptr); 23835288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23855288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_PASSKEY_NOTIFY: 238642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_passkey_notify(index, ptr); 23875288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23895288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_OOB_DATA_REQUEST: 239042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_oob_data_request(index, ptr); 23915288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 23925288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 23935288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23945288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 23955288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 23965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 23975a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedbergstatic void start_hci_dev(int index) 23985288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 2399fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2400fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg GIOChannel *chan = dev->io; 2401e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg GIOCondition cond; 24025288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_filter flt; 24035288199788ecb17183d6517da3062cd94692a900Johan Hedberg 24045288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (chan) 24055288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 24065288199788ecb17183d6517da3062cd94692a900Johan Hedberg 24075a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg info("Listening for HCI events on hci%d", index); 24085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 24095288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Set filter */ 24105288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_clear(&flt); 24115288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 24125288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CMD_STATUS, &flt); 24135288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CMD_COMPLETE, &flt); 24145288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); 24155288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); 24165288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); 24175288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_RETURN_LINK_KEYS, &flt); 24185288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_IO_CAPABILITY_REQUEST, &flt); 24195288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_IO_CAPABILITY_RESPONSE, &flt); 24205288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_CONFIRM_REQUEST, &flt); 24215288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_PASSKEY_REQUEST, &flt); 24225288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_OOB_DATA_REQUEST, &flt); 24235288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_PASSKEY_NOTIFY, &flt); 24245288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_KEYPRESS_NOTIFY, &flt); 24255288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_SIMPLE_PAIRING_COMPLETE, &flt); 24265288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_AUTH_COMPLETE, &flt); 24275288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); 24285288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt); 24295288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); 24305288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_HOST_FEATURES_NOTIFY, &flt); 24315288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); 24325288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); 24335288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); 24345288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); 24355288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CONN_REQUEST, &flt); 24365288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CONN_COMPLETE, &flt); 24375288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt); 24385288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LE_META_EVENT, &flt); 2439fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (setsockopt(dev->sk, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { 24405288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Can't set filter on hci%d: %s (%d)", 24415a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg index, strerror(errno), errno); 24425288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 24435288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 24445288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2445fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg chan = g_io_channel_unix_new(dev->sk); 2446e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg cond = G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR; 2447fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->watch_id = g_io_add_watch_full(chan, G_PRIORITY_LOW, cond, 2448e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg io_security_event, 2449e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg GINT_TO_POINTER(index), NULL); 2450fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->io = chan; 24511522d6568002afa27ee7a3280b3166f7ecb02f06Johan Hedberg dev->pin_length = 0; 24525288199788ecb17183d6517da3062cd94692a900Johan Hedberg 24535288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 24545288199788ecb17183d6517da3062cd94692a900Johan Hedberg 24555288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* End of HCI event callbacks */ 24565288199788ecb17183d6517da3062cd94692a900Johan Hedberg 2457a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodestatic gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data) 2458a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2459a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode int status, fd = g_io_channel_unix_get_fd(io); 2460a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid_t child_pid; 2461a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2462a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) { 2463a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("child_exit: unable to read child pid from pipe"); 2464a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return TRUE; 2465a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2466a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2467a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (waitpid(child_pid, &status, 0) != child_pid) 2468a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("waitpid(%d) failed", child_pid); 2469a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode else 24708e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("child %d exited", child_pid); 2471a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2472a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return TRUE; 2473a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2474a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2475a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodestatic void at_child_exit(void) 2476a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2477a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid_t pid = getpid(); 2478a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2479a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid)) 2480a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("unable to write to child pipe"); 2481a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2482a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2483fccdf4a50765ef5a2dbde00d95f65e94ce0a543bJohan Hedbergstatic void device_devup_setup(int index) 2484a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2485fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2486a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_info di; 24875a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg read_stored_link_key_cp cp; 2488a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 24890e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 24900e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2491ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (hci_devinfo(index, &di) < 0) 2492a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2493a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 249465bf1321203b55b11167ac8b869da28a86ce49d2David Scherba if (ignore_device(&di)) 2495a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 2496a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2497fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(&dev->bdaddr, &di.bdaddr); 2498fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->features, di.features, 8); 2499a352058752e541539b09e55124d411a534cc14afJohan Hedberg 2500a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Set page timeout */ 2501a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if ((main_opts.flags & (1 << HCID_SET_PAGETO))) { 2502a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode write_page_timeout_cp cp; 2503a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2504a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode cp.timeout = htobs(main_opts.pageto); 2505fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, 2506a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode WRITE_PAGE_TIMEOUT_CP_SIZE, &cp); 2507a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2508a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 25095a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 25105a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg cp.read_all = 1; 2511fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY, 25126d2ce6e859049d6cf56e5db2197e02b0359ac442Johan Hedberg READ_STORED_LINK_KEY_CP_SIZE, &cp); 2513fccdf4a50765ef5a2dbde00d95f65e94ce0a543bJohan Hedberg 2514fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->pending) 25155c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg init_adapter(index); 2516a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2517a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2518be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void init_pending(int index) 2519be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 2520fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2521fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2522fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_BDADDR, &dev->pending); 2523fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_VERSION, &dev->pending); 2524fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_FEATURES, &dev->pending); 2525fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_NAME, &dev->pending); 2526be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 2527be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 252871ba00415bd2941db24958d1e6e265611945194eJohan Hedbergstatic struct dev_info *init_device(int index, gboolean already_up) 2529a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 253071ba00415bd2941db24958d1e6e265611945194eJohan Hedberg struct dev_info *dev; 2531a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_req dr; 2532c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg int dd; 25336844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg pid_t pid; 25346844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 25350e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 25360e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 25376844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg dd = hci_open_dev(index); 25386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (dd < 0) { 25396844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Unable to open hci%d: %s (%d)", index, 25406844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg strerror(errno), errno); 254171ba00415bd2941db24958d1e6e265611945194eJohan Hedberg return NULL; 25426844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 25436844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 25446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (index > max_dev) { 25456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg max_dev = index; 2546ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg devs = g_realloc(devs, sizeof(devs[0]) * (max_dev + 1)); 25476844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 25486844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 254971ba00415bd2941db24958d1e6e265611945194eJohan Hedberg dev = init_dev_info(index, dd, FALSE, already_up); 2550be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg init_pending(index); 25515a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg start_hci_dev(index); 2552a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2553149f5d0b49d7c52e64e3c63505f689a9f872af8bLuiz Augusto von Dentz /* Avoid forking if nothing else has to be done */ 2554149f5d0b49d7c52e64e3c63505f689a9f872af8bLuiz Augusto von Dentz if (already_up) 255571ba00415bd2941db24958d1e6e265611945194eJohan Hedberg return dev; 2556149f5d0b49d7c52e64e3c63505f689a9f872af8bLuiz Augusto von Dentz 2557a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Do initialization in the separate process */ 2558a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid = fork(); 2559a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode switch (pid) { 2560a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case 0: 2561a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode atexit(at_child_exit); 2562a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2563a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case -1: 2564a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Fork failed. Can't init device hci%d: %s (%d)", 2565c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg index, strerror(errno), errno); 2566a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode default: 25678e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("child %d forked", pid); 256871ba00415bd2941db24958d1e6e265611945194eJohan Hedberg return dev; 2569a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2570a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2571a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode memset(&dr, 0, sizeof(dr)); 2572ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode dr.dev_id = index; 2573a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2574a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Set link mode */ 2575a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode dr.dev_opt = main_opts.link_mode; 2576c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) 2577a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Can't set link mode on hci%d: %s (%d)", 2578ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg index, strerror(errno), errno); 2579a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2580a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Start HCI device */ 2581ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (ioctl(dd, HCIDEVUP, index) < 0 && errno != EALREADY) { 2582a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Can't init device hci%d: %s (%d)", 2583ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode index, strerror(errno), errno); 2584a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode goto fail; 2585a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2586a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2587a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode hci_close_dev(dd); 2588a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode exit(0); 2589a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2590a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodefail: 2591a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode hci_close_dev(dd); 2592a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode exit(1); 2593a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2594a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2595cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedbergstatic void init_conn_list(int index) 2596cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg{ 2597cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg struct dev_info *dev = &devs[index]; 2598cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg struct hci_conn_list_req *cl; 2599cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg struct hci_conn_info *ci; 2600cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg int err, i; 2601cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2602cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg DBG("hci%d", index); 2603cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2604cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); 2605cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2606cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg cl->dev_id = index; 2607cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg cl->conn_num = 10; 2608cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg ci = cl->conn_info; 2609cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2610cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg if (ioctl(dev->sk, HCIGETCONNLIST, cl) < 0) { 2611cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg error("Unable to get connection list: %s (%d)", 2612cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg strerror(errno), errno); 2613cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg goto failed; 2614cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg } 2615cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2616cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg for (i = 0; i < cl->conn_num; i++, ci++) { 2617b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 2618cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2619cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg if (ci->type != ACL_LINK) 2620cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg continue; 2621cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2622b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = get_connection(dev, &ci->bdaddr); 2623cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg conn->handle = ci->handle; 2624cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg } 2625cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2626cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg err = 0; 2627cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2628cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedbergfailed: 2629cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg g_free(cl); 2630cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg} 2631cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 2632ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void device_event(int event, int index) 2633a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 2634a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode switch (event) { 2635a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_REG: 2636ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d registered", index); 2637149f5d0b49d7c52e64e3c63505f689a9f872af8bLuiz Augusto von Dentz init_device(index, FALSE); 2638a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2639a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2640a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_UNREG: 2641ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d unregistered", index); 264255694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 2643fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (devs[index].registered) 26445c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg btd_manager_unregister_adapter(index); 2645a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2646a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2647a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_UP: 2648ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d up", index); 2649fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].up = TRUE; 2650ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode device_devup_setup(index); 2651a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2652a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2653a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_DOWN: 2654ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d down", index); 2655fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].up = FALSE; 2656fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].pending_cod = 0; 2657fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg devs[index].cache_enable = TRUE; 2658fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!devs[index].pending) { 265965edd4d5397d00d204123432fd83326486860783Johan Hedberg struct btd_adapter *adapter; 266065edd4d5397d00d204123432fd83326486860783Johan Hedberg 2661f674830abac4c9e7ee4d96a354e0f7850942d548Johan Hedberg adapter = manager_find_adapter_by_id(index); 266265edd4d5397d00d204123432fd83326486860783Johan Hedberg if (adapter) 2663f674830abac4c9e7ee4d96a354e0f7850942d548Johan Hedberg btd_adapter_stop(adapter); 266465edd4d5397d00d204123432fd83326486860783Johan Hedberg 2665be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg init_pending(index); 26665a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg } 2667a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 2668a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2669a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 2670cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2671f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedbergstatic gboolean init_known_adapters(gpointer user_data) 267294e91856179a268805256055ffd5155d1468b99cAlok Barsode{ 2673cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_dev_list_req *dl; 2674cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_dev_req *dr; 2675f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg int i, err, ctl = GPOINTER_TO_INT(user_data); 2676ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg size_t req_size; 2677cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 26780e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 26790e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2680ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg req_size = HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t); 2681ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg 2682ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg dl = g_try_malloc0(req_size); 2683cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (!dl) { 2684ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg error("Can't allocate devlist buffer"); 2685f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 2686cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2687cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2688cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode dl->dev_num = HCI_MAX_DEV; 2689cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode dr = dl->dev_req; 2690cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2691ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg if (ioctl(ctl, HCIGETDEVLIST, dl) < 0) { 2692c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2693ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg error("Can't get device list: %s (%d)", strerror(-err), -err); 269483003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi g_free(dl); 2695f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 2696cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2697cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2698cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode for (i = 0; i < dl->dev_num; i++, dr++) { 2699fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev; 2700149f5d0b49d7c52e64e3c63505f689a9f872af8bLuiz Augusto von Dentz gboolean already_up; 2701fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 2702149f5d0b49d7c52e64e3c63505f689a9f872af8bLuiz Augusto von Dentz already_up = hci_test_bit(HCI_UP, &dr->dev_opt); 2703cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 270471ba00415bd2941db24958d1e6e265611945194eJohan Hedberg dev = init_device(dr->dev_id, already_up); 270571ba00415bd2941db24958d1e6e265611945194eJohan Hedberg if (dev == NULL) 270671ba00415bd2941db24958d1e6e265611945194eJohan Hedberg continue; 27075c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2708fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->already_up) 2709be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg continue; 2710be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 27119ac53f53be09b96ebd6379b3c7113a05324b47dfLuiz Augusto von Dentz init_conn_list(dr->dev_id); 27125c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 2713fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pending = 0; 2714fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_set_bit(PENDING_VERSION, &dev->pending); 2715fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg hci_send_cmd(dev->sk, OGF_INFO_PARAM, 2716be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg OCF_READ_LOCAL_VERSION, 0, NULL); 2717be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg device_event(HCI_DEV_UP, dr->dev_id); 2718cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2719cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2720cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_free(dl); 2721f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg 2722f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 272394e91856179a268805256055ffd5155d1468b99cAlok Barsode} 272494e91856179a268805256055ffd5155d1468b99cAlok Barsode 2725cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsodestatic gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, 2726cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode gpointer data) 2727cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode{ 2728cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; 2729cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode evt_stack_internal *si; 2730cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode evt_si_device *sd; 2731cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_event_hdr *eh; 273290e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz int type, fd; 273390e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz ssize_t len; 2734cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2735cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ptr = buf; 2736cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 273790e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz fd = g_io_channel_unix_get_fd(chan); 273890e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz 273990e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz len = read(fd, buf, sizeof(buf)); 274090e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz if (len < 0) { 274190e78131e3e347eeee25e5cd831b374907359e3fLuiz Augusto von Dentz if (errno == EAGAIN) 2742cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2743cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2744cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode error("Read from control socket failed: %s (%d)", 2745ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg strerror(errno), errno); 2746cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return FALSE; 2747cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2748cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2749cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode type = *ptr++; 2750cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2751cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (type != HCI_EVENT_PKT) 2752cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2753cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2754cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode eh = (hci_event_hdr *) ptr; 2755cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (eh->evt != EVT_STACK_INTERNAL) 2756cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2757cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2758cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ptr += HCI_EVENT_HDR_SIZE; 2759cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2760cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode si = (evt_stack_internal *) ptr; 2761cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode switch (si->type) { 2762cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode case EVT_SI_DEVICE: 2763cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode sd = (void *) &si->data; 2764cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode device_event(sd->event, sd->dev_id); 2765cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode break; 2766cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2767cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2768cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 2769cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode} 2770cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 277134c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic int hciops_setup(void) 2772cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode{ 2773cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct sockaddr_hci addr; 2774cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_filter flt; 2775a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode GIOChannel *ctl_io, *child_io; 277618e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg int sock, err; 277718e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg 27780e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 27790e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 278018e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg if (child_pipe[0] != -1) 278118e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg return -EALREADY; 2782cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2783a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (pipe(child_pipe) < 0) { 2784c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2785c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("pipe(): %s (%d)", strerror(-err), -err); 2786c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2787a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 2788a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2789a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode child_io = g_io_channel_unix_new(child_pipe[0]); 2790a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode g_io_channel_set_close_on_unref(child_io, TRUE); 27918b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_io_id = g_io_add_watch(child_io, 27928b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, 27938b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_exit, NULL); 2794a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode g_io_channel_unref(child_io); 2795a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 2796cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode /* Create and bind HCI socket */ 2797cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); 2798cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (sock < 0) { 2799c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2800c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("Can't open HCI socket: %s (%d)", strerror(-err), 2801c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg -err); 2802c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2803cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2804cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2805cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode /* Set filter */ 2806cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_clear(&flt); 2807cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 2808cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_set_event(EVT_STACK_INTERNAL, &flt); 28096844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { 2810c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2811c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("Can't set filter: %s (%d)", strerror(-err), -err); 2812c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2813cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2814cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2815cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode memset(&addr, 0, sizeof(addr)); 2816cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode addr.hci_family = AF_BLUETOOTH; 2817cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode addr.hci_dev = HCI_DEV_NONE; 28186844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 2819c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 28206844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Can't bind HCI socket: %s (%d)", strerror(-err), -err); 2821c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2822cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 2823cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2824cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ctl_io = g_io_channel_unix_new(sock); 2825cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_io_channel_set_close_on_unref(ctl_io, TRUE); 2826cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 28278b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL); 2828cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2829cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_io_channel_unref(ctl_io); 2830cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 2831f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg g_idle_add(init_known_adapters, GINT_TO_POINTER(sock)); 2832f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg 2833f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return 0; 2834cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode} 2835cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 283634c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic void hciops_cleanup(void) 283734c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode{ 28386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int i; 28396844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 28400e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 28410e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2842b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg for (i = 0; i <= max_dev; i++) 2843b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg stop_hci_dev(i); 28446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 28456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg g_free(devs); 28466844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg devs = NULL; 28476844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg max_dev = -1; 28486844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 28498b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_io_id) { 28508b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg g_source_remove(child_io_id); 28518b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_io_id = 0; 28528b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 28538b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 28548b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (ctl_io_id) { 28558b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg g_source_remove(ctl_io_id); 28568b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg ctl_io_id = 0; 28578b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 28588b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 28598b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_pipe[0] >= 0) { 28608b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg close(child_pipe[0]); 28618b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_pipe[0] = -1; 28628b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 28638b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 28648b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_pipe[1] >= 0) { 28658b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg close(child_pipe[1]); 28668b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_pipe[1] = -1; 28678b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 286834c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode} 286934c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode 287027c58425af807521e618f29b08e7a99496aeda3bJohan Hedbergstatic int hciops_set_powered(int index, gboolean powered) 2871076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode{ 2872fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 28736844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2874076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 287527c58425af807521e618f29b08e7a99496aeda3bJohan Hedberg DBG("hci%d powered %d", index, powered); 287627c58425af807521e618f29b08e7a99496aeda3bJohan Hedberg 287727c58425af807521e618f29b08e7a99496aeda3bJohan Hedberg if (powered == FALSE) 287827c58425af807521e618f29b08e7a99496aeda3bJohan Hedberg return hciops_power_off(index); 28790e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2880fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIDEVUP, index) == 0) 28816844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2882076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 28836844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (errno == EALREADY) 28846844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2885076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 28866844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 28876844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Can't init device hci%d: %s (%d)", 28886844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg index, strerror(-err), -err); 2889076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 2890c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 2891076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode} 2892076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 289300c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_set_dev_class(int index, uint8_t major, uint8_t minor) 2894d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode{ 2895fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 289600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int err; 2897d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 28985c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d major %u minor %u", index, major, minor); 28995c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 290000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Update only the major and minor class bits keeping remaining bits 290100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * intact*/ 2902fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod &= 0xffe000; 2903fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod |= ((major & 0x1f) << 8) | minor; 2904d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 2905fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->wanted_cod == dev->current_cod || 2906fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->cache_enable || dev->pending_cod) 290700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 29080e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2909fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg DBG("Changing Major/Minor class to 0x%06x", dev->wanted_cod); 2910eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode 2911fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = write_class(index, dev->wanted_cod); 291200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (err < 0) 291300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg error("Adapter class update failed: %s (%d)", 291400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg strerror(-err), -err); 2915d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 291600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return err; 2917eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode} 2918eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode 29193af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasistatic int hciops_start_inquiry(int index, uint8_t length, gboolean periodic) 2920a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode{ 2921fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 2922a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; 29236844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2924a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 29250e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d length %u periodic %d", index, length, periodic); 29260e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 2927a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode if (periodic) { 2928a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode periodic_inquiry_cp cp; 2929a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2930a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memset(&cp, 0, sizeof(cp)); 2931a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memcpy(&cp.lap, lap, 3); 2932a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.max_period = htobs(24); 2933a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.min_period = htobs(16); 2934388cdea43870fe5c5163cfbe96d3218111ba39b5Claudio Takahasi cp.length = length; 2935a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.num_rsp = 0x00; 2936a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2937fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 29386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_PERIODIC_INQUIRY, 29396844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg PERIODIC_INQUIRY_CP_SIZE, &cp); 2940a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode } else { 2941a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode inquiry_cp inq_cp; 2942a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2943a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memset(&inq_cp, 0, sizeof(inq_cp)); 2944a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memcpy(&inq_cp.lap, lap, 3); 2945388cdea43870fe5c5163cfbe96d3218111ba39b5Claudio Takahasi inq_cp.length = length; 2946a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode inq_cp.num_rsp = 0x00; 2947a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2948fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 29496844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_INQUIRY, INQUIRY_CP_SIZE, &inq_cp); 2950a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode } 2951a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2952a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode if (err < 0) 2953a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode err = -errno; 2954a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 2955a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode return err; 2956a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode} 2957a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 29583ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int le_set_scan_enable(int index, uint8_t enable) 295970cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi{ 2960fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 29613ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi le_set_scan_enable_cp cp; 29623ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 29630e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d enable %u", index, enable); 29640e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 29653ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi memset(&cp, 0, sizeof(cp)); 29663ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.enable = enable; 29673ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.filter_dup = 0; 296870cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 2969fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE, 29703ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi LE_SET_SCAN_ENABLE_CP_SIZE, &cp) < 0) 29716844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 297270cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 29736844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 297470cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi} 297570cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 29763ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int hciops_start_scanning(int index) 297770cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi{ 2978fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 29793ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi le_set_scan_parameters_cp cp; 29803ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 29810e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 29820e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 29833ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi memset(&cp, 0, sizeof(cp)); 29843ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.type = 0x01; /* Active scanning */ 2985051ad18433a74feb39f8f3296ea1ddf2ae009aecBruna Moreira /* The recommended value for scan interval and window is 11.25 msec. 2986051ad18433a74feb39f8f3296ea1ddf2ae009aecBruna Moreira * It is calculated by: time = n * 0.625 msec */ 2987051ad18433a74feb39f8f3296ea1ddf2ae009aecBruna Moreira cp.interval = htobs(0x0012); 2988051ad18433a74feb39f8f3296ea1ddf2ae009aecBruna Moreira cp.window = htobs(0x0012); 29893ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.own_bdaddr_type = 0; /* Public address */ 29903ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.filter = 0; /* Accept all adv packets */ 29913ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 2992fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LE_CTL, OCF_LE_SET_SCAN_PARAMETERS, 29933ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi LE_SET_SCAN_PARAMETERS_CP_SIZE, &cp) < 0) 299470cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi return -errno; 299570cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 29963ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi return le_set_scan_enable(index, 1); 29973ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi} 29983ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 29993ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int hciops_stop_scanning(int index) 30003ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi{ 30010e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 30020e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 30033ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi return le_set_scan_enable(index, 0); 300470cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi} 300570cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 3006ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsodestatic int hciops_resolve_name(int index, bdaddr_t *bdaddr) 3007ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode{ 3008fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3009ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode remote_name_req_cp cp; 30100e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 30110e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 30120e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 30130e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 3014ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 3015ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode memset(&cp, 0, sizeof(cp)); 3016ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode bacpy(&cp.bdaddr, bdaddr); 3017ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode cp.pscan_rep_mode = 0x02; 3018ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 3019fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ, 30206844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg REMOTE_NAME_REQ_CP_SIZE, &cp) < 0) 30216844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 3022ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 30236844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 3024ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode} 3025ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 3026164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsodestatic int hciops_set_name(int index, const char *name) 3027164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode{ 3028fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3029164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode change_local_name_cp cp; 3030164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 30310e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d, name %s", index, name); 30320e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3033164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode memset(&cp, 0, sizeof(cp)); 3034164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode strncpy((char *) cp.name, name, sizeof(cp.name)); 3035164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 3036fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, 30376844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg CHANGE_LOCAL_NAME_CP_SIZE, &cp) < 0) 30386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 3039164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 3040fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(dev->name, cp.name, 248); 304100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 304200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 30436844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 3044164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode} 3045164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 3046b96f44db8e91325968a0149595b2522d4a22481aAlok Barsodestatic int hciops_cancel_resolve_name(int index, bdaddr_t *bdaddr) 3047b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode{ 3048fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3049b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode remote_name_req_cancel_cp cp; 30500e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 30510e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 30520e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 30530e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 3054b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 3055b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode memset(&cp, 0, sizeof(cp)); 3056b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode bacpy(&cp.bdaddr, bdaddr); 3057b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 3058fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL, 30596844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg REMOTE_NAME_REQ_CANCEL_CP_SIZE, &cp) < 0) 30606844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 3061b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 30626844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 3063b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode} 3064b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 306561f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliystatic int hciops_fast_connectable(int index, gboolean enable) 306661f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy{ 3067fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 306861f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy write_page_activity_cp cp; 306961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy uint8_t type; 307061f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 30710e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d enable %d", index, enable); 30720e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 307361f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy if (enable) { 307461f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy type = PAGE_SCAN_TYPE_INTERLACED; 307561f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.interval = 0x0024; /* 22.5 msec page scan interval */ 307661f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy } else { 307761f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy type = PAGE_SCAN_TYPE_STANDARD; /* default */ 307861f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.interval = 0x0800; /* default 1.28 sec page scan */ 307961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy } 308061f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 308161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.window = 0x0012; /* default 11.25 msec page scan window */ 308261f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 3083fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_PAGE_ACTIVITY, 308461f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy WRITE_PAGE_ACTIVITY_CP_SIZE, &cp) < 0) 30856844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 3086fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg else if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 30876844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_PAGE_SCAN_TYPE, 1, &type) < 0) 30886844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 308961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 30906844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 309161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy} 309261f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 30936b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedbergstatic int hciops_read_clock(int index, bdaddr_t *bdaddr, int which, 309458b68d33c5fad024f2b235555be0234e97721920Johan Hedberg int timeout, uint32_t *clock, 309558b68d33c5fad024f2b235555be0234e97721920Johan Hedberg uint16_t *accuracy) 30965bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter{ 3097fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 30986b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg uint16_t handle = 0; 30996b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg char addr[18]; 31006b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg int ret; 3101fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 31026b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg ba2str(bdaddr, addr); 31036b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg DBG("hci%d addr %s which %d timeout %d", index, addr, which, timeout); 31046b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg 31056b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg ret = get_handle(index, bdaddr, &handle); 31066b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg if (ret < 0) 31076b9921107e0346f0fc6f5475b0dea17f65dc94ceJohan Hedberg return ret; 31080e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 310958b68d33c5fad024f2b235555be0234e97721920Johan Hedberg if (hci_read_clock(dev->sk, htobs(handle), which, clock, accuracy, 31106844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg timeout) < 0) 31116844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 31125bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 31136844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 31145bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter} 31155bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 3116b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedbergstatic int hciops_read_bdaddr(int index, bdaddr_t *bdaddr) 3117b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg{ 3118fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3119fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 31200e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 3121fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 3122fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg bacpy(bdaddr, &dev->bdaddr); 3123fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 31246844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 3125b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg} 3126b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg 3127885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedbergstatic int hciops_block_device(int index, bdaddr_t *bdaddr) 3128885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg{ 3129fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 31300e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 31310e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 31320e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 31330e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 31340e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3135fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIBLOCKADDR, bdaddr) < 0) 3136885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg return -errno; 3137885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 31386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 3139885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg} 3140885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 3141885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedbergstatic int hciops_unblock_device(int index, bdaddr_t *bdaddr) 3142885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg{ 3143fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 31440e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 31450e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 31460e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 31470e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 31480e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3149fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (ioctl(dev->sk, HCIUNBLOCKADDR, bdaddr) < 0) 3150885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg return -errno; 3151885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 31526844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 3153885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg} 3154885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 3155f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedbergstatic int hciops_get_conn_list(int index, GSList **conns) 3156f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg{ 3157fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3158cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg GSList *l; 3159f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 31600e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 31610e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3162f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg *conns = NULL; 3163f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 3164cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg for (l = dev->connections; l != NULL; l = g_slist_next(l)) { 3165b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn = l->data; 3166cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg 316776522723bdf7cb46a692f88a6ad616045bfa46e8Johan Hedberg *conns = g_slist_append(*conns, 3168cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg g_memdup(&conn->bdaddr, sizeof(bdaddr_t))); 3169cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg } 3170f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 3171cc0e50e3ab1a612ffb72b9021229f660d54f9388Johan Hedberg return 0; 3172f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg} 3173f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 3174e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedbergstatic int hciops_read_local_version(int index, struct hci_version *ver) 3175e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg{ 3176fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3177fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 31780e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 3179fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 3180fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(ver, &dev->ver, sizeof(*ver)); 3181fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 31826844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 3183e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg} 3184e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg 318548e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedbergstatic int hciops_read_local_features(int index, uint8_t *features) 318648e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg{ 3187fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3188fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 31890e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d", index); 3190fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 3191fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg memcpy(features, dev->features, 8); 3192fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 31936844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 319448e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg} 319548e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg 3196bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedbergstatic int hciops_disconnect(int index, bdaddr_t *bdaddr) 319706dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg{ 3198bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg DBG("hci%d", index); 319906dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 3200bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg return disconnect_addr(index, bdaddr, HCI_OE_USER_ENDED_CONNECTION); 320106dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg} 320206dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 32031bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedbergstatic int hciops_remove_bonding(int index, bdaddr_t *bdaddr) 32041bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg{ 3205fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 320673c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg delete_stored_link_key_cp cp; 3207b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg GSList *match; 32080e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 32090e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 32100e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 32110e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 32121bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 3213b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg match = g_slist_find_custom(dev->keys, bdaddr, (GCompareFunc) bacmp); 3214b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (match) { 3215b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg g_free(match->data); 3216b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg dev->keys = g_slist_delete_link(dev->keys, match); 3217b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg } 3218b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 321973c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg memset(&cp, 0, sizeof(cp)); 322073c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg bacpy(&cp.bdaddr, bdaddr); 322173c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg 32221bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg /* Delete the link key from the Bluetooth chip */ 3223fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_DELETE_STORED_LINK_KEY, 322473c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg DELETE_STORED_LINK_KEY_CP_SIZE, &cp) < 0) 32256844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 32261bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 32276844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 32281bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg} 32291bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 3230e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedbergstatic int hciops_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin) 3231e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg{ 3232fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 32330e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 32346844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 3235e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 32360e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 32370e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 32380e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3239e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg if (pin) { 3240e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg pin_code_reply_cp pr; 3241e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg size_t len = strlen(pin); 3242e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 3243fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->pin_length = len; 324442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 3245e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg memset(&pr, 0, sizeof(pr)); 3246e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg bacpy(&pr.bdaddr, bdaddr); 3247e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg memcpy(pr.pin_code, pin, len); 3248e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg pr.pin_len = len; 3249fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 32506844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_PIN_CODE_REPLY, 3251e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg PIN_CODE_REPLY_CP_SIZE, &pr); 3252e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg } else 3253fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 3254e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg OCF_PIN_CODE_NEG_REPLY, 6, bdaddr); 3255e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 32566844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 32576844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 3258e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 3259e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg return err; 3260e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg} 3261e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 3262889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedbergstatic int hciops_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey) 3263889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg{ 3264fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 32650e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg char addr[18]; 32666844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 3267889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 32680e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg ba2str(bdaddr, addr); 32690e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG("hci%d dba %s", index, addr); 32700e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 3271889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg if (passkey != INVALID_PASSKEY) { 3272889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg user_passkey_reply_cp cp; 3273889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 3274889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg memset(&cp, 0, sizeof(cp)); 3275889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg bacpy(&cp.bdaddr, bdaddr); 3276889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg cp.passkey = passkey; 3277889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 3278fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 32796844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_USER_PASSKEY_REPLY, 3280889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg USER_PASSKEY_REPLY_CP_SIZE, &cp); 3281889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg } else 3282fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = hci_send_cmd(dev->sk, OGF_LINK_CTL, 3283889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg OCF_USER_PASSKEY_NEG_REPLY, 6, bdaddr); 3284889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 32856844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 32866844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 3287889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 3288889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg return err; 3289889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg} 3290889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 32915c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_enable_le(int index) 32927ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi{ 3293fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 32947ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi write_le_host_supported_cp cp; 32957ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 32965c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d", index); 32975c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3298fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!(dev->features[4] & LMP_LE)) 32995c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return -ENOTSUP; 33000e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg 33015c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg cp.le = 0x01; 3302fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg cp.simul = (dev->features[6] & LMP_LE_BREDR) ? 0x01 : 0x00; 33037ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 3304fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (hci_send_cmd(dev->sk, OGF_HOST_CTL, 33056844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_LE_HOST_SUPPORTED, 33066844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg WRITE_LE_HOST_SUPPORTED_CP_SIZE, &cp) < 0) 33076844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 33087ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 33096844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 33107ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi} 33117ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 33123e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedbergstatic uint8_t generate_service_class(int index) 331300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 3314fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 33153e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg GSList *l; 33163e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg uint8_t val = 0; 33173e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg 33183e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg for (l = dev->uuids; l != NULL; l = g_slist_next(l)) { 3319006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg struct uuid_info *uuid = l->data; 33203e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg 3321006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg val |= uuid->svc_hint; 33223e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg } 33233e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg 33243e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg return val; 33253e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg} 33263e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg 33273e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedbergstatic int update_service_classes(int index) 33283e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg{ 33293e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg struct dev_info *dev = &devs[index]; 33303e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg uint8_t value; 333100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg int err; 333200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 33333e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg value = generate_service_class(index); 33343e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg 33355c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg DBG("hci%d value %u", index, value); 33365c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 333700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Update only the service class, keep the limited bit, 333800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * major/minor class bits intact */ 3339fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod &= 0x00ffff; 3340fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->wanted_cod |= (value << 16); 334100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 334200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* If the cache is enabled or an existing CoD write is in progress 334300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * just bail out */ 3344fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->cache_enable || dev->pending_cod) 334500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 334600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 334700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* If we already have the CoD we want, update EIR and return */ 3348fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->current_cod == dev->wanted_cod) { 334900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 335000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 335100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 335200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3353fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg DBG("Changing service classes to 0x%06x", dev->wanted_cod); 335400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3355fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg err = write_class(index, dev->wanted_cod); 335600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg if (err < 0) 335700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg error("Adapter class update failed: %s (%d)", 335800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg strerror(-err), -err); 335900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 336000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return err; 336100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 336200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3363006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedbergstatic int hciops_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint) 336400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 33653e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg struct dev_info *dev = &devs[index]; 3366006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg struct uuid_info *info; 336700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 336800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d", index); 336900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3370006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg info = g_new0(struct uuid_info, 1); 3371006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg memcpy(&info->uuid, uuid, sizeof(*uuid)); 3372006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg info->svc_hint = svc_hint; 3373006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg 3374006301ab40fc71da92f593ddfb2dba70202bd061Johan Hedberg dev->uuids = g_slist_append(dev->uuids, info); 337500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 33763e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg return update_service_classes(index); 33773e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg} 337800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 33793e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedbergstatic int hciops_remove_uuid(int index, uuid_t *uuid) 33803e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg{ 33813e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg struct dev_info *dev = &devs[index]; 33823e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg GSList *match; 338300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 33843e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg match = g_slist_find_custom(dev->uuids, uuid, sdp_uuid_cmp); 33853e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg if (match) { 33863e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg g_free(match->data); 33873e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg dev->uuids = g_slist_delete_link(dev->uuids, match); 338800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 338900c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 33903e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg DBG("hci%d", index); 33913e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg 33923e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg return update_service_classes(index); 339300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 339400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 339500c2267405ff3416672401cf394f06017a6814c1Johan Hedbergstatic int hciops_disable_cod_cache(int index) 339600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg{ 3397fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 339800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3399fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg DBG("hci%d cache_enable %d", index, dev->cache_enable); 3400fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 3401fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->cache_enable) 340200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 340300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 340400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg DBG("hci%d current_cod 0x%06x wanted_cod 0x%06x", index, 3405fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->current_cod, dev->wanted_cod); 340600c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 340700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg /* Disable and flush svc cache. All successive service class 340800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg * updates * will be written to the device */ 3409fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg dev->cache_enable = FALSE; 341000c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3411fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (dev->current_cod == dev->wanted_cod) { 341200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg update_ext_inquiry_response(index); 341300c2267405ff3416672401cf394f06017a6814c1Johan Hedberg return 0; 341400c2267405ff3416672401cf394f06017a6814c1Johan Hedberg } 341500c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 3416fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg return write_class(index, dev->wanted_cod); 341700c2267405ff3416672401cf394f06017a6814c1Johan Hedberg} 341800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg 34195c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedbergstatic int hciops_restore_powered(int index) 34205c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg{ 3421fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg struct dev_info *dev = &devs[index]; 3422fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg 3423fdb266b6797638b89b9ba9fe0d89670bf71d47c5Johan Hedberg if (!dev->already_up && dev->up) 342463ff6738abc6bf21becbbfde583062502e7728a6Johan Hedberg return hciops_power_off(index); 34255c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 34265c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg return 0; 34275c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg} 34285c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg 3429dccef4954d8dcaa4559be66263ea0945cd9be528Johan Hedbergstatic int hciops_load_keys(int index, GSList *keys, gboolean debug_keys) 3430b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg{ 3431b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg struct dev_info *dev = &devs[index]; 3432b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 3433dccef4954d8dcaa4559be66263ea0945cd9be528Johan Hedberg DBG("hci%d keys %d debug_keys %d", index, g_slist_length(keys), 3434dccef4954d8dcaa4559be66263ea0945cd9be528Johan Hedberg debug_keys); 3435b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 3436b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg if (dev->keys != NULL) 3437b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg return -EEXIST; 3438b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 3439b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg dev->keys = keys; 3440dccef4954d8dcaa4559be66263ea0945cd9be528Johan Hedberg dev->debug_keys = debug_keys; 3441b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 3442b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg return 0; 3443b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg} 3444b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg 34459634f5c410e761219037129f71c591459a854391Johan Hedbergstatic int hciops_set_io_capability(int index, uint8_t io_capability) 34469634f5c410e761219037129f71c591459a854391Johan Hedberg{ 3447b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct dev_info *dev = &devs[index]; 3448b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3449b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg dev->io_capability = io_capability; 3450b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3451b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return 0; 3452b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 3453b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3454596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedbergstatic int request_authentication(int index, bdaddr_t *bdaddr) 3455596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg{ 3456596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg struct dev_info *dev = &devs[index]; 3457596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg auth_requested_cp cp; 3458596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg uint16_t handle; 3459596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg int err; 3460596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg 3461596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg DBG("hci%d", index); 3462596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg 3463596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg err = get_handle(index, bdaddr, &handle); 3464596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg if (err < 0) 3465596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg return err; 3466596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg 3467596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg memset(&cp, 0, sizeof(cp)); 3468596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg cp.handle = htobs(handle); 3469596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg 3470596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_AUTH_REQUESTED, 3471596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg AUTH_REQUESTED_CP_SIZE, &cp) < 0) 3472596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg return -errno; 3473596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg 3474596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg return 0; 3475596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg} 3476596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg 3477b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic void bonding_connect_cb(GIOChannel *io, GError *err, gpointer user_data) 3478b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 3479b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn = user_data; 3480b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct dev_info *dev = conn->dev; 3481b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3482b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (!conn->io) { 3483b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (!err) 3484b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_io_channel_shutdown(io, TRUE, NULL); 3485b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return; 3486b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 3487b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3488b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (err) 3489b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* Wait proper error to be propagated by bonding complete */ 3490b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return; 3491b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3492596e8ddd21ff0074f79acc9b0577a7050ade5bf6Johan Hedberg if (request_authentication(dev->id, &conn->bdaddr) < 0) 3493b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg goto failed; 3494b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3495b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return; 3496b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3497b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergfailed: 3498b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg bonding_complete(dev, conn, HCI_UNSPECIFIED_ERROR); 3499b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 3500b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3501b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic int hciops_create_bonding(int index, bdaddr_t *bdaddr, uint8_t io_cap) 3502b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 3503b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct dev_info *dev = &devs[index]; 3504b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg BtIOSecLevel sec_level; 3505b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 3506b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg GError *err = NULL; 3507b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3508b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = get_connection(dev, bdaddr); 3509b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3510b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->io != NULL) 3511b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return -EBUSY; 3512b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3513b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->loc_cap = io_cap; 3514b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3515b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If our IO capability is NoInputNoOutput use medium security 3516b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * level (i.e. don't require MITM protection) else use high 3517b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg * security level */ 3518b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (io_cap == 0x03) 3519b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg sec_level = BT_IO_SEC_MEDIUM; 3520b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg else 3521b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg sec_level = BT_IO_SEC_HIGH; 3522b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3523b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->io = bt_io_connect(BT_IO_L2RAW, bonding_connect_cb, conn, 3524b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg NULL, &err, 3525b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg BT_IO_OPT_SOURCE_BDADDR, &dev->bdaddr, 3526b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg BT_IO_OPT_DEST_BDADDR, bdaddr, 3527b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg BT_IO_OPT_SEC_LEVEL, sec_level, 3528b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg BT_IO_OPT_INVALID); 3529b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn->io == NULL) { 3530b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg error("bt_io_connect: %s", err->message); 3531b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_error_free(err); 3532b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return -EIO; 3533b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg } 3534b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3535b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->bonding_initiator = TRUE; 3536b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3537b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return 0; 3538b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg} 3539b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3540b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedbergstatic int hciops_cancel_bonding(int index, bdaddr_t *bdaddr) 3541b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg{ 3542b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct dev_info *dev = &devs[index]; 3543b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct bt_conn *conn; 3544b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3545629c9dbe7f161c0c285749bb014f55a2b30fd65cJohan Hedberg DBG("hci%d", index); 3546629c9dbe7f161c0c285749bb014f55a2b30fd65cJohan Hedberg 3547b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn = find_connection(dev, bdaddr); 3548b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (conn == NULL || conn->io == NULL) 3549b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return -ENOTCONN; 3550b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 3551b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_io_channel_shutdown(conn->io, TRUE, NULL); 3552b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg g_io_channel_unref(conn->io); 3553b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg conn->io = NULL; 3554b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 35559634f5c410e761219037129f71c591459a854391Johan Hedberg return 0; 35569634f5c410e761219037129f71c591459a854391Johan Hedberg} 35579634f5c410e761219037129f71c591459a854391Johan Hedberg 355834c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic struct btd_adapter_ops hci_ops = { 355934c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode .setup = hciops_setup, 356034c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode .cleanup = hciops_cleanup, 356127c58425af807521e618f29b08e7a99496aeda3bJohan Hedberg .set_powered = hciops_set_powered, 35625c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .set_discoverable = hciops_set_discoverable, 35635c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .set_pairable = hciops_set_pairable, 3564eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode .set_limited_discoverable = hciops_set_limited_discoverable, 35653af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasi .start_inquiry = hciops_start_inquiry, 35663af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasi .stop_inquiry = hciops_stop_inquiry, 356770cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi .start_scanning = hciops_start_scanning, 356870cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi .stop_scanning = hciops_stop_scanning, 3569ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode .resolve_name = hciops_resolve_name, 3570b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode .cancel_resolve_name = hciops_cancel_resolve_name, 3571164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode .set_name = hciops_set_name, 357200c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .set_dev_class = hciops_set_dev_class, 357361f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy .set_fast_connectable = hciops_fast_connectable, 35745bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter .read_clock = hciops_read_clock, 3575b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg .read_bdaddr = hciops_read_bdaddr, 3576885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg .block_device = hciops_block_device, 3577885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg .unblock_device = hciops_unblock_device, 3578f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg .get_conn_list = hciops_get_conn_list, 3579e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg .read_local_version = hciops_read_local_version, 358048e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg .read_local_features = hciops_read_local_features, 358106dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg .disconnect = hciops_disconnect, 35821bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg .remove_bonding = hciops_remove_bonding, 3583e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg .pincode_reply = hciops_pincode_reply, 3584df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg .confirm_reply = hciops_confirm_reply, 3585889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg .passkey_reply = hciops_passkey_reply, 35865c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .enable_le = hciops_enable_le, 3587abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg .encrypt_link = hciops_encrypt_link, 358800c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .set_did = hciops_set_did, 35893e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg .add_uuid = hciops_add_uuid, 35903e1b64c81d0ef4ae92b601114aa06d85c735d646Johan Hedberg .remove_uuid = hciops_remove_uuid, 359100c2267405ff3416672401cf394f06017a6814c1Johan Hedberg .disable_cod_cache = hciops_disable_cod_cache, 35925c1c35eb38790bd068bfd37e0355aafb194f7812Johan Hedberg .restore_powered = hciops_restore_powered, 3593b95ef500f79d9c2fb81be4866037bc1c7780e6f6Johan Hedberg .load_keys = hciops_load_keys, 35949634f5c410e761219037129f71c591459a854391Johan Hedberg .set_io_capability = hciops_set_io_capability, 3595b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg .create_bonding = hciops_create_bonding, 3596b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg .cancel_bonding = hciops_cancel_bonding, 359734c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode}; 359834c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode 359934c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic int hciops_init(void) 360034c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode{ 36010e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 3602d30044157466e7f34e7f2d5d7ce70215ea013338Johan Hedberg return btd_register_adapter_ops(&hci_ops, FALSE); 360334c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode} 3604d57934d1d09c34d1b136c572cad1dff6306c8c48Johan Hedberg 360594e91856179a268805256055ffd5155d1468b99cAlok Barsodestatic void hciops_exit(void) 360694e91856179a268805256055ffd5155d1468b99cAlok Barsode{ 36070e9aac1c77cac6e125ea0dbf68769e12e0928964Johan Hedberg DBG(""); 3608929393b82db06368ff5fa4074bc209d1d4d03a48Marcel Holtmann btd_adapter_cleanup_ops(&hci_ops); 360994e91856179a268805256055ffd5155d1468b99cAlok Barsode} 361094e91856179a268805256055ffd5155d1468b99cAlok Barsode 361194e91856179a268805256055ffd5155d1468b99cAlok BarsodeBLUETOOTH_PLUGIN_DEFINE(hciops, VERSION, 36121ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann BLUETOOTH_PLUGIN_PRIORITY_LOW, hciops_init, hciops_exit) 3613