hciops.c revision be49c2621d577da4fafd462265b611289547f183
194e91856179a268805256055ffd5155d1468b99cAlok Barsode/* 294e91856179a268805256055ffd5155d1468b99cAlok Barsode * 394e91856179a268805256055ffd5155d1468b99cAlok Barsode * BlueZ - Bluetooth protocol stack for Linux 494e91856179a268805256055ffd5155d1468b99cAlok Barsode * 59184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> 694e91856179a268805256055ffd5155d1468b99cAlok Barsode * 794e91856179a268805256055ffd5155d1468b99cAlok Barsode * This program is free software; you can redistribute it and/or modify 894e91856179a268805256055ffd5155d1468b99cAlok Barsode * it under the terms of the GNU General Public License as published by 994e91856179a268805256055ffd5155d1468b99cAlok Barsode * the Free Software Foundation; either version 2 of the License, or 1094e91856179a268805256055ffd5155d1468b99cAlok Barsode * (at your option) any later version. 1194e91856179a268805256055ffd5155d1468b99cAlok Barsode * 1294e91856179a268805256055ffd5155d1468b99cAlok Barsode * This program is distributed in the hope that it will be useful, 1394e91856179a268805256055ffd5155d1468b99cAlok Barsode * but WITHOUT ANY WARRANTY; without even the implied warranty of 1494e91856179a268805256055ffd5155d1468b99cAlok Barsode * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1594e91856179a268805256055ffd5155d1468b99cAlok Barsode * GNU General Public License for more details. 1694e91856179a268805256055ffd5155d1468b99cAlok Barsode * 1794e91856179a268805256055ffd5155d1468b99cAlok Barsode * You should have received a copy of the GNU General Public License 1894e91856179a268805256055ffd5155d1468b99cAlok Barsode * along with this program; if not, write to the Free Software 1994e91856179a268805256055ffd5155d1468b99cAlok Barsode * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2094e91856179a268805256055ffd5155d1468b99cAlok Barsode * 2194e91856179a268805256055ffd5155d1468b99cAlok Barsode */ 2294e91856179a268805256055ffd5155d1468b99cAlok Barsode 2394e91856179a268805256055ffd5155d1468b99cAlok Barsode#ifdef HAVE_CONFIG_H 2494e91856179a268805256055ffd5155d1468b99cAlok Barsode#include <config.h> 2594e91856179a268805256055ffd5155d1468b99cAlok Barsode#endif 26a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 27a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include <stdio.h> 28cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <errno.h> 29a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include <unistd.h> 30a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include <stdlib.h> 31cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <sys/types.h> 32cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <sys/ioctl.h> 33a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include <sys/wait.h> 3494e91856179a268805256055ffd5155d1468b99cAlok Barsode 3594e91856179a268805256055ffd5155d1468b99cAlok Barsode#include <bluetooth/bluetooth.h> 36cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <bluetooth/hci.h> 37cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <bluetooth/hci_lib.h> 3894e91856179a268805256055ffd5155d1468b99cAlok Barsode 39cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include <glib.h> 40cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 41cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode#include "hcid.h" 42a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include "sdpd.h" 43a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include "adapter.h" 4494e91856179a268805256055ffd5155d1468b99cAlok Barsode#include "plugin.h" 45e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h" 465288199788ecb17183d6517da3062cd94692a900Johan Hedberg#include "storage.h" 475288199788ecb17183d6517da3062cd94692a900Johan Hedberg#include "event.h" 485288199788ecb17183d6517da3062cd94692a900Johan Hedberg#include "device.h" 49a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode#include "manager.h" 50a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 515ade59881c2ee8b57116414dc21615c4c94afd92Claudio Takahasi#define HCI_REQ_TIMEOUT 5000 525ade59881c2ee8b57116414dc21615c4c94afd92Claudio Takahasi 5318e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedbergstatic int child_pipe[2] = { -1, -1 }; 5494e91856179a268805256055ffd5155d1468b99cAlok Barsode 558b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedbergstatic guint child_io_id = 0; 568b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedbergstatic guint ctl_io_id = 0; 578b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 58be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg/* Commands sent by kernel on starting an adapter */ 59be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergenum { 60be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING_BDADDR, 61be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING_VERSION, 62be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING_FEATURES, 63fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg PENDING_NAME, 64be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg}; 65be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 66be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg#define set_bit(nr, addr) (*(addr) |= (1 << (nr))) 67be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg#define clear_bit(nr, addr) (*(addr) &= ~(1 << (nr))) 68be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 69ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg#define SK(index) devs[(index)].sk 70a352058752e541539b09e55124d411a534cc14afJohan Hedberg#define BDADDR(index) devs[(index)].bdaddr 71be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg#define FEATURES(index) devs[(index)].features 72be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg#define VER(index) devs[(index)].ver 735a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg#define UP(index) devs[(index)].up 74be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg#define PENDING(index) devs[(index)].pending 7555694454017b04a416931a81964bb695f48b3d93Johan Hedberg#define CHANNEL(index) devs[(index)].channel 7655694454017b04a416931a81964bb695f48b3d93Johan Hedberg#define WATCH_ID(index) devs[(index)].watch_id 7755694454017b04a416931a81964bb695f48b3d93Johan Hedberg#define PIN_LENGTH(index) devs[(index)].pin_length 78ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg 796844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedbergstatic int max_dev = -1; 80ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedbergstatic struct dev_info { 81ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg int sk; 82a352058752e541539b09e55124d411a534cc14afJohan Hedberg bdaddr_t bdaddr; 83be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg uint8_t features[8]; 84be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg struct hci_version ver; 85be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 865a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg gboolean up; 87be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg unsigned long pending; 8855694454017b04a416931a81964bb695f48b3d93Johan Hedberg 8955694454017b04a416931a81964bb695f48b3d93Johan Hedberg GIOChannel *channel; 9055694454017b04a416931a81964bb695f48b3d93Johan Hedberg guint watch_id; 9155694454017b04a416931a81964bb695f48b3d93Johan Hedberg int pin_length; 92ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg} *devs = NULL; 93ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg 94db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedbergstatic int ignore_device(struct hci_dev_info *di) 95db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg{ 96db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR; 97db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg} 98db5266f0afedc33e2fd6fc3601c16498865f746dJohan Hedberg 99ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedbergstatic void init_dev_info(int index, int sk) 100ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg{ 101ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg memset(&devs[index], 0, sizeof(struct dev_info)); 102ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg SK(index) = sk; 10355694454017b04a416931a81964bb695f48b3d93Johan Hedberg PIN_LENGTH(index) = -1; 104ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg} 1056844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 106abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg/* Async HCI command handling with callback support */ 107abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 108abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstruct hci_cmd_data { 109abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg bt_hci_result_t cb; 110abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t handle; 111abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t ocf; 112abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg gpointer caller_data; 113abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg}; 114abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 115abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstatic gboolean hci_event_watch(GIOChannel *io, 116abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg GIOCondition cond, gpointer user_data) 117abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg{ 118abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg unsigned char buf[HCI_MAX_EVENT_SIZE], *body; 119abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_cmd_data *cmd = user_data; 120abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_cmd_status *evt_status; 121abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_auth_complete *evt_auth; 122abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_encrypt_change *evt_enc; 123abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_event_hdr *hdr; 124abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg set_conn_encrypt_cp cp; 125abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg int dd; 126abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t ocf; 127abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint8_t status = HCI_OE_POWER_OFF; 128abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 129abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (cond & G_IO_NVAL) { 130abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb(status, cmd->caller_data); 131abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return FALSE; 132abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 133abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 134abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (cond & (G_IO_ERR | G_IO_HUP)) 135abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 136abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 137abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg dd = g_io_channel_unix_get_fd(io); 138abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 139abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (read(dd, buf, sizeof(buf)) < 0) 140abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 141abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 142abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hdr = (hci_event_hdr *) (buf + 1); 143abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg body = buf + (1 + HCI_EVENT_HDR_SIZE); 144abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 145abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg switch (hdr->evt) { 146abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_CMD_STATUS: 147abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_status = (evt_cmd_status *) body; 148abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg ocf = cmd_opcode_ocf(evt_status->opcode); 149abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (ocf != cmd->ocf) 150abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 151abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg switch (ocf) { 152abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case OCF_AUTH_REQUESTED: 153abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case OCF_SET_CONN_ENCRYPT: 154abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_status->status != 0) { 155abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Baseband rejected command */ 156abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_status->status; 157abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 158abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 159abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg break; 160abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg default: 161abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 162abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 163abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Wait for the next event */ 164abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 165abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_AUTH_COMPLETE: 166abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_auth = (evt_auth_complete *) body; 167abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_auth->handle != cmd->handle) { 168abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Skipping */ 169abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 170abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 171abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 172abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_auth->status != 0x00) { 173abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_auth->status; 174abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Abort encryption */ 175abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 176abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 177abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 178abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg memset(&cp, 0, sizeof(cp)); 179abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.handle = cmd->handle; 180abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.encrypt = 1; 181abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 182abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->ocf = OCF_SET_CONN_ENCRYPT; 183abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 184abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, 185abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg SET_CONN_ENCRYPT_CP_SIZE, &cp) < 0) { 186abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = HCI_COMMAND_DISALLOWED; 187abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg goto failed; 188abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 189abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Wait for encrypt change event */ 190abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 191abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg case EVT_ENCRYPT_CHANGE: 192abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg evt_enc = (evt_encrypt_change *) body; 193abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (evt_enc->handle != cmd->handle) 194abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 195abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 196abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Procedure finished: reporting status */ 197abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg status = evt_enc->status; 198abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg break; 199abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg default: 200abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg /* Skipping */ 201abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return TRUE; 202abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 203abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 204abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergfailed: 205abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb(status, cmd->caller_data); 206abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_shutdown(io, TRUE, NULL); 207abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 208abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return FALSE; 209abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg} 210abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 211b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic int write_inq_mode(int index, uint8_t mode) 212b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 213b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg write_inquiry_mode_cp cp; 214b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 215b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg memset(&cp, 0, sizeof(cp)); 216b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg cp.mode = mode; 217b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 218b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, 219b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg WRITE_INQUIRY_MODE_CP_SIZE, &cp) < 0) 220b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return -errno; 221b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 222b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 0; 223b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 224b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 225b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic uint8_t get_inquiry_mode(int index) 226b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 227b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[6] & LMP_EXT_INQ) 228b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 2; 229b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 230b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[3] & LMP_RSSI_INQ) 231b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 232b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 233b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (VER(index).manufacturer == 11 && VER(index).hci_rev == 0x00 && 234b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg VER(index).lmp_subver == 0x0757) 235b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 236b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 237b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (VER(index).manufacturer == 15) { 238b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (VER(index).hci_rev == 0x03 && 239b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg VER(index).lmp_subver == 0x6963) 240b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 241b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (VER(index).hci_rev == 0x09 && 242b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg VER(index).lmp_subver == 0x6963) 243b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 244b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (VER(index).hci_rev == 0x00 && 245b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg VER(index).lmp_subver == 0x6965) 246b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 247b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 248b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 249b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (VER(index).manufacturer == 31 && VER(index).hci_rev == 0x2005 && 250b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg VER(index).lmp_subver == 0x1805) 251b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 1; 252b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 253b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg return 0; 254b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 255b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 256be49c2621d577da4fafd462265b611289547f183Johan Hedbergstatic int init_ssp_mode(int index) 257be49c2621d577da4fafd462265b611289547f183Johan Hedberg{ 258be49c2621d577da4fafd462265b611289547f183Johan Hedberg write_simple_pairing_mode_cp cp; 259be49c2621d577da4fafd462265b611289547f183Johan Hedberg 260be49c2621d577da4fafd462265b611289547f183Johan Hedberg if (ioctl(SK(index), HCIGETAUTHINFO, NULL) < 0 && errno == EINVAL) 261be49c2621d577da4fafd462265b611289547f183Johan Hedberg return 0; 262be49c2621d577da4fafd462265b611289547f183Johan Hedberg 263be49c2621d577da4fafd462265b611289547f183Johan Hedberg memset(&cp, 0, sizeof(cp)); 264be49c2621d577da4fafd462265b611289547f183Johan Hedberg cp.mode = 0x01; 265be49c2621d577da4fafd462265b611289547f183Johan Hedberg 266be49c2621d577da4fafd462265b611289547f183Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, 267be49c2621d577da4fafd462265b611289547f183Johan Hedberg OCF_WRITE_SIMPLE_PAIRING_MODE, 268be49c2621d577da4fafd462265b611289547f183Johan Hedberg WRITE_SIMPLE_PAIRING_MODE_CP_SIZE, &cp) < 0) 269be49c2621d577da4fafd462265b611289547f183Johan Hedberg return -errno; 270be49c2621d577da4fafd462265b611289547f183Johan Hedberg 271be49c2621d577da4fafd462265b611289547f183Johan Hedberg return 0; 272be49c2621d577da4fafd462265b611289547f183Johan Hedberg} 273be49c2621d577da4fafd462265b611289547f183Johan Hedberg 274b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedbergstatic void start_adapter(int index) 275b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg{ 276b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 }; 277b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg uint8_t inqmode; 278b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 279b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (VER(index).lmp_ver > 1) { 280b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[5] & LMP_SNIFF_SUBR) 281b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[5] |= 0x20; 282b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 283b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[5] & LMP_PAUSE_ENC) 284b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[5] |= 0x80; 285b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 286b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[6] & LMP_EXT_INQ) 287b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[5] |= 0x40; 288b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 289b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[6] & LMP_NFLUSH_PKTS) 290b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x01; 291b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 292b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[7] & LMP_LSTO) 293b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x80; 294b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 295b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[6] & LMP_SIMPLE_PAIR) { 296b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 297b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 298b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 299b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 300b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 301b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 302b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 303b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 304b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 305b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg * Features Notification */ 306b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 307b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 308b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[4] & LMP_LE) 309b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 310b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 311b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_SET_EVENT_MASK, 312b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg sizeof(events), events); 313b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg } 314b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 315be49c2621d577da4fafd462265b611289547f183Johan Hedberg if (FEATURES(index)[6] & LMP_SIMPLE_PAIR) 316be49c2621d577da4fafd462265b611289547f183Johan Hedberg init_ssp_mode(index); 317be49c2621d577da4fafd462265b611289547f183Johan Hedberg 318b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg inqmode = get_inquiry_mode(index); 319b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (inqmode) 320b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg write_inq_mode(index, inqmode); 321b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 322b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg if (FEATURES(index)[7] & LMP_INQ_TX_PWR) 323b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg hci_send_cmd(SK(index), OGF_HOST_CTL, 324b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL, 0, NULL); 325b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 326b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg manager_start_adapter(index); 327b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg} 328b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg 329abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedbergstatic int hciops_encrypt_link(int index, bdaddr_t *dst, bt_hci_result_t cb, 330abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg gpointer user_data) 331abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg{ 332abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg GIOChannel *io; 333abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_cmd_data *cmd; 334abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_conn_info_req *cr; 335abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg auth_requested_cp cp; 336abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg struct hci_filter nf; 337abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg int dd, err; 338abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint32_t link_mode; 339abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg uint16_t handle; 340abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 341abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); 342abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cr->type = ACL_LINK; 343abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg bacpy(&cr->bdaddr, dst); 344abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 345abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg err = ioctl(SK(index), HCIGETCONNINFO, cr); 346abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg link_mode = cr->conn_info->link_mode; 347abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg handle = cr->conn_info->handle; 348abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_free(cr); 349abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 350abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (err < 0) 351abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return -errno; 352abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 353abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (link_mode & HCI_LM_ENCRYPT) 354abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return -EALREADY; 355abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 356abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg memset(&cp, 0, sizeof(cp)); 357abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cp.handle = htobs(handle); 358abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 359abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_AUTH_REQUESTED, 360abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg AUTH_REQUESTED_CP_SIZE, &cp) < 0) 361abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return -errno; 362abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 363abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg dd = dup(SK(index)); 364abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (dd < 0) 365abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return -errno; 366abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 367abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd = g_new0(struct hci_cmd_data, 1); 368abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->handle = handle; 369abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->ocf = OCF_AUTH_REQUESTED; 370abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->cb = cb; 371abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg cmd->caller_data = user_data; 372abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 373abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_clear(&nf); 374abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_ptype(HCI_EVENT_PKT, &nf); 375abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_CMD_STATUS, &nf); 376abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_AUTH_COMPLETE, &nf); 377abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_filter_set_event(EVT_ENCRYPT_CHANGE, &nf); 378abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 379abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) { 380abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg err = -errno; 381abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_free(cmd); 382abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg close(dd); 383abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return -err; 384abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg } 385abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 386abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg io = g_io_channel_unix_new(dup(SK(index))); 387abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_set_close_on_unref(io, FALSE); 388abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_add_watch_full(io, G_PRIORITY_DEFAULT, 389abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg G_IO_HUP | G_IO_ERR | G_IO_NVAL | G_IO_IN, 390abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg hci_event_watch, cmd, g_free); 391abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg g_io_channel_unref(io); 392abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 393abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg return 0; 394abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg} 395abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 396abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg/* End async HCI command handling */ 397abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg 3985288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Start of HCI event callbacks */ 3995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 40042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic int get_handle(int index, bdaddr_t *dba, uint16_t *handle) 4015288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 4025288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_list_req *cl; 4035288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_info *ci; 4045288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 4055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4065288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); 4075288199788ecb17183d6517da3062cd94692a900Johan Hedberg 40842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cl->dev_id = index; 4095288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl->conn_num = 10; 4105288199788ecb17183d6517da3062cd94692a900Johan Hedberg ci = cl->conn_info; 4115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 41242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (ioctl(SK(index), HCIGETCONNLIST, (void *) cl) < 0) { 4135288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 4145288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -EIO; 4155288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 4165288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4175288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < cl->conn_num; i++, ci++) { 4185288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (bacmp(&ci->bdaddr, dba) == 0) { 4195288199788ecb17183d6517da3062cd94692a900Johan Hedberg *handle = ci->handle; 4205288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 4215288199788ecb17183d6517da3062cd94692a900Johan Hedberg return 0; 4225288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 4235288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 4245288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4255288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 4265288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4275288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -ENOENT; 4285288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 4295288199788ecb17183d6517da3062cd94692a900Johan Hedberg 43042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline int get_bdaddr(int index, uint16_t handle, bdaddr_t *dba) 4315288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 4325288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_list_req *cl; 4335288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_info *ci; 4345288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 4355288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4365288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); 4375288199788ecb17183d6517da3062cd94692a900Johan Hedberg 43842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cl->dev_id = index; 4395288199788ecb17183d6517da3062cd94692a900Johan Hedberg cl->conn_num = 10; 4405288199788ecb17183d6517da3062cd94692a900Johan Hedberg ci = cl->conn_info; 4415288199788ecb17183d6517da3062cd94692a900Johan Hedberg 44242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (ioctl(SK(index), HCIGETCONNLIST, (void *) cl) < 0) { 4435288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 4445288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -EIO; 4455288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 4465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4475288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < cl->conn_num; i++, ci++) 4485288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (ci->handle == handle) { 4495288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(dba, &ci->bdaddr); 4505288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 4515288199788ecb17183d6517da3062cd94692a900Johan Hedberg return 0; 4525288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 4535288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4545288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cl); 4555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4565288199788ecb17183d6517da3062cd94692a900Johan Hedberg return -ENOENT; 4575288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 4585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4595288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic inline void update_lastseen(bdaddr_t *sba, bdaddr_t *dba) 4605288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 4615288199788ecb17183d6517da3062cd94692a900Johan Hedberg time_t t; 4625288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct tm *tm; 4635288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4645288199788ecb17183d6517da3062cd94692a900Johan Hedberg t = time(NULL); 4655288199788ecb17183d6517da3062cd94692a900Johan Hedberg tm = gmtime(&t); 4665288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4675288199788ecb17183d6517da3062cd94692a900Johan Hedberg write_lastseen_info(sba, dba, tm); 4685288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 4695288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4705288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic inline void update_lastused(bdaddr_t *sba, bdaddr_t *dba) 4715288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 4725288199788ecb17183d6517da3062cd94692a900Johan Hedberg time_t t; 4735288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct tm *tm; 4745288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4755288199788ecb17183d6517da3062cd94692a900Johan Hedberg t = time(NULL); 4765288199788ecb17183d6517da3062cd94692a900Johan Hedberg tm = gmtime(&t); 4775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4785288199788ecb17183d6517da3062cd94692a900Johan Hedberg write_lastused_info(sba, dba, tm); 4795288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 4805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 4815288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Link Key handling */ 4825288199788ecb17183d6517da3062cd94692a900Johan Hedberg 48342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void link_key_request(int index, bdaddr_t *dba) 4845288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 4855288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 4865288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_device *device; 4875288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_auth_info_req req; 4885288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char key[16]; 4895288199788ecb17183d6517da3062cd94692a900Johan Hedberg char sa[18], da[18]; 4905288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t type; 4915288199788ecb17183d6517da3062cd94692a900Johan Hedberg int err; 4925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 49342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg ba2str(&BDADDR(index), sa); ba2str(dba, da); 4945288199788ecb17183d6517da3062cd94692a900Johan Hedberg info("link_key_request (sba=%s, dba=%s)", sa, da); 4955288199788ecb17183d6517da3062cd94692a900Johan Hedberg 49642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg adapter = manager_find_adapter(&BDADDR(index)); 4975288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (adapter) 4985288199788ecb17183d6517da3062cd94692a900Johan Hedberg device = adapter_find_device(adapter, da); 4995288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 5005288199788ecb17183d6517da3062cd94692a900Johan Hedberg device = NULL; 5015288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5025288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&req, 0, sizeof(req)); 5035288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&req.bdaddr, dba); 5045288199788ecb17183d6517da3062cd94692a900Johan Hedberg 50542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg err = ioctl(SK(index), HCIGETAUTHINFO, (unsigned long) &req); 5065288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err < 0) { 5075288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (errno != EINVAL) 5085288199788ecb17183d6517da3062cd94692a900Johan Hedberg DBG("HCIGETAUTHINFO failed %s (%d)", 5095288199788ecb17183d6517da3062cd94692a900Johan Hedberg strerror(errno), errno); 5105288199788ecb17183d6517da3062cd94692a900Johan Hedberg req.type = 0x00; 5115288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5125288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5135288199788ecb17183d6517da3062cd94692a900Johan Hedberg DBG("kernel auth requirements = 0x%02x", req.type); 5145288199788ecb17183d6517da3062cd94692a900Johan Hedberg 515e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg if (main_opts.debug_keys && device && 516e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg device_get_debug_key(device, key)) 5175288199788ecb17183d6517da3062cd94692a900Johan Hedberg type = 0x03; 51842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg else if (read_link_key(&BDADDR(index), dba, key, &type) < 0 || 51942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg type == 0x03) { 5205288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Link key not found */ 52142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 52242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 6, dba); 5235288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 5245288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5255288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5265288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Link key found */ 5275288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5285288199788ecb17183d6517da3062cd94692a900Johan Hedberg DBG("link key type = 0x%02x", type); 5295288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5305288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't use unauthenticated combination keys if MITM is 5315288199788ecb17183d6517da3062cd94692a900Johan Hedberg * required */ 5325288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (type == 0x04 && req.type != 0xff && (req.type & 0x01)) 53342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 5345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6, dba); 5355288199788ecb17183d6517da3062cd94692a900Johan Hedberg else { 5365288199788ecb17183d6517da3062cd94692a900Johan Hedberg link_key_reply_cp lr; 5375288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5385288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(lr.link_key, key, 16); 5395288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&lr.bdaddr, dba); 5405288199788ecb17183d6517da3062cd94692a900Johan Hedberg 54142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_LINK_KEY_REPLY, 5425288199788ecb17183d6517da3062cd94692a900Johan Hedberg LINK_KEY_REPLY_CP_SIZE, &lr); 5435288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5445288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 5455288199788ecb17183d6517da3062cd94692a900Johan Hedberg 54642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void link_key_notify(int index, void *ptr) 5475288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 5485288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_link_key_notify *evt = ptr; 5495288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t *dba = &evt->bdaddr; 5505288199788ecb17183d6517da3062cd94692a900Johan Hedberg char sa[18], da[18]; 55142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg int err; 5525288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char old_key[16]; 5535288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t old_key_type; 5545288199788ecb17183d6517da3062cd94692a900Johan Hedberg 55542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg ba2str(&BDADDR(index), sa); ba2str(dba, da); 5565288199788ecb17183d6517da3062cd94692a900Johan Hedberg info("link_key_notify (sba=%s, dba=%s, type=%d)", sa, da, 5575288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt->key_type); 5585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 55942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg err = read_link_key(&BDADDR(index), dba, old_key, &old_key_type); 5605288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err < 0) 5615288199788ecb17183d6517da3062cd94692a900Johan Hedberg old_key_type = 0xff; 5625288199788ecb17183d6517da3062cd94692a900Johan Hedberg 56342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg err = btd_event_link_key_notify(&BDADDR(index), dba, evt->link_key, 56442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg evt->key_type, PIN_LENGTH(index), 56542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg old_key_type); 56642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg PIN_LENGTH(index) = -1; 5675288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5685288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err < 0) { 5695288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t handle; 5705288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5715288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err == -ENODEV) 57242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_bonding_process_complete(&BDADDR(index), dba, 5735288199788ecb17183d6517da3062cd94692a900Johan Hedberg HCI_OE_LOW_RESOURCES); 5745288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 57542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_bonding_process_complete(&BDADDR(index), dba, 5765288199788ecb17183d6517da3062cd94692a900Johan Hedberg HCI_MEMORY_FULL); 5775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 57842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_handle(index, dba, &handle) == 0) { 5795288199788ecb17183d6517da3062cd94692a900Johan Hedberg disconnect_cp cp; 5805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 5815288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 5825288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.handle = htobs(handle); 5835288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.reason = HCI_OE_LOW_RESOURCES; 5845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 58542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_DISCONNECT, 5865288199788ecb17183d6517da3062cd94692a900Johan Hedberg DISCONNECT_CP_SIZE, &cp); 5875288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5885288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 5895288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 5905288199788ecb17183d6517da3062cd94692a900Johan Hedberg 59142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void return_link_keys(int index, void *ptr) 5925288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 5935288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_return_link_keys *evt = ptr; 5945288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = evt->num_keys; 5955288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char key[16]; 5965288199788ecb17183d6517da3062cd94692a900Johan Hedberg char sa[18], da[18]; 5975288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 5985288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 5995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 60042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg ba2str(&BDADDR(index), sa); 6015288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr++; 6025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6035288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 6045288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&dba, ptr); ba2str(&dba, da); 6055288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(key, ptr + 6, 16); 6065288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6075288199788ecb17183d6517da3062cd94692a900Johan Hedberg info("return_link_keys (sba=%s, dba=%s)", sa, da); 6085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 60942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_returned_link_key(&BDADDR(index), &dba); 6105288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6115288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += 22; 6125288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6135288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6145288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6155288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* Simple Pairing handling */ 6165288199788ecb17183d6517da3062cd94692a900Johan Hedberg 61742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_confirm_request(int index, void *ptr) 6185288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 6195288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_confirm_request *req = ptr; 6205288199788ecb17183d6517da3062cd94692a900Johan Hedberg 62142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (btd_event_user_confirm(&BDADDR(index), &req->bdaddr, 6225288199788ecb17183d6517da3062cd94692a900Johan Hedberg btohl(req->passkey)) < 0) 62342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, 6245288199788ecb17183d6517da3062cd94692a900Johan Hedberg OCF_USER_CONFIRM_NEG_REPLY, 6, ptr); 6255288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6265288199788ecb17183d6517da3062cd94692a900Johan Hedberg 62742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_passkey_request(int index, void *ptr) 6285288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 6295288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_passkey_request *req = ptr; 6305288199788ecb17183d6517da3062cd94692a900Johan Hedberg 63142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (btd_event_user_passkey(&BDADDR(index), &req->bdaddr) < 0) 63242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, 6335288199788ecb17183d6517da3062cd94692a900Johan Hedberg OCF_USER_PASSKEY_NEG_REPLY, 6, ptr); 6345288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6355288199788ecb17183d6517da3062cd94692a900Johan Hedberg 63642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void user_passkey_notify(int index, void *ptr) 6375288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 6385288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_user_passkey_notify *req = ptr; 6395288199788ecb17183d6517da3062cd94692a900Johan Hedberg 64042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_user_notify(&BDADDR(index), &req->bdaddr, 64142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btohl(req->passkey)); 6425288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 64442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void remote_oob_data_request(int index, void *ptr) 6455288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 64642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, 64742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr); 6485288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6495288199788ecb17183d6517da3062cd94692a900Johan Hedberg 65042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void io_capa_request(int index, void *ptr) 6515288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 65242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg bdaddr_t *dba = ptr; 6535288199788ecb17183d6517da3062cd94692a900Johan Hedberg char sa[18], da[18]; 6545288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t cap, auth; 6555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 65642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg ba2str(&BDADDR(index), sa); ba2str(dba, da); 6575288199788ecb17183d6517da3062cd94692a900Johan Hedberg info("io_capa_request (sba=%s, dba=%s)", sa, da); 6585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 65942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (btd_event_get_io_cap(&BDADDR(index), dba, &cap, &auth) < 0) { 6605288199788ecb17183d6517da3062cd94692a900Johan Hedberg io_capability_neg_reply_cp cp; 6615288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 6625288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cp.bdaddr, dba); 6635288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.reason = HCI_PAIRING_NOT_ALLOWED; 66442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, 66542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg OCF_IO_CAPABILITY_NEG_REPLY, 6665288199788ecb17183d6517da3062cd94692a900Johan Hedberg IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp); 6675288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 6685288199788ecb17183d6517da3062cd94692a900Johan Hedberg io_capability_reply_cp cp; 6695288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&cp, 0, sizeof(cp)); 6705288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cp.bdaddr, dba); 6715288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.capability = cap; 6725288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.oob_data = 0x00; 6735288199788ecb17183d6517da3062cd94692a900Johan Hedberg cp.authentication = auth; 67442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY, 6755288199788ecb17183d6517da3062cd94692a900Johan Hedberg IO_CAPABILITY_REPLY_CP_SIZE, &cp); 6765288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 6775288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6785288199788ecb17183d6517da3062cd94692a900Johan Hedberg 67942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void io_capa_response(int index, void *ptr) 6805288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 6815288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_io_capability_response *evt = ptr; 6825288199788ecb17183d6517da3062cd94692a900Johan Hedberg char sa[18], da[18]; 6835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 68442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg ba2str(&BDADDR(index), sa); ba2str(&evt->bdaddr, da); 6855288199788ecb17183d6517da3062cd94692a900Johan Hedberg info("io_capa_response (sba=%s, dba=%s)", sa, da); 6865288199788ecb17183d6517da3062cd94692a900Johan Hedberg 68742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_set_io_cap(&BDADDR(index), &evt->bdaddr, 6885288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt->capability, evt->authentication); 6895288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 6905288199788ecb17183d6517da3062cd94692a900Johan Hedberg 6915288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* PIN code handling */ 6925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 69342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void pin_code_request(int index, bdaddr_t *dba) 6945288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 6955288199788ecb17183d6517da3062cd94692a900Johan Hedberg pin_code_reply_cp pr; 6965288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_info_req *cr; 6975288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_conn_info *ci; 6985288199788ecb17183d6517da3062cd94692a900Johan Hedberg char sa[18], da[18], pin[17]; 6995288199788ecb17183d6517da3062cd94692a900Johan Hedberg int pinlen; 7005288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7015288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(&pr, 0, sizeof(pr)); 7025288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&pr.bdaddr, dba); 7035288199788ecb17183d6517da3062cd94692a900Johan Hedberg 70442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg ba2str(&BDADDR(index), sa); ba2str(dba, da); 7055288199788ecb17183d6517da3062cd94692a900Johan Hedberg info("pin_code_request (sba=%s, dba=%s)", sa, da); 7065288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7075288199788ecb17183d6517da3062cd94692a900Johan Hedberg cr = g_malloc0(sizeof(*cr) + sizeof(*ci)); 7085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7095288199788ecb17183d6517da3062cd94692a900Johan Hedberg bacpy(&cr->bdaddr, dba); 7105288199788ecb17183d6517da3062cd94692a900Johan Hedberg cr->type = ACL_LINK; 71142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (ioctl(SK(index), HCIGETCONNINFO, (unsigned long) cr) < 0) { 7125288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Can't get conn info: %s (%d)", strerror(errno), errno); 7135288199788ecb17183d6517da3062cd94692a900Johan Hedberg goto reject; 7145288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7155288199788ecb17183d6517da3062cd94692a900Johan Hedberg ci = cr->conn_info; 7165288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7175288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(pin, 0, sizeof(pin)); 71842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg pinlen = read_pin_code(&BDADDR(index), dba, pin); 7195288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7205288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (pinlen > 0) { 72142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg PIN_LENGTH(index) = pinlen; 7225288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(pr.pin_code, pin, pinlen); 7235288199788ecb17183d6517da3062cd94692a900Johan Hedberg pr.pin_len = pinlen; 72442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_PIN_CODE_REPLY, 72542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg PIN_CODE_REPLY_CP_SIZE, &pr); 7265288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 7275288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Request PIN from passkey agent */ 728cc758c498ed98de11e890e56d4500ca85587bc07Johan Hedberg if (btd_event_request_pin(&BDADDR(index), ci) < 0) 7295288199788ecb17183d6517da3062cd94692a900Johan Hedberg goto reject; 7305288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7315288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7325288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cr); 7335288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7345288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 7355288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7365288199788ecb17183d6517da3062cd94692a900Johan Hedbergreject: 7375288199788ecb17183d6517da3062cd94692a900Johan Hedberg g_free(cr); 7385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 73942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); 7405288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7415288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7425288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic void start_inquiry(bdaddr_t *local, uint8_t status, gboolean periodic) 7435288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 7445288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 7455288199788ecb17183d6517da3062cd94692a900Johan Hedberg int state; 7465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7475288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't send the signal if the cmd failed */ 7485288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) { 7495288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Inquiry Failed with status 0x%02x", status); 7505288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 7515288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7525288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7535288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(local); 7545288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 7555288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 7565288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 7575288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7595288199788ecb17183d6517da3062cd94692a900Johan Hedberg state = adapter_get_state(adapter); 7605288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7615288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (periodic) 7625288199788ecb17183d6517da3062cd94692a900Johan Hedberg state |= STATE_PINQ; 7635288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 7645288199788ecb17183d6517da3062cd94692a900Johan Hedberg state |= STATE_STDINQ; 7655288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7665288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_set_state(adapter, state); 7675288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 769e5828c7e30453232e930dbead0e359175dc1decfJohan Hedbergstatic void inquiry_complete(bdaddr_t *local, uint8_t status, 770e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg gboolean periodic) 7715288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 7725288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 7735288199788ecb17183d6517da3062cd94692a900Johan Hedberg int state; 7745288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7755288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Don't send the signal if the cmd failed */ 7765288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) { 7775288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Inquiry Failed with status 0x%02x", status); 7785288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 7795288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7815288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(local); 7825288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 7835288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 7845288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 7855288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 7865288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7875288199788ecb17183d6517da3062cd94692a900Johan Hedberg state = adapter_get_state(adapter); 7885288199788ecb17183d6517da3062cd94692a900Johan Hedberg state &= ~(STATE_STDINQ | STATE_PINQ); 7895288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_set_state(adapter, state); 7905288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 7915288199788ecb17183d6517da3062cd94692a900Johan Hedberg 79242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_features_notify(int index, void *ptr) 7935288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 7945288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_remote_host_features_notify *evt = ptr; 7955288199788ecb17183d6517da3062cd94692a900Johan Hedberg 7965288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->features[0] & 0x01) 79742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_set_legacy_pairing(&BDADDR(index), &evt->bdaddr, 79842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg FALSE); 7995288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 80042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_set_legacy_pairing(&BDADDR(index), &evt->bdaddr, 80142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg TRUE); 8025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 80342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg write_features_info(&BDADDR(index), &evt->bdaddr, NULL, evt->features); 8045288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8065288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic void write_le_host_complete(bdaddr_t *sba, uint8_t status) 8075288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 8085288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 8095288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8105288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (status) 8115288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 8125288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8135288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(sba); 8145288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 8155288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("No matching adapter found"); 8165288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 8175288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 8185288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8195288199788ecb17183d6517da3062cd94692a900Johan Hedberg btd_adapter_read_local_ext_features(adapter); 8205288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 8215288199788ecb17183d6517da3062cd94692a900Johan Hedberg 822be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void read_local_version_complete(int index, 823be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg const read_local_version_rp *rp) 824be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 825be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (rp->status) 826be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 827be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 828be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg VER(index).manufacturer = btohs(bt_get_unaligned(&rp->manufacturer)); 829be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg VER(index).hci_ver = rp->hci_ver; 830be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg VER(index).hci_rev = btohs(bt_get_unaligned(&rp->hci_rev)); 831be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg VER(index).lmp_ver = rp->lmp_ver; 832be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg VER(index).lmp_subver = btohs(bt_get_unaligned(&rp->lmp_subver)); 833be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 834be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (!PENDING(index)) 835be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 836be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 837be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg clear_bit(PENDING_VERSION, &PENDING(index)); 838be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 839be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg DBG("Got version for hci%d", index); 840be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 841be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (!PENDING(index) && UP(index)) 842b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg start_adapter(index); 843be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 844be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 845be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void read_local_features_complete(int index, 846be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg const read_local_features_rp *rp) 847be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 848be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (rp->status) 849be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 850be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 851be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg memcpy(FEATURES(index), rp->features, 8); 852be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 853be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (!PENDING(index)) 854be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg return; 855be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 856be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg clear_bit(PENDING_FEATURES, &PENDING(index)); 857be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 858be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg DBG("Got features for hci%d", index); 859be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 860be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (!PENDING(index) && UP(index)) 861b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg start_adapter(index); 862be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 863be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 864fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedbergstatic void read_local_name_complete(int index, read_local_name_rp *rp) 865fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg{ 866fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg if (rp->status) 867fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg return; 868fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 869fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg if (!PENDING(index)) { 870fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg adapter_update_local_name(&BDADDR(index), rp); 871fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg return; 872fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg } 873fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 874fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg clear_bit(PENDING_NAME, &PENDING(index)); 875fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 876fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg DBG("Got name for hci%d", index); 877fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 878fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg if (!PENDING(index) && UP(index)) 879b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg start_adapter(index); 880fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg} 881fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg 8825288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic void read_local_ext_features_complete(bdaddr_t *sba, 8835288199788ecb17183d6517da3062cd94692a900Johan Hedberg const read_local_ext_features_rp *rp) 8845288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 8855288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 8865288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8875288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (rp->status) 8885288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 8895288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8905288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter = manager_find_adapter(sba); 8915288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 8925288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("No matching adapter found"); 8935288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 8945288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 8955288199788ecb17183d6517da3062cd94692a900Johan Hedberg 8965288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Local Extended feature page number is 1 */ 8975288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (rp->page_num != 1) 8985288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 8995288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9005288199788ecb17183d6517da3062cd94692a900Johan Hedberg btd_adapter_update_local_ext_features(adapter, rp->features); 9015288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9035a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedbergstatic void read_bd_addr_complete(int index, read_bd_addr_rp *rp) 9045a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg{ 9055a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg if (rp->status) 9065a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg return; 9075a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 9085a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg bacpy(&BDADDR(index), &rp->bdaddr); 9095a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 910be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (!PENDING(index)) 9115a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg return; 9125a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 913be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg clear_bit(PENDING_BDADDR, &PENDING(index)); 9145a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 91528c405b17a3131494c11599705885ae630c52ee2Johan Hedberg DBG("Got bdaddr for hci%d", index); 9165a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 917be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (!PENDING(index) && UP(index)) 918b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg start_adapter(index); 9195a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg} 9205a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg 92142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void cmd_status(int index, void *ptr) 9225288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 9235288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_status *evt = ptr; 9245288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t opcode = btohs(evt->opcode); 9255288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9265288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) 92742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg start_inquiry(&BDADDR(index), evt->status, FALSE); 9285288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9295288199788ecb17183d6517da3062cd94692a900Johan Hedberg 93042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic void read_scan_complete(int index, uint8_t status, void *ptr) 9315288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 9325288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 9335288199788ecb17183d6517da3062cd94692a900Johan Hedberg read_scan_enable_rp *rp = ptr; 9345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 93542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg adapter = manager_find_adapter(&BDADDR(index)); 9365288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9375288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 9385288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 9395288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 9405288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 9415288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9425288199788ecb17183d6517da3062cd94692a900Johan Hedberg adapter_mode_changed(adapter, rp->enable); 9435288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 9445288199788ecb17183d6517da3062cd94692a900Johan Hedberg 94542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void cmd_complete(int index, void *ptr) 9465288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 9475288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_complete *evt = ptr; 9485288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint16_t opcode = btohs(evt->opcode); 9495288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t status = *((uint8_t *) ptr + EVT_CMD_COMPLETE_SIZE); 9505288199788ecb17183d6517da3062cd94692a900Johan Hedberg 9515288199788ecb17183d6517da3062cd94692a900Johan Hedberg switch (opcode) { 952be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION): 953be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg ptr += sizeof(evt_cmd_complete); 954be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg read_local_version_complete(index, ptr); 955be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg break; 956be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES): 957be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg ptr += sizeof(evt_cmd_complete); 958be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg read_local_features_complete(index, ptr); 959be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg break; 9605288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_EXT_FEATURES): 9615288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 96242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg read_local_ext_features_complete(&BDADDR(index), ptr); 9635288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9645a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BD_ADDR): 9655a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg ptr += sizeof(evt_cmd_complete); 9665a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg read_bd_addr_complete(index, ptr); 9675a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg break; 9685288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_PERIODIC_INQUIRY): 96942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg start_inquiry(&BDADDR(index), status, TRUE); 9705288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9715288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY): 97242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_complete(&BDADDR(index), status, TRUE); 9735288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9745288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL): 97542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_complete(&BDADDR(index), status, FALSE); 9765288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9775288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_LE_HOST_SUPPORTED): 97842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg write_le_host_complete(&BDADDR(index), status); 9795288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9805288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE): 98142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_le_set_scan_enable_complete(&BDADDR(index), status); 9825288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9835288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME): 98442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg adapter_setname_complete(&BDADDR(index), status); 9855288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9865288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE): 98742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_setscan_enable_complete(&BDADDR(index)); 9885288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9895288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SCAN_ENABLE): 9905288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 99142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg read_scan_complete(index, status, ptr); 9925288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9935288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV): 99442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg adapter_set_class_complete(&BDADDR(index), status); 9955288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9965288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SIMPLE_PAIRING_MODE): 99742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_write_simple_pairing_mode_complete(&BDADDR(index)); 9985288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 9995288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SIMPLE_PAIRING_MODE): 10005288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 100142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_read_simple_pairing_mode_complete(&BDADDR(index), 100242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg ptr); 10035288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 10045288199788ecb17183d6517da3062cd94692a900Johan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_NAME): 10055288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 1006fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg read_local_name_complete(index, ptr); 10075288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 1008e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg case cmd_opcode_pack(OGF_HOST_CTL, 1009e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL): 10105288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += sizeof(evt_cmd_complete); 101142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg adapter_update_tx_power(&BDADDR(index), status, ptr); 10125288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 10135288199788ecb17183d6517da3062cd94692a900Johan Hedberg }; 10145288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 10155288199788ecb17183d6517da3062cd94692a900Johan Hedberg 101642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_name_information(int index, void *ptr) 10175288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 10185288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_remote_name_req_complete *evt = ptr; 10195288199788ecb17183d6517da3062cd94692a900Johan Hedberg char name[MAX_NAME_LENGTH + 1]; 10205288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10215288199788ecb17183d6517da3062cd94692a900Johan Hedberg memset(name, 0, sizeof(name)); 10225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10235288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!evt->status) 10245288199788ecb17183d6517da3062cd94692a900Johan Hedberg memcpy(name, evt->name, MAX_NAME_LENGTH); 10255288199788ecb17183d6517da3062cd94692a900Johan Hedberg 102642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_remote_name(&BDADDR(index), &evt->bdaddr, evt->status, name); 10275288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 10285288199788ecb17183d6517da3062cd94692a900Johan Hedberg 102942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_version_information(int index, void *ptr) 10305288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 10315288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_read_remote_version_complete *evt = ptr; 10325288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 10335288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10345288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 10355288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 10365288199788ecb17183d6517da3062cd94692a900Johan Hedberg 103742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) 10385288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 10395288199788ecb17183d6517da3062cd94692a900Johan Hedberg 104042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg write_version_info(&BDADDR(index), &dba, btohs(evt->manufacturer), 10415288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt->lmp_ver, btohs(evt->lmp_subver)); 10425288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 10435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 104442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void inquiry_result(int index, int plen, void *ptr) 10455288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 10465288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 10475288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 10485288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10495288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 10505288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info *info = ptr; 105142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg uint32_t class = info->dev_class[0] | 105242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg (info->dev_class[1] << 8) | 105342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg (info->dev_class[2] << 16); 10545288199788ecb17183d6517da3062cd94692a900Johan Hedberg 105542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, class, 105642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 0, NULL); 10575288199788ecb17183d6517da3062cd94692a900Johan Hedberg 105842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg update_lastseen(&BDADDR(index), &info->bdaddr); 10595288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10605288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_SIZE; 10615288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 10625288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 10635288199788ecb17183d6517da3062cd94692a900Johan Hedberg 106442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void inquiry_result_with_rssi(int index, int plen, void *ptr) 10655288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 10665288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 10675288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 10685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10695288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!num) 10705288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 10715288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10725288199788ecb17183d6517da3062cd94692a900Johan Hedberg if ((plen - 1) / num == INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE) { 10735288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 10745288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info_with_rssi_and_pscan_mode *info = ptr; 10755288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 107642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 107742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 10785288199788ecb17183d6517da3062cd94692a900Johan Hedberg 107942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, 10805288199788ecb17183d6517da3062cd94692a900Johan Hedberg class, info->rssi, NULL); 10815288199788ecb17183d6517da3062cd94692a900Johan Hedberg 108242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg update_lastseen(&BDADDR(index), &info->bdaddr); 10835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10845288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; 10855288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 10865288199788ecb17183d6517da3062cd94692a900Johan Hedberg } else { 10875288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 10885288199788ecb17183d6517da3062cd94692a900Johan Hedberg inquiry_info_with_rssi *info = ptr; 10895288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 109042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 109142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 10925288199788ecb17183d6517da3062cd94692a900Johan Hedberg 109342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, 10945288199788ecb17183d6517da3062cd94692a900Johan Hedberg class, info->rssi, NULL); 10955288199788ecb17183d6517da3062cd94692a900Johan Hedberg 109642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg update_lastseen(&BDADDR(index), &info->bdaddr); 10975288199788ecb17183d6517da3062cd94692a900Johan Hedberg 10985288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += INQUIRY_INFO_WITH_RSSI_SIZE; 10995288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 11005288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 11015288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 11025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 110342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void extended_inquiry_result(int index, int plen, void *ptr) 11045288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 11055288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t num = *(uint8_t *) ptr++; 11065288199788ecb17183d6517da3062cd94692a900Johan Hedberg int i; 11075288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11085288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 11095288199788ecb17183d6517da3062cd94692a900Johan Hedberg extended_inquiry_info *info = ptr; 11105288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = info->dev_class[0] 111142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[1] << 8) 111242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg | (info->dev_class[2] << 16); 11135288199788ecb17183d6517da3062cd94692a900Johan Hedberg 111442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, class, 11155288199788ecb17183d6517da3062cd94692a900Johan Hedberg info->rssi, info->data); 11165288199788ecb17183d6517da3062cd94692a900Johan Hedberg 111742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg update_lastseen(&BDADDR(index), &info->bdaddr); 11185288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11195288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += EXTENDED_INQUIRY_INFO_SIZE; 11205288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 11215288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 11225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 112342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void remote_features_information(int index, void *ptr) 11245288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 11255288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_read_remote_features_complete *evt = ptr; 11265288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 11275288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11285288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 11295288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 11305288199788ecb17183d6517da3062cd94692a900Johan Hedberg 113142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) 11325288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 11335288199788ecb17183d6517da3062cd94692a900Johan Hedberg 113442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg write_features_info(&BDADDR(index), &dba, evt->features, NULL); 11355288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 11365288199788ecb17183d6517da3062cd94692a900Johan Hedberg 113742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void conn_complete(int index, void *ptr) 11385288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 11395288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_conn_complete *evt = ptr; 11405288199788ecb17183d6517da3062cd94692a900Johan Hedberg char filename[PATH_MAX]; 11415288199788ecb17183d6517da3062cd94692a900Johan Hedberg char local_addr[18], peer_addr[18], *str; 11425288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct btd_adapter *adapter; 11435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 114442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg adapter = manager_find_adapter(&BDADDR(index)); 11455288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!adapter) { 11465288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Unable to find matching adapter"); 11475288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 11485288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 11495288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11505288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->link_type != ACL_LINK) 11515288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 11525288199788ecb17183d6517da3062cd94692a900Johan Hedberg 115342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_conn_complete(&BDADDR(index), evt->status, 115442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btohs(evt->handle), &evt->bdaddr); 11555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11565288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (evt->status) 11575288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 11585288199788ecb17183d6517da3062cd94692a900Johan Hedberg 115942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg update_lastused(&BDADDR(index), &evt->bdaddr); 11605288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11615288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* check if the remote version needs be requested */ 116242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg ba2str(&BDADDR(index), local_addr); 11635288199788ecb17183d6517da3062cd94692a900Johan Hedberg ba2str(&evt->bdaddr, peer_addr); 11645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11655288199788ecb17183d6517da3062cd94692a900Johan Hedberg create_name(filename, sizeof(filename), STORAGEDIR, local_addr, 11665288199788ecb17183d6517da3062cd94692a900Johan Hedberg "manufacturers"); 11675288199788ecb17183d6517da3062cd94692a900Johan Hedberg 11685288199788ecb17183d6517da3062cd94692a900Johan Hedberg str = textfile_get(filename, peer_addr); 11695288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!str) 11705288199788ecb17183d6517da3062cd94692a900Johan Hedberg btd_adapter_get_remote_version(adapter, btohs(evt->handle), 11715288199788ecb17183d6517da3062cd94692a900Johan Hedberg TRUE); 11725288199788ecb17183d6517da3062cd94692a900Johan Hedberg else 11735288199788ecb17183d6517da3062cd94692a900Johan Hedberg free(str); 11745288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 11755288199788ecb17183d6517da3062cd94692a900Johan Hedberg 117642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void disconn_complete(int index, void *ptr) 11775288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 11785288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_disconn_complete *evt = ptr; 11795288199788ecb17183d6517da3062cd94692a900Johan Hedberg 118042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_disconn_complete(&BDADDR(index), evt->status, 118142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btohs(evt->handle), evt->reason); 11825288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 11835288199788ecb17183d6517da3062cd94692a900Johan Hedberg 118442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void auth_complete(int index, void *ptr) 11855288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 11865288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_auth_complete *evt = ptr; 11875288199788ecb17183d6517da3062cd94692a900Johan Hedberg bdaddr_t dba; 11885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 118942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) 11905288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 11915288199788ecb17183d6517da3062cd94692a900Johan Hedberg 119242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_bonding_process_complete(&BDADDR(index), &dba, evt->status); 11935288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 11945288199788ecb17183d6517da3062cd94692a900Johan Hedberg 119542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void simple_pairing_complete(int index, void *ptr) 11965288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 11975288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_simple_pairing_complete *evt = ptr; 11985288199788ecb17183d6517da3062cd94692a900Johan Hedberg 119942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_simple_pairing_complete(&BDADDR(index), &evt->bdaddr, 120042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg evt->status); 12015288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 12025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 120342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void conn_request(int index, void *ptr) 12045288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 12055288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_conn_request *evt = ptr; 12065288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint32_t class = evt->dev_class[0] | (evt->dev_class[1] << 8) 12075288199788ecb17183d6517da3062cd94692a900Johan Hedberg | (evt->dev_class[2] << 16); 12085288199788ecb17183d6517da3062cd94692a900Johan Hedberg 120942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_remote_class(&BDADDR(index), &evt->bdaddr, class); 12105288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 12115288199788ecb17183d6517da3062cd94692a900Johan Hedberg 121242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedbergstatic inline void le_metaevent(int index, void *ptr) 12135288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 12145288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_le_meta_event *meta = ptr; 12155288199788ecb17183d6517da3062cd94692a900Johan Hedberg le_advertising_info *info; 12165288199788ecb17183d6517da3062cd94692a900Johan Hedberg uint8_t *rssi, num, i; 12175288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12185288199788ecb17183d6517da3062cd94692a900Johan Hedberg DBG("LE Meta Event"); 12195288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12205288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (meta->subevent != EVT_LE_ADVERTISING_REPORT) 12215288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 12225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12235288199788ecb17183d6517da3062cd94692a900Johan Hedberg num = meta->data[0]; 12245288199788ecb17183d6517da3062cd94692a900Johan Hedberg info = (le_advertising_info *) (meta->data + 1); 12255288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12265288199788ecb17183d6517da3062cd94692a900Johan Hedberg for (i = 0; i < num; i++) { 12275288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* RSSI is last byte of the advertising report event */ 12285288199788ecb17183d6517da3062cd94692a900Johan Hedberg rssi = info->data + info->length; 122942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, 0, 123042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg *rssi, NULL); 12315288199788ecb17183d6517da3062cd94692a900Johan Hedberg info = (le_advertising_info *) (rssi + 1); 12325288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 12335288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 12345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 123555694454017b04a416931a81964bb695f48b3d93Johan Hedbergstatic void stop_hci_dev(int index) 12365288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 123755694454017b04a416931a81964bb695f48b3d93Johan Hedberg GIOChannel *chan = CHANNEL(index); 12385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12395288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (!chan) 12405288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 12415288199788ecb17183d6517da3062cd94692a900Johan Hedberg 124255694454017b04a416931a81964bb695f48b3d93Johan Hedberg info("Stopping hci%d event socket", index); 12435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 124455694454017b04a416931a81964bb695f48b3d93Johan Hedberg g_source_remove(WATCH_ID(index)); 124555694454017b04a416931a81964bb695f48b3d93Johan Hedberg g_io_channel_unref(CHANNEL(index)); 124655694454017b04a416931a81964bb695f48b3d93Johan Hedberg hci_close_dev(SK(index)); 124755694454017b04a416931a81964bb695f48b3d93Johan Hedberg init_dev_info(index, -1); 12485288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 12495288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12505288199788ecb17183d6517da3062cd94692a900Johan Hedbergstatic gboolean io_security_event(GIOChannel *chan, GIOCondition cond, 12515288199788ecb17183d6517da3062cd94692a900Johan Hedberg gpointer data) 12525288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 12535288199788ecb17183d6517da3062cd94692a900Johan Hedberg unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; 125442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg int type, index = GPOINTER_TO_INT(data); 125542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg struct hci_dev_info di; 12565288199788ecb17183d6517da3062cd94692a900Johan Hedberg size_t len; 12575288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_event_hdr *eh; 12585288199788ecb17183d6517da3062cd94692a900Johan Hedberg GIOError err; 12595288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt_cmd_status *evt; 12605288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12615288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { 126255694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 12635288199788ecb17183d6517da3062cd94692a900Johan Hedberg return FALSE; 12645288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 12655288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12665288199788ecb17183d6517da3062cd94692a900Johan Hedberg if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { 12675288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (err == G_IO_ERROR_AGAIN) 12685288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 126955694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 12705288199788ecb17183d6517da3062cd94692a900Johan Hedberg return FALSE; 12715288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 12725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12735288199788ecb17183d6517da3062cd94692a900Johan Hedberg type = *ptr++; 12745288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12755288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (type != HCI_EVENT_PKT) 12765288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 12775288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12785288199788ecb17183d6517da3062cd94692a900Johan Hedberg eh = (hci_event_hdr *) ptr; 12795288199788ecb17183d6517da3062cd94692a900Johan Hedberg ptr += HCI_EVENT_HDR_SIZE; 12805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 128142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg memset(&di, 0, sizeof(di)); 128242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (hci_devinfo(index, &di) == 0) { 128342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg bacpy(&BDADDR(index), &di.bdaddr); 12845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 128542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg if (ignore_device(&di)) 128642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg return TRUE; 128742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg } 128855694454017b04a416931a81964bb695f48b3d93Johan Hedberg 12895288199788ecb17183d6517da3062cd94692a900Johan Hedberg switch (eh->evt) { 12905288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CMD_STATUS: 129142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cmd_status(index, ptr); 12925288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 12935288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12945288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CMD_COMPLETE: 129542bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg cmd_complete(index, ptr); 12965288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 12975288199788ecb17183d6517da3062cd94692a900Johan Hedberg 12985288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_NAME_REQ_COMPLETE: 129942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_name_information(index, ptr); 13005288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13015288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13025288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_READ_REMOTE_VERSION_COMPLETE: 130342bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_version_information(index, ptr); 13045288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13065288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_READ_REMOTE_FEATURES_COMPLETE: 130742bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_features_information(index, ptr); 13085288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13095288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13105288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_HOST_FEATURES_NOTIFY: 131142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_features_notify(index, ptr); 13125288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13135288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13145288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_COMPLETE: 13155288199788ecb17183d6517da3062cd94692a900Johan Hedberg evt = (evt_cmd_status *) ptr; 131642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_complete(&BDADDR(index), evt->status, FALSE); 13175288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13185288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13195288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_RESULT: 132042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_result(index, eh->plen, ptr); 13215288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13225288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13235288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_INQUIRY_RESULT_WITH_RSSI: 132442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg inquiry_result_with_rssi(index, eh->plen, ptr); 13255288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13265288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13275288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_EXTENDED_INQUIRY_RESULT: 132842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg extended_inquiry_result(index, eh->plen, ptr); 13295288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13305288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13315288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CONN_COMPLETE: 133242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg conn_complete(index, ptr); 13335288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13345288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13355288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_DISCONN_COMPLETE: 133642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg disconn_complete(index, ptr); 13375288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13385288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13395288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_AUTH_COMPLETE: 134042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg auth_complete(index, ptr); 13415288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13425288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13435288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_SIMPLE_PAIRING_COMPLETE: 134442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg simple_pairing_complete(index, ptr); 13455288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13465288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13475288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_CONN_REQUEST: 134842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg conn_request(index, ptr); 13495288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13505288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LE_META_EVENT: 135142bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg le_metaevent(index, ptr); 13525288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13535288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_PIN_CODE_REQ: 135442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg pin_code_request(index, (bdaddr_t *) ptr); 13555288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13565288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13575288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LINK_KEY_REQ: 135842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg link_key_request(index, (bdaddr_t *) ptr); 13595288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13605288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13615288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_LINK_KEY_NOTIFY: 136242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg link_key_notify(index, ptr); 13635288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13645288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13655288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_RETURN_LINK_KEYS: 136642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg return_link_keys(index, ptr); 13675288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13685288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13695288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_IO_CAPABILITY_REQUEST: 137042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg io_capa_request(index, ptr); 13715288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13725288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13735288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_IO_CAPABILITY_RESPONSE: 137442bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg io_capa_response(index, ptr); 13755288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13765288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13775288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_CONFIRM_REQUEST: 137842bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_confirm_request(index, ptr); 13795288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13805288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13815288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_PASSKEY_REQUEST: 138242bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_passkey_request(index, ptr); 13835288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13845288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13855288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_USER_PASSKEY_NOTIFY: 138642bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg user_passkey_notify(index, ptr); 13875288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13885288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13895288199788ecb17183d6517da3062cd94692a900Johan Hedberg case EVT_REMOTE_OOB_DATA_REQUEST: 139042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg remote_oob_data_request(index, ptr); 13915288199788ecb17183d6517da3062cd94692a900Johan Hedberg break; 13925288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 13935288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13945288199788ecb17183d6517da3062cd94692a900Johan Hedberg return TRUE; 13955288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 13965288199788ecb17183d6517da3062cd94692a900Johan Hedberg 13975a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedbergstatic void start_hci_dev(int index) 13985288199788ecb17183d6517da3062cd94692a900Johan Hedberg{ 139955694454017b04a416931a81964bb695f48b3d93Johan Hedberg GIOChannel *chan = CHANNEL(index); 1400e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg GIOCondition cond; 14015288199788ecb17183d6517da3062cd94692a900Johan Hedberg struct hci_filter flt; 14025288199788ecb17183d6517da3062cd94692a900Johan Hedberg 14035288199788ecb17183d6517da3062cd94692a900Johan Hedberg if (chan) 14045288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 14055288199788ecb17183d6517da3062cd94692a900Johan Hedberg 14065a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg info("Listening for HCI events on hci%d", index); 14075288199788ecb17183d6517da3062cd94692a900Johan Hedberg 14085288199788ecb17183d6517da3062cd94692a900Johan Hedberg /* Set filter */ 14095288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_clear(&flt); 14105288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 14115288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CMD_STATUS, &flt); 14125288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CMD_COMPLETE, &flt); 14135288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); 14145288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); 14155288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); 14165288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_RETURN_LINK_KEYS, &flt); 14175288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_IO_CAPABILITY_REQUEST, &flt); 14185288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_IO_CAPABILITY_RESPONSE, &flt); 14195288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_CONFIRM_REQUEST, &flt); 14205288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_PASSKEY_REQUEST, &flt); 14215288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_OOB_DATA_REQUEST, &flt); 14225288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_USER_PASSKEY_NOTIFY, &flt); 14235288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_KEYPRESS_NOTIFY, &flt); 14245288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_SIMPLE_PAIRING_COMPLETE, &flt); 14255288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_AUTH_COMPLETE, &flt); 14265288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); 14275288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt); 14285288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); 14295288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_REMOTE_HOST_FEATURES_NOTIFY, &flt); 14305288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); 14315288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); 14325288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); 14335288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); 14345288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CONN_REQUEST, &flt); 14355288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_CONN_COMPLETE, &flt); 14365288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt); 14375288199788ecb17183d6517da3062cd94692a900Johan Hedberg hci_filter_set_event(EVT_LE_META_EVENT, &flt); 14385a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg if (setsockopt(SK(index), SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { 14395288199788ecb17183d6517da3062cd94692a900Johan Hedberg error("Can't set filter on hci%d: %s (%d)", 14405a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg index, strerror(errno), errno); 14415288199788ecb17183d6517da3062cd94692a900Johan Hedberg return; 14425288199788ecb17183d6517da3062cd94692a900Johan Hedberg } 14435288199788ecb17183d6517da3062cd94692a900Johan Hedberg 14445a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg chan = g_io_channel_unix_new(SK(index)); 1445e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg cond = G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR; 1446e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg WATCH_ID(index) = g_io_add_watch_full(chan, G_PRIORITY_LOW, cond, 1447e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg io_security_event, 1448e5828c7e30453232e930dbead0e359175dc1decfJohan Hedberg GINT_TO_POINTER(index), NULL); 144955694454017b04a416931a81964bb695f48b3d93Johan Hedberg CHANNEL(index) = chan; 145055694454017b04a416931a81964bb695f48b3d93Johan Hedberg PIN_LENGTH(index) = -1; 14515288199788ecb17183d6517da3062cd94692a900Johan Hedberg 14525288199788ecb17183d6517da3062cd94692a900Johan Hedberg} 14535288199788ecb17183d6517da3062cd94692a900Johan Hedberg 14545288199788ecb17183d6517da3062cd94692a900Johan Hedberg/* End of HCI event callbacks */ 14555288199788ecb17183d6517da3062cd94692a900Johan Hedberg 1456a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodestatic gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data) 1457a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 1458a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode int status, fd = g_io_channel_unix_get_fd(io); 1459a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid_t child_pid; 1460a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1461a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) { 1462a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("child_exit: unable to read child pid from pipe"); 1463a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return TRUE; 1464a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 1465a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1466a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (waitpid(child_pid, &status, 0) != child_pid) 1467a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("waitpid(%d) failed", child_pid); 1468a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode else 14698e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("child %d exited", child_pid); 1470a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1471a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return TRUE; 1472a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 1473a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1474a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodestatic void at_child_exit(void) 1475a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 1476a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid_t pid = getpid(); 1477a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1478a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid)) 1479a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("unable to write to child pipe"); 1480a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 1481a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1482fccdf4a50765ef5a2dbde00d95f65e94ce0a543bJohan Hedbergstatic void device_devup_setup(int index) 1483a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 1484a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_info di; 1485a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode uint16_t policy; 14865a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg read_stored_link_key_cp cp; 1487a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1488ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (hci_devinfo(index, &di) < 0) 1489a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 1490a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 149165bf1321203b55b11167ac8b869da28a86ce49d2David Scherba if (ignore_device(&di)) 1492a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 1493a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1494a352058752e541539b09e55124d411a534cc14afJohan Hedberg bacpy(&BDADDR(index), &di.bdaddr); 1495be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg memcpy(FEATURES(index), di.features, 8); 1496a352058752e541539b09e55124d411a534cc14afJohan Hedberg 1497a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Set page timeout */ 1498a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if ((main_opts.flags & (1 << HCID_SET_PAGETO))) { 1499a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode write_page_timeout_cp cp; 1500a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1501a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode cp.timeout = htobs(main_opts.pageto); 1502ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, 1503a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode WRITE_PAGE_TIMEOUT_CP_SIZE, &cp); 1504a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 1505a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1506a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Set default link policy */ 1507a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode policy = htobs(main_opts.link_policy); 1508ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg hci_send_cmd(SK(index), OGF_LINK_POLICY, 15096844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy); 1510fccdf4a50765ef5a2dbde00d95f65e94ce0a543bJohan Hedberg 15115a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg bacpy(&cp.bdaddr, BDADDR_ANY); 15125a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg cp.read_all = 1; 15135a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY, 15145a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg READ_STORED_LINK_KEY_CP_SIZE, (void *) &cp); 1515fccdf4a50765ef5a2dbde00d95f65e94ce0a543bJohan Hedberg 1516be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (!PENDING(index)) 1517b8486f046aadbe0145519c86a087e880fd1d638fJohan Hedberg start_adapter(index); 1518a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 1519a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1520be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedbergstatic void init_pending(int index) 1521be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg{ 1522be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg set_bit(PENDING_BDADDR, &PENDING(index)); 1523be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg set_bit(PENDING_VERSION, &PENDING(index)); 1524be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg set_bit(PENDING_FEATURES, &PENDING(index)); 1525fa472e0c7092af97d6f9d5c997003f443991aea9Johan Hedberg set_bit(PENDING_NAME, &PENDING(index)); 1526be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg} 1527be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1528ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void init_device(int index) 1529a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 1530a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_req dr; 153165bf1321203b55b11167ac8b869da28a86ce49d2David Scherba struct hci_dev_info di; 1532c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg int dd; 15336844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg pid_t pid; 15346844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 15356844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg dd = hci_open_dev(index); 15366844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (dd < 0) { 15376844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Unable to open hci%d: %s (%d)", index, 15386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg strerror(errno), errno); 15396844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return; 15406844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 15416844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 15426844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (index > max_dev) { 15436844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg max_dev = index; 1544ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg devs = g_realloc(devs, sizeof(devs[0]) * (max_dev + 1)); 15456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 15466844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 1547ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg init_dev_info(index, dd); 1548be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg init_pending(index); 15495a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg start_hci_dev(index); 1550a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1551a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Do initialization in the separate process */ 1552a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode pid = fork(); 1553a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode switch (pid) { 1554a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case 0: 1555a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode atexit(at_child_exit); 1556a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 1557a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case -1: 1558a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Fork failed. Can't init device hci%d: %s (%d)", 1559c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg index, strerror(errno), errno); 1560a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode default: 15618e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("child %d forked", pid); 1562a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 1563a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 1564a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1565a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode memset(&dr, 0, sizeof(dr)); 1566ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode dr.dev_id = index; 1567a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1568a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Set link mode */ 1569a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode dr.dev_opt = main_opts.link_mode; 1570c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) 1571a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Can't set link mode on hci%d: %s (%d)", 1572ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg index, strerror(errno), errno); 1573a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 157465bf1321203b55b11167ac8b869da28a86ce49d2David Scherba /* Set link policy for BR/EDR HCI devices */ 157565bf1321203b55b11167ac8b869da28a86ce49d2David Scherba if (hci_devinfo(index, &di) < 0) 157665bf1321203b55b11167ac8b869da28a86ce49d2David Scherba goto fail; 157765bf1321203b55b11167ac8b869da28a86ce49d2David Scherba 157865bf1321203b55b11167ac8b869da28a86ce49d2David Scherba if (!ignore_device(&di)) { 157965bf1321203b55b11167ac8b869da28a86ce49d2David Scherba dr.dev_opt = main_opts.link_policy; 158065bf1321203b55b11167ac8b869da28a86ce49d2David Scherba if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 && 1581a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode errno != ENETDOWN) { 158265bf1321203b55b11167ac8b869da28a86ce49d2David Scherba error("Can't set link policy on hci%d: %s (%d)", 158365bf1321203b55b11167ac8b869da28a86ce49d2David Scherba index, strerror(errno), errno); 158465bf1321203b55b11167ac8b869da28a86ce49d2David Scherba } 1585a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 1586a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1587a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode /* Start HCI device */ 1588ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (ioctl(dd, HCIDEVUP, index) < 0 && errno != EALREADY) { 1589a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode error("Can't init device hci%d: %s (%d)", 1590ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode index, strerror(errno), errno); 1591a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode goto fail; 1592a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 1593a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1594a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode hci_close_dev(dd); 1595a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode exit(0); 1596a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1597a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsodefail: 1598a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode hci_close_dev(dd); 1599a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode exit(1); 1600a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 1601a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1602ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void device_devreg_setup(int index) 1603a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 1604a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode struct hci_dev_info di; 1605a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode gboolean devup; 1606a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1607ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode init_device(index); 1608a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1609a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode memset(&di, 0, sizeof(di)); 1610a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1611ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode if (hci_devinfo(index, &di) < 0) 1612a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode return; 1613a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1614a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode devup = hci_test_bit(HCI_UP, &di.flags); 1615a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 161665bf1321203b55b11167ac8b869da28a86ce49d2David Scherba if (!ignore_device(&di)) 1617ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode manager_register_adapter(index, devup); 1618a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 1619a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1620ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsodestatic void device_event(int event, int index) 1621a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode{ 1622a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode switch (event) { 1623a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_REG: 1624ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d registered", index); 1625ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode device_devreg_setup(index); 1626a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 1627a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1628a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_UNREG: 1629ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d unregistered", index); 163055694454017b04a416931a81964bb695f48b3d93Johan Hedberg stop_hci_dev(index); 1631ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode manager_unregister_adapter(index); 1632a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 1633a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1634a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_UP: 1635ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d up", index); 16365a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg UP(index) = TRUE; 1637ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode device_devup_setup(index); 1638a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 1639a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1640a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode case HCI_DEV_DOWN: 1641ffff055ee50ab909b61e2b904bfa71dde42ee5c7Alok Barsode info("HCI dev %d down", index); 16425a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg UP(index) = FALSE; 1643be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (!PENDING(index)) { 16445a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg manager_stop_adapter(index); 1645be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg init_pending(index); 16465a58cd8ac9a93cfde63371872cd89ff8b190c52cJohan Hedberg } 1647a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode break; 1648a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 1649a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode} 1650cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1651f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedbergstatic gboolean init_known_adapters(gpointer user_data) 165294e91856179a268805256055ffd5155d1468b99cAlok Barsode{ 1653cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_dev_list_req *dl; 1654cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_dev_req *dr; 1655f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg int i, err, ctl = GPOINTER_TO_INT(user_data); 1656ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg size_t req_size; 1657cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1658ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg req_size = HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t); 1659ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg 1660ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg dl = g_try_malloc0(req_size); 1661cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (!dl) { 1662ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg error("Can't allocate devlist buffer"); 1663f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 1664cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 1665cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1666cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode dl->dev_num = HCI_MAX_DEV; 1667cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode dr = dl->dev_req; 1668cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1669ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg if (ioctl(ctl, HCIGETDEVLIST, dl) < 0) { 1670c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 1671ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg error("Can't get device list: %s (%d)", strerror(-err), -err); 167283003660808c30390f21c569a5ba7dbdd8344a41Claudio Takahasi g_free(dl); 1673f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 1674cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 1675cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1676cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode for (i = 0; i < dl->dev_num; i++, dr++) { 1677cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode device_event(HCI_DEV_REG, dr->dev_id); 1678cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1679be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg if (!hci_test_bit(HCI_UP, &dr->dev_opt)) 1680be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg continue; 1681be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg 1682be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg PENDING(dr->dev_id) = 0; 1683be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg set_bit(PENDING_VERSION, &PENDING(dr->dev_id)); 1684be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg hci_send_cmd(SK(dr->dev_id), OGF_INFO_PARAM, 1685be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg OCF_READ_LOCAL_VERSION, 0, NULL); 1686be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg device_event(HCI_DEV_UP, dr->dev_id); 1687cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 1688cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1689cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_free(dl); 1690f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg 1691f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return FALSE; 169294e91856179a268805256055ffd5155d1468b99cAlok Barsode} 169394e91856179a268805256055ffd5155d1468b99cAlok Barsode 1694cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsodestatic gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, 1695cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode gpointer data) 1696cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode{ 1697cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; 1698cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode evt_stack_internal *si; 1699cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode evt_si_device *sd; 1700cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_event_hdr *eh; 1701cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode int type; 1702cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode size_t len; 1703cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode GIOError err; 1704cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1705cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ptr = buf; 1706cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1707cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len); 1708cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (err) { 1709cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (err == G_IO_ERROR_AGAIN) 1710cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 1711cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1712cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode error("Read from control socket failed: %s (%d)", 1713ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg strerror(errno), errno); 1714cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return FALSE; 1715cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 1716cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1717cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode type = *ptr++; 1718cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1719cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (type != HCI_EVENT_PKT) 1720cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 1721cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1722cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode eh = (hci_event_hdr *) ptr; 1723cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (eh->evt != EVT_STACK_INTERNAL) 1724cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 1725cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1726cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ptr += HCI_EVENT_HDR_SIZE; 1727cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1728cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode si = (evt_stack_internal *) ptr; 1729cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode switch (si->type) { 1730cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode case EVT_SI_DEVICE: 1731cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode sd = (void *) &si->data; 1732cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode device_event(sd->event, sd->dev_id); 1733cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode break; 1734cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 1735cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1736cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode return TRUE; 1737cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode} 1738cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 173934c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic int hciops_setup(void) 1740cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode{ 1741cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct sockaddr_hci addr; 1742cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode struct hci_filter flt; 1743a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode GIOChannel *ctl_io, *child_io; 174418e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg int sock, err; 174518e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg 174618e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg if (child_pipe[0] != -1) 174718e8b33f0d60b9e1f4a6521720e14e9db1cda01dJohan Hedberg return -EALREADY; 1748cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1749a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode if (pipe(child_pipe) < 0) { 1750c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 1751c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("pipe(): %s (%d)", strerror(-err), -err); 1752c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 1753a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode } 1754a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1755a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode child_io = g_io_channel_unix_new(child_pipe[0]); 1756a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode g_io_channel_set_close_on_unref(child_io, TRUE); 17578b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_io_id = g_io_add_watch(child_io, 17588b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, 17598b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_exit, NULL); 1760a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode g_io_channel_unref(child_io); 1761a557e08d8c3e39439e922b1267d13c8cf34e37eaAlok Barsode 1762cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode /* Create and bind HCI socket */ 1763cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); 1764cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode if (sock < 0) { 1765c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 1766c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("Can't open HCI socket: %s (%d)", strerror(-err), 1767c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg -err); 1768c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 1769cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 1770cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1771cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode /* Set filter */ 1772cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_clear(&flt); 1773cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 1774cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode hci_filter_set_event(EVT_STACK_INTERNAL, &flt); 17756844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { 1776c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 1777c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg error("Can't set filter: %s (%d)", strerror(-err), -err); 1778c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 1779cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 1780cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1781cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode memset(&addr, 0, sizeof(addr)); 1782cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode addr.hci_family = AF_BLUETOOTH; 1783cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode addr.hci_dev = HCI_DEV_NONE; 17846844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1785c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 17866844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Can't bind HCI socket: %s (%d)", strerror(-err), -err); 1787c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 1788cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode } 1789cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1790cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode ctl_io = g_io_channel_unix_new(sock); 1791cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_io_channel_set_close_on_unref(ctl_io, TRUE); 1792cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 17938b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL); 1794cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1795cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode g_io_channel_unref(ctl_io); 1796cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 1797f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg g_idle_add(init_known_adapters, GINT_TO_POINTER(sock)); 1798f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg 1799f92841301d17330745d286ed35249a3a51c1e4e4Johan Hedberg return 0; 1800cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode} 1801cce9e28ea1ea1cbf5f9e9027c949632ce67cd27fAlok Barsode 180234c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic void hciops_cleanup(void) 180334c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode{ 18046844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int i; 18056844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 18066844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg for (i = 0; i <= max_dev; i++) { 1807ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (SK(i) >= 0) 1808ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg hci_close_dev(SK(i)); 18096844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg } 18106844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 18116844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg g_free(devs); 18126844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg devs = NULL; 18136844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg max_dev = -1; 18146844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 18158b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_io_id) { 18168b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg g_source_remove(child_io_id); 18178b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_io_id = 0; 18188b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 18198b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 18208b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (ctl_io_id) { 18218b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg g_source_remove(ctl_io_id); 18228b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg ctl_io_id = 0; 18238b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 18248b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 18258b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_pipe[0] >= 0) { 18268b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg close(child_pipe[0]); 18278b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_pipe[0] = -1; 18288b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 18298b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg 18308b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg if (child_pipe[1] >= 0) { 18318b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg close(child_pipe[1]); 18328b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg child_pipe[1] = -1; 18338b9bab24d5e35777c6838a48d487355ad790a5f4Johan Hedberg } 183434c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode} 183534c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode 1836076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsodestatic int hciops_start(int index) 1837076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode{ 18386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 1839076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 1840ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (ioctl(SK(index), HCIDEVUP, index) == 0) 18416844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 1842076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 18436844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (errno == EALREADY) 18446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 1845076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 18466844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 18476844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg error("Can't init device hci%d: %s (%d)", 18486844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg index, strerror(-err), -err); 1849076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 1850c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 1851076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode} 1852076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode 18534e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsodestatic int hciops_stop(int index) 18544e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode{ 18554e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode int err = 0; 18564e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode 1857ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (ioctl(SK(index), HCIDEVDOWN, index) == 0) 18584e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode goto done; /* on success */ 18594e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode 18604e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode if (errno != EALREADY) { 1861c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 18624e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode error("Can't stop device hci%d: %s (%d)", 1863c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg index, strerror(-err), -err); 18644e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode } 18654e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode 18664e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsodedone: 1867c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg return err; 18684e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode} 18694e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode 1870030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsodestatic int hciops_powered(int index, gboolean powered) 1871030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode{ 1872030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode uint8_t mode = SCAN_DISABLED; 1873030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode 1874030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode if (powered) 1875030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode return hciops_start(index); 1876030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode 1877ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, 18786844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_SCAN_ENABLE, 1, &mode) < 0) 18796844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 1880030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode 1881030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode return hciops_stop(index); 1882030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode} 1883030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode 18848b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsodestatic int hciops_connectable(int index) 18858b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode{ 18868b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode uint8_t mode = SCAN_PAGE; 18878b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode 1888ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, 18896844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_SCAN_ENABLE, 1, &mode) < 0) 18906844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 18918b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode 18926844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 18938b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode} 18948b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode 189555927114c520807297b2fc63148aa467bed60218Alok Barsodestatic int hciops_discoverable(int index) 189655927114c520807297b2fc63148aa467bed60218Alok Barsode{ 189755927114c520807297b2fc63148aa467bed60218Alok Barsode uint8_t mode = (SCAN_PAGE | SCAN_INQUIRY); 189855927114c520807297b2fc63148aa467bed60218Alok Barsode 1899ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 19006844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 1, &mode) < 0) 19016844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 190255927114c520807297b2fc63148aa467bed60218Alok Barsode 19036844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 190455927114c520807297b2fc63148aa467bed60218Alok Barsode} 190555927114c520807297b2fc63148aa467bed60218Alok Barsode 1906d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsodestatic int hciops_set_class(int index, uint32_t class) 1907d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode{ 1908d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode write_class_of_dev_cp cp; 1909d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 1910d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode memcpy(cp.dev_class, &class, 3); 1911d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 1912ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, 19136844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg WRITE_CLASS_OF_DEV_CP_SIZE, &cp) < 0) 19146844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 1915d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 19166844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 1917d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode} 1918d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 1919d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsodestatic int hciops_set_limited_discoverable(int index, uint32_t class, 1920eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode gboolean limited) 1921eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode{ 1922eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode int num = (limited ? 2 : 1); 1923eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode uint8_t lap[] = { 0x33, 0x8b, 0x9e, 0x00, 0x8b, 0x9e }; 1924d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode write_current_iac_lap_cp cp; 1925d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 1926eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode /* 1927eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode * 1: giac 1928eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode * 2: giac + liac 1929eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode */ 1930d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode memset(&cp, 0, sizeof(cp)); 1931d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode cp.num_current_iac = num; 1932d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode memcpy(&cp.lap, lap, num * 3); 1933eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode 1934ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_WRITE_CURRENT_IAC_LAP, 19356844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg (num * 3 + 1), &cp) < 0) 19366844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 1937d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode 19386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return hciops_set_class(index, class); 1939eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode} 1940eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode 19413af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasistatic int hciops_start_inquiry(int index, uint8_t length, gboolean periodic) 1942a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode{ 1943a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; 19446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 1945a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 1946a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode if (periodic) { 1947a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode periodic_inquiry_cp cp; 1948a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 1949a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memset(&cp, 0, sizeof(cp)); 1950a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memcpy(&cp.lap, lap, 3); 1951a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.max_period = htobs(24); 1952a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.min_period = htobs(16); 1953388cdea43870fe5c5163cfbe96d3218111ba39b5Claudio Takahasi cp.length = length; 1954a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode cp.num_rsp = 0x00; 1955a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 1956ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 19576844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_PERIODIC_INQUIRY, 19586844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg PERIODIC_INQUIRY_CP_SIZE, &cp); 1959a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode } else { 1960a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode inquiry_cp inq_cp; 1961a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 1962a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memset(&inq_cp, 0, sizeof(inq_cp)); 1963a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode memcpy(&inq_cp.lap, lap, 3); 1964388cdea43870fe5c5163cfbe96d3218111ba39b5Claudio Takahasi inq_cp.length = length; 1965a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode inq_cp.num_rsp = 0x00; 1966a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 1967ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 19686844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_INQUIRY, INQUIRY_CP_SIZE, &inq_cp); 1969a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode } 1970a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 1971a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode if (err < 0) 1972a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode err = -errno; 1973a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 1974a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode return err; 1975a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode} 1976a67cf482f872ae7c87de9478a471cd1e478d688fAlok Barsode 19773af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasistatic int hciops_stop_inquiry(int index) 1978f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode{ 1979f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode struct hci_dev_info di; 19806844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 1981f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode 1982f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode if (hci_devinfo(index, &di) < 0) 1983f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode return -errno; 1984f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode 1985f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode if (hci_test_bit(HCI_INQUIRY, &di.flags)) 1986ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 19876844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_INQUIRY_CANCEL, 0, 0); 1988f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode else 1989ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 19906844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_EXIT_PERIODIC_INQUIRY, 0, 0); 1991f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode if (err < 0) 1992f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode err = -errno; 1993f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode 1994f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode return err; 1995f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode} 1996f8c3e9f4a68af6e6687e754f871e03e2e8cc80b8Alok Barsode 19973ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int le_set_scan_enable(int index, uint8_t enable) 199870cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi{ 19993ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi le_set_scan_enable_cp cp; 20003ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 20013ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi memset(&cp, 0, sizeof(cp)); 20023ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.enable = enable; 20033ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.filter_dup = 0; 200470cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 20053ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi if (hci_send_cmd(SK(index), OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE, 20063ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi LE_SET_SCAN_ENABLE_CP_SIZE, &cp) < 0) 20076844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 200870cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 20096844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 201070cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi} 201170cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 20123ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int hciops_start_scanning(int index) 201370cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi{ 20143ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi le_set_scan_parameters_cp cp; 20153ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 20163ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi memset(&cp, 0, sizeof(cp)); 20173ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.type = 0x01; /* Active scanning */ 20183ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.interval = htobs(0x0010); 20193ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.window = htobs(0x0010); 20203ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.own_bdaddr_type = 0; /* Public address */ 20213ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi cp.filter = 0; /* Accept all adv packets */ 20223ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 20233ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi if (hci_send_cmd(SK(index), OGF_LE_CTL, OCF_LE_SET_SCAN_PARAMETERS, 20243ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi LE_SET_SCAN_PARAMETERS_CP_SIZE, &cp) < 0) 202570cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi return -errno; 202670cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 20273ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi return le_set_scan_enable(index, 1); 20283ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi} 20293ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi 20303ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasistatic int hciops_stop_scanning(int index) 20313ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi{ 20323ef2b1cae64036f074908a927803a45a86e65f04Claudio Takahasi return le_set_scan_enable(index, 0); 203370cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi} 203470cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi 2035ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsodestatic int hciops_resolve_name(int index, bdaddr_t *bdaddr) 2036ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode{ 2037ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode remote_name_req_cp cp; 2038ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 2039ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode memset(&cp, 0, sizeof(cp)); 2040ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode bacpy(&cp.bdaddr, bdaddr); 2041ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode cp.pscan_rep_mode = 0x02; 2042ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 2043ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_REMOTE_NAME_REQ, 20446844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg REMOTE_NAME_REQ_CP_SIZE, &cp) < 0) 20456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2046ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 20476844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2048ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode} 2049ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode 2050164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsodestatic int hciops_set_name(int index, const char *name) 2051164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode{ 2052164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode change_local_name_cp cp; 2053164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 2054164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode memset(&cp, 0, sizeof(cp)); 2055164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode strncpy((char *) cp.name, name, sizeof(cp.name)); 2056164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 2057ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, 20586844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg CHANGE_LOCAL_NAME_CP_SIZE, &cp) < 0) 20596844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2060164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 20616844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2062164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode} 2063164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode 2064d209c50141349ee9413d0717002af3d036db4762Alok Barsodestatic int hciops_read_name(int index) 2065d209c50141349ee9413d0717002af3d036db4762Alok Barsode{ 2066ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_READ_LOCAL_NAME, 20676844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 0, 0) < 0) 20686844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2069d209c50141349ee9413d0717002af3d036db4762Alok Barsode 20706844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2071d209c50141349ee9413d0717002af3d036db4762Alok Barsode} 2072d209c50141349ee9413d0717002af3d036db4762Alok Barsode 2073b96f44db8e91325968a0149595b2522d4a22481aAlok Barsodestatic int hciops_cancel_resolve_name(int index, bdaddr_t *bdaddr) 2074b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode{ 2075b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode remote_name_req_cancel_cp cp; 2076b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 2077b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode memset(&cp, 0, sizeof(cp)); 2078b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode bacpy(&cp.bdaddr, bdaddr); 2079b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 2080ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL, 20816844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg REMOTE_NAME_REQ_CANCEL_CP_SIZE, &cp) < 0) 20826844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2083b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 20846844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2085b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode} 2086b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode 208761f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliystatic int hciops_fast_connectable(int index, gboolean enable) 208861f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy{ 208961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy write_page_activity_cp cp; 209061f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy uint8_t type; 209161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 209261f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy if (enable) { 209361f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy type = PAGE_SCAN_TYPE_INTERLACED; 209461f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.interval = 0x0024; /* 22.5 msec page scan interval */ 209561f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy } else { 209661f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy type = PAGE_SCAN_TYPE_STANDARD; /* default */ 209761f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.interval = 0x0800; /* default 1.28 sec page scan */ 209861f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy } 209961f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 210061f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy cp.window = 0x0012; /* default 11.25 msec page scan window */ 210161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 2102ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_WRITE_PAGE_ACTIVITY, 210361f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy WRITE_PAGE_ACTIVITY_CP_SIZE, &cp) < 0) 21046844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2105ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg else if (hci_send_cmd(SK(index), OGF_HOST_CTL, 21066844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_PAGE_SCAN_TYPE, 1, &type) < 0) 21076844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 210861f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 21096844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 211061f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy} 211161f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy 21125bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuterstatic int hciops_read_clock(int index, int handle, int which, int timeout, 2113ad737e6427a5bfb09bc26c4af071a7aa7045f0acJohan Hedberg uint32_t *clock, uint16_t *accuracy) 21145bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter{ 2115ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_read_clock(SK(index), handle, which, clock, accuracy, 21166844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg timeout) < 0) 21176844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 21185bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 21196844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 21205bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter} 21215bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 21225bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuterstatic int hciops_conn_handle(int index, const bdaddr_t *bdaddr, int *handle) 21235bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter{ 21246844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 21255bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter struct hci_conn_info_req *cr; 21265bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 21275bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); 21285bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter bacpy(&cr->bdaddr, bdaddr); 21295bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter cr->type = ACL_LINK; 21305bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 2131ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (ioctl(SK(index), HCIGETCONNINFO, (unsigned long) cr) < 0) { 2132c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg err = -errno; 2133c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg goto fail; 2134c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg } 21355bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 21366844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = 0; 2137c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedberg *handle = htobs(cr->conn_info->handle); 21385bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 2139c67ba167cc642c34b4b85abbe3a9866cb00c0e57Johan Hedbergfail: 21405bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter g_free(cr); 21415bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter return err; 21425bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter} 21435bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter 2144e070bc11469123aefc412ce4e408fe5ad5b525e5Johan Hedbergstatic int hciops_write_eir_data(int index, uint8_t *data) 2145e070bc11469123aefc412ce4e408fe5ad5b525e5Johan Hedberg{ 2146197eb53c0b5a3a0997ad0cb85d828236c6228700Johan Hedberg write_ext_inquiry_response_cp cp; 2147e070bc11469123aefc412ce4e408fe5ad5b525e5Johan Hedberg 2148197eb53c0b5a3a0997ad0cb85d828236c6228700Johan Hedberg memset(&cp, 0, sizeof(cp)); 2149197eb53c0b5a3a0997ad0cb85d828236c6228700Johan Hedberg memcpy(cp.data, data, 240); 2150197eb53c0b5a3a0997ad0cb85d828236c6228700Johan Hedberg 2151ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, 21526844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_EXT_INQUIRY_RESPONSE, 2153197eb53c0b5a3a0997ad0cb85d828236c6228700Johan Hedberg WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &cp) < 0) 21546844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2155e070bc11469123aefc412ce4e408fe5ad5b525e5Johan Hedberg 21566844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2157e070bc11469123aefc412ce4e408fe5ad5b525e5Johan Hedberg} 2158e070bc11469123aefc412ce4e408fe5ad5b525e5Johan Hedberg 2159b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedbergstatic int hciops_read_bdaddr(int index, bdaddr_t *bdaddr) 2160b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg{ 2161a352058752e541539b09e55124d411a534cc14afJohan Hedberg bacpy(bdaddr, &BDADDR(index)); 21626844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2163b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg} 2164b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg 2165885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedbergstatic int hciops_block_device(int index, bdaddr_t *bdaddr) 2166885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg{ 2167ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (ioctl(SK(index), HCIBLOCKADDR, bdaddr) < 0) 2168885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg return -errno; 2169885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 21706844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2171885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg} 2172885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 2173885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedbergstatic int hciops_unblock_device(int index, bdaddr_t *bdaddr) 2174885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg{ 2175ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (ioctl(SK(index), HCIUNBLOCKADDR, bdaddr) < 0) 2176885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg return -errno; 2177885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 21786844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2179885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg} 2180885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg 2181f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedbergstatic int hciops_get_conn_list(int index, GSList **conns) 2182f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg{ 2183f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg struct hci_conn_list_req *cl; 2184f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg struct hci_conn_info *ci; 21856844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err, i; 2186f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2187f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); 2188f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2189f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg cl->dev_id = index; 2190f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg cl->conn_num = 10; 2191f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg ci = cl->conn_info; 2192f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2193ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (ioctl(SK(index), HCIGETCONNLIST, cl) < 0) { 2194f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg err = -errno; 2195f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg goto fail; 2196f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg } 2197f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2198f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg err = 0; 2199f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg *conns = NULL; 2200f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2201f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg for (i = 0; i < cl->conn_num; i++, ci++) 2202f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg *conns = g_slist_append(*conns, g_memdup(ci, sizeof(*ci))); 2203f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2204f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedbergfail: 2205f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg g_free(cl); 2206f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg return err; 2207f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg} 2208f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg 2209e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedbergstatic int hciops_read_local_version(int index, struct hci_version *ver) 2210e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg{ 2211be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg memcpy(ver, &VER(index), sizeof(*ver)); 22126844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2213e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg} 2214e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg 221548e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedbergstatic int hciops_read_local_features(int index, uint8_t *features) 221648e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg{ 2217be3d4f5e4c621718de0dc0fb4f947635682f1a95Johan Hedberg memcpy(features, FEATURES(index), 8); 22186844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 221948e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg} 222048e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg 22219ebc8d3b0f66a24f3821bf243dcd3f59527e8612Claudio Takahasistatic int hciops_read_local_ext_features(int index) 22229ebc8d3b0f66a24f3821bf243dcd3f59527e8612Claudio Takahasi{ 22239ebc8d3b0f66a24f3821bf243dcd3f59527e8612Claudio Takahasi uint8_t page_num = 1; 22249ebc8d3b0f66a24f3821bf243dcd3f59527e8612Claudio Takahasi 2225ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_INFO_PARAM, 22266844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_READ_LOCAL_EXT_FEATURES, 1, &page_num) < 0) 22279ebc8d3b0f66a24f3821bf243dcd3f59527e8612Claudio Takahasi return -errno; 22289ebc8d3b0f66a24f3821bf243dcd3f59527e8612Claudio Takahasi 22296844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 22309ebc8d3b0f66a24f3821bf243dcd3f59527e8612Claudio Takahasi} 22319ebc8d3b0f66a24f3821bf243dcd3f59527e8612Claudio Takahasi 223298dbebb8edf59666e226386caf38824e40c8ff33Johan Hedbergstatic int hciops_read_link_policy(int index) 223398dbebb8edf59666e226386caf38824e40c8ff33Johan Hedberg{ 2234ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_LINK_POLICY, 22356844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_READ_DEFAULT_LINK_POLICY, 0, NULL) < 0) 223698dbebb8edf59666e226386caf38824e40c8ff33Johan Hedberg return -errno; 223798dbebb8edf59666e226386caf38824e40c8ff33Johan Hedberg 22386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 223998dbebb8edf59666e226386caf38824e40c8ff33Johan Hedberg} 224098dbebb8edf59666e226386caf38824e40c8ff33Johan Hedberg 224106dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedbergstatic int hciops_disconnect(int index, uint16_t handle) 224206dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg{ 224306dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg disconnect_cp cp; 224406dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 224506dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg memset(&cp, 0, sizeof(cp)); 224606dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg cp.handle = htobs(handle); 224706dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg cp.reason = HCI_OE_USER_ENDED_CONNECTION; 224806dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 2249ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_DISCONNECT, 225006dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg DISCONNECT_CP_SIZE, &cp) < 0) 22516844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 225206dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 22536844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 225406dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg} 225506dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg 22561bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedbergstatic int hciops_remove_bonding(int index, bdaddr_t *bdaddr) 22571bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg{ 225873c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg delete_stored_link_key_cp cp; 22591bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 226073c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg memset(&cp, 0, sizeof(cp)); 226173c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg bacpy(&cp.bdaddr, bdaddr); 226273c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg 22631bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg /* Delete the link key from the Bluetooth chip */ 2264ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_DELETE_STORED_LINK_KEY, 226573c8e7ac377f0f6ea0df6396b96cb9e8a11eb070Johan Hedberg DELETE_STORED_LINK_KEY_CP_SIZE, &cp) < 0) 22666844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 22671bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 22686844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 22691bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg} 22701bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg 2271424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedbergstatic int hciops_request_authentication(int index, uint16_t handle, 2272424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg uint8_t *status) 2273424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg{ 2274424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg struct hci_request rq; 2275424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg auth_requested_cp cp; 2276424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg evt_cmd_status rp; 2277424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2278424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg memset(&rp, 0, sizeof(rp)); 2279424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2280424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg memset(&cp, 0, sizeof(cp)); 2281424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg cp.handle = htobs(handle); 2282424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2283424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg memset(&rq, 0, sizeof(rq)); 2284424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg rq.ogf = OGF_LINK_CTL; 2285424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg rq.ocf = OCF_AUTH_REQUESTED; 2286424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg rq.cparam = &cp; 2287424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg rq.clen = AUTH_REQUESTED_CP_SIZE; 2288424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg rq.rparam = &rp; 2289424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg rq.rlen = EVT_CMD_STATUS_SIZE; 2290424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg rq.event = EVT_CMD_STATUS; 2291424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2292ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_req(SK(index), &rq, HCI_REQ_TIMEOUT) < 0) 22936844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 2294424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2295424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg if (status) 2296424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg *status = rp.status; 2297424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 22986844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2299424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg} 2300424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg 2301e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedbergstatic int hciops_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin) 2302e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg{ 23036844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2304e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 2305e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg if (pin) { 2306e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg pin_code_reply_cp pr; 2307e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg size_t len = strlen(pin); 2308e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 230942bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg PIN_LENGTH(index) = len; 231042bb162ca16e92eac264127a88063cadf7d48af7Johan Hedberg 2311e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg memset(&pr, 0, sizeof(pr)); 2312e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg bacpy(&pr.bdaddr, bdaddr); 2313e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg memcpy(pr.pin_code, pin, len); 2314e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg pr.pin_len = len; 2315ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 23166844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_PIN_CODE_REPLY, 2317e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg PIN_CODE_REPLY_CP_SIZE, &pr); 2318e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg } else 2319ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 2320e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg OCF_PIN_CODE_NEG_REPLY, 6, bdaddr); 2321e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 23226844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 23236844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 2324e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 2325e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg return err; 2326e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg} 2327e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg 2328df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedbergstatic int hciops_confirm_reply(int index, bdaddr_t *bdaddr, gboolean success) 2329df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg{ 23306844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2331df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg user_confirm_reply_cp cp; 2332df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2333df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg memset(&cp, 0, sizeof(cp)); 2334df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 2335df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2336df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg if (success) 2337ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 23386844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_USER_CONFIRM_REPLY, 2339df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg USER_CONFIRM_REPLY_CP_SIZE, &cp); 2340df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg else 2341ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 2342df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg OCF_USER_CONFIRM_NEG_REPLY, 2343df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg USER_CONFIRM_REPLY_CP_SIZE, &cp); 2344df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 23456844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 23466844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 2347df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2348df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg return err; 2349df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg} 2350df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg 2351889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedbergstatic int hciops_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey) 2352889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg{ 23536844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg int err; 2354889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 2355889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg if (passkey != INVALID_PASSKEY) { 2356889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg user_passkey_reply_cp cp; 2357889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 2358889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg memset(&cp, 0, sizeof(cp)); 2359889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg bacpy(&cp.bdaddr, bdaddr); 2360889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg cp.passkey = passkey; 2361889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 2362ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 23636844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_USER_PASSKEY_REPLY, 2364889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg USER_PASSKEY_REPLY_CP_SIZE, &cp); 2365889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg } else 2366ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg err = hci_send_cmd(SK(index), OGF_LINK_CTL, 2367889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg OCF_USER_PASSKEY_NEG_REPLY, 6, bdaddr); 2368889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 23696844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg if (err < 0) 23706844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg err = -errno; 2371889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 2372889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg return err; 2373889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg} 2374889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg 23754b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedbergstatic int hciops_get_auth_info(int index, bdaddr_t *bdaddr, uint8_t *auth) 23764b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg{ 23774b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg struct hci_auth_info_req req; 23784b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 23794b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg memset(&req, 0, sizeof(req)); 23804b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg bacpy(&req.bdaddr, bdaddr); 23814b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 2382ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (ioctl(SK(index), HCIGETAUTHINFO, (unsigned long) &req) < 0) 23836844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 23844b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 23854b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg if (auth) 23864b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg *auth = req.type; 23874b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 23886844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 23894b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg} 23904b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg 2391f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedbergstatic int hciops_read_scan_enable(int index) 2392f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg{ 2393ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_READ_SCAN_ENABLE, 23946844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg 0, NULL) < 0) 2395f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg return -errno; 2396f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg 23976844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2398f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg} 2399f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg 2400132374b5125787fd2be0ea9c6985ad9a88600474Johan Hedbergstatic int hciops_read_ssp_mode(int index) 2401132374b5125787fd2be0ea9c6985ad9a88600474Johan Hedberg{ 2402ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, 24036844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_READ_SIMPLE_PAIRING_MODE, 0, NULL) < 0) 2404132374b5125787fd2be0ea9c6985ad9a88600474Johan Hedberg return -errno; 2405132374b5125787fd2be0ea9c6985ad9a88600474Johan Hedberg 24066844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 2407132374b5125787fd2be0ea9c6985ad9a88600474Johan Hedberg} 2408132374b5125787fd2be0ea9c6985ad9a88600474Johan Hedberg 24097ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasistatic int hciops_write_le_host(int index, uint8_t le, uint8_t simul) 24107ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi{ 24117ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi write_le_host_supported_cp cp; 24127ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 24137ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi memset(&cp, 0, sizeof(cp)); 24147ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi cp.le = le; 24157ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi cp.simul = simul; 24167ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 2417ef071f94a765fa0b0e96935abef7508c76cace00Johan Hedberg if (hci_send_cmd(SK(index), OGF_HOST_CTL, 24186844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg OCF_WRITE_LE_HOST_SUPPORTED, 24196844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg WRITE_LE_HOST_SUPPORTED_CP_SIZE, &cp) < 0) 24206844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return -errno; 24217ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 24226844ac4ce59e05b8857f18fa620adf42479d6aa5Johan Hedberg return 0; 24237ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi} 24247ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi 2425646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedbergstruct remote_version_req { 2426646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg int index; 2427646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg uint16_t handle; 2428646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg}; 2429646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 2430646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedbergstatic gboolean get_remote_version(gpointer user_data) 2431646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg{ 2432646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg struct remote_version_req *req = user_data; 2433646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg read_remote_version_cp cp; 2434646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 2435646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg memset(&cp, 0, sizeof(cp)); 2436646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg cp.handle = htobs(req->handle); 2437646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 2438646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg hci_send_cmd(SK(req->index), OGF_LINK_CTL, OCF_READ_REMOTE_VERSION, 2439646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg READ_REMOTE_VERSION_CP_SIZE, &cp); 2440646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 2441646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg return FALSE; 2442646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg} 2443646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 2444646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedbergstatic int hciops_get_remote_version(int index, uint16_t handle, 2445646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg gboolean delayed) 2446646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg{ 2447646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg struct remote_version_req *req; 2448646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 2449646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg req = g_new0(struct remote_version_req, 1); 2450646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg req->handle = handle; 2451646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg req->index = index; 2452646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 2453646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg if (!delayed) { 2454646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg get_remote_version(req); 2455646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg g_free(req); 2456646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg return 0; 2457646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg } 2458646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 2459646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1, get_remote_version, 2460646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg req, g_free); 2461646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 2462646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg return 0; 2463646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg} 2464646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg 246534c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic struct btd_adapter_ops hci_ops = { 246634c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode .setup = hciops_setup, 246734c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode .cleanup = hciops_cleanup, 2468076540a14a41acf8eba0bdb65e2dd5d4d42c7946Alok Barsode .start = hciops_start, 24694e71ac8617182584edf8ca57879e33d98879eb5dAlok Barsode .stop = hciops_stop, 2470030d865e4a2c9ff498a925a63264a419ff6c0780Alok Barsode .set_powered = hciops_powered, 24718b000e17009d5b6772ab3b4367881dfcef763e7eAlok Barsode .set_connectable = hciops_connectable, 247255927114c520807297b2fc63148aa467bed60218Alok Barsode .set_discoverable = hciops_discoverable, 2473eeba5fdb9c807191893b9e82cb4952e23df3ca56Alok Barsode .set_limited_discoverable = hciops_set_limited_discoverable, 24743af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasi .start_inquiry = hciops_start_inquiry, 24753af792e57b7ccb82d3139748a2b3c6b44d2e7ce2Claudio Takahasi .stop_inquiry = hciops_stop_inquiry, 247670cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi .start_scanning = hciops_start_scanning, 247770cd37db7cdadd72b0cd4c7e3e1b329b79e0d868Claudio Takahasi .stop_scanning = hciops_stop_scanning, 2478ef876daebf32cbe65fb4d9ec6fb1ffead60086eaAlok Barsode .resolve_name = hciops_resolve_name, 2479b96f44db8e91325968a0149595b2522d4a22481aAlok Barsode .cancel_resolve_name = hciops_cancel_resolve_name, 2480164ccf9a6641fe646d8476f6b860d5ff4905632bAlok Barsode .set_name = hciops_set_name, 2481d209c50141349ee9413d0717002af3d036db4762Alok Barsode .read_name = hciops_read_name, 2482d2a6bf00afbaeef82f9210639150e1f93cb44589Alok Barsode .set_class = hciops_set_class, 248361f0df8f18c417df50a296e10893c82b5eb83879Dmitriy Paliy .set_fast_connectable = hciops_fast_connectable, 24845bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter .read_clock = hciops_read_clock, 24855bca34b67c59a01d72adcf6601ce2c8553464142Elvis Pfützenreuter .get_conn_handle = hciops_conn_handle, 2486e070bc11469123aefc412ce4e408fe5ad5b525e5Johan Hedberg .write_eir_data = hciops_write_eir_data, 2487b5c556ef59a9a8318b239453c3d4a8aad951689fJohan Hedberg .read_bdaddr = hciops_read_bdaddr, 2488885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg .block_device = hciops_block_device, 2489885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg .unblock_device = hciops_unblock_device, 2490f7b4b3fcd1190d231b864730c821b98fb945e439Johan Hedberg .get_conn_list = hciops_get_conn_list, 2491e38fdde63c8f385b99bf17c9e5794e7f08575f7eJohan Hedberg .read_local_version = hciops_read_local_version, 249248e6007a98222853a0e1bcbbd6ac17a37098bb49Johan Hedberg .read_local_features = hciops_read_local_features, 24939ebc8d3b0f66a24f3821bf243dcd3f59527e8612Claudio Takahasi .read_local_ext_features = hciops_read_local_ext_features, 249498dbebb8edf59666e226386caf38824e40c8ff33Johan Hedberg .read_link_policy = hciops_read_link_policy, 249506dcf6ada5042f6f8a52ae64cfca8327399c09b1Johan Hedberg .disconnect = hciops_disconnect, 24961bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg .remove_bonding = hciops_remove_bonding, 2497424ffb26405690b9d9653a9418a9c4d332a85176Johan Hedberg .request_authentication = hciops_request_authentication, 2498e7daece858070d71cecf6ade4f0e3c93272c53acJohan Hedberg .pincode_reply = hciops_pincode_reply, 2499df6c074158bc0f2caf76178dc00d50c7bf1b444aJohan Hedberg .confirm_reply = hciops_confirm_reply, 2500889c7513b312854e7f5c274696ad92a233c1ce78Johan Hedberg .passkey_reply = hciops_passkey_reply, 25014b625a87bd009aa6a61443d802d63a5f81c58cc8Johan Hedberg .get_auth_info = hciops_get_auth_info, 2502f8b7d84e2cceed2f113d1688c87326ea2505cd16Johan Hedberg .read_scan_enable = hciops_read_scan_enable, 2503132374b5125787fd2be0ea9c6985ad9a88600474Johan Hedberg .read_ssp_mode = hciops_read_ssp_mode, 25047ff8fd32ebaec606c8ee9d063a277eeba7352f5fClaudio Takahasi .write_le_host = hciops_write_le_host, 2505646f0c7e6b557c5413825ce7b04bee52bf0129e8Johan Hedberg .get_remote_version = hciops_get_remote_version, 2506abe7cd44124a6955c1a3fd5c828ec2934f38a528Johan Hedberg .encrypt_link = hciops_encrypt_link, 250734c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode}; 250834c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode 250934c4239984722c169e3e821ec5ca7c88528827bdAlok Barsodestatic int hciops_init(void) 251034c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode{ 2511d30044157466e7f34e7f2d5d7ce70215ea013338Johan Hedberg return btd_register_adapter_ops(&hci_ops, FALSE); 251234c4239984722c169e3e821ec5ca7c88528827bdAlok Barsode} 2513d57934d1d09c34d1b136c572cad1dff6306c8c48Johan Hedberg 251494e91856179a268805256055ffd5155d1468b99cAlok Barsodestatic void hciops_exit(void) 251594e91856179a268805256055ffd5155d1468b99cAlok Barsode{ 2516929393b82db06368ff5fa4074bc209d1d4d03a48Marcel Holtmann btd_adapter_cleanup_ops(&hci_ops); 251794e91856179a268805256055ffd5155d1468b99cAlok Barsode} 251894e91856179a268805256055ffd5155d1468b99cAlok Barsode 251994e91856179a268805256055ffd5155d1468b99cAlok BarsodeBLUETOOTH_PLUGIN_DEFINE(hciops, VERSION, 25201ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann BLUETOOTH_PLUGIN_PRIORITY_LOW, hciops_init, hciops_exit) 2521