blob: 8417ab387d1a0f99a84a29c4fbe47e13d3d93062 [file] [log] [blame]
Johan Hedberg03811012010-12-08 00:21:06 +02001/*
2 BlueZ - Bluetooth protocol stack for Linux
Johan Hedbergea585ab2012-02-17 14:50:39 +02003
Johan Hedberg03811012010-12-08 00:21:06 +02004 Copyright (C) 2010 Nokia Corporation
Johan Hedbergea585ab2012-02-17 14:50:39 +02005 Copyright (C) 2011-2012 Intel Corporation
Johan Hedberg03811012010-12-08 00:21:06 +02006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI Management interface */
26
Paul Gortmaker3a9a2312011-05-27 09:12:25 -040027#include <linux/module.h>
Johan Hedberg03811012010-12-08 00:21:06 +020028#include <asm/unaligned.h>
29
30#include <net/bluetooth/bluetooth.h>
31#include <net/bluetooth/hci_core.h>
Johan Hedberg4bc58f52014-05-20 09:45:47 +030032#include <net/bluetooth/l2cap.h>
Johan Hedberg03811012010-12-08 00:21:06 +020033#include <net/bluetooth/mgmt.h>
Marcel Holtmannac4b7232013-10-10 14:54:16 -070034
Johan Hedberg0857dd32014-12-19 13:40:20 +020035#include "hci_request.h"
Marcel Holtmannac4b7232013-10-10 14:54:16 -070036#include "smp.h"
Johan Hedberg03811012010-12-08 00:21:06 +020037
Johan Hedberg2da9c552012-02-17 14:39:28 +020038#define MGMT_VERSION 1
Marcel Holtmann854bda12014-12-03 19:52:43 +010039#define MGMT_REVISION 8
Johan Hedberg02d98122010-12-13 21:07:04 +020040
Johan Hedberge70bb2e2012-02-13 16:59:33 +020041static const u16 mgmt_commands[] = {
42 MGMT_OP_READ_INDEX_LIST,
43 MGMT_OP_READ_INFO,
44 MGMT_OP_SET_POWERED,
45 MGMT_OP_SET_DISCOVERABLE,
46 MGMT_OP_SET_CONNECTABLE,
47 MGMT_OP_SET_FAST_CONNECTABLE,
Johan Hedbergb2939472014-07-30 09:22:23 +030048 MGMT_OP_SET_BONDABLE,
Johan Hedberge70bb2e2012-02-13 16:59:33 +020049 MGMT_OP_SET_LINK_SECURITY,
50 MGMT_OP_SET_SSP,
51 MGMT_OP_SET_HS,
52 MGMT_OP_SET_LE,
53 MGMT_OP_SET_DEV_CLASS,
54 MGMT_OP_SET_LOCAL_NAME,
55 MGMT_OP_ADD_UUID,
56 MGMT_OP_REMOVE_UUID,
57 MGMT_OP_LOAD_LINK_KEYS,
58 MGMT_OP_LOAD_LONG_TERM_KEYS,
59 MGMT_OP_DISCONNECT,
60 MGMT_OP_GET_CONNECTIONS,
61 MGMT_OP_PIN_CODE_REPLY,
62 MGMT_OP_PIN_CODE_NEG_REPLY,
63 MGMT_OP_SET_IO_CAPABILITY,
64 MGMT_OP_PAIR_DEVICE,
65 MGMT_OP_CANCEL_PAIR_DEVICE,
66 MGMT_OP_UNPAIR_DEVICE,
67 MGMT_OP_USER_CONFIRM_REPLY,
68 MGMT_OP_USER_CONFIRM_NEG_REPLY,
69 MGMT_OP_USER_PASSKEY_REPLY,
70 MGMT_OP_USER_PASSKEY_NEG_REPLY,
71 MGMT_OP_READ_LOCAL_OOB_DATA,
72 MGMT_OP_ADD_REMOTE_OOB_DATA,
73 MGMT_OP_REMOVE_REMOTE_OOB_DATA,
74 MGMT_OP_START_DISCOVERY,
75 MGMT_OP_STOP_DISCOVERY,
76 MGMT_OP_CONFIRM_NAME,
77 MGMT_OP_BLOCK_DEVICE,
78 MGMT_OP_UNBLOCK_DEVICE,
Marcel Holtmanncdbaccc2012-03-11 20:00:29 -070079 MGMT_OP_SET_DEVICE_ID,
Johan Hedberg4375f102013-09-25 13:26:10 +030080 MGMT_OP_SET_ADVERTISING,
Johan Hedberg0663ca22013-10-02 13:43:14 +030081 MGMT_OP_SET_BREDR,
Marcel Holtmannd13eafc2013-10-02 04:41:30 -070082 MGMT_OP_SET_STATIC_ADDRESS,
Marcel Holtmann7f72134e2013-10-11 14:44:58 -070083 MGMT_OP_SET_SCAN_PARAMS,
Marcel Holtmanne98d2ce2014-01-10 02:07:22 -080084 MGMT_OP_SET_SECURE_CONN,
Marcel Holtmann4e39ac82014-01-31 11:55:22 -080085 MGMT_OP_SET_DEBUG_KEYS,
Johan Hedberg62b04cd2014-02-23 19:42:27 +020086 MGMT_OP_SET_PRIVACY,
Johan Hedberg41edf162014-02-18 10:19:35 +020087 MGMT_OP_LOAD_IRKS,
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +020088 MGMT_OP_GET_CONN_INFO,
Johan Hedberg95868422014-06-28 17:54:07 +030089 MGMT_OP_GET_CLOCK_INFO,
Marcel Holtmann2faade52014-06-29 19:44:03 +020090 MGMT_OP_ADD_DEVICE,
91 MGMT_OP_REMOVE_DEVICE,
Johan Hedberga26f3dc2014-07-02 17:37:29 +030092 MGMT_OP_LOAD_CONN_PARAM,
Marcel Holtmann73d1df22014-07-02 22:10:52 +020093 MGMT_OP_READ_UNCONF_INDEX_LIST,
Marcel Holtmann9fc3bfb2014-07-04 00:46:56 +020094 MGMT_OP_READ_CONFIG_INFO,
Marcel Holtmanndbece372014-07-04 18:11:55 +020095 MGMT_OP_SET_EXTERNAL_CONFIG,
Marcel Holtmann9713c172014-07-06 12:11:15 +020096 MGMT_OP_SET_PUBLIC_ADDRESS,
Jakub Pawlowski66ea9422014-12-05 10:55:59 +010097 MGMT_OP_START_SERVICE_DISCOVERY,
Johan Hedberge70bb2e2012-02-13 16:59:33 +020098};
99
100static const u16 mgmt_events[] = {
101 MGMT_EV_CONTROLLER_ERROR,
102 MGMT_EV_INDEX_ADDED,
103 MGMT_EV_INDEX_REMOVED,
104 MGMT_EV_NEW_SETTINGS,
105 MGMT_EV_CLASS_OF_DEV_CHANGED,
106 MGMT_EV_LOCAL_NAME_CHANGED,
107 MGMT_EV_NEW_LINK_KEY,
108 MGMT_EV_NEW_LONG_TERM_KEY,
109 MGMT_EV_DEVICE_CONNECTED,
110 MGMT_EV_DEVICE_DISCONNECTED,
111 MGMT_EV_CONNECT_FAILED,
112 MGMT_EV_PIN_CODE_REQUEST,
113 MGMT_EV_USER_CONFIRM_REQUEST,
114 MGMT_EV_USER_PASSKEY_REQUEST,
115 MGMT_EV_AUTH_FAILED,
116 MGMT_EV_DEVICE_FOUND,
117 MGMT_EV_DISCOVERING,
118 MGMT_EV_DEVICE_BLOCKED,
119 MGMT_EV_DEVICE_UNBLOCKED,
120 MGMT_EV_DEVICE_UNPAIRED,
Johan Hedberg92a25252012-09-06 18:39:26 +0300121 MGMT_EV_PASSKEY_NOTIFY,
Marcel Holtmann1b60ef22014-02-21 21:35:30 -0800122 MGMT_EV_NEW_IRK,
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700123 MGMT_EV_NEW_CSRK,
Marcel Holtmann8afef092014-06-29 22:28:34 +0200124 MGMT_EV_DEVICE_ADDED,
125 MGMT_EV_DEVICE_REMOVED,
Andre Guedesffb5a8272014-07-01 18:10:11 -0300126 MGMT_EV_NEW_CONN_PARAM,
Marcel Holtmann0602a8a2014-07-02 21:30:54 +0200127 MGMT_EV_UNCONF_INDEX_ADDED,
Marcel Holtmannedd38962014-07-02 21:30:55 +0200128 MGMT_EV_UNCONF_INDEX_REMOVED,
Marcel Holtmannf4537c02014-07-04 19:06:23 +0200129 MGMT_EV_NEW_CONFIG_OPTIONS,
Johan Hedberge70bb2e2012-02-13 16:59:33 +0200130};
131
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800132#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
Johan Hedberg7d785252011-12-15 00:47:39 +0200133
Johan Hedbergd25b78e2015-01-27 12:55:52 +0200134#define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
135 "\x00\x00\x00\x00\x00\x00\x00\x00"
136
Johan Hedbergeec8d2b2010-12-16 10:17:38 +0200137struct pending_cmd {
138 struct list_head list;
Johan Hedbergfc2f4b12011-11-09 13:58:56 +0200139 u16 opcode;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +0200140 int index;
Szymon Jancc68fb7f2011-03-22 13:12:19 +0100141 void *param;
Johan Hedberg323b0b82014-12-05 13:36:01 +0200142 size_t param_len;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +0200143 struct sock *sk;
Johan Hedberge9a416b2011-02-19 12:05:56 -0300144 void *user_data;
Johan Hedberg9df74652014-12-19 22:26:03 +0200145 int (*cmd_complete)(struct pending_cmd *cmd, u8 status);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +0200146};
147
Johan Hedbergca69b792011-11-11 18:10:00 +0200148/* HCI to MGMT error code conversion table */
149static u8 mgmt_status_table[] = {
150 MGMT_STATUS_SUCCESS,
151 MGMT_STATUS_UNKNOWN_COMMAND, /* Unknown Command */
152 MGMT_STATUS_NOT_CONNECTED, /* No Connection */
153 MGMT_STATUS_FAILED, /* Hardware Failure */
154 MGMT_STATUS_CONNECT_FAILED, /* Page Timeout */
155 MGMT_STATUS_AUTH_FAILED, /* Authentication Failed */
Johan Hedbergeadd6632014-01-13 17:15:53 +0200156 MGMT_STATUS_AUTH_FAILED, /* PIN or Key Missing */
Johan Hedbergca69b792011-11-11 18:10:00 +0200157 MGMT_STATUS_NO_RESOURCES, /* Memory Full */
158 MGMT_STATUS_TIMEOUT, /* Connection Timeout */
159 MGMT_STATUS_NO_RESOURCES, /* Max Number of Connections */
160 MGMT_STATUS_NO_RESOURCES, /* Max Number of SCO Connections */
161 MGMT_STATUS_ALREADY_CONNECTED, /* ACL Connection Exists */
162 MGMT_STATUS_BUSY, /* Command Disallowed */
163 MGMT_STATUS_NO_RESOURCES, /* Rejected Limited Resources */
164 MGMT_STATUS_REJECTED, /* Rejected Security */
165 MGMT_STATUS_REJECTED, /* Rejected Personal */
166 MGMT_STATUS_TIMEOUT, /* Host Timeout */
167 MGMT_STATUS_NOT_SUPPORTED, /* Unsupported Feature */
168 MGMT_STATUS_INVALID_PARAMS, /* Invalid Parameters */
169 MGMT_STATUS_DISCONNECTED, /* OE User Ended Connection */
170 MGMT_STATUS_NO_RESOURCES, /* OE Low Resources */
171 MGMT_STATUS_DISCONNECTED, /* OE Power Off */
172 MGMT_STATUS_DISCONNECTED, /* Connection Terminated */
173 MGMT_STATUS_BUSY, /* Repeated Attempts */
174 MGMT_STATUS_REJECTED, /* Pairing Not Allowed */
175 MGMT_STATUS_FAILED, /* Unknown LMP PDU */
176 MGMT_STATUS_NOT_SUPPORTED, /* Unsupported Remote Feature */
177 MGMT_STATUS_REJECTED, /* SCO Offset Rejected */
178 MGMT_STATUS_REJECTED, /* SCO Interval Rejected */
179 MGMT_STATUS_REJECTED, /* Air Mode Rejected */
180 MGMT_STATUS_INVALID_PARAMS, /* Invalid LMP Parameters */
181 MGMT_STATUS_FAILED, /* Unspecified Error */
182 MGMT_STATUS_NOT_SUPPORTED, /* Unsupported LMP Parameter Value */
183 MGMT_STATUS_FAILED, /* Role Change Not Allowed */
184 MGMT_STATUS_TIMEOUT, /* LMP Response Timeout */
185 MGMT_STATUS_FAILED, /* LMP Error Transaction Collision */
186 MGMT_STATUS_FAILED, /* LMP PDU Not Allowed */
187 MGMT_STATUS_REJECTED, /* Encryption Mode Not Accepted */
188 MGMT_STATUS_FAILED, /* Unit Link Key Used */
189 MGMT_STATUS_NOT_SUPPORTED, /* QoS Not Supported */
190 MGMT_STATUS_TIMEOUT, /* Instant Passed */
191 MGMT_STATUS_NOT_SUPPORTED, /* Pairing Not Supported */
192 MGMT_STATUS_FAILED, /* Transaction Collision */
193 MGMT_STATUS_INVALID_PARAMS, /* Unacceptable Parameter */
194 MGMT_STATUS_REJECTED, /* QoS Rejected */
195 MGMT_STATUS_NOT_SUPPORTED, /* Classification Not Supported */
196 MGMT_STATUS_REJECTED, /* Insufficient Security */
197 MGMT_STATUS_INVALID_PARAMS, /* Parameter Out Of Range */
198 MGMT_STATUS_BUSY, /* Role Switch Pending */
199 MGMT_STATUS_FAILED, /* Slot Violation */
200 MGMT_STATUS_FAILED, /* Role Switch Failed */
201 MGMT_STATUS_INVALID_PARAMS, /* EIR Too Large */
202 MGMT_STATUS_NOT_SUPPORTED, /* Simple Pairing Not Supported */
203 MGMT_STATUS_BUSY, /* Host Busy Pairing */
204 MGMT_STATUS_REJECTED, /* Rejected, No Suitable Channel */
205 MGMT_STATUS_BUSY, /* Controller Busy */
206 MGMT_STATUS_INVALID_PARAMS, /* Unsuitable Connection Interval */
207 MGMT_STATUS_TIMEOUT, /* Directed Advertising Timeout */
208 MGMT_STATUS_AUTH_FAILED, /* Terminated Due to MIC Failure */
209 MGMT_STATUS_CONNECT_FAILED, /* Connection Establishment Failed */
210 MGMT_STATUS_CONNECT_FAILED, /* MAC Connection Failed */
211};
212
213static u8 mgmt_status(u8 hci_status)
214{
215 if (hci_status < ARRAY_SIZE(mgmt_status_table))
216 return mgmt_status_table[hci_status];
217
218 return MGMT_STATUS_FAILED;
219}
220
Marcel Holtmann04c60f052014-07-04 19:06:22 +0200221static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
222 struct sock *skip_sk)
223{
224 struct sk_buff *skb;
225 struct mgmt_hdr *hdr;
226
227 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL);
228 if (!skb)
229 return -ENOMEM;
230
231 hdr = (void *) skb_put(skb, sizeof(*hdr));
232 hdr->opcode = cpu_to_le16(event);
233 if (hdev)
234 hdr->index = cpu_to_le16(hdev->id);
235 else
236 hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
237 hdr->len = cpu_to_le16(data_len);
238
239 if (data)
240 memcpy(skb_put(skb, data_len), data, data_len);
241
242 /* Time stamp */
243 __net_timestamp(skb);
244
245 hci_send_to_control(skb, skip_sk);
246 kfree_skb(skb);
247
248 return 0;
249}
250
Szymon Janc4e51eae2011-02-25 19:05:48 +0100251static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200252{
253 struct sk_buff *skb;
254 struct mgmt_hdr *hdr;
255 struct mgmt_ev_cmd_status *ev;
Gustavo F. Padovan56b7d132011-10-14 19:20:01 -0300256 int err;
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200257
Szymon Janc34eb5252011-02-28 14:10:08 +0100258 BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status);
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200259
Andre Guedes790eff42012-06-07 19:05:46 -0300260 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL);
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200261 if (!skb)
262 return -ENOMEM;
263
264 hdr = (void *) skb_put(skb, sizeof(*hdr));
265
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700266 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
Szymon Janc4e51eae2011-02-25 19:05:48 +0100267 hdr->index = cpu_to_le16(index);
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200268 hdr->len = cpu_to_le16(sizeof(*ev));
269
270 ev = (void *) skb_put(skb, sizeof(*ev));
271 ev->status = status;
Marcel Holtmanneb55ef02012-03-14 18:08:46 +0200272 ev->opcode = cpu_to_le16(cmd);
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200273
Gustavo F. Padovan56b7d132011-10-14 19:20:01 -0300274 err = sock_queue_rcv_skb(sk, skb);
275 if (err < 0)
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200276 kfree_skb(skb);
277
Gustavo F. Padovan56b7d132011-10-14 19:20:01 -0300278 return err;
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200279}
280
Johan Hedbergaee9b2182012-02-18 15:07:59 +0200281static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300282 void *rp, size_t rp_len)
Johan Hedberg02d98122010-12-13 21:07:04 +0200283{
284 struct sk_buff *skb;
285 struct mgmt_hdr *hdr;
286 struct mgmt_ev_cmd_complete *ev;
Gustavo F. Padovan56b7d132011-10-14 19:20:01 -0300287 int err;
Johan Hedberg02d98122010-12-13 21:07:04 +0200288
289 BT_DBG("sock %p", sk);
290
Andre Guedes790eff42012-06-07 19:05:46 -0300291 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL);
Johan Hedberg02d98122010-12-13 21:07:04 +0200292 if (!skb)
293 return -ENOMEM;
294
295 hdr = (void *) skb_put(skb, sizeof(*hdr));
Johan Hedberga38528f2011-01-22 06:46:43 +0200296
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700297 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
Szymon Janc4e51eae2011-02-25 19:05:48 +0100298 hdr->index = cpu_to_le16(index);
Johan Hedberga38528f2011-01-22 06:46:43 +0200299 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
Johan Hedberg02d98122010-12-13 21:07:04 +0200300
Johan Hedberga38528f2011-01-22 06:46:43 +0200301 ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
Marcel Holtmanneb55ef02012-03-14 18:08:46 +0200302 ev->opcode = cpu_to_le16(cmd);
Johan Hedbergaee9b2182012-02-18 15:07:59 +0200303 ev->status = status;
Szymon Janc8020c162011-02-28 14:09:50 +0100304
305 if (rp)
306 memcpy(ev->data, rp, rp_len);
Johan Hedberg02d98122010-12-13 21:07:04 +0200307
Gustavo F. Padovan56b7d132011-10-14 19:20:01 -0300308 err = sock_queue_rcv_skb(sk, skb);
309 if (err < 0)
Johan Hedberg02d98122010-12-13 21:07:04 +0200310 kfree_skb(skb);
311
Marcel Holtmanne5f0e152012-02-22 11:59:01 +0100312 return err;
Johan Hedberg02d98122010-12-13 21:07:04 +0200313}
314
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300315static int read_version(struct sock *sk, struct hci_dev *hdev, void *data,
316 u16 data_len)
Johan Hedberga38528f2011-01-22 06:46:43 +0200317{
318 struct mgmt_rp_read_version rp;
319
320 BT_DBG("sock %p", sk);
321
322 rp.version = MGMT_VERSION;
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700323 rp.revision = cpu_to_le16(MGMT_REVISION);
Johan Hedberga38528f2011-01-22 06:46:43 +0200324
Johan Hedbergaee9b2182012-02-18 15:07:59 +0200325 return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0, &rp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300326 sizeof(rp));
Johan Hedberga38528f2011-01-22 06:46:43 +0200327}
328
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300329static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data,
330 u16 data_len)
Johan Hedberge70bb2e2012-02-13 16:59:33 +0200331{
332 struct mgmt_rp_read_commands *rp;
Marcel Holtmanneb55ef02012-03-14 18:08:46 +0200333 const u16 num_commands = ARRAY_SIZE(mgmt_commands);
334 const u16 num_events = ARRAY_SIZE(mgmt_events);
Andrei Emeltchenko2e3c35e2012-03-14 18:54:15 +0200335 __le16 *opcode;
Johan Hedberge70bb2e2012-02-13 16:59:33 +0200336 size_t rp_size;
337 int i, err;
338
339 BT_DBG("sock %p", sk);
340
341 rp_size = sizeof(*rp) + ((num_commands + num_events) * sizeof(u16));
342
343 rp = kmalloc(rp_size, GFP_KERNEL);
344 if (!rp)
345 return -ENOMEM;
346
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700347 rp->num_commands = cpu_to_le16(num_commands);
348 rp->num_events = cpu_to_le16(num_events);
Johan Hedberge70bb2e2012-02-13 16:59:33 +0200349
350 for (i = 0, opcode = rp->opcodes; i < num_commands; i++, opcode++)
351 put_unaligned_le16(mgmt_commands[i], opcode);
352
353 for (i = 0; i < num_events; i++, opcode++)
354 put_unaligned_le16(mgmt_events[i], opcode);
355
Johan Hedbergaee9b2182012-02-18 15:07:59 +0200356 err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_COMMANDS, 0, rp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300357 rp_size);
Johan Hedberge70bb2e2012-02-13 16:59:33 +0200358 kfree(rp);
359
360 return err;
361}
362
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300363static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
364 u16 data_len)
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200365{
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200366 struct mgmt_rp_read_index_list *rp;
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200367 struct hci_dev *d;
Johan Hedberga38528f2011-01-22 06:46:43 +0200368 size_t rp_len;
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200369 u16 count;
Johan Hedberg476e44c2012-10-19 20:10:46 +0300370 int err;
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200371
372 BT_DBG("sock %p", sk);
373
374 read_lock(&hci_dev_list_lock);
375
376 count = 0;
Andrei Emeltchenkobb4b2a92012-07-19 17:03:40 +0300377 list_for_each_entry(d, &hci_dev_list, list) {
Marcel Holtmann73d1df22014-07-02 22:10:52 +0200378 if (d->dev_type == HCI_BREDR &&
379 !test_bit(HCI_UNCONFIGURED, &d->dev_flags))
Marcel Holtmann1514b892013-10-06 08:25:01 -0700380 count++;
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200381 }
382
Johan Hedberga38528f2011-01-22 06:46:43 +0200383 rp_len = sizeof(*rp) + (2 * count);
384 rp = kmalloc(rp_len, GFP_ATOMIC);
385 if (!rp) {
Jesper Juhlb2c60d42011-01-14 00:18:49 +0100386 read_unlock(&hci_dev_list_lock);
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200387 return -ENOMEM;
Jesper Juhlb2c60d42011-01-14 00:18:49 +0100388 }
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200389
Johan Hedberg476e44c2012-10-19 20:10:46 +0300390 count = 0;
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200391 list_for_each_entry(d, &hci_dev_list, list) {
Marcel Holtmann73d1df22014-07-02 22:10:52 +0200392 if (test_bit(HCI_SETUP, &d->dev_flags) ||
Marcel Holtmannd603b762014-07-06 12:11:14 +0200393 test_bit(HCI_CONFIG, &d->dev_flags) ||
Marcel Holtmann73d1df22014-07-02 22:10:52 +0200394 test_bit(HCI_USER_CHANNEL, &d->dev_flags))
Johan Hedbergab81cbf2010-12-15 13:53:18 +0200395 continue;
396
Marcel Holtmann73d1df22014-07-02 22:10:52 +0200397 /* Devices marked as raw-only are neither configured
398 * nor unconfigured controllers.
399 */
400 if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks))
Marcel Holtmann0736cfa2013-08-26 21:40:51 -0700401 continue;
402
Marcel Holtmann73d1df22014-07-02 22:10:52 +0200403 if (d->dev_type == HCI_BREDR &&
404 !test_bit(HCI_UNCONFIGURED, &d->dev_flags)) {
Marcel Holtmann1514b892013-10-06 08:25:01 -0700405 rp->index[count++] = cpu_to_le16(d->id);
406 BT_DBG("Added hci%u", d->id);
407 }
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200408 }
409
Johan Hedberg476e44c2012-10-19 20:10:46 +0300410 rp->num_controllers = cpu_to_le16(count);
411 rp_len = sizeof(*rp) + (2 * count);
412
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200413 read_unlock(&hci_dev_list_lock);
414
Johan Hedbergaee9b2182012-02-18 15:07:59 +0200415 err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300416 rp_len);
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200417
Johan Hedberga38528f2011-01-22 06:46:43 +0200418 kfree(rp);
419
420 return err;
Johan Hedbergfaba42e2010-12-13 21:07:05 +0200421}
422
Marcel Holtmann73d1df22014-07-02 22:10:52 +0200423static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
424 void *data, u16 data_len)
425{
426 struct mgmt_rp_read_unconf_index_list *rp;
427 struct hci_dev *d;
428 size_t rp_len;
429 u16 count;
430 int err;
431
432 BT_DBG("sock %p", sk);
433
434 read_lock(&hci_dev_list_lock);
435
436 count = 0;
437 list_for_each_entry(d, &hci_dev_list, list) {
438 if (d->dev_type == HCI_BREDR &&
439 test_bit(HCI_UNCONFIGURED, &d->dev_flags))
440 count++;
441 }
442
443 rp_len = sizeof(*rp) + (2 * count);
444 rp = kmalloc(rp_len, GFP_ATOMIC);
445 if (!rp) {
446 read_unlock(&hci_dev_list_lock);
447 return -ENOMEM;
448 }
449
450 count = 0;
451 list_for_each_entry(d, &hci_dev_list, list) {
452 if (test_bit(HCI_SETUP, &d->dev_flags) ||
Marcel Holtmannd603b762014-07-06 12:11:14 +0200453 test_bit(HCI_CONFIG, &d->dev_flags) ||
Marcel Holtmann73d1df22014-07-02 22:10:52 +0200454 test_bit(HCI_USER_CHANNEL, &d->dev_flags))
455 continue;
456
457 /* Devices marked as raw-only are neither configured
458 * nor unconfigured controllers.
459 */
460 if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks))
461 continue;
462
463 if (d->dev_type == HCI_BREDR &&
464 test_bit(HCI_UNCONFIGURED, &d->dev_flags)) {
465 rp->index[count++] = cpu_to_le16(d->id);
466 BT_DBG("Added hci%u", d->id);
467 }
468 }
469
470 rp->num_controllers = cpu_to_le16(count);
471 rp_len = sizeof(*rp) + (2 * count);
472
473 read_unlock(&hci_dev_list_lock);
474
475 err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_UNCONF_INDEX_LIST,
476 0, rp, rp_len);
477
478 kfree(rp);
479
480 return err;
481}
482
Marcel Holtmanndbece372014-07-04 18:11:55 +0200483static bool is_configured(struct hci_dev *hdev)
484{
485 if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) &&
486 !test_bit(HCI_EXT_CONFIGURED, &hdev->dev_flags))
487 return false;
488
489 if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
490 !bacmp(&hdev->public_addr, BDADDR_ANY))
491 return false;
492
493 return true;
494}
495
Marcel Holtmann89bc22d2014-07-04 16:54:37 +0200496static __le32 get_missing_options(struct hci_dev *hdev)
497{
498 u32 options = 0;
499
Marcel Holtmanndbece372014-07-04 18:11:55 +0200500 if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) &&
501 !test_bit(HCI_EXT_CONFIGURED, &hdev->dev_flags))
Marcel Holtmanneb1904f2014-07-04 17:23:33 +0200502 options |= MGMT_OPTION_EXTERNAL_CONFIG;
503
Marcel Holtmann89bc22d2014-07-04 16:54:37 +0200504 if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
505 !bacmp(&hdev->public_addr, BDADDR_ANY))
506 options |= MGMT_OPTION_PUBLIC_ADDRESS;
507
508 return cpu_to_le32(options);
509}
510
Marcel Holtmannf4537c02014-07-04 19:06:23 +0200511static int new_options(struct hci_dev *hdev, struct sock *skip)
512{
513 __le32 options = get_missing_options(hdev);
514
515 return mgmt_event(MGMT_EV_NEW_CONFIG_OPTIONS, hdev, &options,
516 sizeof(options), skip);
517}
518
Marcel Holtmanndbece372014-07-04 18:11:55 +0200519static int send_options_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
520{
521 __le32 options = get_missing_options(hdev);
522
523 return cmd_complete(sk, hdev->id, opcode, 0, &options,
524 sizeof(options));
525}
526
Marcel Holtmann9fc3bfb2014-07-04 00:46:56 +0200527static int read_config_info(struct sock *sk, struct hci_dev *hdev,
528 void *data, u16 data_len)
529{
530 struct mgmt_rp_read_config_info rp;
Marcel Holtmann89bc22d2014-07-04 16:54:37 +0200531 u32 options = 0;
Marcel Holtmann9fc3bfb2014-07-04 00:46:56 +0200532
533 BT_DBG("sock %p %s", sk, hdev->name);
534
535 hci_dev_lock(hdev);
536
537 memset(&rp, 0, sizeof(rp));
538 rp.manufacturer = cpu_to_le16(hdev->manufacturer);
Marcel Holtmann89bc22d2014-07-04 16:54:37 +0200539
Marcel Holtmanneb1904f2014-07-04 17:23:33 +0200540 if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks))
541 options |= MGMT_OPTION_EXTERNAL_CONFIG;
542
Marcel Holtmann9fc3bfb2014-07-04 00:46:56 +0200543 if (hdev->set_bdaddr)
Marcel Holtmann89bc22d2014-07-04 16:54:37 +0200544 options |= MGMT_OPTION_PUBLIC_ADDRESS;
545
546 rp.supported_options = cpu_to_le32(options);
547 rp.missing_options = get_missing_options(hdev);
Marcel Holtmann9fc3bfb2014-07-04 00:46:56 +0200548
549 hci_dev_unlock(hdev);
550
551 return cmd_complete(sk, hdev->id, MGMT_OP_READ_CONFIG_INFO, 0, &rp,
552 sizeof(rp));
553}
554
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200555static u32 get_supported_settings(struct hci_dev *hdev)
Johan Hedberg03811012010-12-08 00:21:06 +0200556{
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200557 u32 settings = 0;
Johan Hedberg03811012010-12-08 00:21:06 +0200558
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200559 settings |= MGMT_SETTING_POWERED;
Johan Hedbergb2939472014-07-30 09:22:23 +0300560 settings |= MGMT_SETTING_BONDABLE;
Marcel Holtmannb1de97d2014-01-31 11:55:21 -0800561 settings |= MGMT_SETTING_DEBUG_KEYS;
Johan Hedberg3742abf2014-07-08 16:07:34 +0300562 settings |= MGMT_SETTING_CONNECTABLE;
563 settings |= MGMT_SETTING_DISCOVERABLE;
Johan Hedberg03811012010-12-08 00:21:06 +0200564
Andre Guedesed3fa312012-07-24 15:03:46 -0300565 if (lmp_bredr_capable(hdev)) {
Johan Hedberg1a47aee2013-03-15 17:07:06 -0500566 if (hdev->hci_ver >= BLUETOOTH_VER_1_2)
567 settings |= MGMT_SETTING_FAST_CONNECTABLE;
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200568 settings |= MGMT_SETTING_BREDR;
569 settings |= MGMT_SETTING_LINK_SECURITY;
Marcel Holtmanna82974c2013-10-11 09:48:47 -0700570
571 if (lmp_ssp_capable(hdev)) {
572 settings |= MGMT_SETTING_SSP;
573 settings |= MGMT_SETTING_HS;
574 }
Marcel Holtmanne98d2ce2014-01-10 02:07:22 -0800575
Marcel Holtmann05b3c3e2014-12-31 14:43:18 -0800576 if (lmp_sc_capable(hdev))
Marcel Holtmanne98d2ce2014-01-10 02:07:22 -0800577 settings |= MGMT_SETTING_SECURE_CONN;
Marcel Holtmann848566b2013-10-01 22:59:22 -0700578 }
Marcel Holtmannd7b7e792012-02-20 21:47:49 +0100579
Johan Hedbergeeca6f82013-09-25 13:26:09 +0300580 if (lmp_le_capable(hdev)) {
Marcel Holtmann9d428202012-05-03 07:12:31 +0200581 settings |= MGMT_SETTING_LE;
Johan Hedbergeeca6f82013-09-25 13:26:09 +0300582 settings |= MGMT_SETTING_ADVERTISING;
Johan Hedberga3209692014-05-26 11:23:35 +0300583 settings |= MGMT_SETTING_SECURE_CONN;
Johan Hedberg0f4bd942014-02-22 19:06:35 +0200584 settings |= MGMT_SETTING_PRIVACY;
Johan Hedbergeeca6f82013-09-25 13:26:09 +0300585 }
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200586
Marcel Holtmanneb1904f2014-07-04 17:23:33 +0200587 if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
588 hdev->set_bdaddr)
Marcel Holtmann9fc3bfb2014-07-04 00:46:56 +0200589 settings |= MGMT_SETTING_CONFIGURATION;
590
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200591 return settings;
592}
Johan Hedbergebc99fe2011-01-04 11:54:26 +0200593
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200594static u32 get_current_settings(struct hci_dev *hdev)
595{
596 u32 settings = 0;
Johan Hedbergdc4fe302011-03-16 14:29:36 +0200597
Johan Hedbergf1f0eb02012-02-21 17:15:41 +0200598 if (hdev_is_powered(hdev))
Marcel Holtmannf0d4b782012-02-21 12:14:25 +0100599 settings |= MGMT_SETTING_POWERED;
600
Johan Hedberg5e5282b2012-02-21 16:01:30 +0200601 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200602 settings |= MGMT_SETTING_CONNECTABLE;
603
Johan Hedberg1a4d3c42013-03-15 17:07:08 -0500604 if (test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags))
605 settings |= MGMT_SETTING_FAST_CONNECTABLE;
606
Johan Hedberg5e5282b2012-02-21 16:01:30 +0200607 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200608 settings |= MGMT_SETTING_DISCOVERABLE;
609
Johan Hedbergb6ae8452014-07-30 09:22:22 +0300610 if (test_bit(HCI_BONDABLE, &hdev->dev_flags))
Johan Hedbergb2939472014-07-30 09:22:23 +0300611 settings |= MGMT_SETTING_BONDABLE;
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200612
Johan Hedberg56f87902013-10-02 13:43:13 +0300613 if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200614 settings |= MGMT_SETTING_BREDR;
615
Johan Hedberg06199cf2012-02-22 16:37:11 +0200616 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200617 settings |= MGMT_SETTING_LE;
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200618
Johan Hedberg47990ea2012-02-22 11:58:37 +0200619 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200620 settings |= MGMT_SETTING_LINK_SECURITY;
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200621
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200622 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200623 settings |= MGMT_SETTING_SSP;
Johan Hedbergf7b64e62010-12-13 21:07:06 +0200624
Johan Hedberg6d80dfd2012-02-20 23:50:38 +0200625 if (test_bit(HCI_HS_ENABLED, &hdev->dev_flags))
626 settings |= MGMT_SETTING_HS;
627
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200628 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
Johan Hedbergeeca6f82013-09-25 13:26:09 +0300629 settings |= MGMT_SETTING_ADVERTISING;
630
Marcel Holtmanne98d2ce2014-01-10 02:07:22 -0800631 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
632 settings |= MGMT_SETTING_SECURE_CONN;
633
Johan Hedberg0663b292014-06-24 13:15:50 +0300634 if (test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags))
Marcel Holtmannb1de97d2014-01-31 11:55:21 -0800635 settings |= MGMT_SETTING_DEBUG_KEYS;
636
Johan Hedberg0f4bd942014-02-22 19:06:35 +0200637 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
638 settings |= MGMT_SETTING_PRIVACY;
639
Johan Hedberg69ab39e2011-12-15 00:47:35 +0200640 return settings;
Johan Hedbergc542a062011-01-26 13:11:03 +0200641}
642
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300643#define PNP_INFO_SVCLASS_ID 0x1200
644
Johan Hedberg213202e2013-01-27 00:31:33 +0200645static u8 *create_uuid16_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
646{
647 u8 *ptr = data, *uuids_start = NULL;
648 struct bt_uuid *uuid;
649
650 if (len < 4)
651 return ptr;
652
653 list_for_each_entry(uuid, &hdev->uuids, list) {
654 u16 uuid16;
655
656 if (uuid->size != 16)
657 continue;
658
659 uuid16 = get_unaligned_le16(&uuid->uuid[12]);
660 if (uuid16 < 0x1100)
661 continue;
662
663 if (uuid16 == PNP_INFO_SVCLASS_ID)
664 continue;
665
666 if (!uuids_start) {
667 uuids_start = ptr;
668 uuids_start[0] = 1;
669 uuids_start[1] = EIR_UUID16_ALL;
670 ptr += 2;
671 }
672
673 /* Stop if not enough space to put next UUID */
674 if ((ptr - data) + sizeof(u16) > len) {
675 uuids_start[1] = EIR_UUID16_SOME;
676 break;
677 }
678
679 *ptr++ = (uuid16 & 0x00ff);
680 *ptr++ = (uuid16 & 0xff00) >> 8;
681 uuids_start[0] += sizeof(uuid16);
682 }
683
684 return ptr;
685}
686
Johan Hedbergcdf19632013-01-27 00:31:34 +0200687static u8 *create_uuid32_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
688{
689 u8 *ptr = data, *uuids_start = NULL;
690 struct bt_uuid *uuid;
691
692 if (len < 6)
693 return ptr;
694
695 list_for_each_entry(uuid, &hdev->uuids, list) {
696 if (uuid->size != 32)
697 continue;
698
699 if (!uuids_start) {
700 uuids_start = ptr;
701 uuids_start[0] = 1;
702 uuids_start[1] = EIR_UUID32_ALL;
703 ptr += 2;
704 }
705
706 /* Stop if not enough space to put next UUID */
707 if ((ptr - data) + sizeof(u32) > len) {
708 uuids_start[1] = EIR_UUID32_SOME;
709 break;
710 }
711
712 memcpy(ptr, &uuid->uuid[12], sizeof(u32));
713 ptr += sizeof(u32);
714 uuids_start[0] += sizeof(u32);
715 }
716
717 return ptr;
718}
719
Johan Hedbergc00d5752013-01-27 00:31:35 +0200720static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
721{
722 u8 *ptr = data, *uuids_start = NULL;
723 struct bt_uuid *uuid;
724
725 if (len < 18)
726 return ptr;
727
728 list_for_each_entry(uuid, &hdev->uuids, list) {
729 if (uuid->size != 128)
730 continue;
731
732 if (!uuids_start) {
733 uuids_start = ptr;
734 uuids_start[0] = 1;
735 uuids_start[1] = EIR_UUID128_ALL;
736 ptr += 2;
737 }
738
739 /* Stop if not enough space to put next UUID */
740 if ((ptr - data) + 16 > len) {
741 uuids_start[1] = EIR_UUID128_SOME;
742 break;
743 }
744
745 memcpy(ptr, uuid->uuid, 16);
746 ptr += 16;
747 uuids_start[0] += 16;
748 }
749
750 return ptr;
751}
752
Johan Hedbergeb2a8d22013-10-19 23:38:20 +0300753static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev)
754{
755 struct pending_cmd *cmd;
756
757 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
758 if (cmd->opcode == opcode)
759 return cmd;
760 }
761
762 return NULL;
763}
764
Johan Hedberg95868422014-06-28 17:54:07 +0300765static struct pending_cmd *mgmt_pending_find_data(u16 opcode,
766 struct hci_dev *hdev,
767 const void *data)
768{
769 struct pending_cmd *cmd;
770
771 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
772 if (cmd->user_data != data)
773 continue;
774 if (cmd->opcode == opcode)
775 return cmd;
776 }
777
778 return NULL;
779}
780
Marcel Holtmannf14d8f62013-10-16 00:16:48 -0700781static u8 create_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
782{
Marcel Holtmann7a5f4992013-10-16 00:16:49 -0700783 u8 ad_len = 0;
784 size_t name_len;
785
786 name_len = strlen(hdev->dev_name);
787 if (name_len > 0) {
788 size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
789
790 if (name_len > max_len) {
791 name_len = max_len;
792 ptr[1] = EIR_NAME_SHORT;
793 } else
794 ptr[1] = EIR_NAME_COMPLETE;
795
796 ptr[0] = name_len + 1;
797
798 memcpy(ptr + 2, hdev->dev_name, name_len);
799
800 ad_len += (name_len + 2);
801 ptr += (name_len + 2);
802 }
803
804 return ad_len;
Marcel Holtmannf14d8f62013-10-16 00:16:48 -0700805}
806
807static void update_scan_rsp_data(struct hci_request *req)
808{
809 struct hci_dev *hdev = req->hdev;
810 struct hci_cp_le_set_scan_rsp_data cp;
811 u8 len;
812
Johan Hedberg7751ef12013-10-19 23:38:15 +0300813 if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
Marcel Holtmannf14d8f62013-10-16 00:16:48 -0700814 return;
815
816 memset(&cp, 0, sizeof(cp));
817
818 len = create_scan_rsp_data(hdev, cp.data);
819
Johan Hedbergeb438b52013-10-16 15:31:07 +0300820 if (hdev->scan_rsp_data_len == len &&
821 memcmp(cp.data, hdev->scan_rsp_data, len) == 0)
Marcel Holtmannf14d8f62013-10-16 00:16:48 -0700822 return;
823
Johan Hedbergeb438b52013-10-16 15:31:07 +0300824 memcpy(hdev->scan_rsp_data, cp.data, sizeof(cp.data));
825 hdev->scan_rsp_data_len = len;
Marcel Holtmannf14d8f62013-10-16 00:16:48 -0700826
827 cp.length = len;
828
829 hci_req_add(req, HCI_OP_LE_SET_SCAN_RSP_DATA, sizeof(cp), &cp);
830}
831
Johan Hedberg9a43e252013-10-20 19:00:07 +0300832static u8 get_adv_discov_flags(struct hci_dev *hdev)
833{
834 struct pending_cmd *cmd;
835
836 /* If there's a pending mgmt command the flags will not yet have
837 * their final values, so check for this first.
838 */
839 cmd = mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev);
840 if (cmd) {
841 struct mgmt_mode *cp = cmd->param;
842 if (cp->val == 0x01)
843 return LE_AD_GENERAL;
844 else if (cp->val == 0x02)
845 return LE_AD_LIMITED;
846 } else {
847 if (test_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags))
848 return LE_AD_LIMITED;
849 else if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
850 return LE_AD_GENERAL;
851 }
852
853 return 0;
854}
855
Marcel Holtmann46cad2e2013-10-16 00:16:46 -0700856static u8 create_adv_data(struct hci_dev *hdev, u8 *ptr)
Marcel Holtmann441ad2d2013-10-15 06:33:52 -0700857{
858 u8 ad_len = 0, flags = 0;
Marcel Holtmann441ad2d2013-10-15 06:33:52 -0700859
Johan Hedberg9a43e252013-10-20 19:00:07 +0300860 flags |= get_adv_discov_flags(hdev);
Marcel Holtmann441ad2d2013-10-15 06:33:52 -0700861
Johan Hedberge8340042014-01-30 11:16:50 -0800862 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
Marcel Holtmann441ad2d2013-10-15 06:33:52 -0700863 flags |= LE_AD_NO_BREDR;
Marcel Holtmann441ad2d2013-10-15 06:33:52 -0700864
865 if (flags) {
866 BT_DBG("adv flags 0x%02x", flags);
867
868 ptr[0] = 2;
869 ptr[1] = EIR_FLAGS;
870 ptr[2] = flags;
871
872 ad_len += 3;
873 ptr += 3;
874 }
875
876 if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
877 ptr[0] = 2;
878 ptr[1] = EIR_TX_POWER;
879 ptr[2] = (u8) hdev->adv_tx_power;
880
881 ad_len += 3;
882 ptr += 3;
883 }
884
Marcel Holtmann441ad2d2013-10-15 06:33:52 -0700885 return ad_len;
886}
887
Marcel Holtmann5947f4b2013-10-16 00:16:50 -0700888static void update_adv_data(struct hci_request *req)
Marcel Holtmann441ad2d2013-10-15 06:33:52 -0700889{
890 struct hci_dev *hdev = req->hdev;
891 struct hci_cp_le_set_adv_data cp;
892 u8 len;
893
Johan Hedberg10994ce2013-10-19 23:38:16 +0300894 if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
Marcel Holtmann441ad2d2013-10-15 06:33:52 -0700895 return;
896
897 memset(&cp, 0, sizeof(cp));
898
Marcel Holtmann46cad2e2013-10-16 00:16:46 -0700899 len = create_adv_data(hdev, cp.data);
Marcel Holtmann441ad2d2013-10-15 06:33:52 -0700900
901 if (hdev->adv_data_len == len &&
902 memcmp(cp.data, hdev->adv_data, len) == 0)
903 return;
904
905 memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
906 hdev->adv_data_len = len;
907
908 cp.length = len;
909
910 hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
911}
912
Johan Hedbergbc6d2d02014-07-10 12:09:08 +0300913int mgmt_update_adv_data(struct hci_dev *hdev)
914{
915 struct hci_request req;
916
917 hci_req_init(&req, hdev);
918 update_adv_data(&req);
919
920 return hci_req_run(&req, NULL);
921}
922
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300923static void create_eir(struct hci_dev *hdev, u8 *data)
924{
925 u8 *ptr = data;
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300926 size_t name_len;
927
928 name_len = strlen(hdev->dev_name);
929
930 if (name_len > 0) {
931 /* EIR Data type */
932 if (name_len > 48) {
933 name_len = 48;
934 ptr[1] = EIR_NAME_SHORT;
935 } else
936 ptr[1] = EIR_NAME_COMPLETE;
937
938 /* EIR Data length */
939 ptr[0] = name_len + 1;
940
941 memcpy(ptr + 2, hdev->dev_name, name_len);
942
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300943 ptr += (name_len + 2);
944 }
945
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100946 if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) {
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700947 ptr[0] = 2;
948 ptr[1] = EIR_TX_POWER;
949 ptr[2] = (u8) hdev->inq_tx_power;
950
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700951 ptr += 3;
952 }
953
Marcel Holtmann2b9be132012-03-11 19:32:12 -0700954 if (hdev->devid_source > 0) {
955 ptr[0] = 9;
956 ptr[1] = EIR_DEVICE_ID;
957
958 put_unaligned_le16(hdev->devid_source, ptr + 2);
959 put_unaligned_le16(hdev->devid_vendor, ptr + 4);
960 put_unaligned_le16(hdev->devid_product, ptr + 6);
961 put_unaligned_le16(hdev->devid_version, ptr + 8);
962
Marcel Holtmann2b9be132012-03-11 19:32:12 -0700963 ptr += 10;
964 }
965
Johan Hedberg213202e2013-01-27 00:31:33 +0200966 ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
Johan Hedbergcdf19632013-01-27 00:31:34 +0200967 ptr = create_uuid32_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
Johan Hedbergc00d5752013-01-27 00:31:35 +0200968 ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300969}
970
Johan Hedberg890ea892013-03-15 17:06:52 -0500971static void update_eir(struct hci_request *req)
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300972{
Johan Hedberg890ea892013-03-15 17:06:52 -0500973 struct hci_dev *hdev = req->hdev;
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300974 struct hci_cp_write_eir cp;
975
Johan Hedberg504c8dc2012-02-23 13:30:41 +0200976 if (!hdev_is_powered(hdev))
Johan Hedberg890ea892013-03-15 17:06:52 -0500977 return;
Johan Hedberg7770c4a2012-02-22 22:06:38 +0200978
Johan Hedberg976eb202012-10-24 21:12:01 +0300979 if (!lmp_ext_inq_capable(hdev))
Johan Hedberg890ea892013-03-15 17:06:52 -0500980 return;
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300981
Johan Hedberg84bde9d2012-01-25 14:21:06 +0200982 if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
Johan Hedberg890ea892013-03-15 17:06:52 -0500983 return;
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300984
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200985 if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
Johan Hedberg890ea892013-03-15 17:06:52 -0500986 return;
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300987
988 memset(&cp, 0, sizeof(cp));
989
990 create_eir(hdev, cp.data);
991
992 if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
Johan Hedberg890ea892013-03-15 17:06:52 -0500993 return;
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300994
995 memcpy(hdev->eir, cp.data, sizeof(cp.data));
996
Johan Hedberg890ea892013-03-15 17:06:52 -0500997 hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
Johan Hedberg80a1e1d2011-03-28 14:07:23 +0300998}
999
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001000static u8 get_service_classes(struct hci_dev *hdev)
1001{
Gustavo F. Padovan12dc0742011-10-14 19:32:56 -03001002 struct bt_uuid *uuid;
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001003 u8 val = 0;
1004
Gustavo F. Padovan12dc0742011-10-14 19:32:56 -03001005 list_for_each_entry(uuid, &hdev->uuids, list)
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001006 val |= uuid->svc_hint;
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001007
1008 return val;
1009}
1010
Johan Hedberg890ea892013-03-15 17:06:52 -05001011static void update_class(struct hci_request *req)
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001012{
Johan Hedberg890ea892013-03-15 17:06:52 -05001013 struct hci_dev *hdev = req->hdev;
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001014 u8 cod[3];
1015
1016 BT_DBG("%s", hdev->name);
1017
Johan Hedberg504c8dc2012-02-23 13:30:41 +02001018 if (!hdev_is_powered(hdev))
Johan Hedberg890ea892013-03-15 17:06:52 -05001019 return;
Johan Hedberg7770c4a2012-02-22 22:06:38 +02001020
Johan Hedbergf87ea1d2013-10-19 23:38:17 +03001021 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
1022 return;
1023
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001024 if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
Johan Hedberg890ea892013-03-15 17:06:52 -05001025 return;
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001026
1027 cod[0] = hdev->minor_class;
1028 cod[1] = hdev->major_class;
1029 cod[2] = get_service_classes(hdev);
1030
Marcel Holtmann6acd7db2013-10-15 06:33:53 -07001031 if (test_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags))
1032 cod[1] |= 0x20;
1033
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001034 if (memcmp(cod, hdev->dev_class, 3) == 0)
Johan Hedberg890ea892013-03-15 17:06:52 -05001035 return;
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001036
Johan Hedberg890ea892013-03-15 17:06:52 -05001037 hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
Johan Hedberg1aff6f02011-01-13 21:56:52 +02001038}
1039
Johan Hedberga4858cb2014-02-25 19:56:31 +02001040static bool get_connectable(struct hci_dev *hdev)
Johan Hedberg199a2fb2014-02-22 19:06:33 +02001041{
1042 struct pending_cmd *cmd;
Johan Hedberg199a2fb2014-02-22 19:06:33 +02001043
1044 /* If there's a pending mgmt command the flag will not yet have
1045 * it's final value, so check for this first.
1046 */
1047 cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
1048 if (cmd) {
1049 struct mgmt_mode *cp = cmd->param;
Johan Hedberga4858cb2014-02-25 19:56:31 +02001050 return cp->val;
Johan Hedberg199a2fb2014-02-22 19:06:33 +02001051 }
1052
Johan Hedberga4858cb2014-02-25 19:56:31 +02001053 return test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
Johan Hedberg199a2fb2014-02-22 19:06:33 +02001054}
1055
Johan Hedberg0ec5ae82014-07-08 15:07:50 +03001056static void disable_advertising(struct hci_request *req)
1057{
1058 u8 enable = 0x00;
1059
1060 hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
1061}
1062
Johan Hedberg199a2fb2014-02-22 19:06:33 +02001063static void enable_advertising(struct hci_request *req)
1064{
1065 struct hci_dev *hdev = req->hdev;
1066 struct hci_cp_le_set_adv_param cp;
Johan Hedberg8f2a0602014-02-23 19:42:23 +02001067 u8 own_addr_type, enable = 0x01;
Johan Hedberga4858cb2014-02-25 19:56:31 +02001068 bool connectable;
Johan Hedberg199a2fb2014-02-22 19:06:33 +02001069
Johan Hedberg0ec5ae82014-07-08 15:07:50 +03001070 if (hci_conn_num(hdev, LE_LINK) > 0)
1071 return;
1072
1073 if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
1074 disable_advertising(req);
1075
Johan Hedberg5ce194c2014-07-08 15:07:49 +03001076 /* Clear the HCI_LE_ADV bit temporarily so that the
Johan Hedberg8d972502014-02-28 12:54:14 +02001077 * hci_update_random_address knows that it's safe to go ahead
1078 * and write a new random address. The flag will be set back on
1079 * as soon as the SET_ADV_ENABLE HCI command completes.
1080 */
Johan Hedberg5ce194c2014-07-08 15:07:49 +03001081 clear_bit(HCI_LE_ADV, &hdev->dev_flags);
Johan Hedberg8d972502014-02-28 12:54:14 +02001082
Johan Hedberga4858cb2014-02-25 19:56:31 +02001083 connectable = get_connectable(hdev);
Johan Hedberg8f2a0602014-02-23 19:42:23 +02001084
Johan Hedberga4858cb2014-02-25 19:56:31 +02001085 /* Set require_privacy to true only when non-connectable
1086 * advertising is used. In that case it is fine to use a
1087 * non-resolvable private address.
1088 */
1089 if (hci_update_random_address(req, !connectable, &own_addr_type) < 0)
Johan Hedberg8f2a0602014-02-23 19:42:23 +02001090 return;
1091
Marcel Holtmann41c90c12014-02-23 20:25:55 -08001092 memset(&cp, 0, sizeof(cp));
Georg Lukas628531c2014-07-26 13:59:57 +02001093 cp.min_interval = cpu_to_le16(hdev->le_adv_min_interval);
1094 cp.max_interval = cpu_to_le16(hdev->le_adv_max_interval);
Johan Hedberga4858cb2014-02-25 19:56:31 +02001095 cp.type = connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND;
Johan Hedberg8f2a0602014-02-23 19:42:23 +02001096 cp.own_address_type = own_addr_type;
Johan Hedberg199a2fb2014-02-22 19:06:33 +02001097 cp.channel_map = hdev->le_adv_channel_map;
1098
1099 hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);
1100
1101 hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
1102}
1103
Johan Hedberg7d785252011-12-15 00:47:39 +02001104static void service_cache_off(struct work_struct *work)
1105{
1106 struct hci_dev *hdev = container_of(work, struct hci_dev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001107 service_cache.work);
Johan Hedberg890ea892013-03-15 17:06:52 -05001108 struct hci_request req;
Johan Hedberg7d785252011-12-15 00:47:39 +02001109
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001110 if (!test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
Johan Hedberg7d785252011-12-15 00:47:39 +02001111 return;
1112
Johan Hedberg890ea892013-03-15 17:06:52 -05001113 hci_req_init(&req, hdev);
1114
Johan Hedberg7d785252011-12-15 00:47:39 +02001115 hci_dev_lock(hdev);
1116
Johan Hedberg890ea892013-03-15 17:06:52 -05001117 update_eir(&req);
1118 update_class(&req);
Johan Hedberg7d785252011-12-15 00:47:39 +02001119
1120 hci_dev_unlock(hdev);
Johan Hedberg890ea892013-03-15 17:06:52 -05001121
1122 hci_req_run(&req, NULL);
Johan Hedberg7d785252011-12-15 00:47:39 +02001123}
1124
Johan Hedbergd6bfd592014-02-23 19:42:20 +02001125static void rpa_expired(struct work_struct *work)
1126{
1127 struct hci_dev *hdev = container_of(work, struct hci_dev,
1128 rpa_expired.work);
1129 struct hci_request req;
1130
1131 BT_DBG("");
1132
1133 set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
1134
Johan Hedberg0ec5ae82014-07-08 15:07:50 +03001135 if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
Johan Hedbergd6bfd592014-02-23 19:42:20 +02001136 return;
1137
1138 /* The generation of a new RPA and programming it into the
1139 * controller happens in the enable_advertising() function.
1140 */
Johan Hedbergd6bfd592014-02-23 19:42:20 +02001141 hci_req_init(&req, hdev);
Johan Hedbergd6bfd592014-02-23 19:42:20 +02001142 enable_advertising(&req);
Johan Hedbergd6bfd592014-02-23 19:42:20 +02001143 hci_req_run(&req, NULL);
1144}
1145
Johan Hedberg6a919082012-02-28 06:17:26 +02001146static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
Johan Hedberg7d785252011-12-15 00:47:39 +02001147{
Johan Hedberg4f87da82012-03-02 19:55:56 +02001148 if (test_and_set_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg6a919082012-02-28 06:17:26 +02001149 return;
1150
Johan Hedberg4f87da82012-03-02 19:55:56 +02001151 INIT_DELAYED_WORK(&hdev->service_cache, service_cache_off);
Johan Hedbergd6bfd592014-02-23 19:42:20 +02001152 INIT_DELAYED_WORK(&hdev->rpa_expired, rpa_expired);
Johan Hedberg7d785252011-12-15 00:47:39 +02001153
Johan Hedberg4f87da82012-03-02 19:55:56 +02001154 /* Non-mgmt controlled devices get this bit set
1155 * implicitly so that pairing works for them, however
1156 * for mgmt we require user-space to explicitly enable
1157 * it
1158 */
Johan Hedbergb6ae8452014-07-30 09:22:22 +03001159 clear_bit(HCI_BONDABLE, &hdev->dev_flags);
Johan Hedberg7d785252011-12-15 00:47:39 +02001160}
1161
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02001162static int read_controller_info(struct sock *sk, struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001163 void *data, u16 data_len)
Johan Hedberg03811012010-12-08 00:21:06 +02001164{
1165 struct mgmt_rp_read_info rp;
Johan Hedberg03811012010-12-08 00:21:06 +02001166
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001167 BT_DBG("sock %p %s", sk, hdev->name);
Johan Hedberg03811012010-12-08 00:21:06 +02001168
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001169 hci_dev_lock(hdev);
Johan Hedberg03811012010-12-08 00:21:06 +02001170
Johan Hedberg03811012010-12-08 00:21:06 +02001171 memset(&rp, 0, sizeof(rp));
1172
Johan Hedberg03811012010-12-08 00:21:06 +02001173 bacpy(&rp.bdaddr, &hdev->bdaddr);
Johan Hedberg69ab39e2011-12-15 00:47:35 +02001174
1175 rp.version = hdev->hci_ver;
Marcel Holtmanneb55ef02012-03-14 18:08:46 +02001176 rp.manufacturer = cpu_to_le16(hdev->manufacturer);
Johan Hedberg69ab39e2011-12-15 00:47:35 +02001177
1178 rp.supported_settings = cpu_to_le32(get_supported_settings(hdev));
1179 rp.current_settings = cpu_to_le32(get_current_settings(hdev));
1180
1181 memcpy(rp.dev_class, hdev->dev_class, 3);
Johan Hedberg03811012010-12-08 00:21:06 +02001182
1183 memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name));
Johan Hedberg27fcc362012-02-22 21:46:22 +02001184 memcpy(rp.short_name, hdev->short_name, sizeof(hdev->short_name));
Johan Hedberg03811012010-12-08 00:21:06 +02001185
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001186 hci_dev_unlock(hdev);
Johan Hedberg03811012010-12-08 00:21:06 +02001187
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001188 return cmd_complete(sk, hdev->id, MGMT_OP_READ_INFO, 0, &rp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001189 sizeof(rp));
Johan Hedberg03811012010-12-08 00:21:06 +02001190}
1191
1192static void mgmt_pending_free(struct pending_cmd *cmd)
1193{
1194 sock_put(cmd->sk);
1195 kfree(cmd->param);
1196 kfree(cmd);
1197}
1198
1199static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001200 struct hci_dev *hdev, void *data,
1201 u16 len)
Johan Hedberg03811012010-12-08 00:21:06 +02001202{
1203 struct pending_cmd *cmd;
1204
Johan Hedbergfca20012014-06-28 17:54:05 +03001205 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
Johan Hedberg03811012010-12-08 00:21:06 +02001206 if (!cmd)
1207 return NULL;
1208
1209 cmd->opcode = opcode;
1210 cmd->index = hdev->id;
1211
Johan Hedberg323b0b82014-12-05 13:36:01 +02001212 cmd->param = kmemdup(data, len, GFP_KERNEL);
Johan Hedberg03811012010-12-08 00:21:06 +02001213 if (!cmd->param) {
1214 kfree(cmd);
1215 return NULL;
1216 }
1217
Johan Hedberg323b0b82014-12-05 13:36:01 +02001218 cmd->param_len = len;
Johan Hedberg03811012010-12-08 00:21:06 +02001219
1220 cmd->sk = sk;
1221 sock_hold(sk);
1222
1223 list_add(&cmd->list, &hdev->mgmt_pending);
1224
1225 return cmd;
1226}
1227
1228static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001229 void (*cb)(struct pending_cmd *cmd,
1230 void *data),
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001231 void *data)
Johan Hedberg03811012010-12-08 00:21:06 +02001232{
Andre Guedesa3d09352013-02-01 11:21:30 -03001233 struct pending_cmd *cmd, *tmp;
Johan Hedberg03811012010-12-08 00:21:06 +02001234
Andre Guedesa3d09352013-02-01 11:21:30 -03001235 list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
Johan Hedberg03811012010-12-08 00:21:06 +02001236 if (opcode > 0 && cmd->opcode != opcode)
1237 continue;
1238
1239 cb(cmd, data);
1240 }
1241}
1242
Johan Hedberg03811012010-12-08 00:21:06 +02001243static void mgmt_pending_remove(struct pending_cmd *cmd)
1244{
1245 list_del(&cmd->list);
1246 mgmt_pending_free(cmd);
1247}
1248
Johan Hedberg69ab39e2011-12-15 00:47:35 +02001249static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
Johan Hedberg86805702011-11-11 16:18:52 +02001250{
Johan Hedberg69ab39e2011-12-15 00:47:35 +02001251 __le32 settings = cpu_to_le32(get_current_settings(hdev));
Johan Hedberg86805702011-11-11 16:18:52 +02001252
Johan Hedbergaee9b2182012-02-18 15:07:59 +02001253 return cmd_complete(sk, hdev->id, opcode, 0, &settings,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001254 sizeof(settings));
Johan Hedberg86805702011-11-11 16:18:52 +02001255}
1256
Marcel Holtmann1904a852015-01-11 13:50:44 -08001257static void clean_up_hci_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg8b064a32014-02-24 14:52:22 +02001258{
1259 BT_DBG("%s status 0x%02x", hdev->name, status);
1260
Johan Hedberga3172b72014-02-28 09:33:44 +02001261 if (hci_conn_count(hdev) == 0) {
1262 cancel_delayed_work(&hdev->power_off);
Johan Hedberg8b064a32014-02-24 14:52:22 +02001263 queue_work(hdev->req_workqueue, &hdev->power_off.work);
Johan Hedberga3172b72014-02-28 09:33:44 +02001264 }
Johan Hedberg8b064a32014-02-24 14:52:22 +02001265}
1266
Johan Hedberg23a48092014-07-08 16:05:06 +03001267static bool hci_stop_discovery(struct hci_request *req)
Johan Hedberg21a60d32014-06-10 14:05:58 +03001268{
1269 struct hci_dev *hdev = req->hdev;
1270 struct hci_cp_remote_name_req_cancel cp;
1271 struct inquiry_entry *e;
1272
1273 switch (hdev->discovery.state) {
1274 case DISCOVERY_FINDING:
1275 if (test_bit(HCI_INQUIRY, &hdev->flags)) {
1276 hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
1277 } else {
1278 cancel_delayed_work(&hdev->le_scan_disable);
1279 hci_req_add_le_scan_disable(req);
1280 }
1281
Johan Hedberg23a48092014-07-08 16:05:06 +03001282 return true;
Johan Hedberg21a60d32014-06-10 14:05:58 +03001283
1284 case DISCOVERY_RESOLVING:
1285 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
1286 NAME_PENDING);
1287 if (!e)
Johan Hedberg23a48092014-07-08 16:05:06 +03001288 break;
Johan Hedberg21a60d32014-06-10 14:05:58 +03001289
1290 bacpy(&cp.bdaddr, &e->data.bdaddr);
1291 hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
1292 &cp);
1293
Johan Hedberg23a48092014-07-08 16:05:06 +03001294 return true;
Johan Hedberg21a60d32014-06-10 14:05:58 +03001295
1296 default:
1297 /* Passive scanning */
Johan Hedberg23a48092014-07-08 16:05:06 +03001298 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
Johan Hedberg21a60d32014-06-10 14:05:58 +03001299 hci_req_add_le_scan_disable(req);
Johan Hedberg23a48092014-07-08 16:05:06 +03001300 return true;
1301 }
1302
Johan Hedberg21a60d32014-06-10 14:05:58 +03001303 break;
1304 }
Johan Hedberg23a48092014-07-08 16:05:06 +03001305
1306 return false;
Johan Hedberg21a60d32014-06-10 14:05:58 +03001307}
1308
Johan Hedberg8b064a32014-02-24 14:52:22 +02001309static int clean_up_hci_state(struct hci_dev *hdev)
1310{
1311 struct hci_request req;
1312 struct hci_conn *conn;
Johan Hedberg23a48092014-07-08 16:05:06 +03001313 bool discov_stopped;
1314 int err;
Johan Hedberg8b064a32014-02-24 14:52:22 +02001315
1316 hci_req_init(&req, hdev);
1317
1318 if (test_bit(HCI_ISCAN, &hdev->flags) ||
1319 test_bit(HCI_PSCAN, &hdev->flags)) {
1320 u8 scan = 0x00;
1321 hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
1322 }
1323
Johan Hedberg73e082f2014-07-08 15:07:51 +03001324 if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
Johan Hedberg8b064a32014-02-24 14:52:22 +02001325 disable_advertising(&req);
1326
Johan Hedberg23a48092014-07-08 16:05:06 +03001327 discov_stopped = hci_stop_discovery(&req);
Johan Hedberg8b064a32014-02-24 14:52:22 +02001328
1329 list_for_each_entry(conn, &hdev->conn_hash.list, list) {
1330 struct hci_cp_disconnect dc;
Johan Hedbergc9910d02014-02-27 14:35:12 +02001331 struct hci_cp_reject_conn_req rej;
Johan Hedberg8b064a32014-02-24 14:52:22 +02001332
Johan Hedbergc9910d02014-02-27 14:35:12 +02001333 switch (conn->state) {
1334 case BT_CONNECTED:
1335 case BT_CONFIG:
1336 dc.handle = cpu_to_le16(conn->handle);
1337 dc.reason = 0x15; /* Terminated due to Power Off */
1338 hci_req_add(&req, HCI_OP_DISCONNECT, sizeof(dc), &dc);
1339 break;
1340 case BT_CONNECT:
1341 if (conn->type == LE_LINK)
1342 hci_req_add(&req, HCI_OP_LE_CREATE_CONN_CANCEL,
1343 0, NULL);
1344 else if (conn->type == ACL_LINK)
1345 hci_req_add(&req, HCI_OP_CREATE_CONN_CANCEL,
1346 6, &conn->dst);
1347 break;
1348 case BT_CONNECT2:
1349 bacpy(&rej.bdaddr, &conn->dst);
1350 rej.reason = 0x15; /* Terminated due to Power Off */
1351 if (conn->type == ACL_LINK)
1352 hci_req_add(&req, HCI_OP_REJECT_CONN_REQ,
1353 sizeof(rej), &rej);
1354 else if (conn->type == SCO_LINK)
1355 hci_req_add(&req, HCI_OP_REJECT_SYNC_CONN_REQ,
1356 sizeof(rej), &rej);
1357 break;
1358 }
Johan Hedberg8b064a32014-02-24 14:52:22 +02001359 }
1360
Johan Hedberg23a48092014-07-08 16:05:06 +03001361 err = hci_req_run(&req, clean_up_hci_complete);
1362 if (!err && discov_stopped)
1363 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
1364
1365 return err;
Johan Hedberg8b064a32014-02-24 14:52:22 +02001366}
1367
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001368static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001369 u16 len)
Johan Hedberg03811012010-12-08 00:21:06 +02001370{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03001371 struct mgmt_mode *cp = data;
Johan Hedberg03811012010-12-08 00:21:06 +02001372 struct pending_cmd *cmd;
Johan Hedberg4b34ee782012-02-21 14:13:02 +02001373 int err;
Johan Hedberg03811012010-12-08 00:21:06 +02001374
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001375 BT_DBG("request for %s", hdev->name);
Johan Hedberg03811012010-12-08 00:21:06 +02001376
Johan Hedberga7e80f22013-01-09 16:05:19 +02001377 if (cp->val != 0x00 && cp->val != 0x01)
1378 return cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
1379 MGMT_STATUS_INVALID_PARAMS);
1380
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001381 hci_dev_lock(hdev);
Johan Hedberg03811012010-12-08 00:21:06 +02001382
Johan Hedberg87b95ba2013-09-25 13:26:06 +03001383 if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) {
1384 err = cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
1385 MGMT_STATUS_BUSY);
1386 goto failed;
1387 }
1388
Marcel Holtmannf0d4b782012-02-21 12:14:25 +01001389 if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
1390 cancel_delayed_work(&hdev->power_off);
1391
1392 if (cp->val) {
Johan Hedberga1d70452013-01-09 15:29:40 +02001393 mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev,
1394 data, len);
1395 err = mgmt_powered(hdev, 1);
Marcel Holtmannf0d4b782012-02-21 12:14:25 +01001396 goto failed;
1397 }
1398 }
1399
Johan Hedberg4b34ee782012-02-21 14:13:02 +02001400 if (!!cp->val == hdev_is_powered(hdev)) {
Johan Hedberg69ab39e2011-12-15 00:47:35 +02001401 err = send_settings_rsp(sk, MGMT_OP_SET_POWERED, hdev);
Johan Hedberg03811012010-12-08 00:21:06 +02001402 goto failed;
1403 }
1404
Johan Hedberg03811012010-12-08 00:21:06 +02001405 cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, data, len);
1406 if (!cmd) {
1407 err = -ENOMEM;
1408 goto failed;
1409 }
1410
Johan Hedberg8b064a32014-02-24 14:52:22 +02001411 if (cp->val) {
Johan Hedberg19202572013-01-14 22:33:51 +02001412 queue_work(hdev->req_workqueue, &hdev->power_on);
Johan Hedberg8b064a32014-02-24 14:52:22 +02001413 err = 0;
1414 } else {
1415 /* Disconnect connections, stop scans, etc */
1416 err = clean_up_hci_state(hdev);
Johan Hedberga3172b72014-02-28 09:33:44 +02001417 if (!err)
1418 queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
1419 HCI_POWER_OFF_TIMEOUT);
Johan Hedberg03811012010-12-08 00:21:06 +02001420
Johan Hedberg8b064a32014-02-24 14:52:22 +02001421 /* ENODATA means there were no HCI commands queued */
1422 if (err == -ENODATA) {
Johan Hedberga3172b72014-02-28 09:33:44 +02001423 cancel_delayed_work(&hdev->power_off);
Johan Hedberg8b064a32014-02-24 14:52:22 +02001424 queue_work(hdev->req_workqueue, &hdev->power_off.work);
1425 err = 0;
1426 }
1427 }
Johan Hedberg03811012010-12-08 00:21:06 +02001428
1429failed:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001430 hci_dev_unlock(hdev);
Johan Hedberg03811012010-12-08 00:21:06 +02001431 return err;
1432}
1433
Johan Hedbergbeadb2b2012-02-21 16:55:31 +02001434static int new_settings(struct hci_dev *hdev, struct sock *skip)
1435{
1436 __le32 ev;
1437
1438 ev = cpu_to_le32(get_current_settings(hdev));
1439
1440 return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip);
1441}
1442
Johan Hedberg91a668b2014-07-09 13:28:26 +03001443int mgmt_new_settings(struct hci_dev *hdev)
1444{
1445 return new_settings(hdev, NULL);
1446}
1447
Johan Hedbergbd99abd2013-09-25 13:26:07 +03001448struct cmd_lookup {
1449 struct sock *sk;
1450 struct hci_dev *hdev;
1451 u8 mgmt_status;
1452};
1453
1454static void settings_rsp(struct pending_cmd *cmd, void *data)
1455{
1456 struct cmd_lookup *match = data;
1457
1458 send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
1459
1460 list_del(&cmd->list);
1461
1462 if (match->sk == NULL) {
1463 match->sk = cmd->sk;
1464 sock_hold(match->sk);
1465 }
1466
1467 mgmt_pending_free(cmd);
1468}
1469
1470static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
1471{
1472 u8 *status = data;
1473
1474 cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
1475 mgmt_pending_remove(cmd);
1476}
1477
Johan Hedberg1b9b5ee2014-12-05 13:36:00 +02001478static void cmd_complete_rsp(struct pending_cmd *cmd, void *data)
1479{
1480 if (cmd->cmd_complete) {
1481 u8 *status = data;
1482
1483 cmd->cmd_complete(cmd, *status);
1484 mgmt_pending_remove(cmd);
1485
1486 return;
1487 }
1488
1489 cmd_status_rsp(cmd, data);
1490}
1491
Johan Hedberg9df74652014-12-19 22:26:03 +02001492static int generic_cmd_complete(struct pending_cmd *cmd, u8 status)
Johan Hedbergf5818c22014-12-05 13:36:02 +02001493{
Johan Hedberg9df74652014-12-19 22:26:03 +02001494 return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
1495 cmd->param, cmd->param_len);
Johan Hedbergf5818c22014-12-05 13:36:02 +02001496}
1497
Johan Hedberg9df74652014-12-19 22:26:03 +02001498static int addr_cmd_complete(struct pending_cmd *cmd, u8 status)
Johan Hedberg7776d1d2014-12-05 13:36:03 +02001499{
Johan Hedberg9df74652014-12-19 22:26:03 +02001500 return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param,
1501 sizeof(struct mgmt_addr_info));
Johan Hedberg7776d1d2014-12-05 13:36:03 +02001502}
1503
Johan Hedberge6fe7982013-10-02 15:45:22 +03001504static u8 mgmt_bredr_support(struct hci_dev *hdev)
1505{
1506 if (!lmp_bredr_capable(hdev))
1507 return MGMT_STATUS_NOT_SUPPORTED;
1508 else if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
1509 return MGMT_STATUS_REJECTED;
1510 else
1511 return MGMT_STATUS_SUCCESS;
1512}
1513
1514static u8 mgmt_le_support(struct hci_dev *hdev)
1515{
1516 if (!lmp_le_capable(hdev))
1517 return MGMT_STATUS_NOT_SUPPORTED;
1518 else if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
1519 return MGMT_STATUS_REJECTED;
1520 else
1521 return MGMT_STATUS_SUCCESS;
1522}
1523
Marcel Holtmann1904a852015-01-11 13:50:44 -08001524static void set_discoverable_complete(struct hci_dev *hdev, u8 status,
1525 u16 opcode)
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001526{
1527 struct pending_cmd *cmd;
1528 struct mgmt_mode *cp;
Marcel Holtmann970ba522013-10-15 06:33:57 -07001529 struct hci_request req;
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001530 bool changed;
1531
1532 BT_DBG("status 0x%02x", status);
1533
1534 hci_dev_lock(hdev);
1535
1536 cmd = mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev);
1537 if (!cmd)
1538 goto unlock;
1539
1540 if (status) {
1541 u8 mgmt_err = mgmt_status(status);
1542 cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001543 clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001544 goto remove_cmd;
1545 }
1546
1547 cp = cmd->param;
Marcel Holtmannd4462a02013-10-15 08:11:02 -07001548 if (cp->val) {
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001549 changed = !test_and_set_bit(HCI_DISCOVERABLE,
1550 &hdev->dev_flags);
Marcel Holtmannd4462a02013-10-15 08:11:02 -07001551
1552 if (hdev->discov_timeout > 0) {
1553 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
1554 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
1555 to);
1556 }
1557 } else {
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001558 changed = test_and_clear_bit(HCI_DISCOVERABLE,
1559 &hdev->dev_flags);
Marcel Holtmannd4462a02013-10-15 08:11:02 -07001560 }
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001561
1562 send_settings_rsp(cmd->sk, MGMT_OP_SET_DISCOVERABLE, hdev);
1563
1564 if (changed)
1565 new_settings(hdev, cmd->sk);
1566
Marcel Holtmann970ba522013-10-15 06:33:57 -07001567 /* When the discoverable mode gets changed, make sure
1568 * that class of device has the limited discoverable
Johan Hedberg432df052014-08-01 11:13:31 +03001569 * bit correctly set. Also update page scan based on whitelist
1570 * entries.
Marcel Holtmann970ba522013-10-15 06:33:57 -07001571 */
1572 hci_req_init(&req, hdev);
Johan Hedberg1d2dc5b2014-12-19 13:40:19 +02001573 __hci_update_page_scan(&req);
Marcel Holtmann970ba522013-10-15 06:33:57 -07001574 update_class(&req);
1575 hci_req_run(&req, NULL);
1576
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001577remove_cmd:
1578 mgmt_pending_remove(cmd);
1579
1580unlock:
1581 hci_dev_unlock(hdev);
1582}
1583
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001584static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001585 u16 len)
Johan Hedberg03811012010-12-08 00:21:06 +02001586{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03001587 struct mgmt_cp_set_discoverable *cp = data;
Johan Hedberg03811012010-12-08 00:21:06 +02001588 struct pending_cmd *cmd;
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001589 struct hci_request req;
Johan Hedberg5e5282b2012-02-21 16:01:30 +02001590 u16 timeout;
Johan Hedberg9a43e252013-10-20 19:00:07 +03001591 u8 scan;
Johan Hedberg03811012010-12-08 00:21:06 +02001592 int err;
1593
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001594 BT_DBG("request for %s", hdev->name);
Johan Hedberg03811012010-12-08 00:21:06 +02001595
Johan Hedberg9a43e252013-10-20 19:00:07 +03001596 if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
1597 !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
Johan Hedberg33c525c2012-10-24 21:11:58 +03001598 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
Johan Hedberg9a43e252013-10-20 19:00:07 +03001599 MGMT_STATUS_REJECTED);
Johan Hedberg33c525c2012-10-24 21:11:58 +03001600
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001601 if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
Johan Hedberga7e80f22013-01-09 16:05:19 +02001602 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
1603 MGMT_STATUS_INVALID_PARAMS);
1604
Marcel Holtmann1f350c82012-03-12 20:31:08 -07001605 timeout = __le16_to_cpu(cp->timeout);
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001606
1607 /* Disabling discoverable requires that no timeout is set,
1608 * and enabling limited discoverable requires a timeout.
1609 */
1610 if ((cp->val == 0x00 && timeout > 0) ||
1611 (cp->val == 0x02 && timeout == 0))
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001612 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001613 MGMT_STATUS_INVALID_PARAMS);
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001614
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001615 hci_dev_lock(hdev);
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001616
Johan Hedberg5e5282b2012-02-21 16:01:30 +02001617 if (!hdev_is_powered(hdev) && timeout > 0) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001618 err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001619 MGMT_STATUS_NOT_POWERED);
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001620 goto failed;
1621 }
1622
1623 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) ||
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03001624 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001625 err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001626 MGMT_STATUS_BUSY);
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001627 goto failed;
1628 }
1629
Johan Hedberg5e5282b2012-02-21 16:01:30 +02001630 if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001631 err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001632 MGMT_STATUS_REJECTED);
Johan Hedberg5e5282b2012-02-21 16:01:30 +02001633 goto failed;
1634 }
1635
1636 if (!hdev_is_powered(hdev)) {
Johan Hedberg0224d2f2012-02-21 19:40:05 +02001637 bool changed = false;
1638
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001639 /* Setting limited discoverable when powered off is
1640 * not a valid operation since it requires a timeout
1641 * and so no need to check HCI_LIMITED_DISCOVERABLE.
1642 */
Johan Hedberg0224d2f2012-02-21 19:40:05 +02001643 if (!!cp->val != test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) {
1644 change_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
1645 changed = true;
1646 }
1647
Johan Hedberg5e5282b2012-02-21 16:01:30 +02001648 err = send_settings_rsp(sk, MGMT_OP_SET_DISCOVERABLE, hdev);
Johan Hedberg0224d2f2012-02-21 19:40:05 +02001649 if (err < 0)
1650 goto failed;
1651
1652 if (changed)
1653 err = new_settings(hdev, sk);
1654
Johan Hedberg5e5282b2012-02-21 16:01:30 +02001655 goto failed;
1656 }
1657
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001658 /* If the current mode is the same, then just update the timeout
1659 * value with the new value. And if only the timeout gets updated,
1660 * then no need for any HCI transactions.
1661 */
1662 if (!!cp->val == test_bit(HCI_DISCOVERABLE, &hdev->dev_flags) &&
1663 (cp->val == 0x02) == test_bit(HCI_LIMITED_DISCOVERABLE,
1664 &hdev->dev_flags)) {
Marcel Holtmann36261542013-10-15 08:28:51 -07001665 cancel_delayed_work(&hdev->discov_off);
1666 hdev->discov_timeout = timeout;
Marcel Holtmann955638e2012-02-22 18:21:00 +01001667
Marcel Holtmann36261542013-10-15 08:28:51 -07001668 if (cp->val && hdev->discov_timeout > 0) {
1669 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
Marcel Holtmann955638e2012-02-22 18:21:00 +01001670 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Marcel Holtmann36261542013-10-15 08:28:51 -07001671 to);
Marcel Holtmann955638e2012-02-22 18:21:00 +01001672 }
1673
Johan Hedberg69ab39e2011-12-15 00:47:35 +02001674 err = send_settings_rsp(sk, MGMT_OP_SET_DISCOVERABLE, hdev);
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001675 goto failed;
1676 }
1677
1678 cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
1679 if (!cmd) {
1680 err = -ENOMEM;
1681 goto failed;
1682 }
1683
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001684 /* Cancel any potential discoverable timeout that might be
1685 * still active and store new timeout value. The arming of
1686 * the timeout happens in the complete handler.
1687 */
1688 cancel_delayed_work(&hdev->discov_off);
1689 hdev->discov_timeout = timeout;
1690
Johan Hedbergb456f872013-10-19 23:38:22 +03001691 /* Limited discoverable mode */
1692 if (cp->val == 0x02)
1693 set_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
1694 else
1695 clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
1696
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001697 hci_req_init(&req, hdev);
1698
Johan Hedberg9a43e252013-10-20 19:00:07 +03001699 /* The procedure for LE-only controllers is much simpler - just
1700 * update the advertising data.
1701 */
1702 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
1703 goto update_ad;
1704
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001705 scan = SCAN_PAGE;
1706
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001707 if (cp->val) {
1708 struct hci_cp_write_current_iac_lap hci_cp;
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001709
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001710 if (cp->val == 0x02) {
1711 /* Limited discoverable mode */
Marcel Holtmann33337dc2013-10-23 08:28:01 -07001712 hci_cp.num_iac = min_t(u8, hdev->num_iac, 2);
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001713 hci_cp.iac_lap[0] = 0x00; /* LIAC */
1714 hci_cp.iac_lap[1] = 0x8b;
1715 hci_cp.iac_lap[2] = 0x9e;
1716 hci_cp.iac_lap[3] = 0x33; /* GIAC */
1717 hci_cp.iac_lap[4] = 0x8b;
1718 hci_cp.iac_lap[5] = 0x9e;
1719 } else {
1720 /* General discoverable mode */
Marcel Holtmann310a3d42013-10-15 09:13:39 -07001721 hci_cp.num_iac = 1;
1722 hci_cp.iac_lap[0] = 0x33; /* GIAC */
1723 hci_cp.iac_lap[1] = 0x8b;
1724 hci_cp.iac_lap[2] = 0x9e;
1725 }
1726
1727 hci_req_add(&req, HCI_OP_WRITE_CURRENT_IAC_LAP,
1728 (hci_cp.num_iac * 3) + 1, &hci_cp);
1729
1730 scan |= SCAN_INQUIRY;
1731 } else {
1732 clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
1733 }
1734
1735 hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001736
Johan Hedberg9a43e252013-10-20 19:00:07 +03001737update_ad:
1738 update_adv_data(&req);
1739
Johan Hedbergbfaf8c92013-10-14 21:15:27 +03001740 err = hci_req_run(&req, set_discoverable_complete);
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001741 if (err < 0)
1742 mgmt_pending_remove(cmd);
1743
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001744failed:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001745 hci_dev_unlock(hdev);
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001746 return err;
1747}
1748
Johan Hedberg406d7802013-03-15 17:07:09 -05001749static void write_fast_connectable(struct hci_request *req, bool enable)
1750{
Johan Hedbergbd98b992013-03-15 17:07:13 -05001751 struct hci_dev *hdev = req->hdev;
Johan Hedberg406d7802013-03-15 17:07:09 -05001752 struct hci_cp_write_page_scan_activity acp;
1753 u8 type;
1754
Johan Hedberg547003b2013-10-21 16:51:53 +03001755 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
1756 return;
1757
Johan Hedberg4c01f8b2013-03-15 17:07:14 -05001758 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
1759 return;
1760
Johan Hedberg406d7802013-03-15 17:07:09 -05001761 if (enable) {
1762 type = PAGE_SCAN_TYPE_INTERLACED;
1763
1764 /* 160 msec page scan interval */
Joe Perchesdcf4adb2014-03-12 10:52:35 -07001765 acp.interval = cpu_to_le16(0x0100);
Johan Hedberg406d7802013-03-15 17:07:09 -05001766 } else {
1767 type = PAGE_SCAN_TYPE_STANDARD; /* default */
1768
1769 /* default 1.28 sec page scan */
Joe Perchesdcf4adb2014-03-12 10:52:35 -07001770 acp.interval = cpu_to_le16(0x0800);
Johan Hedberg406d7802013-03-15 17:07:09 -05001771 }
1772
Joe Perchesdcf4adb2014-03-12 10:52:35 -07001773 acp.window = cpu_to_le16(0x0012);
Johan Hedberg406d7802013-03-15 17:07:09 -05001774
Johan Hedbergbd98b992013-03-15 17:07:13 -05001775 if (__cpu_to_le16(hdev->page_scan_interval) != acp.interval ||
1776 __cpu_to_le16(hdev->page_scan_window) != acp.window)
1777 hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
1778 sizeof(acp), &acp);
1779
1780 if (hdev->page_scan_type != type)
1781 hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
Johan Hedberg406d7802013-03-15 17:07:09 -05001782}
1783
Marcel Holtmann1904a852015-01-11 13:50:44 -08001784static void set_connectable_complete(struct hci_dev *hdev, u8 status,
1785 u16 opcode)
Johan Hedberg2b76f452013-03-15 17:07:04 -05001786{
1787 struct pending_cmd *cmd;
Johan Hedbergd7b856f2013-10-14 16:20:04 +03001788 struct mgmt_mode *cp;
Johan Hedbergbc6d2d02014-07-10 12:09:08 +03001789 bool conn_changed, discov_changed;
Johan Hedberg2b76f452013-03-15 17:07:04 -05001790
1791 BT_DBG("status 0x%02x", status);
1792
1793 hci_dev_lock(hdev);
1794
1795 cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
1796 if (!cmd)
1797 goto unlock;
1798
Johan Hedberg37438c12013-10-14 16:20:05 +03001799 if (status) {
1800 u8 mgmt_err = mgmt_status(status);
1801 cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
1802 goto remove_cmd;
1803 }
1804
Johan Hedbergd7b856f2013-10-14 16:20:04 +03001805 cp = cmd->param;
Johan Hedbergbc6d2d02014-07-10 12:09:08 +03001806 if (cp->val) {
1807 conn_changed = !test_and_set_bit(HCI_CONNECTABLE,
1808 &hdev->dev_flags);
1809 discov_changed = false;
1810 } else {
1811 conn_changed = test_and_clear_bit(HCI_CONNECTABLE,
1812 &hdev->dev_flags);
1813 discov_changed = test_and_clear_bit(HCI_DISCOVERABLE,
1814 &hdev->dev_flags);
1815 }
Johan Hedbergd7b856f2013-10-14 16:20:04 +03001816
Johan Hedberg2b76f452013-03-15 17:07:04 -05001817 send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
1818
Johan Hedbergbc6d2d02014-07-10 12:09:08 +03001819 if (conn_changed || discov_changed) {
Johan Hedbergd7b856f2013-10-14 16:20:04 +03001820 new_settings(hdev, cmd->sk);
Johan Hedberg1d2dc5b2014-12-19 13:40:19 +02001821 hci_update_page_scan(hdev);
Johan Hedbergbc6d2d02014-07-10 12:09:08 +03001822 if (discov_changed)
1823 mgmt_update_adv_data(hdev);
Johan Hedberg2b7be332014-07-07 14:40:22 +03001824 hci_update_background_scan(hdev);
1825 }
Johan Hedbergd7b856f2013-10-14 16:20:04 +03001826
Johan Hedberg37438c12013-10-14 16:20:05 +03001827remove_cmd:
Johan Hedberg2b76f452013-03-15 17:07:04 -05001828 mgmt_pending_remove(cmd);
1829
1830unlock:
1831 hci_dev_unlock(hdev);
1832}
1833
Johan Hedberge8ba3a12013-10-19 23:38:18 +03001834static int set_connectable_update_settings(struct hci_dev *hdev,
1835 struct sock *sk, u8 val)
1836{
1837 bool changed = false;
1838 int err;
1839
1840 if (!!val != test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
1841 changed = true;
1842
1843 if (val) {
1844 set_bit(HCI_CONNECTABLE, &hdev->dev_flags);
1845 } else {
1846 clear_bit(HCI_CONNECTABLE, &hdev->dev_flags);
1847 clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
1848 }
1849
1850 err = send_settings_rsp(sk, MGMT_OP_SET_CONNECTABLE, hdev);
1851 if (err < 0)
1852 return err;
1853
Johan Hedberg562064e2014-07-08 16:35:34 +03001854 if (changed) {
Johan Hedberg1d2dc5b2014-12-19 13:40:19 +02001855 hci_update_page_scan(hdev);
Johan Hedberg562064e2014-07-08 16:35:34 +03001856 hci_update_background_scan(hdev);
Johan Hedberge8ba3a12013-10-19 23:38:18 +03001857 return new_settings(hdev, sk);
Johan Hedberg562064e2014-07-08 16:35:34 +03001858 }
Johan Hedberge8ba3a12013-10-19 23:38:18 +03001859
1860 return 0;
1861}
1862
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001863static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001864 u16 len)
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001865{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03001866 struct mgmt_mode *cp = data;
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001867 struct pending_cmd *cmd;
Johan Hedberg2b76f452013-03-15 17:07:04 -05001868 struct hci_request req;
Johan Hedberg1987fdc2013-10-14 21:15:24 +03001869 u8 scan;
Johan Hedbergf7b64e62010-12-13 21:07:06 +02001870 int err;
Johan Hedberg03811012010-12-08 00:21:06 +02001871
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001872 BT_DBG("request for %s", hdev->name);
Johan Hedberge41d8b42010-12-13 21:07:03 +02001873
Johan Hedberg1987fdc2013-10-14 21:15:24 +03001874 if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
1875 !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
Johan Hedberg33c525c2012-10-24 21:11:58 +03001876 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
Johan Hedberg1987fdc2013-10-14 21:15:24 +03001877 MGMT_STATUS_REJECTED);
Johan Hedberg33c525c2012-10-24 21:11:58 +03001878
Johan Hedberga7e80f22013-01-09 16:05:19 +02001879 if (cp->val != 0x00 && cp->val != 0x01)
1880 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
1881 MGMT_STATUS_INVALID_PARAMS);
1882
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001883 hci_dev_lock(hdev);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001884
Johan Hedberg4b34ee782012-02-21 14:13:02 +02001885 if (!hdev_is_powered(hdev)) {
Johan Hedberge8ba3a12013-10-19 23:38:18 +03001886 err = set_connectable_update_settings(hdev, sk, cp->val);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001887 goto failed;
1888 }
1889
1890 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) ||
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03001891 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001892 err = cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001893 MGMT_STATUS_BUSY);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001894 goto failed;
1895 }
1896
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001897 cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
1898 if (!cmd) {
1899 err = -ENOMEM;
1900 goto failed;
1901 }
1902
Johan Hedberg2b76f452013-03-15 17:07:04 -05001903 hci_req_init(&req, hdev);
1904
Johan Hedberg9a43e252013-10-20 19:00:07 +03001905 /* If BR/EDR is not enabled and we disable advertising as a
1906 * by-product of disabling connectable, we need to update the
1907 * advertising flags.
1908 */
1909 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
1910 if (!cp->val) {
1911 clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
1912 clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
1913 }
1914 update_adv_data(&req);
1915 } else if (cp->val != test_bit(HCI_PSCAN, &hdev->flags)) {
Johan Hedberg9b742462013-10-14 16:20:03 +03001916 if (cp->val) {
1917 scan = SCAN_PAGE;
1918 } else {
Johan Hedberg3bd27242014-07-28 20:53:58 +03001919 /* If we don't have any whitelist entries just
1920 * disable all scanning. If there are entries
1921 * and we had both page and inquiry scanning
1922 * enabled then fall back to only page scanning.
1923 * Otherwise no changes are needed.
1924 */
1925 if (list_empty(&hdev->whitelist))
1926 scan = SCAN_DISABLED;
1927 else if (test_bit(HCI_ISCAN, &hdev->flags))
1928 scan = SCAN_PAGE;
1929 else
1930 goto no_scan_update;
Johan Hedberg9b742462013-10-14 16:20:03 +03001931
1932 if (test_bit(HCI_ISCAN, &hdev->flags) &&
Marcel Holtmann8d6083f2013-10-14 16:38:45 -07001933 hdev->discov_timeout > 0)
Johan Hedberg9b742462013-10-14 16:20:03 +03001934 cancel_delayed_work(&hdev->discov_off);
1935 }
1936
1937 hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
1938 }
Johan Hedberg2b76f452013-03-15 17:07:04 -05001939
Johan Hedberg3bd27242014-07-28 20:53:58 +03001940no_scan_update:
Johan Hedberg4c01f8b2013-03-15 17:07:14 -05001941 /* If we're going from non-connectable to connectable or
1942 * vice-versa when fast connectable is enabled ensure that fast
1943 * connectable gets disabled. write_fast_connectable won't do
1944 * anything if the page scan parameters are already what they
1945 * should be.
1946 */
1947 if (cp->val || test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags))
Johan Hedberge36a3762013-03-15 17:07:10 -05001948 write_fast_connectable(&req, false);
1949
Johan Hedberge8b12022014-07-10 10:51:27 +03001950 /* Update the advertising parameters if necessary */
1951 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
Johan Hedberg1987fdc2013-10-14 21:15:24 +03001952 enable_advertising(&req);
Johan Hedberg1987fdc2013-10-14 21:15:24 +03001953
Johan Hedberg2b76f452013-03-15 17:07:04 -05001954 err = hci_req_run(&req, set_connectable_complete);
Johan Hedberg9b742462013-10-14 16:20:03 +03001955 if (err < 0) {
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001956 mgmt_pending_remove(cmd);
Johan Hedberg9b742462013-10-14 16:20:03 +03001957 if (err == -ENODATA)
Johan Hedberga81070b2013-10-19 23:38:19 +03001958 err = set_connectable_update_settings(hdev, sk,
1959 cp->val);
Johan Hedberg9b742462013-10-14 16:20:03 +03001960 goto failed;
1961 }
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001962
1963failed:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001964 hci_dev_unlock(hdev);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001965 return err;
1966}
1967
Johan Hedbergb2939472014-07-30 09:22:23 +03001968static int set_bondable(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001969 u16 len)
Johan Hedberg73f22f62010-12-29 16:00:25 +02001970{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03001971 struct mgmt_mode *cp = data;
Marcel Holtmann55594352013-10-06 16:11:57 -07001972 bool changed;
Johan Hedberg73f22f62010-12-29 16:00:25 +02001973 int err;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001974
Johan Hedbergbdb6d972012-02-28 06:13:32 +02001975 BT_DBG("request for %s", hdev->name);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001976
Johan Hedberga7e80f22013-01-09 16:05:19 +02001977 if (cp->val != 0x00 && cp->val != 0x01)
Johan Hedbergb2939472014-07-30 09:22:23 +03001978 return cmd_status(sk, hdev->id, MGMT_OP_SET_BONDABLE,
Johan Hedberga7e80f22013-01-09 16:05:19 +02001979 MGMT_STATUS_INVALID_PARAMS);
1980
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001981 hci_dev_lock(hdev);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001982
1983 if (cp->val)
Johan Hedbergb6ae8452014-07-30 09:22:22 +03001984 changed = !test_and_set_bit(HCI_BONDABLE, &hdev->dev_flags);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001985 else
Johan Hedbergb6ae8452014-07-30 09:22:22 +03001986 changed = test_and_clear_bit(HCI_BONDABLE, &hdev->dev_flags);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001987
Johan Hedbergb2939472014-07-30 09:22:23 +03001988 err = send_settings_rsp(sk, MGMT_OP_SET_BONDABLE, hdev);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001989 if (err < 0)
Marcel Holtmann55594352013-10-06 16:11:57 -07001990 goto unlock;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001991
Marcel Holtmann55594352013-10-06 16:11:57 -07001992 if (changed)
1993 err = new_settings(hdev, sk);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001994
Marcel Holtmann55594352013-10-06 16:11:57 -07001995unlock:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001996 hci_dev_unlock(hdev);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02001997 return err;
1998}
Johan Hedberg72a734e2010-12-30 00:38:22 +02001999
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002000static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data,
2001 u16 len)
Johan Hedberg33ef95e2012-02-16 23:56:27 +02002002{
2003 struct mgmt_mode *cp = data;
2004 struct pending_cmd *cmd;
Johan Hedberge6fe7982013-10-02 15:45:22 +03002005 u8 val, status;
Johan Hedberg33ef95e2012-02-16 23:56:27 +02002006 int err;
2007
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002008 BT_DBG("request for %s", hdev->name);
Johan Hedberg33ef95e2012-02-16 23:56:27 +02002009
Johan Hedberge6fe7982013-10-02 15:45:22 +03002010 status = mgmt_bredr_support(hdev);
2011 if (status)
Johan Hedberg33c525c2012-10-24 21:11:58 +03002012 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
Johan Hedberge6fe7982013-10-02 15:45:22 +03002013 status);
Johan Hedberg33c525c2012-10-24 21:11:58 +03002014
Johan Hedberga7e80f22013-01-09 16:05:19 +02002015 if (cp->val != 0x00 && cp->val != 0x01)
2016 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
2017 MGMT_STATUS_INVALID_PARAMS);
2018
Johan Hedberg33ef95e2012-02-16 23:56:27 +02002019 hci_dev_lock(hdev);
2020
Johan Hedberg4b34ee782012-02-21 14:13:02 +02002021 if (!hdev_is_powered(hdev)) {
Johan Hedberg47990ea2012-02-22 11:58:37 +02002022 bool changed = false;
2023
2024 if (!!cp->val != test_bit(HCI_LINK_SECURITY,
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03002025 &hdev->dev_flags)) {
Johan Hedberg47990ea2012-02-22 11:58:37 +02002026 change_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
2027 changed = true;
2028 }
2029
2030 err = send_settings_rsp(sk, MGMT_OP_SET_LINK_SECURITY, hdev);
2031 if (err < 0)
2032 goto failed;
2033
2034 if (changed)
2035 err = new_settings(hdev, sk);
2036
Johan Hedberg33ef95e2012-02-16 23:56:27 +02002037 goto failed;
2038 }
2039
2040 if (mgmt_pending_find(MGMT_OP_SET_LINK_SECURITY, hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002041 err = cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002042 MGMT_STATUS_BUSY);
Johan Hedberg33ef95e2012-02-16 23:56:27 +02002043 goto failed;
2044 }
2045
2046 val = !!cp->val;
2047
2048 if (test_bit(HCI_AUTH, &hdev->flags) == val) {
2049 err = send_settings_rsp(sk, MGMT_OP_SET_LINK_SECURITY, hdev);
2050 goto failed;
2051 }
2052
2053 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LINK_SECURITY, hdev, data, len);
2054 if (!cmd) {
2055 err = -ENOMEM;
2056 goto failed;
2057 }
2058
2059 err = hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(val), &val);
2060 if (err < 0) {
2061 mgmt_pending_remove(cmd);
2062 goto failed;
2063 }
2064
2065failed:
2066 hci_dev_unlock(hdev);
Johan Hedberg33ef95e2012-02-16 23:56:27 +02002067 return err;
2068}
2069
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002070static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
Johan Hedberged2c4ee2012-02-17 00:56:28 +02002071{
2072 struct mgmt_mode *cp = data;
2073 struct pending_cmd *cmd;
Marcel Holtmann72ef0c12013-10-10 03:08:10 -07002074 u8 status;
Johan Hedberged2c4ee2012-02-17 00:56:28 +02002075 int err;
2076
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002077 BT_DBG("request for %s", hdev->name);
Johan Hedberged2c4ee2012-02-17 00:56:28 +02002078
Marcel Holtmanncdba5282013-10-02 21:31:52 -07002079 status = mgmt_bredr_support(hdev);
2080 if (status)
2081 return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, status);
2082
Johan Hedberg13ecd8b2013-01-09 15:29:38 +02002083 if (!lmp_ssp_capable(hdev))
2084 return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
2085 MGMT_STATUS_NOT_SUPPORTED);
Johan Hedberged2c4ee2012-02-17 00:56:28 +02002086
Johan Hedberga7e80f22013-01-09 16:05:19 +02002087 if (cp->val != 0x00 && cp->val != 0x01)
2088 return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
2089 MGMT_STATUS_INVALID_PARAMS);
2090
Johan Hedberg13ecd8b2013-01-09 15:29:38 +02002091 hci_dev_lock(hdev);
Johan Hedberg6c8f12c2012-02-22 16:35:26 +02002092
Johan Hedberg4b34ee782012-02-21 14:13:02 +02002093 if (!hdev_is_powered(hdev)) {
Marcel Holtmann9ecb3e22013-10-10 03:08:11 -07002094 bool changed;
Johan Hedbergc0ecddc2012-02-22 12:38:31 +02002095
Marcel Holtmann9ecb3e22013-10-10 03:08:11 -07002096 if (cp->val) {
2097 changed = !test_and_set_bit(HCI_SSP_ENABLED,
2098 &hdev->dev_flags);
2099 } else {
2100 changed = test_and_clear_bit(HCI_SSP_ENABLED,
2101 &hdev->dev_flags);
2102 if (!changed)
2103 changed = test_and_clear_bit(HCI_HS_ENABLED,
2104 &hdev->dev_flags);
2105 else
2106 clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +02002107 }
2108
2109 err = send_settings_rsp(sk, MGMT_OP_SET_SSP, hdev);
2110 if (err < 0)
2111 goto failed;
2112
2113 if (changed)
2114 err = new_settings(hdev, sk);
2115
Johan Hedberged2c4ee2012-02-17 00:56:28 +02002116 goto failed;
2117 }
2118
Marcel Holtmann9ecb3e22013-10-10 03:08:11 -07002119 if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev) ||
2120 mgmt_pending_find(MGMT_OP_SET_HS, hdev)) {
Szymon Jancd97dcb62012-03-16 16:02:56 +01002121 err = cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
2122 MGMT_STATUS_BUSY);
Johan Hedberged2c4ee2012-02-17 00:56:28 +02002123 goto failed;
2124 }
2125
Marcel Holtmann72ef0c12013-10-10 03:08:10 -07002126 if (!!cp->val == test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
Johan Hedberged2c4ee2012-02-17 00:56:28 +02002127 err = send_settings_rsp(sk, MGMT_OP_SET_SSP, hdev);
2128 goto failed;
2129 }
2130
2131 cmd = mgmt_pending_add(sk, MGMT_OP_SET_SSP, hdev, data, len);
2132 if (!cmd) {
2133 err = -ENOMEM;
2134 goto failed;
2135 }
2136
Johan Hedberg37699722014-06-24 14:00:27 +03002137 if (!cp->val && test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags))
2138 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
2139 sizeof(cp->val), &cp->val);
2140
Marcel Holtmann72ef0c12013-10-10 03:08:10 -07002141 err = hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &cp->val);
Johan Hedberged2c4ee2012-02-17 00:56:28 +02002142 if (err < 0) {
2143 mgmt_pending_remove(cmd);
2144 goto failed;
2145 }
2146
2147failed:
2148 hci_dev_unlock(hdev);
Johan Hedberged2c4ee2012-02-17 00:56:28 +02002149 return err;
2150}
2151
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002152static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
Johan Hedberg6d80dfd2012-02-20 23:50:38 +02002153{
2154 struct mgmt_mode *cp = data;
Marcel Holtmannee392692013-10-01 22:59:23 -07002155 bool changed;
Johan Hedberge6fe7982013-10-02 15:45:22 +03002156 u8 status;
Marcel Holtmannee392692013-10-01 22:59:23 -07002157 int err;
Johan Hedberg6d80dfd2012-02-20 23:50:38 +02002158
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002159 BT_DBG("request for %s", hdev->name);
Johan Hedberg6d80dfd2012-02-20 23:50:38 +02002160
Johan Hedberge6fe7982013-10-02 15:45:22 +03002161 status = mgmt_bredr_support(hdev);
2162 if (status)
2163 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, status);
Johan Hedberg6d80dfd2012-02-20 23:50:38 +02002164
Marcel Holtmann9ecb3e22013-10-10 03:08:11 -07002165 if (!lmp_ssp_capable(hdev))
2166 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
2167 MGMT_STATUS_NOT_SUPPORTED);
2168
2169 if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
2170 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
2171 MGMT_STATUS_REJECTED);
2172
Johan Hedberga7e80f22013-01-09 16:05:19 +02002173 if (cp->val != 0x00 && cp->val != 0x01)
2174 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
2175 MGMT_STATUS_INVALID_PARAMS);
2176
Marcel Holtmannee392692013-10-01 22:59:23 -07002177 hci_dev_lock(hdev);
Johan Hedberg6d80dfd2012-02-20 23:50:38 +02002178
Marcel Holtmanna0cdf9602013-10-02 00:27:02 -07002179 if (cp->val) {
Marcel Holtmannee392692013-10-01 22:59:23 -07002180 changed = !test_and_set_bit(HCI_HS_ENABLED, &hdev->dev_flags);
Marcel Holtmanna0cdf9602013-10-02 00:27:02 -07002181 } else {
2182 if (hdev_is_powered(hdev)) {
2183 err = cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
2184 MGMT_STATUS_REJECTED);
2185 goto unlock;
2186 }
2187
Marcel Holtmannee392692013-10-01 22:59:23 -07002188 changed = test_and_clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
Marcel Holtmanna0cdf9602013-10-02 00:27:02 -07002189 }
Marcel Holtmannee392692013-10-01 22:59:23 -07002190
2191 err = send_settings_rsp(sk, MGMT_OP_SET_HS, hdev);
2192 if (err < 0)
2193 goto unlock;
2194
2195 if (changed)
2196 err = new_settings(hdev, sk);
2197
2198unlock:
2199 hci_dev_unlock(hdev);
2200 return err;
Johan Hedberg6d80dfd2012-02-20 23:50:38 +02002201}
2202
Marcel Holtmann1904a852015-01-11 13:50:44 -08002203static void le_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg416a4ae2013-09-25 13:26:08 +03002204{
2205 struct cmd_lookup match = { NULL, hdev };
2206
Jaganath Kanakkassery3ad67582014-12-11 11:43:12 +05302207 hci_dev_lock(hdev);
2208
Johan Hedberg416a4ae2013-09-25 13:26:08 +03002209 if (status) {
2210 u8 mgmt_err = mgmt_status(status);
2211
2212 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp,
2213 &mgmt_err);
Jaganath Kanakkassery3ad67582014-12-11 11:43:12 +05302214 goto unlock;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03002215 }
2216
2217 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match);
2218
2219 new_settings(hdev, match.sk);
2220
2221 if (match.sk)
2222 sock_put(match.sk);
Marcel Holtmann441ad2d2013-10-15 06:33:52 -07002223
2224 /* Make sure the controller has a good default for
2225 * advertising data. Restrict the update to when LE
2226 * has actually been enabled. During power on, the
2227 * update in powered_update_hci will take care of it.
2228 */
2229 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
2230 struct hci_request req;
2231
Marcel Holtmann441ad2d2013-10-15 06:33:52 -07002232 hci_req_init(&req, hdev);
Marcel Holtmann5947f4b2013-10-16 00:16:50 -07002233 update_adv_data(&req);
Marcel Holtmannf14d8f62013-10-16 00:16:48 -07002234 update_scan_rsp_data(&req);
Johan Hedberg2cf22212014-12-19 22:26:00 +02002235 __hci_update_background_scan(&req);
Marcel Holtmann441ad2d2013-10-15 06:33:52 -07002236 hci_req_run(&req, NULL);
Marcel Holtmann441ad2d2013-10-15 06:33:52 -07002237 }
Jaganath Kanakkassery3ad67582014-12-11 11:43:12 +05302238
2239unlock:
2240 hci_dev_unlock(hdev);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03002241}
2242
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002243static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
Johan Hedberg06199cf2012-02-22 16:37:11 +02002244{
2245 struct mgmt_mode *cp = data;
2246 struct hci_cp_write_le_host_supported hci_cp;
2247 struct pending_cmd *cmd;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03002248 struct hci_request req;
Johan Hedberg06199cf2012-02-22 16:37:11 +02002249 int err;
Johan Hedberg0b60eba2012-02-28 00:57:24 +02002250 u8 val, enabled;
Johan Hedberg06199cf2012-02-22 16:37:11 +02002251
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002252 BT_DBG("request for %s", hdev->name);
Johan Hedberg06199cf2012-02-22 16:37:11 +02002253
Johan Hedberg13ecd8b2013-01-09 15:29:38 +02002254 if (!lmp_le_capable(hdev))
2255 return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
2256 MGMT_STATUS_NOT_SUPPORTED);
Johan Hedberg1de028c2012-02-29 19:55:35 -08002257
Johan Hedberga7e80f22013-01-09 16:05:19 +02002258 if (cp->val != 0x00 && cp->val != 0x01)
2259 return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
2260 MGMT_STATUS_INVALID_PARAMS);
2261
Johan Hedbergc73eee92013-04-19 18:35:21 +03002262 /* LE-only devices do not allow toggling LE on/off */
Johan Hedberg56f87902013-10-02 13:43:13 +03002263 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
Johan Hedbergc73eee92013-04-19 18:35:21 +03002264 return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
2265 MGMT_STATUS_REJECTED);
2266
Johan Hedberg13ecd8b2013-01-09 15:29:38 +02002267 hci_dev_lock(hdev);
Johan Hedberg06199cf2012-02-22 16:37:11 +02002268
2269 val = !!cp->val;
Gustavo Padovanffa88e02012-11-23 16:50:51 -02002270 enabled = lmp_host_le_capable(hdev);
Johan Hedberg06199cf2012-02-22 16:37:11 +02002271
Johan Hedberg0b60eba2012-02-28 00:57:24 +02002272 if (!hdev_is_powered(hdev) || val == enabled) {
Johan Hedberg06199cf2012-02-22 16:37:11 +02002273 bool changed = false;
2274
2275 if (val != test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
2276 change_bit(HCI_LE_ENABLED, &hdev->dev_flags);
2277 changed = true;
2278 }
2279
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02002280 if (!val && test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
2281 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergeeca6f82013-09-25 13:26:09 +03002282 changed = true;
2283 }
2284
Johan Hedberg06199cf2012-02-22 16:37:11 +02002285 err = send_settings_rsp(sk, MGMT_OP_SET_LE, hdev);
2286 if (err < 0)
Johan Hedberg1de028c2012-02-29 19:55:35 -08002287 goto unlock;
Johan Hedberg06199cf2012-02-22 16:37:11 +02002288
2289 if (changed)
2290 err = new_settings(hdev, sk);
2291
Johan Hedberg1de028c2012-02-29 19:55:35 -08002292 goto unlock;
Johan Hedberg06199cf2012-02-22 16:37:11 +02002293 }
2294
Johan Hedberg4375f102013-09-25 13:26:10 +03002295 if (mgmt_pending_find(MGMT_OP_SET_LE, hdev) ||
2296 mgmt_pending_find(MGMT_OP_SET_ADVERTISING, hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002297 err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002298 MGMT_STATUS_BUSY);
Johan Hedberg1de028c2012-02-29 19:55:35 -08002299 goto unlock;
Johan Hedberg06199cf2012-02-22 16:37:11 +02002300 }
2301
2302 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LE, hdev, data, len);
2303 if (!cmd) {
2304 err = -ENOMEM;
Johan Hedberg1de028c2012-02-29 19:55:35 -08002305 goto unlock;
Johan Hedberg06199cf2012-02-22 16:37:11 +02002306 }
2307
Marcel Holtmann441ad2d2013-10-15 06:33:52 -07002308 hci_req_init(&req, hdev);
2309
Johan Hedberg06199cf2012-02-22 16:37:11 +02002310 memset(&hci_cp, 0, sizeof(hci_cp));
2311
2312 if (val) {
2313 hci_cp.le = val;
Marcel Holtmann32226e42014-07-24 20:04:16 +02002314 hci_cp.simul = 0x00;
Marcel Holtmann441ad2d2013-10-15 06:33:52 -07002315 } else {
Johan Hedberg73e082f2014-07-08 15:07:51 +03002316 if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
Marcel Holtmann441ad2d2013-10-15 06:33:52 -07002317 disable_advertising(&req);
Johan Hedberg06199cf2012-02-22 16:37:11 +02002318 }
2319
Johan Hedberg416a4ae2013-09-25 13:26:08 +03002320 hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
2321 &hci_cp);
2322
2323 err = hci_req_run(&req, le_enable_complete);
Syam Sidhardhan0c01bc42012-04-12 20:33:21 +05302324 if (err < 0)
Johan Hedberg06199cf2012-02-22 16:37:11 +02002325 mgmt_pending_remove(cmd);
Johan Hedberg06199cf2012-02-22 16:37:11 +02002326
Johan Hedberg1de028c2012-02-29 19:55:35 -08002327unlock:
2328 hci_dev_unlock(hdev);
Johan Hedberg06199cf2012-02-22 16:37:11 +02002329 return err;
2330}
2331
Johan Hedberg0cab9c82013-03-15 17:06:54 -05002332/* This is a helper function to test for pending mgmt commands that can
2333 * cause CoD or EIR HCI commands. We can only allow one such pending
2334 * mgmt command at a time since otherwise we cannot easily track what
2335 * the current values are, will be, and based on that calculate if a new
2336 * HCI command needs to be sent and if yes with what value.
2337 */
2338static bool pending_eir_or_class(struct hci_dev *hdev)
2339{
2340 struct pending_cmd *cmd;
2341
2342 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
2343 switch (cmd->opcode) {
2344 case MGMT_OP_ADD_UUID:
2345 case MGMT_OP_REMOVE_UUID:
2346 case MGMT_OP_SET_DEV_CLASS:
2347 case MGMT_OP_SET_POWERED:
2348 return true;
2349 }
2350 }
2351
2352 return false;
2353}
2354
Johan Hedberg83be8ec2013-01-27 00:31:29 +02002355static const u8 bluetooth_base_uuid[] = {
2356 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
2357 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2358};
2359
2360static u8 get_uuid_size(const u8 *uuid)
2361{
2362 u32 val;
2363
2364 if (memcmp(uuid, bluetooth_base_uuid, 12))
2365 return 128;
2366
2367 val = get_unaligned_le32(&uuid[12]);
2368 if (val > 0xffff)
2369 return 32;
2370
2371 return 16;
2372}
2373
Johan Hedberg92da6092013-03-15 17:06:55 -05002374static void mgmt_class_complete(struct hci_dev *hdev, u16 mgmt_op, u8 status)
2375{
2376 struct pending_cmd *cmd;
2377
2378 hci_dev_lock(hdev);
2379
2380 cmd = mgmt_pending_find(mgmt_op, hdev);
2381 if (!cmd)
2382 goto unlock;
2383
2384 cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status),
2385 hdev->dev_class, 3);
2386
2387 mgmt_pending_remove(cmd);
2388
2389unlock:
2390 hci_dev_unlock(hdev);
2391}
2392
Marcel Holtmann1904a852015-01-11 13:50:44 -08002393static void add_uuid_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg92da6092013-03-15 17:06:55 -05002394{
2395 BT_DBG("status 0x%02x", status);
2396
2397 mgmt_class_complete(hdev, MGMT_OP_ADD_UUID, status);
2398}
2399
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002400static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002401{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03002402 struct mgmt_cp_add_uuid *cp = data;
Johan Hedberg90e70452012-02-23 23:09:40 +02002403 struct pending_cmd *cmd;
Johan Hedberg890ea892013-03-15 17:06:52 -05002404 struct hci_request req;
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002405 struct bt_uuid *uuid;
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002406 int err;
2407
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002408 BT_DBG("request for %s", hdev->name);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002409
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002410 hci_dev_lock(hdev);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002411
Johan Hedberg0cab9c82013-03-15 17:06:54 -05002412 if (pending_eir_or_class(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002413 err = cmd_status(sk, hdev->id, MGMT_OP_ADD_UUID,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002414 MGMT_STATUS_BUSY);
Johan Hedbergc95f0ba2012-02-23 22:54:38 +02002415 goto failed;
2416 }
2417
Andre Guedes92c4c202012-06-07 19:05:44 -03002418 uuid = kmalloc(sizeof(*uuid), GFP_KERNEL);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002419 if (!uuid) {
2420 err = -ENOMEM;
2421 goto failed;
2422 }
2423
2424 memcpy(uuid->uuid, cp->uuid, 16);
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002425 uuid->svc_hint = cp->svc_hint;
Johan Hedberg83be8ec2013-01-27 00:31:29 +02002426 uuid->size = get_uuid_size(cp->uuid);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002427
Johan Hedbergde66aa62013-01-27 00:31:27 +02002428 list_add_tail(&uuid->list, &hdev->uuids);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002429
Johan Hedberg890ea892013-03-15 17:06:52 -05002430 hci_req_init(&req, hdev);
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002431
Johan Hedberg890ea892013-03-15 17:06:52 -05002432 update_class(&req);
2433 update_eir(&req);
2434
Johan Hedberg92da6092013-03-15 17:06:55 -05002435 err = hci_req_run(&req, add_uuid_complete);
2436 if (err < 0) {
2437 if (err != -ENODATA)
2438 goto failed;
Johan Hedberg80a1e1d2011-03-28 14:07:23 +03002439
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002440 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_UUID, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002441 hdev->dev_class, 3);
Johan Hedberg90e70452012-02-23 23:09:40 +02002442 goto failed;
2443 }
2444
2445 cmd = mgmt_pending_add(sk, MGMT_OP_ADD_UUID, hdev, data, len);
Johan Hedberg890ea892013-03-15 17:06:52 -05002446 if (!cmd) {
Johan Hedberg90e70452012-02-23 23:09:40 +02002447 err = -ENOMEM;
Johan Hedberg890ea892013-03-15 17:06:52 -05002448 goto failed;
2449 }
2450
2451 err = 0;
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002452
2453failed:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002454 hci_dev_unlock(hdev);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002455 return err;
2456}
2457
Johan Hedberg24b78d02012-02-23 23:24:30 +02002458static bool enable_service_cache(struct hci_dev *hdev)
2459{
2460 if (!hdev_is_powered(hdev))
2461 return false;
2462
2463 if (!test_and_set_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) {
Johan Hedberg46818ed2013-01-14 22:33:52 +02002464 queue_delayed_work(hdev->workqueue, &hdev->service_cache,
2465 CACHE_TIMEOUT);
Johan Hedberg24b78d02012-02-23 23:24:30 +02002466 return true;
2467 }
2468
2469 return false;
2470}
2471
Marcel Holtmann1904a852015-01-11 13:50:44 -08002472static void remove_uuid_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg92da6092013-03-15 17:06:55 -05002473{
2474 BT_DBG("status 0x%02x", status);
2475
2476 mgmt_class_complete(hdev, MGMT_OP_REMOVE_UUID, status);
2477}
2478
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002479static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03002480 u16 len)
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002481{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03002482 struct mgmt_cp_remove_uuid *cp = data;
Johan Hedberg90e70452012-02-23 23:09:40 +02002483 struct pending_cmd *cmd;
Johan Hedberg056341c2013-01-27 00:31:30 +02002484 struct bt_uuid *match, *tmp;
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002485 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Johan Hedberg890ea892013-03-15 17:06:52 -05002486 struct hci_request req;
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002487 int err, found;
2488
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002489 BT_DBG("request for %s", hdev->name);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002490
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002491 hci_dev_lock(hdev);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002492
Johan Hedberg0cab9c82013-03-15 17:06:54 -05002493 if (pending_eir_or_class(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002494 err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002495 MGMT_STATUS_BUSY);
Johan Hedbergc95f0ba2012-02-23 22:54:38 +02002496 goto unlock;
2497 }
2498
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002499 if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) {
Johan Hedberg35f74982014-02-18 17:14:32 +02002500 hci_uuids_clear(hdev);
Johan Hedberg4004b6d2012-02-23 21:30:12 +02002501
Johan Hedberg24b78d02012-02-23 23:24:30 +02002502 if (enable_service_cache(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002503 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002504 0, hdev->dev_class, 3);
Johan Hedberg24b78d02012-02-23 23:24:30 +02002505 goto unlock;
2506 }
Johan Hedberg4004b6d2012-02-23 21:30:12 +02002507
Johan Hedberg9246a862012-02-23 21:33:16 +02002508 goto update_class;
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002509 }
2510
2511 found = 0;
2512
Johan Hedberg056341c2013-01-27 00:31:30 +02002513 list_for_each_entry_safe(match, tmp, &hdev->uuids, list) {
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002514 if (memcmp(match->uuid, cp->uuid, 16) != 0)
2515 continue;
2516
2517 list_del(&match->list);
Johan Hedberg482049f2012-11-08 10:25:26 +01002518 kfree(match);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002519 found++;
2520 }
2521
2522 if (found == 0) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002523 err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002524 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002525 goto unlock;
2526 }
2527
Johan Hedberg9246a862012-02-23 21:33:16 +02002528update_class:
Johan Hedberg890ea892013-03-15 17:06:52 -05002529 hci_req_init(&req, hdev);
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002530
Johan Hedberg890ea892013-03-15 17:06:52 -05002531 update_class(&req);
2532 update_eir(&req);
2533
Johan Hedberg92da6092013-03-15 17:06:55 -05002534 err = hci_req_run(&req, remove_uuid_complete);
2535 if (err < 0) {
2536 if (err != -ENODATA)
2537 goto unlock;
Johan Hedberg80a1e1d2011-03-28 14:07:23 +03002538
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002539 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002540 hdev->dev_class, 3);
Johan Hedberg90e70452012-02-23 23:09:40 +02002541 goto unlock;
2542 }
2543
2544 cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_UUID, hdev, data, len);
Johan Hedberg890ea892013-03-15 17:06:52 -05002545 if (!cmd) {
Johan Hedberg90e70452012-02-23 23:09:40 +02002546 err = -ENOMEM;
Johan Hedberg890ea892013-03-15 17:06:52 -05002547 goto unlock;
2548 }
2549
2550 err = 0;
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002551
2552unlock:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002553 hci_dev_unlock(hdev);
Johan Hedberg2aeb9a12011-01-04 12:08:51 +02002554 return err;
2555}
2556
Marcel Holtmann1904a852015-01-11 13:50:44 -08002557static void set_class_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg92da6092013-03-15 17:06:55 -05002558{
2559 BT_DBG("status 0x%02x", status);
2560
2561 mgmt_class_complete(hdev, MGMT_OP_SET_DEV_CLASS, status);
2562}
2563
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002564static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002565 u16 len)
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002566{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03002567 struct mgmt_cp_set_dev_class *cp = data;
Johan Hedberg90e70452012-02-23 23:09:40 +02002568 struct pending_cmd *cmd;
Johan Hedberg890ea892013-03-15 17:06:52 -05002569 struct hci_request req;
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002570 int err;
2571
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002572 BT_DBG("request for %s", hdev->name);
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002573
Marcel Holtmann6203fc92013-10-02 23:37:29 -07002574 if (!lmp_bredr_capable(hdev))
Johan Hedberg13ecd8b2013-01-09 15:29:38 +02002575 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
2576 MGMT_STATUS_NOT_SUPPORTED);
2577
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002578 hci_dev_lock(hdev);
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002579
Johan Hedberg0cab9c82013-03-15 17:06:54 -05002580 if (pending_eir_or_class(hdev)) {
2581 err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
2582 MGMT_STATUS_BUSY);
2583 goto unlock;
2584 }
2585
2586 if ((cp->minor & 0x03) != 0 || (cp->major & 0xe0) != 0) {
2587 err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
2588 MGMT_STATUS_INVALID_PARAMS);
2589 goto unlock;
2590 }
2591
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002592 hdev->major_class = cp->major;
2593 hdev->minor_class = cp->minor;
2594
Johan Hedberg932f5ff2012-02-22 22:11:32 +02002595 if (!hdev_is_powered(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002596 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002597 hdev->dev_class, 3);
Johan Hedberg932f5ff2012-02-22 22:11:32 +02002598 goto unlock;
2599 }
2600
Johan Hedberg890ea892013-03-15 17:06:52 -05002601 hci_req_init(&req, hdev);
2602
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002603 if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) {
Johan Hedberg7d785252011-12-15 00:47:39 +02002604 hci_dev_unlock(hdev);
2605 cancel_delayed_work_sync(&hdev->service_cache);
2606 hci_dev_lock(hdev);
Johan Hedberg890ea892013-03-15 17:06:52 -05002607 update_eir(&req);
Johan Hedberg7d785252011-12-15 00:47:39 +02002608 }
Johan Hedberg14c0b602011-12-15 00:47:37 +02002609
Johan Hedberg890ea892013-03-15 17:06:52 -05002610 update_class(&req);
2611
Johan Hedberg92da6092013-03-15 17:06:55 -05002612 err = hci_req_run(&req, set_class_complete);
2613 if (err < 0) {
2614 if (err != -ENODATA)
2615 goto unlock;
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002616
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002617 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002618 hdev->dev_class, 3);
Johan Hedberg90e70452012-02-23 23:09:40 +02002619 goto unlock;
2620 }
2621
2622 cmd = mgmt_pending_add(sk, MGMT_OP_SET_DEV_CLASS, hdev, data, len);
Johan Hedberg890ea892013-03-15 17:06:52 -05002623 if (!cmd) {
Johan Hedberg90e70452012-02-23 23:09:40 +02002624 err = -ENOMEM;
Johan Hedberg890ea892013-03-15 17:06:52 -05002625 goto unlock;
2626 }
2627
2628 err = 0;
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002629
Johan Hedbergb5235a62012-02-21 14:32:24 +02002630unlock:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002631 hci_dev_unlock(hdev);
Johan Hedberg1aff6f02011-01-13 21:56:52 +02002632 return err;
2633}
2634
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002635static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03002636 u16 len)
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002637{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03002638 struct mgmt_cp_load_link_keys *cp = data;
Johan Hedbergba1d6932014-07-03 13:52:27 +03002639 const u16 max_key_count = ((U16_MAX - sizeof(*cp)) /
2640 sizeof(struct mgmt_link_key_info));
Szymon Janc4e51eae2011-02-25 19:05:48 +01002641 u16 key_count, expected_len;
Marcel Holtmannb1de97d2014-01-31 11:55:21 -08002642 bool changed;
Vinicius Costa Gomesa492cd52011-08-25 20:02:29 -03002643 int i;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002644
Marcel Holtmann9060d5c2013-10-02 21:16:07 -07002645 BT_DBG("request for %s", hdev->name);
2646
2647 if (!lmp_bredr_capable(hdev))
2648 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
2649 MGMT_STATUS_NOT_SUPPORTED);
2650
Marcel Holtmann1f350c82012-03-12 20:31:08 -07002651 key_count = __le16_to_cpu(cp->key_count);
Johan Hedbergba1d6932014-07-03 13:52:27 +03002652 if (key_count > max_key_count) {
2653 BT_ERR("load_link_keys: too big key_count value %u",
2654 key_count);
2655 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
2656 MGMT_STATUS_INVALID_PARAMS);
2657 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002658
Johan Hedberg86742e12011-11-07 23:13:38 +02002659 expected_len = sizeof(*cp) + key_count *
2660 sizeof(struct mgmt_link_key_info);
Vinicius Costa Gomesa492cd52011-08-25 20:02:29 -03002661 if (expected_len != len) {
Johan Hedberg86742e12011-11-07 23:13:38 +02002662 BT_ERR("load_link_keys: expected %u bytes, got %u bytes",
Johan Hedberg2606ecb2014-03-07 15:04:13 +02002663 expected_len, len);
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002664 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002665 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002666 }
2667
Johan Hedberg4ae14302013-01-20 14:27:13 +02002668 if (cp->debug_keys != 0x00 && cp->debug_keys != 0x01)
2669 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
2670 MGMT_STATUS_INVALID_PARAMS);
2671
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002672 BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys,
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03002673 key_count);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002674
Johan Hedberg4ee71b22013-01-20 14:27:19 +02002675 for (i = 0; i < key_count; i++) {
2676 struct mgmt_link_key_info *key = &cp->keys[i];
2677
Marcel Holtmann8e991132014-01-10 02:07:25 -08002678 if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
Johan Hedberg4ee71b22013-01-20 14:27:19 +02002679 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
2680 MGMT_STATUS_INVALID_PARAMS);
2681 }
2682
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002683 hci_dev_lock(hdev);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002684
2685 hci_link_keys_clear(hdev);
2686
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002687 if (cp->debug_keys)
Johan Hedberg0663b292014-06-24 13:15:50 +03002688 changed = !test_and_set_bit(HCI_KEEP_DEBUG_KEYS,
2689 &hdev->dev_flags);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002690 else
Johan Hedberg0663b292014-06-24 13:15:50 +03002691 changed = test_and_clear_bit(HCI_KEEP_DEBUG_KEYS,
2692 &hdev->dev_flags);
Marcel Holtmannb1de97d2014-01-31 11:55:21 -08002693
2694 if (changed)
2695 new_settings(hdev, NULL);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002696
Vinicius Costa Gomesa492cd52011-08-25 20:02:29 -03002697 for (i = 0; i < key_count; i++) {
Johan Hedberg86742e12011-11-07 23:13:38 +02002698 struct mgmt_link_key_info *key = &cp->keys[i];
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002699
Johan Hedberg58e92932014-06-24 14:00:26 +03002700 /* Always ignore debug keys and require a new pairing if
2701 * the user wants to use them.
2702 */
2703 if (key->type == HCI_LK_DEBUG_COMBINATION)
2704 continue;
2705
Johan Hedberg7652ff62014-06-24 13:15:49 +03002706 hci_add_link_key(hdev, NULL, &key->addr.bdaddr, key->val,
2707 key->type, key->pin_len, NULL);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002708 }
2709
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002710 cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0);
Johan Hedberg0e5f8752011-11-11 16:18:54 +02002711
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002712 hci_dev_unlock(hdev);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002713
Vinicius Costa Gomesa492cd52011-08-25 20:02:29 -03002714 return 0;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002715}
2716
Johan Hedbergb1078ad2012-02-09 17:21:16 +02002717static int device_unpaired(struct hci_dev *hdev, bdaddr_t *bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002718 u8 addr_type, struct sock *skip_sk)
Johan Hedbergb1078ad2012-02-09 17:21:16 +02002719{
2720 struct mgmt_ev_device_unpaired ev;
2721
2722 bacpy(&ev.addr.bdaddr, bdaddr);
2723 ev.addr.type = addr_type;
2724
2725 return mgmt_event(MGMT_EV_DEVICE_UNPAIRED, hdev, &ev, sizeof(ev),
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002726 skip_sk);
Johan Hedbergb1078ad2012-02-09 17:21:16 +02002727}
2728
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002729static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002730 u16 len)
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002731{
Johan Hedberg124f6e32012-02-09 13:50:12 +02002732 struct mgmt_cp_unpair_device *cp = data;
2733 struct mgmt_rp_unpair_device rp;
Johan Hedberga8a1d192011-11-10 15:54:38 +02002734 struct hci_cp_disconnect dc;
2735 struct pending_cmd *cmd;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002736 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002737 int err;
2738
Johan Hedberga8a1d192011-11-10 15:54:38 +02002739 memset(&rp, 0, sizeof(rp));
Johan Hedberg124f6e32012-02-09 13:50:12 +02002740 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2741 rp.addr.type = cp->addr.type;
Johan Hedberga8a1d192011-11-10 15:54:38 +02002742
Johan Hedberg4ee71b22013-01-20 14:27:19 +02002743 if (!bdaddr_type_is_valid(cp->addr.type))
2744 return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
2745 MGMT_STATUS_INVALID_PARAMS,
2746 &rp, sizeof(rp));
2747
Johan Hedberg118da702013-01-20 14:27:20 +02002748 if (cp->disconnect != 0x00 && cp->disconnect != 0x01)
2749 return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
2750 MGMT_STATUS_INVALID_PARAMS,
2751 &rp, sizeof(rp));
2752
Johan Hedberg4ee71b22013-01-20 14:27:19 +02002753 hci_dev_lock(hdev);
2754
Johan Hedberg86a8cfc2012-02-22 22:53:34 +02002755 if (!hdev_is_powered(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002756 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002757 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
Johan Hedberg86a8cfc2012-02-22 22:53:34 +02002758 goto unlock;
2759 }
2760
Johan Hedberge0b2b272014-02-18 17:14:31 +02002761 if (cp->addr.type == BDADDR_BREDR) {
Alfonso Acosta89cbb062014-10-11 21:44:47 +00002762 /* If disconnection is requested, then look up the
2763 * connection. If the remote device is connected, it
2764 * will be later used to terminate the link.
2765 *
2766 * Setting it to NULL explicitly will cause no
2767 * termination of the link.
2768 */
2769 if (cp->disconnect)
2770 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
2771 &cp->addr.bdaddr);
2772 else
2773 conn = NULL;
2774
Johan Hedberg124f6e32012-02-09 13:50:12 +02002775 err = hci_remove_link_key(hdev, &cp->addr.bdaddr);
Johan Hedberge0b2b272014-02-18 17:14:31 +02002776 } else {
2777 u8 addr_type;
2778
Alfonso Acosta89cbb062014-10-11 21:44:47 +00002779 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK,
2780 &cp->addr.bdaddr);
2781 if (conn) {
2782 /* Defer clearing up the connection parameters
2783 * until closing to give a chance of keeping
2784 * them if a repairing happens.
2785 */
2786 set_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags);
2787
2788 /* If disconnection is not requested, then
2789 * clear the connection variable so that the
2790 * link is not terminated.
2791 */
2792 if (!cp->disconnect)
2793 conn = NULL;
2794 }
2795
Johan Hedberge0b2b272014-02-18 17:14:31 +02002796 if (cp->addr.type == BDADDR_LE_PUBLIC)
2797 addr_type = ADDR_LE_DEV_PUBLIC;
2798 else
2799 addr_type = ADDR_LE_DEV_RANDOM;
2800
Johan Hedberga7ec7332014-02-18 17:14:35 +02002801 hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type);
2802
Johan Hedberge0b2b272014-02-18 17:14:31 +02002803 err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type);
2804 }
Vinicius Costa Gomesb0dbfb42012-02-02 21:08:03 -03002805
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002806 if (err < 0) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002807 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002808 MGMT_STATUS_NOT_PAIRED, &rp, sizeof(rp));
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002809 goto unlock;
2810 }
2811
Alfonso Acosta89cbb062014-10-11 21:44:47 +00002812 /* If the connection variable is set, then termination of the
2813 * link is requested.
2814 */
Johan Hedberga8a1d192011-11-10 15:54:38 +02002815 if (!conn) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002816 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002817 &rp, sizeof(rp));
Johan Hedbergb1078ad2012-02-09 17:21:16 +02002818 device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk);
Johan Hedberga8a1d192011-11-10 15:54:38 +02002819 goto unlock;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002820 }
2821
Johan Hedberg124f6e32012-02-09 13:50:12 +02002822 cmd = mgmt_pending_add(sk, MGMT_OP_UNPAIR_DEVICE, hdev, cp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002823 sizeof(*cp));
Johan Hedberga8a1d192011-11-10 15:54:38 +02002824 if (!cmd) {
2825 err = -ENOMEM;
2826 goto unlock;
2827 }
2828
Johan Hedbergd8b7b1e2014-12-05 13:36:05 +02002829 cmd->cmd_complete = addr_cmd_complete;
2830
Marcel Holtmanneb55ef02012-03-14 18:08:46 +02002831 dc.handle = cpu_to_le16(conn->handle);
Johan Hedberga8a1d192011-11-10 15:54:38 +02002832 dc.reason = 0x13; /* Remote User Terminated Connection */
2833 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
2834 if (err < 0)
2835 mgmt_pending_remove(cmd);
2836
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002837unlock:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002838 hci_dev_unlock(hdev);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002839 return err;
2840}
2841
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002842static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002843 u16 len)
Johan Hedberg8962ee72011-01-20 12:40:27 +02002844{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03002845 struct mgmt_cp_disconnect *cp = data;
Johan Hedberg06a63b12013-01-20 14:27:21 +02002846 struct mgmt_rp_disconnect rp;
Johan Hedberg366a0332011-02-19 12:05:55 -03002847 struct pending_cmd *cmd;
Johan Hedberg8962ee72011-01-20 12:40:27 +02002848 struct hci_conn *conn;
Johan Hedberg8962ee72011-01-20 12:40:27 +02002849 int err;
2850
2851 BT_DBG("");
2852
Johan Hedberg06a63b12013-01-20 14:27:21 +02002853 memset(&rp, 0, sizeof(rp));
2854 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2855 rp.addr.type = cp->addr.type;
2856
Johan Hedberg4ee71b22013-01-20 14:27:19 +02002857 if (!bdaddr_type_is_valid(cp->addr.type))
Johan Hedberg06a63b12013-01-20 14:27:21 +02002858 return cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
2859 MGMT_STATUS_INVALID_PARAMS,
2860 &rp, sizeof(rp));
Johan Hedberg4ee71b22013-01-20 14:27:19 +02002861
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002862 hci_dev_lock(hdev);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002863
2864 if (!test_bit(HCI_UP, &hdev->flags)) {
Johan Hedberg06a63b12013-01-20 14:27:21 +02002865 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
2866 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
Johan Hedberg8962ee72011-01-20 12:40:27 +02002867 goto failed;
2868 }
2869
Johan Hedberg2e58ef32011-11-08 20:40:15 +02002870 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) {
Johan Hedberg06a63b12013-01-20 14:27:21 +02002871 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
2872 MGMT_STATUS_BUSY, &rp, sizeof(rp));
Johan Hedberg8962ee72011-01-20 12:40:27 +02002873 goto failed;
2874 }
2875
Andre Guedes591f47f2012-04-24 21:02:49 -03002876 if (cp->addr.type == BDADDR_BREDR)
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002877 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
2878 &cp->addr.bdaddr);
Johan Hedberg88c3df12012-02-09 14:27:38 +02002879 else
2880 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
Vinicius Costa Gomes365227e2011-05-06 18:41:44 -03002881
Vishal Agarwalf9607272012-06-13 05:32:43 +05302882 if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) {
Johan Hedberg06a63b12013-01-20 14:27:21 +02002883 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
2884 MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp));
Johan Hedberg8962ee72011-01-20 12:40:27 +02002885 goto failed;
2886 }
2887
Johan Hedberg2e58ef32011-11-08 20:40:15 +02002888 cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, data, len);
Johan Hedberg366a0332011-02-19 12:05:55 -03002889 if (!cmd) {
2890 err = -ENOMEM;
Johan Hedberg8962ee72011-01-20 12:40:27 +02002891 goto failed;
Johan Hedberg366a0332011-02-19 12:05:55 -03002892 }
Johan Hedberg8962ee72011-01-20 12:40:27 +02002893
Johan Hedbergf5818c22014-12-05 13:36:02 +02002894 cmd->cmd_complete = generic_cmd_complete;
2895
Johan Hedberge3f2f922014-08-18 20:33:33 +03002896 err = hci_disconnect(conn, HCI_ERROR_REMOTE_USER_TERM);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002897 if (err < 0)
Johan Hedberga664b5b2011-02-19 12:06:02 -03002898 mgmt_pending_remove(cmd);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002899
2900failed:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002901 hci_dev_unlock(hdev);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002902 return err;
2903}
2904
Andre Guedes57c14772012-04-24 21:02:50 -03002905static u8 link_to_bdaddr(u8 link_type, u8 addr_type)
Johan Hedberg4c659c32011-11-07 23:13:39 +02002906{
2907 switch (link_type) {
2908 case LE_LINK:
Johan Hedberg48264f02011-11-09 13:58:58 +02002909 switch (addr_type) {
2910 case ADDR_LE_DEV_PUBLIC:
Andre Guedes591f47f2012-04-24 21:02:49 -03002911 return BDADDR_LE_PUBLIC;
Andre Guedes0ed09142012-04-03 08:46:54 -03002912
Johan Hedberg48264f02011-11-09 13:58:58 +02002913 default:
Andre Guedes0ed09142012-04-03 08:46:54 -03002914 /* Fallback to LE Random address type */
Andre Guedes591f47f2012-04-24 21:02:49 -03002915 return BDADDR_LE_RANDOM;
Johan Hedberg48264f02011-11-09 13:58:58 +02002916 }
Andre Guedes0ed09142012-04-03 08:46:54 -03002917
Johan Hedberg4c659c32011-11-07 23:13:39 +02002918 default:
Andre Guedes0ed09142012-04-03 08:46:54 -03002919 /* Fallback to BR/EDR type */
Andre Guedes591f47f2012-04-24 21:02:49 -03002920 return BDADDR_BREDR;
Johan Hedberg4c659c32011-11-07 23:13:39 +02002921 }
2922}
2923
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002924static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data,
2925 u16 data_len)
Johan Hedberg2784eb42011-01-21 13:56:35 +02002926{
Johan Hedberg2784eb42011-01-21 13:56:35 +02002927 struct mgmt_rp_get_connections *rp;
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +02002928 struct hci_conn *c;
Johan Hedberga38528f2011-01-22 06:46:43 +02002929 size_t rp_len;
Johan Hedberg60fc5fb62012-02-23 09:52:28 +02002930 int err;
2931 u16 i;
Johan Hedberg2784eb42011-01-21 13:56:35 +02002932
2933 BT_DBG("");
2934
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002935 hci_dev_lock(hdev);
Johan Hedberg2784eb42011-01-21 13:56:35 +02002936
Johan Hedberg5f97c1d2012-02-22 22:41:18 +02002937 if (!hdev_is_powered(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002938 err = cmd_status(sk, hdev->id, MGMT_OP_GET_CONNECTIONS,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002939 MGMT_STATUS_NOT_POWERED);
Johan Hedberg5f97c1d2012-02-22 22:41:18 +02002940 goto unlock;
2941 }
2942
Johan Hedberg60fc5fb62012-02-23 09:52:28 +02002943 i = 0;
Johan Hedbergb644ba32012-01-17 21:48:47 +02002944 list_for_each_entry(c, &hdev->conn_hash.list, list) {
2945 if (test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
Johan Hedberg60fc5fb62012-02-23 09:52:28 +02002946 i++;
Johan Hedberg2784eb42011-01-21 13:56:35 +02002947 }
2948
Johan Hedberg60fc5fb62012-02-23 09:52:28 +02002949 rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
Andre Guedes92c4c202012-06-07 19:05:44 -03002950 rp = kmalloc(rp_len, GFP_KERNEL);
Johan Hedberga38528f2011-01-22 06:46:43 +02002951 if (!rp) {
Johan Hedberg2784eb42011-01-21 13:56:35 +02002952 err = -ENOMEM;
2953 goto unlock;
2954 }
2955
Johan Hedberg2784eb42011-01-21 13:56:35 +02002956 i = 0;
Johan Hedberg4c659c32011-11-07 23:13:39 +02002957 list_for_each_entry(c, &hdev->conn_hash.list, list) {
Johan Hedbergb644ba32012-01-17 21:48:47 +02002958 if (!test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
2959 continue;
Johan Hedberg4c659c32011-11-07 23:13:39 +02002960 bacpy(&rp->addr[i].bdaddr, &c->dst);
Andre Guedes57c14772012-04-24 21:02:50 -03002961 rp->addr[i].type = link_to_bdaddr(c->type, c->dst_type);
Andre Guedes0ed09142012-04-03 08:46:54 -03002962 if (c->type == SCO_LINK || c->type == ESCO_LINK)
Johan Hedberg4c659c32011-11-07 23:13:39 +02002963 continue;
2964 i++;
2965 }
2966
Marcel Holtmanneb55ef02012-03-14 18:08:46 +02002967 rp->conn_count = cpu_to_le16(i);
Johan Hedberg60fc5fb62012-02-23 09:52:28 +02002968
Johan Hedberg4c659c32011-11-07 23:13:39 +02002969 /* Recalculate length in case of filtered SCO connections, etc */
2970 rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
Johan Hedberg2784eb42011-01-21 13:56:35 +02002971
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002972 err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, 0, rp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002973 rp_len);
Johan Hedberg2784eb42011-01-21 13:56:35 +02002974
Johan Hedberga38528f2011-01-22 06:46:43 +02002975 kfree(rp);
Johan Hedberg5f97c1d2012-02-22 22:41:18 +02002976
2977unlock:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002978 hci_dev_unlock(hdev);
Johan Hedberg2784eb42011-01-21 13:56:35 +02002979 return err;
2980}
2981
Johan Hedbergbdb6d972012-02-28 06:13:32 +02002982static int send_pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002983 struct mgmt_cp_pin_code_neg_reply *cp)
Waldemar Rymarkiewicz96d97a62011-06-01 17:28:48 +02002984{
2985 struct pending_cmd *cmd;
2986 int err;
2987
Johan Hedberg2e58ef32011-11-08 20:40:15 +02002988 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, hdev, cp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002989 sizeof(*cp));
Waldemar Rymarkiewicz96d97a62011-06-01 17:28:48 +02002990 if (!cmd)
2991 return -ENOMEM;
2992
Johan Hedbergd8457692012-02-17 14:24:57 +02002993 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002994 sizeof(cp->addr.bdaddr), &cp->addr.bdaddr);
Waldemar Rymarkiewicz96d97a62011-06-01 17:28:48 +02002995 if (err < 0)
2996 mgmt_pending_remove(cmd);
2997
2998 return err;
2999}
3000
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003001static int pin_code_reply(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003002 u16 len)
Johan Hedberg980e1a52011-01-22 06:10:07 +02003003{
Waldemar Rymarkiewicz96d97a62011-06-01 17:28:48 +02003004 struct hci_conn *conn;
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03003005 struct mgmt_cp_pin_code_reply *cp = data;
Johan Hedberg980e1a52011-01-22 06:10:07 +02003006 struct hci_cp_pin_code_reply reply;
Johan Hedberg366a0332011-02-19 12:05:55 -03003007 struct pending_cmd *cmd;
Johan Hedberg980e1a52011-01-22 06:10:07 +02003008 int err;
3009
3010 BT_DBG("");
3011
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003012 hci_dev_lock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +02003013
Johan Hedberg4b34ee782012-02-21 14:13:02 +02003014 if (!hdev_is_powered(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003015 err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003016 MGMT_STATUS_NOT_POWERED);
Johan Hedberg980e1a52011-01-22 06:10:07 +02003017 goto failed;
3018 }
3019
Johan Hedbergd8457692012-02-17 14:24:57 +02003020 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
Waldemar Rymarkiewicz96d97a62011-06-01 17:28:48 +02003021 if (!conn) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003022 err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003023 MGMT_STATUS_NOT_CONNECTED);
Waldemar Rymarkiewicz96d97a62011-06-01 17:28:48 +02003024 goto failed;
3025 }
3026
3027 if (conn->pending_sec_level == BT_SECURITY_HIGH && cp->pin_len != 16) {
Johan Hedbergd8457692012-02-17 14:24:57 +02003028 struct mgmt_cp_pin_code_neg_reply ncp;
3029
3030 memcpy(&ncp.addr, &cp->addr, sizeof(ncp.addr));
Waldemar Rymarkiewicz96d97a62011-06-01 17:28:48 +02003031
3032 BT_ERR("PIN code is not 16 bytes long");
3033
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003034 err = send_pin_code_neg_reply(sk, hdev, &ncp);
Waldemar Rymarkiewicz96d97a62011-06-01 17:28:48 +02003035 if (err >= 0)
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003036 err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003037 MGMT_STATUS_INVALID_PARAMS);
Waldemar Rymarkiewicz96d97a62011-06-01 17:28:48 +02003038
3039 goto failed;
3040 }
3041
Gustavo F. Padovan00abfe42012-03-01 00:37:10 -03003042 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, data, len);
Johan Hedberg366a0332011-02-19 12:05:55 -03003043 if (!cmd) {
3044 err = -ENOMEM;
Johan Hedberg980e1a52011-01-22 06:10:07 +02003045 goto failed;
Johan Hedberg366a0332011-02-19 12:05:55 -03003046 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02003047
Johan Hedberg7776d1d2014-12-05 13:36:03 +02003048 cmd->cmd_complete = addr_cmd_complete;
3049
Johan Hedbergd8457692012-02-17 14:24:57 +02003050 bacpy(&reply.bdaddr, &cp->addr.bdaddr);
Johan Hedberg980e1a52011-01-22 06:10:07 +02003051 reply.pin_len = cp->pin_len;
Waldemar Rymarkiewicz24718ca2011-06-01 17:28:47 +02003052 memcpy(reply.pin_code, cp->pin_code, sizeof(reply.pin_code));
Johan Hedberg980e1a52011-01-22 06:10:07 +02003053
3054 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
3055 if (err < 0)
Johan Hedberga664b5b2011-02-19 12:06:02 -03003056 mgmt_pending_remove(cmd);
Johan Hedberg980e1a52011-01-22 06:10:07 +02003057
3058failed:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003059 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +02003060 return err;
3061}
3062
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003063static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data,
3064 u16 len)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003065{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03003066 struct mgmt_cp_set_io_capability *cp = data;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003067
3068 BT_DBG("");
3069
Johan Hedberg4ec86d42014-06-17 15:14:48 +03003070 if (cp->io_capability > SMP_IO_KEYBOARD_DISPLAY)
3071 return cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY,
3072 MGMT_STATUS_INVALID_PARAMS, NULL, 0);
3073
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003074 hci_dev_lock(hdev);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003075
3076 hdev->io_capability = cp->io_capability;
3077
3078 BT_DBG("%s IO capability set to 0x%02x", hdev->name,
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03003079 hdev->io_capability);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003080
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003081 hci_dev_unlock(hdev);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003082
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003083 return cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY, 0, NULL,
3084 0);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003085}
3086
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003087static struct pending_cmd *find_pairing(struct hci_conn *conn)
Johan Hedberge9a416b2011-02-19 12:05:56 -03003088{
3089 struct hci_dev *hdev = conn->hdev;
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +02003090 struct pending_cmd *cmd;
Johan Hedberge9a416b2011-02-19 12:05:56 -03003091
Johan Hedberg2e58ef32011-11-08 20:40:15 +02003092 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
Johan Hedberge9a416b2011-02-19 12:05:56 -03003093 if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
3094 continue;
3095
Johan Hedberge9a416b2011-02-19 12:05:56 -03003096 if (cmd->user_data != conn)
3097 continue;
3098
3099 return cmd;
3100 }
3101
3102 return NULL;
3103}
3104
Johan Hedberg9df74652014-12-19 22:26:03 +02003105static int pairing_complete(struct pending_cmd *cmd, u8 status)
Johan Hedberge9a416b2011-02-19 12:05:56 -03003106{
3107 struct mgmt_rp_pair_device rp;
3108 struct hci_conn *conn = cmd->user_data;
Johan Hedberg9df74652014-12-19 22:26:03 +02003109 int err;
Johan Hedberge9a416b2011-02-19 12:05:56 -03003110
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02003111 bacpy(&rp.addr.bdaddr, &conn->dst);
3112 rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
Johan Hedberge9a416b2011-02-19 12:05:56 -03003113
Johan Hedberg9df74652014-12-19 22:26:03 +02003114 err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status,
3115 &rp, sizeof(rp));
Johan Hedberge9a416b2011-02-19 12:05:56 -03003116
3117 /* So we don't get further callbacks for this connection */
3118 conn->connect_cfm_cb = NULL;
3119 conn->security_cfm_cb = NULL;
3120 conn->disconn_cfm_cb = NULL;
3121
David Herrmann76a68ba2013-04-06 20:28:37 +02003122 hci_conn_drop(conn);
Alfonso Acosta89cbb062014-10-11 21:44:47 +00003123
3124 /* The device is paired so there is no need to remove
3125 * its connection parameters anymore.
3126 */
3127 clear_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags);
Johan Hedberg15013ae2014-12-11 21:45:44 +02003128
3129 hci_conn_put(conn);
Johan Hedberg9df74652014-12-19 22:26:03 +02003130
3131 return err;
Johan Hedberge9a416b2011-02-19 12:05:56 -03003132}
3133
Johan Hedbergf4a407b2014-02-18 21:41:34 +02003134void mgmt_smp_complete(struct hci_conn *conn, bool complete)
3135{
3136 u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED;
3137 struct pending_cmd *cmd;
3138
3139 cmd = find_pairing(conn);
Johan Hedberga511b352014-12-11 21:45:45 +02003140 if (cmd) {
Johan Hedberg04ab2742014-12-05 13:36:04 +02003141 cmd->cmd_complete(cmd, status);
Johan Hedberga511b352014-12-11 21:45:45 +02003142 mgmt_pending_remove(cmd);
3143 }
Johan Hedbergf4a407b2014-02-18 21:41:34 +02003144}
3145
Johan Hedberge9a416b2011-02-19 12:05:56 -03003146static void pairing_complete_cb(struct hci_conn *conn, u8 status)
3147{
3148 struct pending_cmd *cmd;
3149
3150 BT_DBG("status %u", status);
3151
Johan Hedberg56e5cb82011-11-08 20:40:16 +02003152 cmd = find_pairing(conn);
Johan Hedberga511b352014-12-11 21:45:45 +02003153 if (!cmd) {
Johan Hedberg56e5cb82011-11-08 20:40:16 +02003154 BT_DBG("Unable to find a pending command");
Johan Hedberga511b352014-12-11 21:45:45 +02003155 return;
3156 }
3157
3158 cmd->cmd_complete(cmd, mgmt_status(status));
3159 mgmt_pending_remove(cmd);
Johan Hedberge9a416b2011-02-19 12:05:56 -03003160}
3161
Johan Hedbergf4a407b2014-02-18 21:41:34 +02003162static void le_pairing_complete_cb(struct hci_conn *conn, u8 status)
Vishal Agarwal4c47d732012-06-07 20:27:35 +05303163{
3164 struct pending_cmd *cmd;
3165
3166 BT_DBG("status %u", status);
3167
3168 if (!status)
3169 return;
3170
3171 cmd = find_pairing(conn);
Johan Hedberga511b352014-12-11 21:45:45 +02003172 if (!cmd) {
Vishal Agarwal4c47d732012-06-07 20:27:35 +05303173 BT_DBG("Unable to find a pending command");
Johan Hedberga511b352014-12-11 21:45:45 +02003174 return;
3175 }
3176
3177 cmd->cmd_complete(cmd, mgmt_status(status));
3178 mgmt_pending_remove(cmd);
Vishal Agarwal4c47d732012-06-07 20:27:35 +05303179}
3180
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003181static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003182 u16 len)
Johan Hedberge9a416b2011-02-19 12:05:56 -03003183{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03003184 struct mgmt_cp_pair_device *cp = data;
Johan Hedberg1425acb2011-11-11 00:07:35 +02003185 struct mgmt_rp_pair_device rp;
Johan Hedberge9a416b2011-02-19 12:05:56 -03003186 struct pending_cmd *cmd;
3187 u8 sec_level, auth_type;
3188 struct hci_conn *conn;
Johan Hedberge9a416b2011-02-19 12:05:56 -03003189 int err;
3190
3191 BT_DBG("");
3192
Szymon Jancf950a30e2013-01-18 12:48:07 +01003193 memset(&rp, 0, sizeof(rp));
3194 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
3195 rp.addr.type = cp->addr.type;
3196
Johan Hedberg4ee71b22013-01-20 14:27:19 +02003197 if (!bdaddr_type_is_valid(cp->addr.type))
3198 return cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
3199 MGMT_STATUS_INVALID_PARAMS,
3200 &rp, sizeof(rp));
3201
Johan Hedberg4ec86d42014-06-17 15:14:48 +03003202 if (cp->io_cap > SMP_IO_KEYBOARD_DISPLAY)
3203 return cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
3204 MGMT_STATUS_INVALID_PARAMS,
3205 &rp, sizeof(rp));
3206
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003207 hci_dev_lock(hdev);
Johan Hedberge9a416b2011-02-19 12:05:56 -03003208
Johan Hedberg5f97c1d2012-02-22 22:41:18 +02003209 if (!hdev_is_powered(hdev)) {
Szymon Jancf950a30e2013-01-18 12:48:07 +01003210 err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
3211 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
Johan Hedberg5f97c1d2012-02-22 22:41:18 +02003212 goto unlock;
3213 }
3214
Vinicius Costa Gomesc908df32011-09-02 14:51:22 -03003215 sec_level = BT_SECURITY_MEDIUM;
Mikel Astiz6fd6b912014-04-08 14:21:32 +02003216 auth_type = HCI_AT_DEDICATED_BONDING;
Johan Hedberge9a416b2011-02-19 12:05:56 -03003217
Andre Guedes6f77d8c2014-02-26 20:21:45 -03003218 if (cp->addr.type == BDADDR_BREDR) {
Andre Guedes04a6c582014-02-26 20:21:44 -03003219 conn = hci_connect_acl(hdev, &cp->addr.bdaddr, sec_level,
3220 auth_type);
Andre Guedes6f77d8c2014-02-26 20:21:45 -03003221 } else {
3222 u8 addr_type;
3223
3224 /* Convert from L2CAP channel address type to HCI address type
3225 */
3226 if (cp->addr.type == BDADDR_LE_PUBLIC)
3227 addr_type = ADDR_LE_DEV_PUBLIC;
3228 else
3229 addr_type = ADDR_LE_DEV_RANDOM;
3230
Marcel Holtmann7c264b12014-06-30 12:34:40 +02003231 /* When pairing a new device, it is expected to remember
3232 * this device for future connections. Adding the connection
3233 * parameter information ahead of time allows tracking
3234 * of the slave preferred values and will speed up any
3235 * further connection establishment.
3236 *
3237 * If connection parameters already exist, then they
3238 * will be kept and this function does nothing.
3239 */
3240 hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
3241
Andre Guedes6f77d8c2014-02-26 20:21:45 -03003242 conn = hci_connect_le(hdev, &cp->addr.bdaddr, addr_type,
Johan Hedberge804d252014-07-16 11:42:28 +03003243 sec_level, HCI_LE_CONN_TIMEOUT,
3244 HCI_ROLE_MASTER);
Andre Guedes6f77d8c2014-02-26 20:21:45 -03003245 }
Vinicius Costa Gomes7a512d02011-08-19 21:06:54 -03003246
Ville Tervo30e76272011-02-22 16:10:53 -03003247 if (IS_ERR(conn)) {
Andrzej Kaczmarek489dc482012-05-30 15:39:22 +02003248 int status;
3249
3250 if (PTR_ERR(conn) == -EBUSY)
3251 status = MGMT_STATUS_BUSY;
3252 else
3253 status = MGMT_STATUS_CONNECT_FAILED;
3254
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003255 err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
Andrzej Kaczmarek489dc482012-05-30 15:39:22 +02003256 status, &rp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003257 sizeof(rp));
Johan Hedberge9a416b2011-02-19 12:05:56 -03003258 goto unlock;
3259 }
3260
3261 if (conn->connect_cfm_cb) {
David Herrmann76a68ba2013-04-06 20:28:37 +02003262 hci_conn_drop(conn);
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003263 err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003264 MGMT_STATUS_BUSY, &rp, sizeof(rp));
Johan Hedberge9a416b2011-02-19 12:05:56 -03003265 goto unlock;
3266 }
3267
Johan Hedberg2e58ef32011-11-08 20:40:15 +02003268 cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len);
Johan Hedberge9a416b2011-02-19 12:05:56 -03003269 if (!cmd) {
3270 err = -ENOMEM;
David Herrmann76a68ba2013-04-06 20:28:37 +02003271 hci_conn_drop(conn);
Johan Hedberge9a416b2011-02-19 12:05:56 -03003272 goto unlock;
3273 }
3274
Johan Hedberg04ab2742014-12-05 13:36:04 +02003275 cmd->cmd_complete = pairing_complete;
3276
Vinicius Costa Gomes7a512d02011-08-19 21:06:54 -03003277 /* For LE, just connecting isn't a proof that the pairing finished */
Johan Hedbergf4a407b2014-02-18 21:41:34 +02003278 if (cp->addr.type == BDADDR_BREDR) {
Vinicius Costa Gomes7a512d02011-08-19 21:06:54 -03003279 conn->connect_cfm_cb = pairing_complete_cb;
Johan Hedbergf4a407b2014-02-18 21:41:34 +02003280 conn->security_cfm_cb = pairing_complete_cb;
3281 conn->disconn_cfm_cb = pairing_complete_cb;
3282 } else {
3283 conn->connect_cfm_cb = le_pairing_complete_cb;
3284 conn->security_cfm_cb = le_pairing_complete_cb;
3285 conn->disconn_cfm_cb = le_pairing_complete_cb;
3286 }
Vinicius Costa Gomes7a512d02011-08-19 21:06:54 -03003287
Johan Hedberge9a416b2011-02-19 12:05:56 -03003288 conn->io_capability = cp->io_cap;
Johan Hedbergf8aaf9b2014-08-17 23:28:57 +03003289 cmd->user_data = hci_conn_get(conn);
Johan Hedberge9a416b2011-02-19 12:05:56 -03003290
Johan Hedberg6f78fd42014-07-30 08:35:48 +03003291 if ((conn->state == BT_CONNECTED || conn->state == BT_CONFIG) &&
Johan Hedberga511b352014-12-11 21:45:45 +02003292 hci_conn_security(conn, sec_level, auth_type, true)) {
3293 cmd->cmd_complete(cmd, 0);
3294 mgmt_pending_remove(cmd);
3295 }
Johan Hedberge9a416b2011-02-19 12:05:56 -03003296
3297 err = 0;
3298
3299unlock:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003300 hci_dev_unlock(hdev);
Johan Hedberge9a416b2011-02-19 12:05:56 -03003301 return err;
3302}
3303
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003304static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
3305 u16 len)
Johan Hedberg28424702012-02-02 04:02:29 +02003306{
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02003307 struct mgmt_addr_info *addr = data;
Johan Hedberg28424702012-02-02 04:02:29 +02003308 struct pending_cmd *cmd;
3309 struct hci_conn *conn;
3310 int err;
3311
3312 BT_DBG("");
3313
Johan Hedberg28424702012-02-02 04:02:29 +02003314 hci_dev_lock(hdev);
3315
Johan Hedberg5f97c1d2012-02-22 22:41:18 +02003316 if (!hdev_is_powered(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003317 err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003318 MGMT_STATUS_NOT_POWERED);
Johan Hedberg5f97c1d2012-02-22 22:41:18 +02003319 goto unlock;
3320 }
3321
Johan Hedberg28424702012-02-02 04:02:29 +02003322 cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev);
3323 if (!cmd) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003324 err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003325 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg28424702012-02-02 04:02:29 +02003326 goto unlock;
3327 }
3328
3329 conn = cmd->user_data;
3330
3331 if (bacmp(&addr->bdaddr, &conn->dst) != 0) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003332 err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003333 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg28424702012-02-02 04:02:29 +02003334 goto unlock;
3335 }
3336
Johan Hedberga511b352014-12-11 21:45:45 +02003337 cmd->cmd_complete(cmd, MGMT_STATUS_CANCELLED);
3338 mgmt_pending_remove(cmd);
Johan Hedberg28424702012-02-02 04:02:29 +02003339
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003340 err = cmd_complete(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003341 addr, sizeof(*addr));
Johan Hedberg28424702012-02-02 04:02:29 +02003342unlock:
3343 hci_dev_unlock(hdev);
Johan Hedberg28424702012-02-02 04:02:29 +02003344 return err;
3345}
3346
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003347static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
Johan Hedberg1707c602013-03-15 17:07:15 -05003348 struct mgmt_addr_info *addr, u16 mgmt_op,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003349 u16 hci_op, __le32 passkey)
Johan Hedberga5c29682011-02-19 12:05:57 -03003350{
Johan Hedberga5c29682011-02-19 12:05:57 -03003351 struct pending_cmd *cmd;
Brian Gix0df4c182011-11-16 13:53:13 -08003352 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003353 int err;
3354
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003355 hci_dev_lock(hdev);
Johan Hedberg08ba5382011-03-16 14:29:34 +02003356
Johan Hedberg4b34ee782012-02-21 14:13:02 +02003357 if (!hdev_is_powered(hdev)) {
Johan Hedbergfeb94d32013-03-15 17:07:16 -05003358 err = cmd_complete(sk, hdev->id, mgmt_op,
3359 MGMT_STATUS_NOT_POWERED, addr,
3360 sizeof(*addr));
Brian Gix0df4c182011-11-16 13:53:13 -08003361 goto done;
Johan Hedberga5c29682011-02-19 12:05:57 -03003362 }
3363
Johan Hedberg1707c602013-03-15 17:07:15 -05003364 if (addr->type == BDADDR_BREDR)
3365 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &addr->bdaddr);
Johan Hedberg272d90d2012-02-09 15:26:12 +02003366 else
Johan Hedberg1707c602013-03-15 17:07:15 -05003367 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &addr->bdaddr);
Brian Gix47c15e22011-11-16 13:53:14 -08003368
Johan Hedberg272d90d2012-02-09 15:26:12 +02003369 if (!conn) {
Johan Hedbergfeb94d32013-03-15 17:07:16 -05003370 err = cmd_complete(sk, hdev->id, mgmt_op,
3371 MGMT_STATUS_NOT_CONNECTED, addr,
3372 sizeof(*addr));
Johan Hedberg272d90d2012-02-09 15:26:12 +02003373 goto done;
3374 }
3375
Johan Hedberg1707c602013-03-15 17:07:15 -05003376 if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
Brian Gix5fe57d92011-12-21 16:12:13 -08003377 err = smp_user_confirm_reply(conn, mgmt_op, passkey);
Brian Gix5fe57d92011-12-21 16:12:13 -08003378 if (!err)
Johan Hedbergfeb94d32013-03-15 17:07:16 -05003379 err = cmd_complete(sk, hdev->id, mgmt_op,
3380 MGMT_STATUS_SUCCESS, addr,
3381 sizeof(*addr));
Brian Gix5fe57d92011-12-21 16:12:13 -08003382 else
Johan Hedbergfeb94d32013-03-15 17:07:16 -05003383 err = cmd_complete(sk, hdev->id, mgmt_op,
3384 MGMT_STATUS_FAILED, addr,
3385 sizeof(*addr));
Brian Gix5fe57d92011-12-21 16:12:13 -08003386
Brian Gix47c15e22011-11-16 13:53:14 -08003387 goto done;
3388 }
3389
Johan Hedberg1707c602013-03-15 17:07:15 -05003390 cmd = mgmt_pending_add(sk, mgmt_op, hdev, addr, sizeof(*addr));
Johan Hedberga5c29682011-02-19 12:05:57 -03003391 if (!cmd) {
3392 err = -ENOMEM;
Brian Gix0df4c182011-11-16 13:53:13 -08003393 goto done;
Johan Hedberga5c29682011-02-19 12:05:57 -03003394 }
3395
Johan Hedberg7776d1d2014-12-05 13:36:03 +02003396 cmd->cmd_complete = addr_cmd_complete;
3397
Brian Gix0df4c182011-11-16 13:53:13 -08003398 /* Continue with pairing via HCI */
Brian Gix604086b2011-11-23 08:28:33 -08003399 if (hci_op == HCI_OP_USER_PASSKEY_REPLY) {
3400 struct hci_cp_user_passkey_reply cp;
3401
Johan Hedberg1707c602013-03-15 17:07:15 -05003402 bacpy(&cp.bdaddr, &addr->bdaddr);
Brian Gix604086b2011-11-23 08:28:33 -08003403 cp.passkey = passkey;
3404 err = hci_send_cmd(hdev, hci_op, sizeof(cp), &cp);
3405 } else
Johan Hedberg1707c602013-03-15 17:07:15 -05003406 err = hci_send_cmd(hdev, hci_op, sizeof(addr->bdaddr),
3407 &addr->bdaddr);
Brian Gix604086b2011-11-23 08:28:33 -08003408
Johan Hedberga664b5b2011-02-19 12:06:02 -03003409 if (err < 0)
3410 mgmt_pending_remove(cmd);
Johan Hedberga5c29682011-02-19 12:05:57 -03003411
Brian Gix0df4c182011-11-16 13:53:13 -08003412done:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003413 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03003414 return err;
3415}
3416
Jaganath Kanakkasseryafeb0192012-07-09 16:11:51 +05303417static int pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev,
3418 void *data, u16 len)
3419{
3420 struct mgmt_cp_pin_code_neg_reply *cp = data;
3421
3422 BT_DBG("");
3423
Johan Hedberg1707c602013-03-15 17:07:15 -05003424 return user_pairing_resp(sk, hdev, &cp->addr,
Jaganath Kanakkasseryafeb0192012-07-09 16:11:51 +05303425 MGMT_OP_PIN_CODE_NEG_REPLY,
3426 HCI_OP_PIN_CODE_NEG_REPLY, 0);
3427}
3428
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003429static int user_confirm_reply(struct sock *sk, struct hci_dev *hdev, void *data,
3430 u16 len)
Brian Gix0df4c182011-11-16 13:53:13 -08003431{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03003432 struct mgmt_cp_user_confirm_reply *cp = data;
Brian Gix0df4c182011-11-16 13:53:13 -08003433
3434 BT_DBG("");
3435
3436 if (len != sizeof(*cp))
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003437 return cmd_status(sk, hdev->id, MGMT_OP_USER_CONFIRM_REPLY,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003438 MGMT_STATUS_INVALID_PARAMS);
Brian Gix0df4c182011-11-16 13:53:13 -08003439
Johan Hedberg1707c602013-03-15 17:07:15 -05003440 return user_pairing_resp(sk, hdev, &cp->addr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003441 MGMT_OP_USER_CONFIRM_REPLY,
3442 HCI_OP_USER_CONFIRM_REPLY, 0);
Brian Gix0df4c182011-11-16 13:53:13 -08003443}
3444
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003445static int user_confirm_neg_reply(struct sock *sk, struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003446 void *data, u16 len)
Brian Gix0df4c182011-11-16 13:53:13 -08003447{
Johan Hedbergc9c26592011-12-15 00:47:41 +02003448 struct mgmt_cp_user_confirm_neg_reply *cp = data;
Brian Gix0df4c182011-11-16 13:53:13 -08003449
3450 BT_DBG("");
3451
Johan Hedberg1707c602013-03-15 17:07:15 -05003452 return user_pairing_resp(sk, hdev, &cp->addr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003453 MGMT_OP_USER_CONFIRM_NEG_REPLY,
3454 HCI_OP_USER_CONFIRM_NEG_REPLY, 0);
Brian Gix0df4c182011-11-16 13:53:13 -08003455}
3456
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003457static int user_passkey_reply(struct sock *sk, struct hci_dev *hdev, void *data,
3458 u16 len)
Brian Gix604086b2011-11-23 08:28:33 -08003459{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03003460 struct mgmt_cp_user_passkey_reply *cp = data;
Brian Gix604086b2011-11-23 08:28:33 -08003461
3462 BT_DBG("");
3463
Johan Hedberg1707c602013-03-15 17:07:15 -05003464 return user_pairing_resp(sk, hdev, &cp->addr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003465 MGMT_OP_USER_PASSKEY_REPLY,
3466 HCI_OP_USER_PASSKEY_REPLY, cp->passkey);
Brian Gix604086b2011-11-23 08:28:33 -08003467}
3468
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003469static int user_passkey_neg_reply(struct sock *sk, struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003470 void *data, u16 len)
Brian Gix604086b2011-11-23 08:28:33 -08003471{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03003472 struct mgmt_cp_user_passkey_neg_reply *cp = data;
Brian Gix604086b2011-11-23 08:28:33 -08003473
3474 BT_DBG("");
3475
Johan Hedberg1707c602013-03-15 17:07:15 -05003476 return user_pairing_resp(sk, hdev, &cp->addr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003477 MGMT_OP_USER_PASSKEY_NEG_REPLY,
3478 HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
Brian Gix604086b2011-11-23 08:28:33 -08003479}
3480
Johan Hedberg13928972013-03-15 17:07:00 -05003481static void update_name(struct hci_request *req)
Johan Hedberg2b4bf392012-03-03 00:19:06 +02003482{
Johan Hedberg13928972013-03-15 17:07:00 -05003483 struct hci_dev *hdev = req->hdev;
Johan Hedberg2b4bf392012-03-03 00:19:06 +02003484 struct hci_cp_write_local_name cp;
3485
Johan Hedberg13928972013-03-15 17:07:00 -05003486 memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
Johan Hedberg2b4bf392012-03-03 00:19:06 +02003487
Johan Hedberg890ea892013-03-15 17:06:52 -05003488 hci_req_add(req, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
Johan Hedberg2b4bf392012-03-03 00:19:06 +02003489}
3490
Marcel Holtmann1904a852015-01-11 13:50:44 -08003491static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg13928972013-03-15 17:07:00 -05003492{
3493 struct mgmt_cp_set_local_name *cp;
3494 struct pending_cmd *cmd;
3495
3496 BT_DBG("status 0x%02x", status);
3497
3498 hci_dev_lock(hdev);
3499
3500 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev);
3501 if (!cmd)
3502 goto unlock;
3503
3504 cp = cmd->param;
3505
3506 if (status)
3507 cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
3508 mgmt_status(status));
3509 else
3510 cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
3511 cp, sizeof(*cp));
3512
3513 mgmt_pending_remove(cmd);
3514
3515unlock:
3516 hci_dev_unlock(hdev);
3517}
3518
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003519static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003520 u16 len)
Johan Hedbergb312b1612011-03-16 14:29:37 +02003521{
Johan Hedberg2b4bf392012-03-03 00:19:06 +02003522 struct mgmt_cp_set_local_name *cp = data;
Johan Hedbergb312b1612011-03-16 14:29:37 +02003523 struct pending_cmd *cmd;
Johan Hedberg890ea892013-03-15 17:06:52 -05003524 struct hci_request req;
Johan Hedbergb312b1612011-03-16 14:29:37 +02003525 int err;
3526
3527 BT_DBG("");
3528
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003529 hci_dev_lock(hdev);
Johan Hedbergb312b1612011-03-16 14:29:37 +02003530
Johan Hedbergb3f2ca92013-03-15 17:07:03 -05003531 /* If the old values are the same as the new ones just return a
3532 * direct command complete event.
3533 */
3534 if (!memcmp(hdev->dev_name, cp->name, sizeof(hdev->dev_name)) &&
3535 !memcmp(hdev->short_name, cp->short_name,
3536 sizeof(hdev->short_name))) {
3537 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
3538 data, len);
3539 goto failed;
3540 }
3541
Johan Hedberg2b4bf392012-03-03 00:19:06 +02003542 memcpy(hdev->short_name, cp->short_name, sizeof(hdev->short_name));
Johan Hedberg28cc7bd2012-02-22 21:06:55 +02003543
Johan Hedbergb5235a62012-02-21 14:32:24 +02003544 if (!hdev_is_powered(hdev)) {
Johan Hedberg2b4bf392012-03-03 00:19:06 +02003545 memcpy(hdev->dev_name, cp->name, sizeof(hdev->dev_name));
Johan Hedberg28cc7bd2012-02-22 21:06:55 +02003546
3547 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003548 data, len);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +02003549 if (err < 0)
3550 goto failed;
3551
3552 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, data, len,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003553 sk);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +02003554
Johan Hedbergb5235a62012-02-21 14:32:24 +02003555 goto failed;
3556 }
3557
Johan Hedberg28cc7bd2012-02-22 21:06:55 +02003558 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len);
Johan Hedbergb312b1612011-03-16 14:29:37 +02003559 if (!cmd) {
3560 err = -ENOMEM;
3561 goto failed;
3562 }
3563
Johan Hedberg13928972013-03-15 17:07:00 -05003564 memcpy(hdev->dev_name, cp->name, sizeof(hdev->dev_name));
3565
Johan Hedberg890ea892013-03-15 17:06:52 -05003566 hci_req_init(&req, hdev);
Johan Hedberg3f985052013-03-15 17:07:02 -05003567
3568 if (lmp_bredr_capable(hdev)) {
3569 update_name(&req);
3570 update_eir(&req);
3571 }
3572
Marcel Holtmann7a5f4992013-10-16 00:16:49 -07003573 /* The name is stored in the scan response data and so
3574 * no need to udpate the advertising data here.
3575 */
Johan Hedberg3f985052013-03-15 17:07:02 -05003576 if (lmp_le_capable(hdev))
Marcel Holtmann7a5f4992013-10-16 00:16:49 -07003577 update_scan_rsp_data(&req);
Johan Hedberg3f985052013-03-15 17:07:02 -05003578
Johan Hedberg13928972013-03-15 17:07:00 -05003579 err = hci_req_run(&req, set_name_complete);
Johan Hedbergb312b1612011-03-16 14:29:37 +02003580 if (err < 0)
3581 mgmt_pending_remove(cmd);
3582
3583failed:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003584 hci_dev_unlock(hdev);
Johan Hedbergb312b1612011-03-16 14:29:37 +02003585 return err;
3586}
3587
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02003588static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003589 void *data, u16 data_len)
Szymon Jancc35938b2011-03-22 13:12:21 +01003590{
Szymon Jancc35938b2011-03-22 13:12:21 +01003591 struct pending_cmd *cmd;
3592 int err;
3593
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003594 BT_DBG("%s", hdev->name);
Szymon Jancc35938b2011-03-22 13:12:21 +01003595
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003596 hci_dev_lock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01003597
Johan Hedberg4b34ee782012-02-21 14:13:02 +02003598 if (!hdev_is_powered(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003599 err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003600 MGMT_STATUS_NOT_POWERED);
Szymon Jancc35938b2011-03-22 13:12:21 +01003601 goto unlock;
3602 }
3603
Andre Guedes9a1a1992012-07-24 15:03:48 -03003604 if (!lmp_ssp_capable(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003605 err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003606 MGMT_STATUS_NOT_SUPPORTED);
Szymon Jancc35938b2011-03-22 13:12:21 +01003607 goto unlock;
3608 }
3609
Johan Hedberg2e58ef32011-11-08 20:40:15 +02003610 if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003611 err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003612 MGMT_STATUS_BUSY);
Szymon Jancc35938b2011-03-22 13:12:21 +01003613 goto unlock;
3614 }
3615
Johan Hedberg2e58ef32011-11-08 20:40:15 +02003616 cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0);
Szymon Jancc35938b2011-03-22 13:12:21 +01003617 if (!cmd) {
3618 err = -ENOMEM;
3619 goto unlock;
3620 }
3621
Johan Hedberg710f11c2014-05-26 11:21:22 +03003622 if (bredr_sc_enabled(hdev))
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08003623 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_EXT_DATA,
3624 0, NULL);
3625 else
3626 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
3627
Szymon Jancc35938b2011-03-22 13:12:21 +01003628 if (err < 0)
3629 mgmt_pending_remove(cmd);
3630
3631unlock:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003632 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01003633 return err;
3634}
3635
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003636static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003637 void *data, u16 len)
Szymon Janc2763eda2011-03-22 13:12:22 +01003638{
Johan Hedberg5d57e792015-01-23 10:10:38 +02003639 struct mgmt_addr_info *addr = data;
Szymon Janc2763eda2011-03-22 13:12:22 +01003640 int err;
3641
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003642 BT_DBG("%s ", hdev->name);
Szymon Janc2763eda2011-03-22 13:12:22 +01003643
Johan Hedberg5d57e792015-01-23 10:10:38 +02003644 if (!bdaddr_type_is_valid(addr->type))
3645 return cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
3646 MGMT_STATUS_INVALID_PARAMS, addr,
3647 sizeof(*addr));
3648
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003649 hci_dev_lock(hdev);
Szymon Janc2763eda2011-03-22 13:12:22 +01003650
Marcel Holtmannec109112014-01-10 02:07:30 -08003651 if (len == MGMT_ADD_REMOTE_OOB_DATA_SIZE) {
3652 struct mgmt_cp_add_remote_oob_data *cp = data;
3653 u8 status;
Johan Hedbergbf1e3542012-02-19 13:16:14 +02003654
Johan Hedbergc19a4952014-11-17 20:52:19 +02003655 if (cp->addr.type != BDADDR_BREDR) {
3656 err = cmd_complete(sk, hdev->id,
3657 MGMT_OP_ADD_REMOTE_OOB_DATA,
3658 MGMT_STATUS_INVALID_PARAMS,
3659 &cp->addr, sizeof(cp->addr));
3660 goto unlock;
3661 }
3662
Marcel Holtmannec109112014-01-10 02:07:30 -08003663 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr,
Johan Hedberg6928a922014-10-26 20:46:09 +01003664 cp->addr.type, cp->hash,
3665 cp->rand, NULL, NULL);
Marcel Holtmannec109112014-01-10 02:07:30 -08003666 if (err < 0)
3667 status = MGMT_STATUS_FAILED;
3668 else
3669 status = MGMT_STATUS_SUCCESS;
3670
3671 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
3672 status, &cp->addr, sizeof(cp->addr));
3673 } else if (len == MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE) {
3674 struct mgmt_cp_add_remote_oob_ext_data *cp = data;
Johan Hedberg86df9202014-10-26 20:52:27 +01003675 u8 *rand192, *hash192;
Marcel Holtmannec109112014-01-10 02:07:30 -08003676 u8 status;
3677
Johan Hedberg86df9202014-10-26 20:52:27 +01003678 if (bdaddr_type_is_le(cp->addr.type)) {
Johan Hedbergd25b78e2015-01-27 12:55:52 +02003679 /* Enforce zero-valued 192-bit parameters as
3680 * long as legacy SMP OOB isn't implemented.
3681 */
3682 if (memcmp(cp->rand192, ZERO_KEY, 16) ||
3683 memcmp(cp->hash192, ZERO_KEY, 16)) {
3684 err = cmd_complete(sk, hdev->id,
3685 MGMT_OP_ADD_REMOTE_OOB_DATA,
3686 MGMT_STATUS_INVALID_PARAMS,
3687 addr, sizeof(*addr));
3688 goto unlock;
3689 }
3690
Johan Hedberg86df9202014-10-26 20:52:27 +01003691 rand192 = NULL;
3692 hash192 = NULL;
3693 } else {
3694 rand192 = cp->rand192;
3695 hash192 = cp->hash192;
3696 }
3697
Johan Hedberg81328d52014-10-26 20:33:47 +01003698 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr,
Johan Hedberg86df9202014-10-26 20:52:27 +01003699 cp->addr.type, hash192, rand192,
3700 cp->hash256, cp->rand256);
Marcel Holtmannec109112014-01-10 02:07:30 -08003701 if (err < 0)
3702 status = MGMT_STATUS_FAILED;
3703 else
3704 status = MGMT_STATUS_SUCCESS;
3705
3706 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
3707 status, &cp->addr, sizeof(cp->addr));
3708 } else {
3709 BT_ERR("add_remote_oob_data: invalid length of %u bytes", len);
3710 err = cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
3711 MGMT_STATUS_INVALID_PARAMS);
3712 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003713
Johan Hedbergc19a4952014-11-17 20:52:19 +02003714unlock:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003715 hci_dev_unlock(hdev);
Szymon Janc2763eda2011-03-22 13:12:22 +01003716 return err;
3717}
3718
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003719static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03003720 void *data, u16 len)
Szymon Janc2763eda2011-03-22 13:12:22 +01003721{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03003722 struct mgmt_cp_remove_remote_oob_data *cp = data;
Johan Hedbergbf1e3542012-02-19 13:16:14 +02003723 u8 status;
Szymon Janc2763eda2011-03-22 13:12:22 +01003724 int err;
3725
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003726 BT_DBG("%s", hdev->name);
Szymon Janc2763eda2011-03-22 13:12:22 +01003727
Johan Hedbergc19a4952014-11-17 20:52:19 +02003728 if (cp->addr.type != BDADDR_BREDR)
3729 return cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
3730 MGMT_STATUS_INVALID_PARAMS,
3731 &cp->addr, sizeof(cp->addr));
3732
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003733 hci_dev_lock(hdev);
Szymon Janc2763eda2011-03-22 13:12:22 +01003734
Johan Hedbergeedbd582014-11-15 09:34:23 +02003735 if (!bacmp(&cp->addr.bdaddr, BDADDR_ANY)) {
3736 hci_remote_oob_data_clear(hdev);
3737 status = MGMT_STATUS_SUCCESS;
3738 goto done;
3739 }
3740
Johan Hedberg6928a922014-10-26 20:46:09 +01003741 err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr, cp->addr.type);
Szymon Janc2763eda2011-03-22 13:12:22 +01003742 if (err < 0)
Johan Hedbergbf1e3542012-02-19 13:16:14 +02003743 status = MGMT_STATUS_INVALID_PARAMS;
Szymon Janc2763eda2011-03-22 13:12:22 +01003744 else
Szymon Janca6785be2012-12-13 15:11:21 +01003745 status = MGMT_STATUS_SUCCESS;
Johan Hedbergbf1e3542012-02-19 13:16:14 +02003746
Johan Hedbergeedbd582014-11-15 09:34:23 +02003747done:
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003748 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003749 status, &cp->addr, sizeof(cp->addr));
Szymon Janc2763eda2011-03-22 13:12:22 +01003750
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003751 hci_dev_unlock(hdev);
Szymon Janc2763eda2011-03-22 13:12:22 +01003752 return err;
3753}
3754
Marcel Holtmann80190442014-12-04 11:36:36 +01003755static bool trigger_discovery(struct hci_request *req, u8 *status)
Andre Guedes41dc2bd2013-04-30 15:29:30 -03003756{
Marcel Holtmann80190442014-12-04 11:36:36 +01003757 struct hci_dev *hdev = req->hdev;
3758 struct hci_cp_le_set_scan_param param_cp;
3759 struct hci_cp_le_set_scan_enable enable_cp;
3760 struct hci_cp_inquiry inq_cp;
3761 /* General inquiry access code (GIAC) */
3762 u8 lap[3] = { 0x33, 0x8b, 0x9e };
3763 u8 own_addr_type;
Andre Guedes41dc2bd2013-04-30 15:29:30 -03003764 int err;
3765
Marcel Holtmann80190442014-12-04 11:36:36 +01003766 switch (hdev->discovery.type) {
3767 case DISCOV_TYPE_BREDR:
3768 *status = mgmt_bredr_support(hdev);
3769 if (*status)
3770 return false;
Andre Guedes41dc2bd2013-04-30 15:29:30 -03003771
Marcel Holtmann80190442014-12-04 11:36:36 +01003772 if (test_bit(HCI_INQUIRY, &hdev->flags)) {
3773 *status = MGMT_STATUS_BUSY;
3774 return false;
3775 }
Andre Guedes41dc2bd2013-04-30 15:29:30 -03003776
Marcel Holtmann80190442014-12-04 11:36:36 +01003777 hci_inquiry_cache_flush(hdev);
Andre Guedes41dc2bd2013-04-30 15:29:30 -03003778
Marcel Holtmann80190442014-12-04 11:36:36 +01003779 memset(&inq_cp, 0, sizeof(inq_cp));
3780 memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap));
3781 inq_cp.length = DISCOV_BREDR_INQUIRY_LEN;
3782 hci_req_add(req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp);
3783 break;
Andre Guedes41dc2bd2013-04-30 15:29:30 -03003784
Marcel Holtmann80190442014-12-04 11:36:36 +01003785 case DISCOV_TYPE_LE:
3786 case DISCOV_TYPE_INTERLEAVED:
3787 *status = mgmt_le_support(hdev);
3788 if (*status)
3789 return false;
3790
3791 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
3792 !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
3793 *status = MGMT_STATUS_NOT_SUPPORTED;
3794 return false;
3795 }
3796
3797 if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) {
3798 /* Don't let discovery abort an outgoing
3799 * connection attempt that's using directed
3800 * advertising.
3801 */
3802 if (hci_conn_hash_lookup_state(hdev, LE_LINK,
3803 BT_CONNECT)) {
3804 *status = MGMT_STATUS_REJECTED;
3805 return false;
3806 }
3807
3808 disable_advertising(req);
3809 }
3810
3811 /* If controller is scanning, it means the background scanning
3812 * is running. Thus, we should temporarily stop it in order to
3813 * set the discovery scanning parameters.
3814 */
3815 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
3816 hci_req_add_le_scan_disable(req);
3817
3818 memset(&param_cp, 0, sizeof(param_cp));
3819
3820 /* All active scans will be done with either a resolvable
3821 * private address (when privacy feature has been enabled)
Marcel Holtmann9437d2e2014-12-07 20:13:17 +01003822 * or non-resolvable private address.
Marcel Holtmann80190442014-12-04 11:36:36 +01003823 */
3824 err = hci_update_random_address(req, true, &own_addr_type);
3825 if (err < 0) {
3826 *status = MGMT_STATUS_FAILED;
3827 return false;
3828 }
3829
3830 param_cp.type = LE_SCAN_ACTIVE;
3831 param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT);
3832 param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
3833 param_cp.own_address_type = own_addr_type;
3834 hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
3835 &param_cp);
3836
3837 memset(&enable_cp, 0, sizeof(enable_cp));
3838 enable_cp.enable = LE_SCAN_ENABLE;
3839 enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
3840 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
3841 &enable_cp);
3842 break;
3843
3844 default:
3845 *status = MGMT_STATUS_INVALID_PARAMS;
3846 return false;
3847 }
3848
3849 return true;
Andre Guedes41dc2bd2013-04-30 15:29:30 -03003850}
3851
Marcel Holtmann1904a852015-01-11 13:50:44 -08003852static void start_discovery_complete(struct hci_dev *hdev, u8 status,
3853 u16 opcode)
Andre Guedes7c307722013-04-30 15:29:28 -03003854{
Marcel Holtmann11e6e252014-12-04 11:36:35 +01003855 struct pending_cmd *cmd;
3856 unsigned long timeout;
Lukasz Rymanowskiae55f592014-03-27 20:55:19 +01003857
Andre Guedes7c307722013-04-30 15:29:28 -03003858 BT_DBG("status %d", status);
3859
Marcel Holtmann11e6e252014-12-04 11:36:35 +01003860 hci_dev_lock(hdev);
3861
3862 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
Jakub Pawlowski66ea9422014-12-05 10:55:59 +01003863 if (!cmd)
3864 cmd = mgmt_pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev);
3865
Marcel Holtmann11e6e252014-12-04 11:36:35 +01003866 if (cmd) {
Johan Hedberg2922a942014-12-05 13:36:06 +02003867 cmd->cmd_complete(cmd, mgmt_status(status));
Marcel Holtmann11e6e252014-12-04 11:36:35 +01003868 mgmt_pending_remove(cmd);
Andre Guedes7c307722013-04-30 15:29:28 -03003869 }
3870
Marcel Holtmann11e6e252014-12-04 11:36:35 +01003871 if (status) {
3872 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
3873 goto unlock;
3874 }
3875
Andre Guedes7c307722013-04-30 15:29:28 -03003876 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedes7c307722013-04-30 15:29:28 -03003877
3878 switch (hdev->discovery.type) {
3879 case DISCOV_TYPE_LE:
Lukasz Rymanowski3d5a76f2014-03-27 20:55:21 +01003880 timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT);
Andre Guedes7c307722013-04-30 15:29:28 -03003881 break;
Andre Guedes7c307722013-04-30 15:29:28 -03003882 case DISCOV_TYPE_INTERLEAVED:
Lukasz Rymanowskib9a7a612014-03-27 20:55:20 +01003883 timeout = msecs_to_jiffies(hdev->discov_interleaved_timeout);
Andre Guedes7c307722013-04-30 15:29:28 -03003884 break;
Andre Guedes7c307722013-04-30 15:29:28 -03003885 case DISCOV_TYPE_BREDR:
Marcel Holtmann11e6e252014-12-04 11:36:35 +01003886 timeout = 0;
Andre Guedes7c307722013-04-30 15:29:28 -03003887 break;
Andre Guedes7c307722013-04-30 15:29:28 -03003888 default:
3889 BT_ERR("Invalid discovery type %d", hdev->discovery.type);
Marcel Holtmann11e6e252014-12-04 11:36:35 +01003890 timeout = 0;
3891 break;
Andre Guedes7c307722013-04-30 15:29:28 -03003892 }
Lukasz Rymanowskiae55f592014-03-27 20:55:19 +01003893
Marcel Holtmann11e6e252014-12-04 11:36:35 +01003894 if (timeout)
3895 queue_delayed_work(hdev->workqueue,
3896 &hdev->le_scan_disable, timeout);
Lukasz Rymanowskiae55f592014-03-27 20:55:19 +01003897
Marcel Holtmann11e6e252014-12-04 11:36:35 +01003898unlock:
3899 hci_dev_unlock(hdev);
Andre Guedes7c307722013-04-30 15:29:28 -03003900}
3901
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003902static int start_discovery(struct sock *sk, struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003903 void *data, u16 len)
Johan Hedberg14a53662011-04-27 10:29:56 -04003904{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03003905 struct mgmt_cp_start_discovery *cp = data;
Johan Hedberg14a53662011-04-27 10:29:56 -04003906 struct pending_cmd *cmd;
Andre Guedes7c307722013-04-30 15:29:28 -03003907 struct hci_request req;
Marcel Holtmann80190442014-12-04 11:36:36 +01003908 u8 status;
Johan Hedberg14a53662011-04-27 10:29:56 -04003909 int err;
3910
Johan Hedbergbdb6d972012-02-28 06:13:32 +02003911 BT_DBG("%s", hdev->name);
Johan Hedberg14a53662011-04-27 10:29:56 -04003912
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003913 hci_dev_lock(hdev);
Johan Hedberg14a53662011-04-27 10:29:56 -04003914
Johan Hedberg4b34ee782012-02-21 14:13:02 +02003915 if (!hdev_is_powered(hdev)) {
Szymon Janca736abc2014-11-03 14:20:56 +01003916 err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
3917 MGMT_STATUS_NOT_POWERED,
3918 &cp->type, sizeof(cp->type));
Johan Hedbergbd2d1332011-11-07 23:13:37 +02003919 goto failed;
3920 }
3921
Marcel Holtmannf5a969f2014-12-04 11:36:34 +01003922 if (hdev->discovery.state != DISCOVERY_STOPPED ||
3923 test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) {
Szymon Janca736abc2014-11-03 14:20:56 +01003924 err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
3925 MGMT_STATUS_BUSY, &cp->type,
3926 sizeof(cp->type));
Andre Guedes642be6c2012-03-21 00:03:37 -03003927 goto failed;
3928 }
3929
Johan Hedberg2922a942014-12-05 13:36:06 +02003930 cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, data, len);
Johan Hedberg14a53662011-04-27 10:29:56 -04003931 if (!cmd) {
3932 err = -ENOMEM;
3933 goto failed;
3934 }
3935
Johan Hedberg2922a942014-12-05 13:36:06 +02003936 cmd->cmd_complete = generic_cmd_complete;
3937
Marcel Holtmann22078802014-12-05 11:45:22 +01003938 /* Clear the discovery filter first to free any previously
3939 * allocated memory for the UUID list.
3940 */
3941 hci_discovery_filter_clear(hdev);
3942
Andre Guedes4aab14e2012-02-17 20:39:36 -03003943 hdev->discovery.type = cp->type;
Marcel Holtmannda25cf62014-12-05 13:03:35 +01003944 hdev->discovery.report_invalid_rssi = false;
Andre Guedes4aab14e2012-02-17 20:39:36 -03003945
Andre Guedes7c307722013-04-30 15:29:28 -03003946 hci_req_init(&req, hdev);
3947
Marcel Holtmann80190442014-12-04 11:36:36 +01003948 if (!trigger_discovery(&req, &status)) {
Szymon Janca736abc2014-11-03 14:20:56 +01003949 err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
Marcel Holtmann80190442014-12-04 11:36:36 +01003950 status, &cp->type, sizeof(cp->type));
Johan Hedberg04106752013-01-10 14:54:09 +02003951 mgmt_pending_remove(cmd);
3952 goto failed;
Andre Guedesf39799f2012-02-17 20:39:35 -03003953 }
Andre Guedes3fd24152012-02-03 17:48:01 -03003954
Andre Guedes7c307722013-04-30 15:29:28 -03003955 err = hci_req_run(&req, start_discovery_complete);
Marcel Holtmannf5a969f2014-12-04 11:36:34 +01003956 if (err < 0) {
Johan Hedberg14a53662011-04-27 10:29:56 -04003957 mgmt_pending_remove(cmd);
Marcel Holtmannf5a969f2014-12-04 11:36:34 +01003958 goto failed;
3959 }
3960
3961 hci_discovery_set_state(hdev, DISCOVERY_STARTING);
Johan Hedberg14a53662011-04-27 10:29:56 -04003962
3963failed:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03003964 hci_dev_unlock(hdev);
Johan Hedberg14a53662011-04-27 10:29:56 -04003965 return err;
3966}
3967
Johan Hedberg9df74652014-12-19 22:26:03 +02003968static int service_discovery_cmd_complete(struct pending_cmd *cmd, u8 status)
Andre Guedes1183fdc2013-04-30 15:29:35 -03003969{
Johan Hedberg9df74652014-12-19 22:26:03 +02003970 return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
3971 cmd->param, 1);
Johan Hedberg2922a942014-12-05 13:36:06 +02003972}
3973
Jakub Pawlowski66ea9422014-12-05 10:55:59 +01003974static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
3975 void *data, u16 len)
3976{
3977 struct mgmt_cp_start_service_discovery *cp = data;
Andre Guedes1183fdc2013-04-30 15:29:35 -03003978 struct pending_cmd *cmd;
Jakub Pawlowski66ea9422014-12-05 10:55:59 +01003979 struct hci_request req;
3980 const u16 max_uuid_count = ((U16_MAX - sizeof(*cp)) / 16);
3981 u16 uuid_count, expected_len;
3982 u8 status;
Andre Guedes1183fdc2013-04-30 15:29:35 -03003983 int err;
3984
Jakub Pawlowski66ea9422014-12-05 10:55:59 +01003985 BT_DBG("%s", hdev->name);
Andre Guedes1183fdc2013-04-30 15:29:35 -03003986
Jakub Pawlowski66ea9422014-12-05 10:55:59 +01003987 hci_dev_lock(hdev);
Andre Guedes1183fdc2013-04-30 15:29:35 -03003988
Jakub Pawlowski66ea9422014-12-05 10:55:59 +01003989 if (!hdev_is_powered(hdev)) {
3990 err = cmd_complete(sk, hdev->id,
3991 MGMT_OP_START_SERVICE_DISCOVERY,
3992 MGMT_STATUS_NOT_POWERED,
3993 &cp->type, sizeof(cp->type));
3994 goto failed;
3995 }
3996
3997 if (hdev->discovery.state != DISCOVERY_STOPPED ||
3998 test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) {
3999 err = cmd_complete(sk, hdev->id,
4000 MGMT_OP_START_SERVICE_DISCOVERY,
4001 MGMT_STATUS_BUSY, &cp->type,
4002 sizeof(cp->type));
4003 goto failed;
4004 }
4005
4006 uuid_count = __le16_to_cpu(cp->uuid_count);
4007 if (uuid_count > max_uuid_count) {
4008 BT_ERR("service_discovery: too big uuid_count value %u",
4009 uuid_count);
4010 err = cmd_complete(sk, hdev->id,
4011 MGMT_OP_START_SERVICE_DISCOVERY,
4012 MGMT_STATUS_INVALID_PARAMS, &cp->type,
4013 sizeof(cp->type));
4014 goto failed;
4015 }
4016
4017 expected_len = sizeof(*cp) + uuid_count * 16;
4018 if (expected_len != len) {
4019 BT_ERR("service_discovery: expected %u bytes, got %u bytes",
4020 expected_len, len);
4021 err = cmd_complete(sk, hdev->id,
4022 MGMT_OP_START_SERVICE_DISCOVERY,
4023 MGMT_STATUS_INVALID_PARAMS, &cp->type,
4024 sizeof(cp->type));
4025 goto failed;
4026 }
4027
4028 cmd = mgmt_pending_add(sk, MGMT_OP_START_SERVICE_DISCOVERY,
Johan Hedberg2922a942014-12-05 13:36:06 +02004029 hdev, data, len);
Jakub Pawlowski66ea9422014-12-05 10:55:59 +01004030 if (!cmd) {
4031 err = -ENOMEM;
4032 goto failed;
4033 }
4034
Johan Hedberg2922a942014-12-05 13:36:06 +02004035 cmd->cmd_complete = service_discovery_cmd_complete;
4036
Marcel Holtmann22078802014-12-05 11:45:22 +01004037 /* Clear the discovery filter first to free any previously
4038 * allocated memory for the UUID list.
4039 */
4040 hci_discovery_filter_clear(hdev);
4041
Jakub Pawlowski66ea9422014-12-05 10:55:59 +01004042 hdev->discovery.type = cp->type;
4043 hdev->discovery.rssi = cp->rssi;
4044 hdev->discovery.uuid_count = uuid_count;
4045
4046 if (uuid_count > 0) {
4047 hdev->discovery.uuids = kmemdup(cp->uuids, uuid_count * 16,
4048 GFP_KERNEL);
4049 if (!hdev->discovery.uuids) {
4050 err = cmd_complete(sk, hdev->id,
4051 MGMT_OP_START_SERVICE_DISCOVERY,
4052 MGMT_STATUS_FAILED,
4053 &cp->type, sizeof(cp->type));
4054 mgmt_pending_remove(cmd);
4055 goto failed;
4056 }
4057 }
4058
4059 hci_req_init(&req, hdev);
4060
4061 if (!trigger_discovery(&req, &status)) {
4062 err = cmd_complete(sk, hdev->id,
4063 MGMT_OP_START_SERVICE_DISCOVERY,
4064 status, &cp->type, sizeof(cp->type));
4065 mgmt_pending_remove(cmd);
4066 goto failed;
4067 }
4068
4069 err = hci_req_run(&req, start_discovery_complete);
4070 if (err < 0) {
4071 mgmt_pending_remove(cmd);
4072 goto failed;
4073 }
4074
4075 hci_discovery_set_state(hdev, DISCOVERY_STARTING);
4076
4077failed:
4078 hci_dev_unlock(hdev);
Andre Guedes1183fdc2013-04-30 15:29:35 -03004079 return err;
4080}
4081
Marcel Holtmann1904a852015-01-11 13:50:44 -08004082static void stop_discovery_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Andre Guedes0e05bba2013-04-30 15:29:33 -03004083{
Marcel Holtmann11e6e252014-12-04 11:36:35 +01004084 struct pending_cmd *cmd;
4085
Andre Guedes0e05bba2013-04-30 15:29:33 -03004086 BT_DBG("status %d", status);
4087
4088 hci_dev_lock(hdev);
4089
Marcel Holtmann11e6e252014-12-04 11:36:35 +01004090 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
4091 if (cmd) {
Johan Hedberg2922a942014-12-05 13:36:06 +02004092 cmd->cmd_complete(cmd, mgmt_status(status));
Marcel Holtmann11e6e252014-12-04 11:36:35 +01004093 mgmt_pending_remove(cmd);
Andre Guedes0e05bba2013-04-30 15:29:33 -03004094 }
4095
Marcel Holtmann11e6e252014-12-04 11:36:35 +01004096 if (!status)
4097 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Andre Guedes0e05bba2013-04-30 15:29:33 -03004098
Andre Guedes0e05bba2013-04-30 15:29:33 -03004099 hci_dev_unlock(hdev);
4100}
4101
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004102static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004103 u16 len)
Johan Hedberg14a53662011-04-27 10:29:56 -04004104{
Johan Hedbergd9306502012-02-20 23:25:18 +02004105 struct mgmt_cp_stop_discovery *mgmt_cp = data;
Johan Hedberg14a53662011-04-27 10:29:56 -04004106 struct pending_cmd *cmd;
Andre Guedes0e05bba2013-04-30 15:29:33 -03004107 struct hci_request req;
Johan Hedberg14a53662011-04-27 10:29:56 -04004108 int err;
4109
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004110 BT_DBG("%s", hdev->name);
Johan Hedberg14a53662011-04-27 10:29:56 -04004111
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03004112 hci_dev_lock(hdev);
Johan Hedberg14a53662011-04-27 10:29:56 -04004113
Johan Hedberg30dc78e2012-01-04 15:44:20 +02004114 if (!hci_discovery_active(hdev)) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004115 err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004116 MGMT_STATUS_REJECTED, &mgmt_cp->type,
4117 sizeof(mgmt_cp->type));
Johan Hedbergd9306502012-02-20 23:25:18 +02004118 goto unlock;
4119 }
4120
4121 if (hdev->discovery.type != mgmt_cp->type) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004122 err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004123 MGMT_STATUS_INVALID_PARAMS, &mgmt_cp->type,
4124 sizeof(mgmt_cp->type));
Johan Hedberg30dc78e2012-01-04 15:44:20 +02004125 goto unlock;
Johan Hedbergff9ef572012-01-04 14:23:45 +02004126 }
4127
Johan Hedberg2922a942014-12-05 13:36:06 +02004128 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, data, len);
Johan Hedberg14a53662011-04-27 10:29:56 -04004129 if (!cmd) {
4130 err = -ENOMEM;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02004131 goto unlock;
Johan Hedberg14a53662011-04-27 10:29:56 -04004132 }
4133
Johan Hedberg2922a942014-12-05 13:36:06 +02004134 cmd->cmd_complete = generic_cmd_complete;
4135
Andre Guedes0e05bba2013-04-30 15:29:33 -03004136 hci_req_init(&req, hdev);
4137
Johan Hedberg21a60d32014-06-10 14:05:58 +03004138 hci_stop_discovery(&req);
Andre Guedes0e05bba2013-04-30 15:29:33 -03004139
Johan Hedberg21a60d32014-06-10 14:05:58 +03004140 err = hci_req_run(&req, stop_discovery_complete);
4141 if (!err) {
4142 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
Andre Guedes0e05bba2013-04-30 15:29:33 -03004143 goto unlock;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02004144 }
4145
Johan Hedberg21a60d32014-06-10 14:05:58 +03004146 mgmt_pending_remove(cmd);
4147
4148 /* If no HCI commands were sent we're done */
4149 if (err == -ENODATA) {
4150 err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0,
4151 &mgmt_cp->type, sizeof(mgmt_cp->type));
4152 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
4153 }
Johan Hedberg14a53662011-04-27 10:29:56 -04004154
Johan Hedberg30dc78e2012-01-04 15:44:20 +02004155unlock:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03004156 hci_dev_unlock(hdev);
Johan Hedberg14a53662011-04-27 10:29:56 -04004157 return err;
4158}
4159
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004160static int confirm_name(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004161 u16 len)
Johan Hedberg561aafb2012-01-04 13:31:59 +02004162{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03004163 struct mgmt_cp_confirm_name *cp = data;
Johan Hedberg561aafb2012-01-04 13:31:59 +02004164 struct inquiry_entry *e;
Johan Hedberg561aafb2012-01-04 13:31:59 +02004165 int err;
4166
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004167 BT_DBG("%s", hdev->name);
Johan Hedberg561aafb2012-01-04 13:31:59 +02004168
Johan Hedberg561aafb2012-01-04 13:31:59 +02004169 hci_dev_lock(hdev);
4170
Johan Hedberg30dc78e2012-01-04 15:44:20 +02004171 if (!hci_discovery_active(hdev)) {
Lukasz Rymanowskid3a25412014-02-27 16:47:28 +01004172 err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME,
4173 MGMT_STATUS_FAILED, &cp->addr,
4174 sizeof(cp->addr));
Johan Hedberg30dc78e2012-01-04 15:44:20 +02004175 goto failed;
4176 }
4177
Johan Hedberga198e7b2012-02-17 14:27:06 +02004178 e = hci_inquiry_cache_lookup_unknown(hdev, &cp->addr.bdaddr);
Johan Hedberg561aafb2012-01-04 13:31:59 +02004179 if (!e) {
Lukasz Rymanowskid3a25412014-02-27 16:47:28 +01004180 err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME,
4181 MGMT_STATUS_INVALID_PARAMS, &cp->addr,
4182 sizeof(cp->addr));
Johan Hedberg561aafb2012-01-04 13:31:59 +02004183 goto failed;
4184 }
4185
4186 if (cp->name_known) {
4187 e->name_state = NAME_KNOWN;
4188 list_del(&e->list);
4189 } else {
4190 e->name_state = NAME_NEEDED;
Johan Hedberga3d4e202012-01-09 00:53:02 +02004191 hci_inquiry_cache_update_resolve(hdev, e);
Johan Hedberg561aafb2012-01-04 13:31:59 +02004192 }
4193
Johan Hedberge3846622013-01-09 15:29:33 +02004194 err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, 0, &cp->addr,
4195 sizeof(cp->addr));
Johan Hedberg561aafb2012-01-04 13:31:59 +02004196
4197failed:
4198 hci_dev_unlock(hdev);
Johan Hedberg561aafb2012-01-04 13:31:59 +02004199 return err;
4200}
4201
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004202static int block_device(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004203 u16 len)
Antti Julku7fbec222011-06-15 12:01:15 +03004204{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03004205 struct mgmt_cp_block_device *cp = data;
Johan Hedbergf0eeea82012-02-19 12:58:54 +02004206 u8 status;
Antti Julku7fbec222011-06-15 12:01:15 +03004207 int err;
4208
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004209 BT_DBG("%s", hdev->name);
Antti Julku7fbec222011-06-15 12:01:15 +03004210
Johan Hedberg4ee71b22013-01-20 14:27:19 +02004211 if (!bdaddr_type_is_valid(cp->addr.type))
Johan Hedberg5d0846d2013-01-20 14:27:22 +02004212 return cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE,
4213 MGMT_STATUS_INVALID_PARAMS,
4214 &cp->addr, sizeof(cp->addr));
Johan Hedberg4ee71b22013-01-20 14:27:19 +02004215
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03004216 hci_dev_lock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +03004217
Johan Hedbergdcc36c12014-07-09 12:59:13 +03004218 err = hci_bdaddr_list_add(&hdev->blacklist, &cp->addr.bdaddr,
4219 cp->addr.type);
Johan Hedberg2a8357f2014-07-01 22:09:47 +03004220 if (err < 0) {
Johan Hedbergf0eeea82012-02-19 12:58:54 +02004221 status = MGMT_STATUS_FAILED;
Johan Hedberg2a8357f2014-07-01 22:09:47 +03004222 goto done;
4223 }
Johan Hedbergf0eeea82012-02-19 12:58:54 +02004224
Johan Hedberg2a8357f2014-07-01 22:09:47 +03004225 mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &cp->addr, sizeof(cp->addr),
4226 sk);
4227 status = MGMT_STATUS_SUCCESS;
4228
4229done:
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004230 err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004231 &cp->addr, sizeof(cp->addr));
Antti Julku5e762442011-08-25 16:48:02 +03004232
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03004233 hci_dev_unlock(hdev);
Antti Julku7fbec222011-06-15 12:01:15 +03004234
4235 return err;
4236}
4237
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004238static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004239 u16 len)
Antti Julku7fbec222011-06-15 12:01:15 +03004240{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03004241 struct mgmt_cp_unblock_device *cp = data;
Johan Hedbergf0eeea82012-02-19 12:58:54 +02004242 u8 status;
Antti Julku7fbec222011-06-15 12:01:15 +03004243 int err;
4244
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004245 BT_DBG("%s", hdev->name);
Antti Julku7fbec222011-06-15 12:01:15 +03004246
Johan Hedberg4ee71b22013-01-20 14:27:19 +02004247 if (!bdaddr_type_is_valid(cp->addr.type))
Johan Hedberg5d0846d2013-01-20 14:27:22 +02004248 return cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE,
4249 MGMT_STATUS_INVALID_PARAMS,
4250 &cp->addr, sizeof(cp->addr));
Johan Hedberg4ee71b22013-01-20 14:27:19 +02004251
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03004252 hci_dev_lock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +03004253
Johan Hedbergdcc36c12014-07-09 12:59:13 +03004254 err = hci_bdaddr_list_del(&hdev->blacklist, &cp->addr.bdaddr,
4255 cp->addr.type);
Johan Hedberg2a8357f2014-07-01 22:09:47 +03004256 if (err < 0) {
Johan Hedbergf0eeea82012-02-19 12:58:54 +02004257 status = MGMT_STATUS_INVALID_PARAMS;
Johan Hedberg2a8357f2014-07-01 22:09:47 +03004258 goto done;
4259 }
Johan Hedbergf0eeea82012-02-19 12:58:54 +02004260
Johan Hedberg2a8357f2014-07-01 22:09:47 +03004261 mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &cp->addr, sizeof(cp->addr),
4262 sk);
4263 status = MGMT_STATUS_SUCCESS;
4264
4265done:
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004266 err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004267 &cp->addr, sizeof(cp->addr));
Antti Julku5e762442011-08-25 16:48:02 +03004268
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03004269 hci_dev_unlock(hdev);
Antti Julku7fbec222011-06-15 12:01:15 +03004270
4271 return err;
4272}
4273
Marcel Holtmanncdbaccc2012-03-11 20:00:29 -07004274static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
4275 u16 len)
4276{
4277 struct mgmt_cp_set_device_id *cp = data;
Johan Hedberg890ea892013-03-15 17:06:52 -05004278 struct hci_request req;
Marcel Holtmanncdbaccc2012-03-11 20:00:29 -07004279 int err;
Szymon Jancc72d4b82012-03-16 16:02:57 +01004280 __u16 source;
Marcel Holtmanncdbaccc2012-03-11 20:00:29 -07004281
4282 BT_DBG("%s", hdev->name);
4283
Szymon Jancc72d4b82012-03-16 16:02:57 +01004284 source = __le16_to_cpu(cp->source);
4285
4286 if (source > 0x0002)
4287 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEVICE_ID,
4288 MGMT_STATUS_INVALID_PARAMS);
4289
Marcel Holtmanncdbaccc2012-03-11 20:00:29 -07004290 hci_dev_lock(hdev);
4291
Szymon Jancc72d4b82012-03-16 16:02:57 +01004292 hdev->devid_source = source;
Marcel Holtmanncdbaccc2012-03-11 20:00:29 -07004293 hdev->devid_vendor = __le16_to_cpu(cp->vendor);
4294 hdev->devid_product = __le16_to_cpu(cp->product);
4295 hdev->devid_version = __le16_to_cpu(cp->version);
4296
4297 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, 0, NULL, 0);
4298
Johan Hedberg890ea892013-03-15 17:06:52 -05004299 hci_req_init(&req, hdev);
4300 update_eir(&req);
4301 hci_req_run(&req, NULL);
Marcel Holtmanncdbaccc2012-03-11 20:00:29 -07004302
4303 hci_dev_unlock(hdev);
4304
4305 return err;
4306}
4307
Marcel Holtmann1904a852015-01-11 13:50:44 -08004308static void set_advertising_complete(struct hci_dev *hdev, u8 status,
4309 u16 opcode)
Johan Hedberg4375f102013-09-25 13:26:10 +03004310{
4311 struct cmd_lookup match = { NULL, hdev };
4312
Jaganath Kanakkassery3ad67582014-12-11 11:43:12 +05304313 hci_dev_lock(hdev);
4314
Johan Hedberg4375f102013-09-25 13:26:10 +03004315 if (status) {
4316 u8 mgmt_err = mgmt_status(status);
4317
4318 mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev,
4319 cmd_status_rsp, &mgmt_err);
Jaganath Kanakkassery3ad67582014-12-11 11:43:12 +05304320 goto unlock;
Johan Hedberg4375f102013-09-25 13:26:10 +03004321 }
4322
Johan Hedbergc93bd152014-07-08 15:07:48 +03004323 if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
4324 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
4325 else
4326 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
4327
Johan Hedberg4375f102013-09-25 13:26:10 +03004328 mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
4329 &match);
4330
4331 new_settings(hdev, match.sk);
4332
4333 if (match.sk)
4334 sock_put(match.sk);
Jaganath Kanakkassery3ad67582014-12-11 11:43:12 +05304335
4336unlock:
4337 hci_dev_unlock(hdev);
Johan Hedberg4375f102013-09-25 13:26:10 +03004338}
4339
Marcel Holtmann21b51872013-10-10 09:47:53 -07004340static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
4341 u16 len)
Johan Hedberg4375f102013-09-25 13:26:10 +03004342{
4343 struct mgmt_mode *cp = data;
4344 struct pending_cmd *cmd;
4345 struct hci_request req;
Johan Hedberge6fe7982013-10-02 15:45:22 +03004346 u8 val, enabled, status;
Johan Hedberg4375f102013-09-25 13:26:10 +03004347 int err;
4348
4349 BT_DBG("request for %s", hdev->name);
4350
Johan Hedberge6fe7982013-10-02 15:45:22 +03004351 status = mgmt_le_support(hdev);
4352 if (status)
Johan Hedberg4375f102013-09-25 13:26:10 +03004353 return cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
Johan Hedberge6fe7982013-10-02 15:45:22 +03004354 status);
Johan Hedberg4375f102013-09-25 13:26:10 +03004355
4356 if (cp->val != 0x00 && cp->val != 0x01)
4357 return cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
4358 MGMT_STATUS_INVALID_PARAMS);
4359
4360 hci_dev_lock(hdev);
4361
4362 val = !!cp->val;
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02004363 enabled = test_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg4375f102013-09-25 13:26:10 +03004364
Johan Hedbergf74ca9b2013-10-08 15:52:18 +02004365 /* The following conditions are ones which mean that we should
4366 * not do any HCI communication but directly send a mgmt
4367 * response to user space (after toggling the flag if
4368 * necessary).
4369 */
4370 if (!hdev_is_powered(hdev) || val == enabled ||
Johan Hedberge8bb6b92014-07-08 15:07:53 +03004371 hci_conn_num(hdev, LE_LINK) > 0 ||
4372 (test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
4373 hdev->le_scan_type == LE_SCAN_ACTIVE)) {
Johan Hedberg4375f102013-09-25 13:26:10 +03004374 bool changed = false;
4375
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02004376 if (val != test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
4377 change_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg4375f102013-09-25 13:26:10 +03004378 changed = true;
4379 }
4380
4381 err = send_settings_rsp(sk, MGMT_OP_SET_ADVERTISING, hdev);
4382 if (err < 0)
4383 goto unlock;
4384
4385 if (changed)
4386 err = new_settings(hdev, sk);
4387
4388 goto unlock;
4389 }
4390
4391 if (mgmt_pending_find(MGMT_OP_SET_ADVERTISING, hdev) ||
4392 mgmt_pending_find(MGMT_OP_SET_LE, hdev)) {
4393 err = cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
4394 MGMT_STATUS_BUSY);
4395 goto unlock;
4396 }
4397
4398 cmd = mgmt_pending_add(sk, MGMT_OP_SET_ADVERTISING, hdev, data, len);
4399 if (!cmd) {
4400 err = -ENOMEM;
4401 goto unlock;
4402 }
4403
4404 hci_req_init(&req, hdev);
4405
Marcel Holtmannbba3aa52013-10-06 02:55:21 -07004406 if (val)
4407 enable_advertising(&req);
4408 else
4409 disable_advertising(&req);
Johan Hedberg4375f102013-09-25 13:26:10 +03004410
4411 err = hci_req_run(&req, set_advertising_complete);
4412 if (err < 0)
4413 mgmt_pending_remove(cmd);
4414
4415unlock:
4416 hci_dev_unlock(hdev);
4417 return err;
4418}
4419
Marcel Holtmannd13eafc2013-10-02 04:41:30 -07004420static int set_static_address(struct sock *sk, struct hci_dev *hdev,
4421 void *data, u16 len)
4422{
4423 struct mgmt_cp_set_static_address *cp = data;
4424 int err;
4425
4426 BT_DBG("%s", hdev->name);
4427
Marcel Holtmann62af4442013-10-02 22:10:32 -07004428 if (!lmp_le_capable(hdev))
Marcel Holtmannd13eafc2013-10-02 04:41:30 -07004429 return cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS,
Marcel Holtmann62af4442013-10-02 22:10:32 -07004430 MGMT_STATUS_NOT_SUPPORTED);
Marcel Holtmannd13eafc2013-10-02 04:41:30 -07004431
4432 if (hdev_is_powered(hdev))
4433 return cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS,
4434 MGMT_STATUS_REJECTED);
4435
4436 if (bacmp(&cp->bdaddr, BDADDR_ANY)) {
4437 if (!bacmp(&cp->bdaddr, BDADDR_NONE))
4438 return cmd_status(sk, hdev->id,
4439 MGMT_OP_SET_STATIC_ADDRESS,
4440 MGMT_STATUS_INVALID_PARAMS);
4441
4442 /* Two most significant bits shall be set */
4443 if ((cp->bdaddr.b[5] & 0xc0) != 0xc0)
4444 return cmd_status(sk, hdev->id,
4445 MGMT_OP_SET_STATIC_ADDRESS,
4446 MGMT_STATUS_INVALID_PARAMS);
4447 }
4448
4449 hci_dev_lock(hdev);
4450
4451 bacpy(&hdev->static_addr, &cp->bdaddr);
4452
4453 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS, 0, NULL, 0);
4454
4455 hci_dev_unlock(hdev);
4456
4457 return err;
4458}
4459
Marcel Holtmann14b49b92013-10-11 08:23:20 -07004460static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
4461 void *data, u16 len)
4462{
4463 struct mgmt_cp_set_scan_params *cp = data;
4464 __u16 interval, window;
4465 int err;
4466
4467 BT_DBG("%s", hdev->name);
4468
4469 if (!lmp_le_capable(hdev))
4470 return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
4471 MGMT_STATUS_NOT_SUPPORTED);
4472
4473 interval = __le16_to_cpu(cp->interval);
4474
4475 if (interval < 0x0004 || interval > 0x4000)
4476 return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
4477 MGMT_STATUS_INVALID_PARAMS);
4478
4479 window = __le16_to_cpu(cp->window);
4480
4481 if (window < 0x0004 || window > 0x4000)
4482 return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
4483 MGMT_STATUS_INVALID_PARAMS);
4484
Marcel Holtmann899e1072013-10-14 09:55:32 -07004485 if (window > interval)
4486 return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
4487 MGMT_STATUS_INVALID_PARAMS);
4488
Marcel Holtmann14b49b92013-10-11 08:23:20 -07004489 hci_dev_lock(hdev);
4490
4491 hdev->le_scan_interval = interval;
4492 hdev->le_scan_window = window;
4493
4494 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, 0, NULL, 0);
4495
Andre Guedesdd2ef8e2014-02-26 20:21:56 -03004496 /* If background scan is running, restart it so new parameters are
4497 * loaded.
4498 */
4499 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
4500 hdev->discovery.state == DISCOVERY_STOPPED) {
4501 struct hci_request req;
4502
4503 hci_req_init(&req, hdev);
4504
4505 hci_req_add_le_scan_disable(&req);
4506 hci_req_add_le_passive_scan(&req);
4507
4508 hci_req_run(&req, NULL);
4509 }
4510
Marcel Holtmann14b49b92013-10-11 08:23:20 -07004511 hci_dev_unlock(hdev);
4512
4513 return err;
4514}
4515
Marcel Holtmann1904a852015-01-11 13:50:44 -08004516static void fast_connectable_complete(struct hci_dev *hdev, u8 status,
4517 u16 opcode)
Johan Hedberg33e38b32013-03-15 17:07:05 -05004518{
4519 struct pending_cmd *cmd;
4520
4521 BT_DBG("status 0x%02x", status);
4522
4523 hci_dev_lock(hdev);
4524
4525 cmd = mgmt_pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev);
4526 if (!cmd)
4527 goto unlock;
4528
4529 if (status) {
4530 cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
4531 mgmt_status(status));
4532 } else {
Johan Hedberg1a4d3c42013-03-15 17:07:08 -05004533 struct mgmt_mode *cp = cmd->param;
4534
4535 if (cp->val)
4536 set_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags);
4537 else
4538 clear_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags);
4539
Johan Hedberg33e38b32013-03-15 17:07:05 -05004540 send_settings_rsp(cmd->sk, MGMT_OP_SET_FAST_CONNECTABLE, hdev);
4541 new_settings(hdev, cmd->sk);
4542 }
4543
4544 mgmt_pending_remove(cmd);
4545
4546unlock:
4547 hci_dev_unlock(hdev);
4548}
4549
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004550static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004551 void *data, u16 len)
Antti Julkuf6422ec2011-06-22 13:11:56 +03004552{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03004553 struct mgmt_mode *cp = data;
Johan Hedberg33e38b32013-03-15 17:07:05 -05004554 struct pending_cmd *cmd;
4555 struct hci_request req;
Antti Julkuf6422ec2011-06-22 13:11:56 +03004556 int err;
4557
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004558 BT_DBG("%s", hdev->name);
Antti Julkuf6422ec2011-06-22 13:11:56 +03004559
Johan Hedberg56f87902013-10-02 13:43:13 +03004560 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) ||
4561 hdev->hci_ver < BLUETOOTH_VER_1_2)
Johan Hedberg33c525c2012-10-24 21:11:58 +03004562 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
4563 MGMT_STATUS_NOT_SUPPORTED);
4564
Johan Hedberga7e80f22013-01-09 16:05:19 +02004565 if (cp->val != 0x00 && cp->val != 0x01)
4566 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
4567 MGMT_STATUS_INVALID_PARAMS);
4568
Johan Hedberg5400c042012-02-21 16:40:33 +02004569 if (!hdev_is_powered(hdev))
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004570 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004571 MGMT_STATUS_NOT_POWERED);
Johan Hedberg5400c042012-02-21 16:40:33 +02004572
4573 if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004574 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004575 MGMT_STATUS_REJECTED);
Antti Julkuf6422ec2011-06-22 13:11:56 +03004576
4577 hci_dev_lock(hdev);
4578
Johan Hedberg05cbf292013-03-15 17:07:07 -05004579 if (mgmt_pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev)) {
4580 err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
4581 MGMT_STATUS_BUSY);
4582 goto unlock;
4583 }
4584
Johan Hedberg1a4d3c42013-03-15 17:07:08 -05004585 if (!!cp->val == test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags)) {
4586 err = send_settings_rsp(sk, MGMT_OP_SET_FAST_CONNECTABLE,
4587 hdev);
4588 goto unlock;
4589 }
4590
Johan Hedberg33e38b32013-03-15 17:07:05 -05004591 cmd = mgmt_pending_add(sk, MGMT_OP_SET_FAST_CONNECTABLE, hdev,
4592 data, len);
4593 if (!cmd) {
4594 err = -ENOMEM;
4595 goto unlock;
4596 }
4597
4598 hci_req_init(&req, hdev);
4599
Johan Hedberg406d7802013-03-15 17:07:09 -05004600 write_fast_connectable(&req, cp->val);
Johan Hedberg33e38b32013-03-15 17:07:05 -05004601
4602 err = hci_req_run(&req, fast_connectable_complete);
Antti Julkuf6422ec2011-06-22 13:11:56 +03004603 if (err < 0) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02004604 err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004605 MGMT_STATUS_FAILED);
Johan Hedberg33e38b32013-03-15 17:07:05 -05004606 mgmt_pending_remove(cmd);
Antti Julkuf6422ec2011-06-22 13:11:56 +03004607 }
4608
Johan Hedberg33e38b32013-03-15 17:07:05 -05004609unlock:
Antti Julkuf6422ec2011-06-22 13:11:56 +03004610 hci_dev_unlock(hdev);
Johan Hedberg33e38b32013-03-15 17:07:05 -05004611
Antti Julkuf6422ec2011-06-22 13:11:56 +03004612 return err;
4613}
4614
Marcel Holtmann1904a852015-01-11 13:50:44 -08004615static void set_bredr_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg0663ca22013-10-02 13:43:14 +03004616{
4617 struct pending_cmd *cmd;
4618
4619 BT_DBG("status 0x%02x", status);
4620
4621 hci_dev_lock(hdev);
4622
4623 cmd = mgmt_pending_find(MGMT_OP_SET_BREDR, hdev);
4624 if (!cmd)
4625 goto unlock;
4626
4627 if (status) {
4628 u8 mgmt_err = mgmt_status(status);
4629
4630 /* We need to restore the flag if related HCI commands
4631 * failed.
4632 */
4633 clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
4634
4635 cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
4636 } else {
4637 send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev);
4638 new_settings(hdev, cmd->sk);
4639 }
4640
4641 mgmt_pending_remove(cmd);
4642
4643unlock:
4644 hci_dev_unlock(hdev);
4645}
4646
4647static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
4648{
4649 struct mgmt_mode *cp = data;
4650 struct pending_cmd *cmd;
4651 struct hci_request req;
4652 int err;
4653
4654 BT_DBG("request for %s", hdev->name);
4655
4656 if (!lmp_bredr_capable(hdev) || !lmp_le_capable(hdev))
4657 return cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
4658 MGMT_STATUS_NOT_SUPPORTED);
4659
4660 if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
4661 return cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
4662 MGMT_STATUS_REJECTED);
4663
4664 if (cp->val != 0x00 && cp->val != 0x01)
4665 return cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
4666 MGMT_STATUS_INVALID_PARAMS);
4667
4668 hci_dev_lock(hdev);
4669
4670 if (cp->val == test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
4671 err = send_settings_rsp(sk, MGMT_OP_SET_BREDR, hdev);
4672 goto unlock;
4673 }
4674
4675 if (!hdev_is_powered(hdev)) {
4676 if (!cp->val) {
Johan Hedberg0663ca22013-10-02 13:43:14 +03004677 clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
4678 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
4679 clear_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
4680 clear_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags);
4681 clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
4682 }
4683
4684 change_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
4685
4686 err = send_settings_rsp(sk, MGMT_OP_SET_BREDR, hdev);
4687 if (err < 0)
4688 goto unlock;
4689
4690 err = new_settings(hdev, sk);
4691 goto unlock;
4692 }
4693
4694 /* Reject disabling when powered on */
4695 if (!cp->val) {
4696 err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
4697 MGMT_STATUS_REJECTED);
4698 goto unlock;
Marcel Holtmann111e4bc2015-01-14 14:40:42 -08004699 } else {
4700 /* When configuring a dual-mode controller to operate
4701 * with LE only and using a static address, then switching
4702 * BR/EDR back on is not allowed.
4703 *
4704 * Dual-mode controllers shall operate with the public
4705 * address as its identity address for BR/EDR and LE. So
4706 * reject the attempt to create an invalid configuration.
Marcel Holtmann3a5486e2015-01-22 11:15:21 -08004707 *
4708 * The same restrictions applies when secure connections
4709 * has been enabled. For BR/EDR this is a controller feature
4710 * while for LE it is a host stack feature. This means that
4711 * switching BR/EDR back on when secure connections has been
4712 * enabled is not a supported transaction.
Marcel Holtmann111e4bc2015-01-14 14:40:42 -08004713 */
4714 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) &&
Marcel Holtmann3a5486e2015-01-22 11:15:21 -08004715 (bacmp(&hdev->static_addr, BDADDR_ANY) ||
4716 test_bit(HCI_SC_ENABLED, &hdev->dev_flags))) {
Marcel Holtmann111e4bc2015-01-14 14:40:42 -08004717 err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
4718 MGMT_STATUS_REJECTED);
4719 goto unlock;
4720 }
Johan Hedberg0663ca22013-10-02 13:43:14 +03004721 }
4722
4723 if (mgmt_pending_find(MGMT_OP_SET_BREDR, hdev)) {
4724 err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
4725 MGMT_STATUS_BUSY);
4726 goto unlock;
4727 }
4728
4729 cmd = mgmt_pending_add(sk, MGMT_OP_SET_BREDR, hdev, data, len);
4730 if (!cmd) {
4731 err = -ENOMEM;
4732 goto unlock;
4733 }
4734
Marcel Holtmann5947f4b2013-10-16 00:16:50 -07004735 /* We need to flip the bit already here so that update_adv_data
Johan Hedberg0663ca22013-10-02 13:43:14 +03004736 * generates the correct flags.
4737 */
4738 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
4739
4740 hci_req_init(&req, hdev);
Johan Hedbergaa8af462013-10-14 21:15:26 +03004741
Johan Hedberg432df052014-08-01 11:13:31 +03004742 write_fast_connectable(&req, false);
Johan Hedberg1d2dc5b2014-12-19 13:40:19 +02004743 __hci_update_page_scan(&req);
Johan Hedbergaa8af462013-10-14 21:15:26 +03004744
Marcel Holtmannf14d8f62013-10-16 00:16:48 -07004745 /* Since only the advertising data flags will change, there
4746 * is no need to update the scan response data.
4747 */
Marcel Holtmann5947f4b2013-10-16 00:16:50 -07004748 update_adv_data(&req);
Johan Hedbergaa8af462013-10-14 21:15:26 +03004749
Johan Hedberg0663ca22013-10-02 13:43:14 +03004750 err = hci_req_run(&req, set_bredr_complete);
4751 if (err < 0)
4752 mgmt_pending_remove(cmd);
4753
4754unlock:
4755 hci_dev_unlock(hdev);
4756 return err;
4757}
4758
Johan Hedberga1443f52015-01-23 15:42:46 +02004759static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
4760{
4761 struct pending_cmd *cmd;
4762 struct mgmt_mode *cp;
4763
4764 BT_DBG("%s status %u", hdev->name, status);
4765
4766 hci_dev_lock(hdev);
4767
4768 cmd = mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev);
4769 if (!cmd)
4770 goto unlock;
4771
4772 if (status) {
4773 cmd_status(cmd->sk, cmd->index, cmd->opcode,
4774 mgmt_status(status));
4775 goto remove;
4776 }
4777
4778 cp = cmd->param;
4779
4780 switch (cp->val) {
4781 case 0x00:
4782 clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
4783 clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
4784 break;
4785 case 0x01:
4786 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
4787 clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
4788 break;
4789 case 0x02:
4790 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
4791 set_bit(HCI_SC_ONLY, &hdev->dev_flags);
4792 break;
4793 }
4794
4795 send_settings_rsp(cmd->sk, MGMT_OP_SET_SECURE_CONN, hdev);
4796 new_settings(hdev, cmd->sk);
4797
4798remove:
4799 mgmt_pending_remove(cmd);
4800unlock:
4801 hci_dev_unlock(hdev);
4802}
4803
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004804static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
4805 void *data, u16 len)
4806{
4807 struct mgmt_mode *cp = data;
4808 struct pending_cmd *cmd;
Johan Hedberga1443f52015-01-23 15:42:46 +02004809 struct hci_request req;
Johan Hedberga3209692014-05-26 11:23:35 +03004810 u8 val;
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004811 int err;
4812
4813 BT_DBG("request for %s", hdev->name);
4814
Marcel Holtmann05b3c3e2014-12-31 14:43:18 -08004815 if (!lmp_sc_capable(hdev) &&
4816 !test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004817 return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
4818 MGMT_STATUS_NOT_SUPPORTED);
4819
Marcel Holtmanned93ec62015-01-22 11:15:22 -08004820 if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) &&
4821 !test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
4822 return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
4823 MGMT_STATUS_REJECTED);
4824
Marcel Holtmann0ab04a92014-02-01 09:19:57 -08004825 if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004826 return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
4827 MGMT_STATUS_INVALID_PARAMS);
4828
4829 hci_dev_lock(hdev);
4830
Marcel Holtmann05b3c3e2014-12-31 14:43:18 -08004831 if (!hdev_is_powered(hdev) || !lmp_sc_capable(hdev) ||
Johan Hedberga3209692014-05-26 11:23:35 +03004832 !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004833 bool changed;
4834
Marcel Holtmann0ab04a92014-02-01 09:19:57 -08004835 if (cp->val) {
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004836 changed = !test_and_set_bit(HCI_SC_ENABLED,
4837 &hdev->dev_flags);
Marcel Holtmann0ab04a92014-02-01 09:19:57 -08004838 if (cp->val == 0x02)
4839 set_bit(HCI_SC_ONLY, &hdev->dev_flags);
4840 else
4841 clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
4842 } else {
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004843 changed = test_and_clear_bit(HCI_SC_ENABLED,
4844 &hdev->dev_flags);
Marcel Holtmann0ab04a92014-02-01 09:19:57 -08004845 clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
4846 }
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004847
4848 err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
4849 if (err < 0)
4850 goto failed;
4851
4852 if (changed)
4853 err = new_settings(hdev, sk);
4854
4855 goto failed;
4856 }
4857
4858 if (mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) {
4859 err = cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
4860 MGMT_STATUS_BUSY);
4861 goto failed;
4862 }
4863
Marcel Holtmann0ab04a92014-02-01 09:19:57 -08004864 val = !!cp->val;
4865
4866 if (val == test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
4867 (cp->val == 0x02) == test_bit(HCI_SC_ONLY, &hdev->dev_flags)) {
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004868 err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
4869 goto failed;
4870 }
4871
4872 cmd = mgmt_pending_add(sk, MGMT_OP_SET_SECURE_CONN, hdev, data, len);
4873 if (!cmd) {
4874 err = -ENOMEM;
4875 goto failed;
4876 }
4877
Johan Hedberga1443f52015-01-23 15:42:46 +02004878 hci_req_init(&req, hdev);
4879 hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT, 1, &val);
4880 err = hci_req_run(&req, sc_enable_complete);
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08004881 if (err < 0) {
4882 mgmt_pending_remove(cmd);
4883 goto failed;
4884 }
4885
4886failed:
4887 hci_dev_unlock(hdev);
4888 return err;
4889}
4890
Marcel Holtmann4e39ac82014-01-31 11:55:22 -08004891static int set_debug_keys(struct sock *sk, struct hci_dev *hdev,
4892 void *data, u16 len)
4893{
4894 struct mgmt_mode *cp = data;
Johan Hedbergb97109792014-06-24 14:00:28 +03004895 bool changed, use_changed;
Marcel Holtmann4e39ac82014-01-31 11:55:22 -08004896 int err;
4897
4898 BT_DBG("request for %s", hdev->name);
4899
Johan Hedbergb97109792014-06-24 14:00:28 +03004900 if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
Marcel Holtmann4e39ac82014-01-31 11:55:22 -08004901 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEBUG_KEYS,
4902 MGMT_STATUS_INVALID_PARAMS);
4903
4904 hci_dev_lock(hdev);
4905
4906 if (cp->val)
Johan Hedberg0663b292014-06-24 13:15:50 +03004907 changed = !test_and_set_bit(HCI_KEEP_DEBUG_KEYS,
4908 &hdev->dev_flags);
Marcel Holtmann4e39ac82014-01-31 11:55:22 -08004909 else
Johan Hedberg0663b292014-06-24 13:15:50 +03004910 changed = test_and_clear_bit(HCI_KEEP_DEBUG_KEYS,
4911 &hdev->dev_flags);
Marcel Holtmann4e39ac82014-01-31 11:55:22 -08004912
Johan Hedbergb97109792014-06-24 14:00:28 +03004913 if (cp->val == 0x02)
4914 use_changed = !test_and_set_bit(HCI_USE_DEBUG_KEYS,
4915 &hdev->dev_flags);
4916 else
4917 use_changed = test_and_clear_bit(HCI_USE_DEBUG_KEYS,
4918 &hdev->dev_flags);
4919
4920 if (hdev_is_powered(hdev) && use_changed &&
4921 test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
4922 u8 mode = (cp->val == 0x02) ? 0x01 : 0x00;
4923 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
4924 sizeof(mode), &mode);
4925 }
4926
Marcel Holtmann4e39ac82014-01-31 11:55:22 -08004927 err = send_settings_rsp(sk, MGMT_OP_SET_DEBUG_KEYS, hdev);
4928 if (err < 0)
4929 goto unlock;
4930
4931 if (changed)
4932 err = new_settings(hdev, sk);
4933
4934unlock:
4935 hci_dev_unlock(hdev);
4936 return err;
4937}
4938
Johan Hedberg62b04cd2014-02-23 19:42:27 +02004939static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data,
4940 u16 len)
4941{
4942 struct mgmt_cp_set_privacy *cp = cp_data;
4943 bool changed;
4944 int err;
4945
4946 BT_DBG("request for %s", hdev->name);
4947
4948 if (!lmp_le_capable(hdev))
4949 return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
4950 MGMT_STATUS_NOT_SUPPORTED);
4951
4952 if (cp->privacy != 0x00 && cp->privacy != 0x01)
4953 return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
4954 MGMT_STATUS_INVALID_PARAMS);
4955
4956 if (hdev_is_powered(hdev))
4957 return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
4958 MGMT_STATUS_REJECTED);
4959
4960 hci_dev_lock(hdev);
4961
Johan Hedbergc21c0ea2014-02-24 11:10:30 +02004962 /* If user space supports this command it is also expected to
4963 * handle IRKs. Therefore, set the HCI_RPA_RESOLVING flag.
4964 */
4965 set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags);
4966
Johan Hedberg62b04cd2014-02-23 19:42:27 +02004967 if (cp->privacy) {
4968 changed = !test_and_set_bit(HCI_PRIVACY, &hdev->dev_flags);
4969 memcpy(hdev->irk, cp->irk, sizeof(hdev->irk));
4970 set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
4971 } else {
4972 changed = test_and_clear_bit(HCI_PRIVACY, &hdev->dev_flags);
4973 memset(hdev->irk, 0, sizeof(hdev->irk));
4974 clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
4975 }
4976
4977 err = send_settings_rsp(sk, MGMT_OP_SET_PRIVACY, hdev);
4978 if (err < 0)
4979 goto unlock;
4980
4981 if (changed)
4982 err = new_settings(hdev, sk);
4983
4984unlock:
4985 hci_dev_unlock(hdev);
4986 return err;
4987}
4988
Johan Hedberg41edf162014-02-18 10:19:35 +02004989static bool irk_is_valid(struct mgmt_irk_info *irk)
4990{
4991 switch (irk->addr.type) {
4992 case BDADDR_LE_PUBLIC:
4993 return true;
4994
4995 case BDADDR_LE_RANDOM:
4996 /* Two most significant bits shall be set */
4997 if ((irk->addr.bdaddr.b[5] & 0xc0) != 0xc0)
4998 return false;
4999 return true;
5000 }
5001
5002 return false;
5003}
5004
5005static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
5006 u16 len)
5007{
5008 struct mgmt_cp_load_irks *cp = cp_data;
Johan Hedbergba1d6932014-07-03 13:52:27 +03005009 const u16 max_irk_count = ((U16_MAX - sizeof(*cp)) /
5010 sizeof(struct mgmt_irk_info));
Johan Hedberg41edf162014-02-18 10:19:35 +02005011 u16 irk_count, expected_len;
5012 int i, err;
5013
5014 BT_DBG("request for %s", hdev->name);
5015
5016 if (!lmp_le_capable(hdev))
5017 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
5018 MGMT_STATUS_NOT_SUPPORTED);
5019
5020 irk_count = __le16_to_cpu(cp->irk_count);
Johan Hedbergba1d6932014-07-03 13:52:27 +03005021 if (irk_count > max_irk_count) {
5022 BT_ERR("load_irks: too big irk_count value %u", irk_count);
5023 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
5024 MGMT_STATUS_INVALID_PARAMS);
5025 }
Johan Hedberg41edf162014-02-18 10:19:35 +02005026
5027 expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info);
5028 if (expected_len != len) {
5029 BT_ERR("load_irks: expected %u bytes, got %u bytes",
Johan Hedberg2606ecb2014-03-07 15:04:13 +02005030 expected_len, len);
Johan Hedberg41edf162014-02-18 10:19:35 +02005031 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
5032 MGMT_STATUS_INVALID_PARAMS);
5033 }
5034
5035 BT_DBG("%s irk_count %u", hdev->name, irk_count);
5036
5037 for (i = 0; i < irk_count; i++) {
5038 struct mgmt_irk_info *key = &cp->irks[i];
5039
5040 if (!irk_is_valid(key))
5041 return cmd_status(sk, hdev->id,
5042 MGMT_OP_LOAD_IRKS,
5043 MGMT_STATUS_INVALID_PARAMS);
5044 }
5045
5046 hci_dev_lock(hdev);
5047
5048 hci_smp_irks_clear(hdev);
5049
5050 for (i = 0; i < irk_count; i++) {
5051 struct mgmt_irk_info *irk = &cp->irks[i];
5052 u8 addr_type;
5053
5054 if (irk->addr.type == BDADDR_LE_PUBLIC)
5055 addr_type = ADDR_LE_DEV_PUBLIC;
5056 else
5057 addr_type = ADDR_LE_DEV_RANDOM;
5058
5059 hci_add_irk(hdev, &irk->addr.bdaddr, addr_type, irk->val,
5060 BDADDR_ANY);
5061 }
5062
5063 set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags);
5064
5065 err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_IRKS, 0, NULL, 0);
5066
5067 hci_dev_unlock(hdev);
5068
5069 return err;
5070}
5071
Johan Hedberg3f706b72013-01-20 14:27:16 +02005072static bool ltk_is_valid(struct mgmt_ltk_info *key)
5073{
5074 if (key->master != 0x00 && key->master != 0x01)
5075 return false;
Marcel Holtmann490cb0b2014-02-16 12:59:05 -08005076
5077 switch (key->addr.type) {
5078 case BDADDR_LE_PUBLIC:
5079 return true;
5080
5081 case BDADDR_LE_RANDOM:
5082 /* Two most significant bits shall be set */
5083 if ((key->addr.bdaddr.b[5] & 0xc0) != 0xc0)
5084 return false;
5085 return true;
5086 }
5087
5088 return false;
Johan Hedberg3f706b72013-01-20 14:27:16 +02005089}
5090
Johan Hedbergbdb6d972012-02-28 06:13:32 +02005091static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03005092 void *cp_data, u16 len)
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005093{
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005094 struct mgmt_cp_load_long_term_keys *cp = cp_data;
Johan Hedbergba1d6932014-07-03 13:52:27 +03005095 const u16 max_key_count = ((U16_MAX - sizeof(*cp)) /
5096 sizeof(struct mgmt_ltk_info));
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005097 u16 key_count, expected_len;
Johan Hedberg715a5bf2013-01-09 15:29:34 +02005098 int i, err;
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005099
Marcel Holtmanncf99ba12013-10-02 21:16:08 -07005100 BT_DBG("request for %s", hdev->name);
5101
5102 if (!lmp_le_capable(hdev))
5103 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
5104 MGMT_STATUS_NOT_SUPPORTED);
5105
Marcel Holtmann1f350c82012-03-12 20:31:08 -07005106 key_count = __le16_to_cpu(cp->key_count);
Johan Hedbergba1d6932014-07-03 13:52:27 +03005107 if (key_count > max_key_count) {
5108 BT_ERR("load_ltks: too big key_count value %u", key_count);
5109 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
5110 MGMT_STATUS_INVALID_PARAMS);
5111 }
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005112
5113 expected_len = sizeof(*cp) + key_count *
5114 sizeof(struct mgmt_ltk_info);
5115 if (expected_len != len) {
5116 BT_ERR("load_keys: expected %u bytes, got %u bytes",
Johan Hedberg2606ecb2014-03-07 15:04:13 +02005117 expected_len, len);
Johan Hedbergbdb6d972012-02-28 06:13:32 +02005118 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
Johan Hedberge57e6192013-01-20 14:27:14 +02005119 MGMT_STATUS_INVALID_PARAMS);
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005120 }
5121
Johan Hedbergbdb6d972012-02-28 06:13:32 +02005122 BT_DBG("%s key_count %u", hdev->name, key_count);
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005123
Johan Hedberg54ad6d82013-01-20 14:27:15 +02005124 for (i = 0; i < key_count; i++) {
5125 struct mgmt_ltk_info *key = &cp->keys[i];
5126
Johan Hedberg3f706b72013-01-20 14:27:16 +02005127 if (!ltk_is_valid(key))
Johan Hedberg54ad6d82013-01-20 14:27:15 +02005128 return cmd_status(sk, hdev->id,
5129 MGMT_OP_LOAD_LONG_TERM_KEYS,
5130 MGMT_STATUS_INVALID_PARAMS);
5131 }
5132
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005133 hci_dev_lock(hdev);
5134
5135 hci_smp_ltks_clear(hdev);
5136
5137 for (i = 0; i < key_count; i++) {
5138 struct mgmt_ltk_info *key = &cp->keys[i];
Johan Hedbergd7b25452014-05-23 13:19:53 +03005139 u8 type, addr_type, authenticated;
Marcel Holtmann79d95a12013-10-13 03:57:38 -07005140
5141 if (key->addr.type == BDADDR_LE_PUBLIC)
5142 addr_type = ADDR_LE_DEV_PUBLIC;
5143 else
5144 addr_type = ADDR_LE_DEV_RANDOM;
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005145
Johan Hedberg61b43352014-05-29 19:36:53 +03005146 switch (key->type) {
5147 case MGMT_LTK_UNAUTHENTICATED:
Johan Hedbergd7b25452014-05-23 13:19:53 +03005148 authenticated = 0x00;
Johan Hedberg23fb8de2014-05-23 13:15:37 +03005149 type = key->master ? SMP_LTK : SMP_LTK_SLAVE;
Johan Hedberg61b43352014-05-29 19:36:53 +03005150 break;
5151 case MGMT_LTK_AUTHENTICATED:
Johan Hedbergd7b25452014-05-23 13:19:53 +03005152 authenticated = 0x01;
Johan Hedberg23fb8de2014-05-23 13:15:37 +03005153 type = key->master ? SMP_LTK : SMP_LTK_SLAVE;
Johan Hedberg61b43352014-05-29 19:36:53 +03005154 break;
Johan Hedberg23fb8de2014-05-23 13:15:37 +03005155 case MGMT_LTK_P256_UNAUTH:
5156 authenticated = 0x00;
5157 type = SMP_LTK_P256;
5158 break;
5159 case MGMT_LTK_P256_AUTH:
5160 authenticated = 0x01;
5161 type = SMP_LTK_P256;
5162 break;
5163 case MGMT_LTK_P256_DEBUG:
5164 authenticated = 0x00;
5165 type = SMP_LTK_P256_DEBUG;
Johan Hedberg61b43352014-05-29 19:36:53 +03005166 default:
5167 continue;
5168 }
Johan Hedbergd7b25452014-05-23 13:19:53 +03005169
Johan Hedberg35d70272014-02-19 14:57:47 +02005170 hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type,
Johan Hedbergd7b25452014-05-23 13:19:53 +03005171 authenticated, key->val, key->enc_size, key->ediv,
Johan Hedberg35d70272014-02-19 14:57:47 +02005172 key->rand);
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005173 }
5174
Johan Hedberg715a5bf2013-01-09 15:29:34 +02005175 err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0,
5176 NULL, 0);
5177
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005178 hci_dev_unlock(hdev);
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005179
Johan Hedberg715a5bf2013-01-09 15:29:34 +02005180 return err;
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03005181}
5182
Johan Hedberg9df74652014-12-19 22:26:03 +02005183static int conn_info_cmd_complete(struct pending_cmd *cmd, u8 status)
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005184{
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005185 struct hci_conn *conn = cmd->user_data;
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005186 struct mgmt_rp_get_conn_info rp;
Johan Hedberg9df74652014-12-19 22:26:03 +02005187 int err;
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005188
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005189 memcpy(&rp.addr, cmd->param, sizeof(rp.addr));
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005190
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005191 if (status == MGMT_STATUS_SUCCESS) {
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005192 rp.rssi = conn->rssi;
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005193 rp.tx_power = conn->tx_power;
5194 rp.max_tx_power = conn->max_tx_power;
5195 } else {
5196 rp.rssi = HCI_RSSI_INVALID;
5197 rp.tx_power = HCI_TX_POWER_INVALID;
5198 rp.max_tx_power = HCI_TX_POWER_INVALID;
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005199 }
5200
Johan Hedberg9df74652014-12-19 22:26:03 +02005201 err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status,
5202 &rp, sizeof(rp));
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005203
5204 hci_conn_drop(conn);
Johan Hedbergf8aaf9b2014-08-17 23:28:57 +03005205 hci_conn_put(conn);
Johan Hedberg9df74652014-12-19 22:26:03 +02005206
5207 return err;
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005208}
5209
Marcel Holtmann1904a852015-01-11 13:50:44 -08005210static void conn_info_refresh_complete(struct hci_dev *hdev, u8 hci_status,
5211 u16 opcode)
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005212{
5213 struct hci_cp_read_rssi *cp;
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005214 struct pending_cmd *cmd;
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005215 struct hci_conn *conn;
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005216 u16 handle;
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005217 u8 status;
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005218
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005219 BT_DBG("status 0x%02x", hci_status);
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005220
5221 hci_dev_lock(hdev);
5222
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005223 /* Commands sent in request are either Read RSSI or Read Transmit Power
5224 * Level so we check which one was last sent to retrieve connection
5225 * handle. Both commands have handle as first parameter so it's safe to
5226 * cast data on the same command struct.
5227 *
5228 * First command sent is always Read RSSI and we fail only if it fails.
5229 * In other case we simply override error to indicate success as we
5230 * already remembered if TX power value is actually valid.
5231 */
5232 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_RSSI);
5233 if (!cp) {
5234 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER);
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005235 status = MGMT_STATUS_SUCCESS;
5236 } else {
5237 status = mgmt_status(hci_status);
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005238 }
5239
5240 if (!cp) {
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005241 BT_ERR("invalid sent_cmd in conn_info response");
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005242 goto unlock;
5243 }
5244
5245 handle = __le16_to_cpu(cp->handle);
5246 conn = hci_conn_hash_lookup_handle(hdev, handle);
5247 if (!conn) {
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005248 BT_ERR("unknown handle (%d) in conn_info response", handle);
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005249 goto unlock;
5250 }
5251
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005252 cmd = mgmt_pending_find_data(MGMT_OP_GET_CONN_INFO, hdev, conn);
5253 if (!cmd)
5254 goto unlock;
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005255
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005256 cmd->cmd_complete(cmd, status);
5257 mgmt_pending_remove(cmd);
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005258
5259unlock:
5260 hci_dev_unlock(hdev);
5261}
5262
5263static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
5264 u16 len)
5265{
5266 struct mgmt_cp_get_conn_info *cp = data;
5267 struct mgmt_rp_get_conn_info rp;
5268 struct hci_conn *conn;
5269 unsigned long conn_info_age;
5270 int err = 0;
5271
5272 BT_DBG("%s", hdev->name);
5273
5274 memset(&rp, 0, sizeof(rp));
5275 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
5276 rp.addr.type = cp->addr.type;
5277
5278 if (!bdaddr_type_is_valid(cp->addr.type))
5279 return cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
5280 MGMT_STATUS_INVALID_PARAMS,
5281 &rp, sizeof(rp));
5282
5283 hci_dev_lock(hdev);
5284
5285 if (!hdev_is_powered(hdev)) {
5286 err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
5287 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
5288 goto unlock;
5289 }
5290
5291 if (cp->addr.type == BDADDR_BREDR)
5292 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
5293 &cp->addr.bdaddr);
5294 else
5295 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
5296
5297 if (!conn || conn->state != BT_CONNECTED) {
5298 err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
5299 MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp));
5300 goto unlock;
5301 }
5302
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005303 if (mgmt_pending_find_data(MGMT_OP_GET_CONN_INFO, hdev, conn)) {
5304 err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
5305 MGMT_STATUS_BUSY, &rp, sizeof(rp));
5306 goto unlock;
5307 }
5308
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005309 /* To avoid client trying to guess when to poll again for information we
5310 * calculate conn info age as random value between min/max set in hdev.
5311 */
5312 conn_info_age = hdev->conn_info_min_age +
5313 prandom_u32_max(hdev->conn_info_max_age -
5314 hdev->conn_info_min_age);
5315
5316 /* Query controller to refresh cached values if they are too old or were
5317 * never read.
5318 */
Andrzej Kaczmarekf4e2dd52014-05-16 16:48:57 +02005319 if (time_after(jiffies, conn->conn_info_timestamp +
5320 msecs_to_jiffies(conn_info_age)) ||
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005321 !conn->conn_info_timestamp) {
5322 struct hci_request req;
5323 struct hci_cp_read_tx_power req_txp_cp;
5324 struct hci_cp_read_rssi req_rssi_cp;
5325 struct pending_cmd *cmd;
5326
5327 hci_req_init(&req, hdev);
5328 req_rssi_cp.handle = cpu_to_le16(conn->handle);
5329 hci_req_add(&req, HCI_OP_READ_RSSI, sizeof(req_rssi_cp),
5330 &req_rssi_cp);
5331
Andrzej Kaczmarekf7faab02014-05-14 13:43:04 +02005332 /* For LE links TX power does not change thus we don't need to
5333 * query for it once value is known.
5334 */
5335 if (!bdaddr_type_is_le(cp->addr.type) ||
5336 conn->tx_power == HCI_TX_POWER_INVALID) {
5337 req_txp_cp.handle = cpu_to_le16(conn->handle);
5338 req_txp_cp.type = 0x00;
5339 hci_req_add(&req, HCI_OP_READ_TX_POWER,
5340 sizeof(req_txp_cp), &req_txp_cp);
5341 }
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005342
Andrzej Kaczmarekeed5daf2014-05-14 13:43:06 +02005343 /* Max TX power needs to be read only once per connection */
5344 if (conn->max_tx_power == HCI_TX_POWER_INVALID) {
5345 req_txp_cp.handle = cpu_to_le16(conn->handle);
5346 req_txp_cp.type = 0x01;
5347 hci_req_add(&req, HCI_OP_READ_TX_POWER,
5348 sizeof(req_txp_cp), &req_txp_cp);
5349 }
5350
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005351 err = hci_req_run(&req, conn_info_refresh_complete);
5352 if (err < 0)
5353 goto unlock;
5354
5355 cmd = mgmt_pending_add(sk, MGMT_OP_GET_CONN_INFO, hdev,
5356 data, len);
5357 if (!cmd) {
5358 err = -ENOMEM;
5359 goto unlock;
5360 }
5361
5362 hci_conn_hold(conn);
Johan Hedbergf8aaf9b2014-08-17 23:28:57 +03005363 cmd->user_data = hci_conn_get(conn);
Johan Hedberg9981bdb2014-12-05 13:42:57 +02005364 cmd->cmd_complete = conn_info_cmd_complete;
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005365
5366 conn->conn_info_timestamp = jiffies;
5367 } else {
5368 /* Cache is valid, just reply with values cached in hci_conn */
5369 rp.rssi = conn->rssi;
5370 rp.tx_power = conn->tx_power;
Andrzej Kaczmarekeed5daf2014-05-14 13:43:06 +02005371 rp.max_tx_power = conn->max_tx_power;
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02005372
5373 err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
5374 MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
5375 }
5376
5377unlock:
5378 hci_dev_unlock(hdev);
5379 return err;
5380}
5381
Johan Hedberg9df74652014-12-19 22:26:03 +02005382static int clock_info_cmd_complete(struct pending_cmd *cmd, u8 status)
Johan Hedberg69487372014-12-05 13:36:07 +02005383{
5384 struct hci_conn *conn = cmd->user_data;
5385 struct mgmt_rp_get_clock_info rp;
5386 struct hci_dev *hdev;
Johan Hedberg9df74652014-12-19 22:26:03 +02005387 int err;
Johan Hedberg69487372014-12-05 13:36:07 +02005388
5389 memset(&rp, 0, sizeof(rp));
5390 memcpy(&rp.addr, &cmd->param, sizeof(rp.addr));
5391
5392 if (status)
5393 goto complete;
5394
5395 hdev = hci_dev_get(cmd->index);
5396 if (hdev) {
5397 rp.local_clock = cpu_to_le32(hdev->clock);
5398 hci_dev_put(hdev);
5399 }
5400
5401 if (conn) {
5402 rp.piconet_clock = cpu_to_le32(conn->clock);
5403 rp.accuracy = cpu_to_le16(conn->clock_accuracy);
5404 }
5405
5406complete:
Johan Hedberg9df74652014-12-19 22:26:03 +02005407 err = cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp,
5408 sizeof(rp));
Johan Hedberg69487372014-12-05 13:36:07 +02005409
5410 if (conn) {
5411 hci_conn_drop(conn);
5412 hci_conn_put(conn);
5413 }
Johan Hedberg9df74652014-12-19 22:26:03 +02005414
5415 return err;
Johan Hedberg69487372014-12-05 13:36:07 +02005416}
5417
Marcel Holtmann1904a852015-01-11 13:50:44 -08005418static void get_clock_info_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg95868422014-06-28 17:54:07 +03005419{
Johan Hedberg95868422014-06-28 17:54:07 +03005420 struct hci_cp_read_clock *hci_cp;
5421 struct pending_cmd *cmd;
5422 struct hci_conn *conn;
5423
5424 BT_DBG("%s status %u", hdev->name, status);
5425
5426 hci_dev_lock(hdev);
5427
5428 hci_cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
5429 if (!hci_cp)
5430 goto unlock;
5431
5432 if (hci_cp->which) {
5433 u16 handle = __le16_to_cpu(hci_cp->handle);
5434 conn = hci_conn_hash_lookup_handle(hdev, handle);
5435 } else {
5436 conn = NULL;
5437 }
5438
5439 cmd = mgmt_pending_find_data(MGMT_OP_GET_CLOCK_INFO, hdev, conn);
5440 if (!cmd)
5441 goto unlock;
5442
Johan Hedberg69487372014-12-05 13:36:07 +02005443 cmd->cmd_complete(cmd, mgmt_status(status));
Johan Hedberg95868422014-06-28 17:54:07 +03005444 mgmt_pending_remove(cmd);
Johan Hedberg95868422014-06-28 17:54:07 +03005445
5446unlock:
5447 hci_dev_unlock(hdev);
5448}
5449
5450static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
5451 u16 len)
5452{
5453 struct mgmt_cp_get_clock_info *cp = data;
5454 struct mgmt_rp_get_clock_info rp;
5455 struct hci_cp_read_clock hci_cp;
5456 struct pending_cmd *cmd;
5457 struct hci_request req;
5458 struct hci_conn *conn;
5459 int err;
5460
5461 BT_DBG("%s", hdev->name);
5462
5463 memset(&rp, 0, sizeof(rp));
5464 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
5465 rp.addr.type = cp->addr.type;
5466
5467 if (cp->addr.type != BDADDR_BREDR)
5468 return cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO,
5469 MGMT_STATUS_INVALID_PARAMS,
5470 &rp, sizeof(rp));
5471
5472 hci_dev_lock(hdev);
5473
5474 if (!hdev_is_powered(hdev)) {
5475 err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO,
5476 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
5477 goto unlock;
5478 }
5479
5480 if (bacmp(&cp->addr.bdaddr, BDADDR_ANY)) {
5481 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
5482 &cp->addr.bdaddr);
5483 if (!conn || conn->state != BT_CONNECTED) {
5484 err = cmd_complete(sk, hdev->id,
5485 MGMT_OP_GET_CLOCK_INFO,
5486 MGMT_STATUS_NOT_CONNECTED,
5487 &rp, sizeof(rp));
5488 goto unlock;
5489 }
5490 } else {
5491 conn = NULL;
5492 }
5493
5494 cmd = mgmt_pending_add(sk, MGMT_OP_GET_CLOCK_INFO, hdev, data, len);
5495 if (!cmd) {
5496 err = -ENOMEM;
5497 goto unlock;
5498 }
5499
Johan Hedberg69487372014-12-05 13:36:07 +02005500 cmd->cmd_complete = clock_info_cmd_complete;
5501
Johan Hedberg95868422014-06-28 17:54:07 +03005502 hci_req_init(&req, hdev);
5503
5504 memset(&hci_cp, 0, sizeof(hci_cp));
5505 hci_req_add(&req, HCI_OP_READ_CLOCK, sizeof(hci_cp), &hci_cp);
5506
5507 if (conn) {
5508 hci_conn_hold(conn);
Johan Hedbergf8aaf9b2014-08-17 23:28:57 +03005509 cmd->user_data = hci_conn_get(conn);
Johan Hedberg95868422014-06-28 17:54:07 +03005510
5511 hci_cp.handle = cpu_to_le16(conn->handle);
5512 hci_cp.which = 0x01; /* Piconet clock */
5513 hci_req_add(&req, HCI_OP_READ_CLOCK, sizeof(hci_cp), &hci_cp);
5514 }
5515
5516 err = hci_req_run(&req, get_clock_info_complete);
5517 if (err < 0)
5518 mgmt_pending_remove(cmd);
5519
5520unlock:
5521 hci_dev_unlock(hdev);
5522 return err;
5523}
5524
Johan Hedberg5a154e62014-12-19 22:26:02 +02005525static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
5526{
5527 struct hci_conn *conn;
5528
5529 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
5530 if (!conn)
5531 return false;
5532
5533 if (conn->dst_type != type)
5534 return false;
5535
5536 if (conn->state != BT_CONNECTED)
5537 return false;
5538
5539 return true;
5540}
5541
5542/* This function requires the caller holds hdev->lock */
5543static int hci_conn_params_set(struct hci_request *req, bdaddr_t *addr,
5544 u8 addr_type, u8 auto_connect)
5545{
5546 struct hci_dev *hdev = req->hdev;
5547 struct hci_conn_params *params;
5548
5549 params = hci_conn_params_add(hdev, addr, addr_type);
5550 if (!params)
5551 return -EIO;
5552
5553 if (params->auto_connect == auto_connect)
5554 return 0;
5555
5556 list_del_init(&params->action);
5557
5558 switch (auto_connect) {
5559 case HCI_AUTO_CONN_DISABLED:
5560 case HCI_AUTO_CONN_LINK_LOSS:
5561 __hci_update_background_scan(req);
5562 break;
5563 case HCI_AUTO_CONN_REPORT:
5564 list_add(&params->action, &hdev->pend_le_reports);
5565 __hci_update_background_scan(req);
5566 break;
5567 case HCI_AUTO_CONN_DIRECT:
5568 case HCI_AUTO_CONN_ALWAYS:
5569 if (!is_connected(hdev, addr, addr_type)) {
5570 list_add(&params->action, &hdev->pend_le_conns);
5571 __hci_update_background_scan(req);
5572 }
5573 break;
5574 }
5575
5576 params->auto_connect = auto_connect;
5577
5578 BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
5579 auto_connect);
5580
5581 return 0;
5582}
5583
Marcel Holtmann8afef092014-06-29 22:28:34 +02005584static void device_added(struct sock *sk, struct hci_dev *hdev,
5585 bdaddr_t *bdaddr, u8 type, u8 action)
5586{
5587 struct mgmt_ev_device_added ev;
5588
5589 bacpy(&ev.addr.bdaddr, bdaddr);
5590 ev.addr.type = type;
5591 ev.action = action;
5592
5593 mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk);
5594}
5595
Marcel Holtmann1904a852015-01-11 13:50:44 -08005596static void add_device_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg5a154e62014-12-19 22:26:02 +02005597{
5598 struct pending_cmd *cmd;
5599
5600 BT_DBG("status 0x%02x", status);
5601
5602 hci_dev_lock(hdev);
5603
5604 cmd = mgmt_pending_find(MGMT_OP_ADD_DEVICE, hdev);
5605 if (!cmd)
5606 goto unlock;
5607
5608 cmd->cmd_complete(cmd, mgmt_status(status));
5609 mgmt_pending_remove(cmd);
5610
5611unlock:
5612 hci_dev_unlock(hdev);
5613}
5614
Marcel Holtmann2faade52014-06-29 19:44:03 +02005615static int add_device(struct sock *sk, struct hci_dev *hdev,
5616 void *data, u16 len)
5617{
5618 struct mgmt_cp_add_device *cp = data;
Johan Hedberg5a154e62014-12-19 22:26:02 +02005619 struct pending_cmd *cmd;
5620 struct hci_request req;
Marcel Holtmann2faade52014-06-29 19:44:03 +02005621 u8 auto_conn, addr_type;
5622 int err;
5623
5624 BT_DBG("%s", hdev->name);
5625
Johan Hedberg66593582014-07-09 12:59:14 +03005626 if (!bdaddr_type_is_valid(cp->addr.type) ||
Marcel Holtmann2faade52014-06-29 19:44:03 +02005627 !bacmp(&cp->addr.bdaddr, BDADDR_ANY))
5628 return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
5629 MGMT_STATUS_INVALID_PARAMS,
5630 &cp->addr, sizeof(cp->addr));
5631
Marcel Holtmann4b9e7e72014-07-23 21:55:23 +02005632 if (cp->action != 0x00 && cp->action != 0x01 && cp->action != 0x02)
Marcel Holtmann2faade52014-06-29 19:44:03 +02005633 return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
5634 MGMT_STATUS_INVALID_PARAMS,
5635 &cp->addr, sizeof(cp->addr));
5636
Johan Hedberg5a154e62014-12-19 22:26:02 +02005637 hci_req_init(&req, hdev);
5638
Marcel Holtmann2faade52014-06-29 19:44:03 +02005639 hci_dev_lock(hdev);
5640
Johan Hedberg5a154e62014-12-19 22:26:02 +02005641 cmd = mgmt_pending_add(sk, MGMT_OP_ADD_DEVICE, hdev, data, len);
5642 if (!cmd) {
5643 err = -ENOMEM;
5644 goto unlock;
5645 }
5646
5647 cmd->cmd_complete = addr_cmd_complete;
5648
Johan Hedberg66593582014-07-09 12:59:14 +03005649 if (cp->addr.type == BDADDR_BREDR) {
Marcel Holtmann4b9e7e72014-07-23 21:55:23 +02005650 /* Only incoming connections action is supported for now */
Johan Hedberg66593582014-07-09 12:59:14 +03005651 if (cp->action != 0x01) {
Johan Hedberg9df74652014-12-19 22:26:03 +02005652 err = cmd->cmd_complete(cmd,
5653 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg5a154e62014-12-19 22:26:02 +02005654 mgmt_pending_remove(cmd);
Johan Hedberg66593582014-07-09 12:59:14 +03005655 goto unlock;
5656 }
5657
5658 err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr,
5659 cp->addr.type);
5660 if (err)
5661 goto unlock;
Johan Hedberga3974072014-07-09 12:59:15 +03005662
Johan Hedberg5a154e62014-12-19 22:26:02 +02005663 __hci_update_page_scan(&req);
Johan Hedberga3974072014-07-09 12:59:15 +03005664
Johan Hedberg66593582014-07-09 12:59:14 +03005665 goto added;
5666 }
5667
Marcel Holtmann2faade52014-06-29 19:44:03 +02005668 if (cp->addr.type == BDADDR_LE_PUBLIC)
5669 addr_type = ADDR_LE_DEV_PUBLIC;
5670 else
5671 addr_type = ADDR_LE_DEV_RANDOM;
5672
Marcel Holtmann4b9e7e72014-07-23 21:55:23 +02005673 if (cp->action == 0x02)
Marcel Holtmann2faade52014-06-29 19:44:03 +02005674 auto_conn = HCI_AUTO_CONN_ALWAYS;
Marcel Holtmann4b9e7e72014-07-23 21:55:23 +02005675 else if (cp->action == 0x01)
5676 auto_conn = HCI_AUTO_CONN_DIRECT;
Marcel Holtmann2faade52014-06-29 19:44:03 +02005677 else
Johan Hedberga3451d22014-07-02 17:37:27 +03005678 auto_conn = HCI_AUTO_CONN_REPORT;
Marcel Holtmann2faade52014-06-29 19:44:03 +02005679
Marcel Holtmannbf5b3c82014-06-30 12:34:39 +02005680 /* If the connection parameters don't exist for this device,
5681 * they will be created and configured with defaults.
5682 */
Johan Hedberg5a154e62014-12-19 22:26:02 +02005683 if (hci_conn_params_set(&req, &cp->addr.bdaddr, addr_type,
Marcel Holtmannd06b50c2014-07-01 12:11:06 +02005684 auto_conn) < 0) {
Johan Hedberg9df74652014-12-19 22:26:03 +02005685 err = cmd->cmd_complete(cmd, MGMT_STATUS_FAILED);
Johan Hedberg5a154e62014-12-19 22:26:02 +02005686 mgmt_pending_remove(cmd);
Marcel Holtmann2faade52014-06-29 19:44:03 +02005687 goto unlock;
5688 }
5689
Johan Hedberg66593582014-07-09 12:59:14 +03005690added:
Marcel Holtmann8afef092014-06-29 22:28:34 +02005691 device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
5692
Johan Hedberg5a154e62014-12-19 22:26:02 +02005693 err = hci_req_run(&req, add_device_complete);
5694 if (err < 0) {
5695 /* ENODATA means no HCI commands were needed (e.g. if
5696 * the adapter is powered off).
5697 */
Johan Hedberg9df74652014-12-19 22:26:03 +02005698 if (err == -ENODATA)
5699 err = cmd->cmd_complete(cmd, MGMT_STATUS_SUCCESS);
Johan Hedberg5a154e62014-12-19 22:26:02 +02005700 mgmt_pending_remove(cmd);
5701 }
Marcel Holtmann2faade52014-06-29 19:44:03 +02005702
5703unlock:
5704 hci_dev_unlock(hdev);
5705 return err;
5706}
5707
Marcel Holtmann8afef092014-06-29 22:28:34 +02005708static void device_removed(struct sock *sk, struct hci_dev *hdev,
5709 bdaddr_t *bdaddr, u8 type)
5710{
5711 struct mgmt_ev_device_removed ev;
5712
5713 bacpy(&ev.addr.bdaddr, bdaddr);
5714 ev.addr.type = type;
5715
5716 mgmt_event(MGMT_EV_DEVICE_REMOVED, hdev, &ev, sizeof(ev), sk);
5717}
5718
Marcel Holtmann1904a852015-01-11 13:50:44 -08005719static void remove_device_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005720{
5721 struct pending_cmd *cmd;
5722
5723 BT_DBG("status 0x%02x", status);
5724
5725 hci_dev_lock(hdev);
5726
5727 cmd = mgmt_pending_find(MGMT_OP_REMOVE_DEVICE, hdev);
5728 if (!cmd)
5729 goto unlock;
5730
5731 cmd->cmd_complete(cmd, mgmt_status(status));
5732 mgmt_pending_remove(cmd);
5733
5734unlock:
5735 hci_dev_unlock(hdev);
5736}
5737
Marcel Holtmann2faade52014-06-29 19:44:03 +02005738static int remove_device(struct sock *sk, struct hci_dev *hdev,
5739 void *data, u16 len)
5740{
5741 struct mgmt_cp_remove_device *cp = data;
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005742 struct pending_cmd *cmd;
5743 struct hci_request req;
Marcel Holtmann2faade52014-06-29 19:44:03 +02005744 int err;
5745
5746 BT_DBG("%s", hdev->name);
5747
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005748 hci_req_init(&req, hdev);
5749
Marcel Holtmann2faade52014-06-29 19:44:03 +02005750 hci_dev_lock(hdev);
5751
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005752 cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_DEVICE, hdev, data, len);
5753 if (!cmd) {
5754 err = -ENOMEM;
5755 goto unlock;
5756 }
5757
5758 cmd->cmd_complete = addr_cmd_complete;
5759
Marcel Holtmann2faade52014-06-29 19:44:03 +02005760 if (bacmp(&cp->addr.bdaddr, BDADDR_ANY)) {
Johan Hedbergc71593d2014-07-02 17:37:28 +03005761 struct hci_conn_params *params;
Marcel Holtmann2faade52014-06-29 19:44:03 +02005762 u8 addr_type;
5763
Johan Hedberg66593582014-07-09 12:59:14 +03005764 if (!bdaddr_type_is_valid(cp->addr.type)) {
Johan Hedberg9df74652014-12-19 22:26:03 +02005765 err = cmd->cmd_complete(cmd,
5766 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005767 mgmt_pending_remove(cmd);
Marcel Holtmann2faade52014-06-29 19:44:03 +02005768 goto unlock;
5769 }
5770
Johan Hedberg66593582014-07-09 12:59:14 +03005771 if (cp->addr.type == BDADDR_BREDR) {
5772 err = hci_bdaddr_list_del(&hdev->whitelist,
5773 &cp->addr.bdaddr,
5774 cp->addr.type);
5775 if (err) {
Johan Hedberg9df74652014-12-19 22:26:03 +02005776 err = cmd->cmd_complete(cmd,
5777 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005778 mgmt_pending_remove(cmd);
Johan Hedberg66593582014-07-09 12:59:14 +03005779 goto unlock;
5780 }
5781
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005782 __hci_update_page_scan(&req);
Johan Hedberga3974072014-07-09 12:59:15 +03005783
Johan Hedberg66593582014-07-09 12:59:14 +03005784 device_removed(sk, hdev, &cp->addr.bdaddr,
5785 cp->addr.type);
5786 goto complete;
5787 }
5788
Marcel Holtmann2faade52014-06-29 19:44:03 +02005789 if (cp->addr.type == BDADDR_LE_PUBLIC)
5790 addr_type = ADDR_LE_DEV_PUBLIC;
5791 else
5792 addr_type = ADDR_LE_DEV_RANDOM;
5793
Johan Hedbergc71593d2014-07-02 17:37:28 +03005794 params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
5795 addr_type);
5796 if (!params) {
Johan Hedberg9df74652014-12-19 22:26:03 +02005797 err = cmd->cmd_complete(cmd,
5798 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005799 mgmt_pending_remove(cmd);
Johan Hedbergc71593d2014-07-02 17:37:28 +03005800 goto unlock;
5801 }
5802
5803 if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
Johan Hedberg9df74652014-12-19 22:26:03 +02005804 err = cmd->cmd_complete(cmd,
5805 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005806 mgmt_pending_remove(cmd);
Johan Hedbergc71593d2014-07-02 17:37:28 +03005807 goto unlock;
5808 }
5809
Johan Hedbergd1dbf122014-07-04 16:17:23 +03005810 list_del(&params->action);
Johan Hedbergc71593d2014-07-02 17:37:28 +03005811 list_del(&params->list);
5812 kfree(params);
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005813 __hci_update_background_scan(&req);
Marcel Holtmann8afef092014-06-29 22:28:34 +02005814
5815 device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type);
Marcel Holtmann2faade52014-06-29 19:44:03 +02005816 } else {
Johan Hedberg19de0822014-07-06 13:06:51 +03005817 struct hci_conn_params *p, *tmp;
Johan Hedberg66593582014-07-09 12:59:14 +03005818 struct bdaddr_list *b, *btmp;
Johan Hedberg19de0822014-07-06 13:06:51 +03005819
Marcel Holtmann2faade52014-06-29 19:44:03 +02005820 if (cp->addr.type) {
Johan Hedberg9df74652014-12-19 22:26:03 +02005821 err = cmd->cmd_complete(cmd,
5822 MGMT_STATUS_INVALID_PARAMS);
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005823 mgmt_pending_remove(cmd);
Marcel Holtmann2faade52014-06-29 19:44:03 +02005824 goto unlock;
5825 }
5826
Johan Hedberg66593582014-07-09 12:59:14 +03005827 list_for_each_entry_safe(b, btmp, &hdev->whitelist, list) {
5828 device_removed(sk, hdev, &b->bdaddr, b->bdaddr_type);
5829 list_del(&b->list);
5830 kfree(b);
5831 }
5832
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005833 __hci_update_page_scan(&req);
Johan Hedberga3974072014-07-09 12:59:15 +03005834
Johan Hedberg19de0822014-07-06 13:06:51 +03005835 list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) {
5836 if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
5837 continue;
5838 device_removed(sk, hdev, &p->addr, p->addr_type);
5839 list_del(&p->action);
5840 list_del(&p->list);
5841 kfree(p);
5842 }
5843
5844 BT_DBG("All LE connection parameters were removed");
5845
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005846 __hci_update_background_scan(&req);
Marcel Holtmann2faade52014-06-29 19:44:03 +02005847 }
5848
Johan Hedberg66593582014-07-09 12:59:14 +03005849complete:
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005850 err = hci_req_run(&req, remove_device_complete);
5851 if (err < 0) {
5852 /* ENODATA means no HCI commands were needed (e.g. if
5853 * the adapter is powered off).
5854 */
Johan Hedberg9df74652014-12-19 22:26:03 +02005855 if (err == -ENODATA)
5856 err = cmd->cmd_complete(cmd, MGMT_STATUS_SUCCESS);
Johan Hedberg51ef3eb2014-12-19 22:26:01 +02005857 mgmt_pending_remove(cmd);
5858 }
Marcel Holtmann2faade52014-06-29 19:44:03 +02005859
5860unlock:
5861 hci_dev_unlock(hdev);
5862 return err;
5863}
5864
Johan Hedberga26f3dc2014-07-02 17:37:29 +03005865static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
5866 u16 len)
5867{
5868 struct mgmt_cp_load_conn_param *cp = data;
Johan Hedbergba1d6932014-07-03 13:52:27 +03005869 const u16 max_param_count = ((U16_MAX - sizeof(*cp)) /
5870 sizeof(struct mgmt_conn_param));
Johan Hedberga26f3dc2014-07-02 17:37:29 +03005871 u16 param_count, expected_len;
5872 int i;
5873
5874 if (!lmp_le_capable(hdev))
5875 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
5876 MGMT_STATUS_NOT_SUPPORTED);
5877
5878 param_count = __le16_to_cpu(cp->param_count);
Johan Hedbergba1d6932014-07-03 13:52:27 +03005879 if (param_count > max_param_count) {
5880 BT_ERR("load_conn_param: too big param_count value %u",
5881 param_count);
5882 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
5883 MGMT_STATUS_INVALID_PARAMS);
5884 }
Johan Hedberga26f3dc2014-07-02 17:37:29 +03005885
5886 expected_len = sizeof(*cp) + param_count *
5887 sizeof(struct mgmt_conn_param);
5888 if (expected_len != len) {
5889 BT_ERR("load_conn_param: expected %u bytes, got %u bytes",
5890 expected_len, len);
5891 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
5892 MGMT_STATUS_INVALID_PARAMS);
5893 }
5894
5895 BT_DBG("%s param_count %u", hdev->name, param_count);
5896
5897 hci_dev_lock(hdev);
5898
5899 hci_conn_params_clear_disabled(hdev);
5900
5901 for (i = 0; i < param_count; i++) {
5902 struct mgmt_conn_param *param = &cp->params[i];
5903 struct hci_conn_params *hci_param;
5904 u16 min, max, latency, timeout;
5905 u8 addr_type;
5906
5907 BT_DBG("Adding %pMR (type %u)", &param->addr.bdaddr,
5908 param->addr.type);
5909
5910 if (param->addr.type == BDADDR_LE_PUBLIC) {
5911 addr_type = ADDR_LE_DEV_PUBLIC;
5912 } else if (param->addr.type == BDADDR_LE_RANDOM) {
5913 addr_type = ADDR_LE_DEV_RANDOM;
5914 } else {
5915 BT_ERR("Ignoring invalid connection parameters");
5916 continue;
5917 }
5918
5919 min = le16_to_cpu(param->min_interval);
5920 max = le16_to_cpu(param->max_interval);
5921 latency = le16_to_cpu(param->latency);
5922 timeout = le16_to_cpu(param->timeout);
5923
5924 BT_DBG("min 0x%04x max 0x%04x latency 0x%04x timeout 0x%04x",
5925 min, max, latency, timeout);
5926
5927 if (hci_check_conn_params(min, max, latency, timeout) < 0) {
5928 BT_ERR("Ignoring invalid connection parameters");
5929 continue;
5930 }
5931
5932 hci_param = hci_conn_params_add(hdev, &param->addr.bdaddr,
5933 addr_type);
5934 if (!hci_param) {
5935 BT_ERR("Failed to add connection parameters");
5936 continue;
5937 }
5938
5939 hci_param->conn_min_interval = min;
5940 hci_param->conn_max_interval = max;
5941 hci_param->conn_latency = latency;
5942 hci_param->supervision_timeout = timeout;
5943 }
5944
5945 hci_dev_unlock(hdev);
5946
5947 return cmd_complete(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, 0, NULL, 0);
5948}
5949
Marcel Holtmanndbece372014-07-04 18:11:55 +02005950static int set_external_config(struct sock *sk, struct hci_dev *hdev,
5951 void *data, u16 len)
5952{
5953 struct mgmt_cp_set_external_config *cp = data;
5954 bool changed;
5955 int err;
5956
5957 BT_DBG("%s", hdev->name);
5958
5959 if (hdev_is_powered(hdev))
5960 return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
5961 MGMT_STATUS_REJECTED);
5962
5963 if (cp->config != 0x00 && cp->config != 0x01)
5964 return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
5965 MGMT_STATUS_INVALID_PARAMS);
5966
5967 if (!test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks))
5968 return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
5969 MGMT_STATUS_NOT_SUPPORTED);
5970
5971 hci_dev_lock(hdev);
5972
5973 if (cp->config)
5974 changed = !test_and_set_bit(HCI_EXT_CONFIGURED,
5975 &hdev->dev_flags);
5976 else
5977 changed = test_and_clear_bit(HCI_EXT_CONFIGURED,
5978 &hdev->dev_flags);
5979
5980 err = send_options_rsp(sk, MGMT_OP_SET_EXTERNAL_CONFIG, hdev);
5981 if (err < 0)
5982 goto unlock;
5983
5984 if (!changed)
5985 goto unlock;
5986
Marcel Holtmannf4537c02014-07-04 19:06:23 +02005987 err = new_options(hdev, sk);
5988
Marcel Holtmanndbece372014-07-04 18:11:55 +02005989 if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) == is_configured(hdev)) {
5990 mgmt_index_removed(hdev);
Marcel Holtmannd603b762014-07-06 12:11:14 +02005991
5992 if (test_and_change_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
5993 set_bit(HCI_CONFIG, &hdev->dev_flags);
5994 set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
5995
5996 queue_work(hdev->req_workqueue, &hdev->power_on);
5997 } else {
Marcel Holtmann5ea234d2014-07-06 12:11:16 +02005998 set_bit(HCI_RAW, &hdev->flags);
Marcel Holtmannd603b762014-07-06 12:11:14 +02005999 mgmt_index_added(hdev);
6000 }
Marcel Holtmanndbece372014-07-04 18:11:55 +02006001 }
6002
6003unlock:
6004 hci_dev_unlock(hdev);
6005 return err;
6006}
6007
Marcel Holtmann9713c172014-07-06 12:11:15 +02006008static int set_public_address(struct sock *sk, struct hci_dev *hdev,
6009 void *data, u16 len)
6010{
6011 struct mgmt_cp_set_public_address *cp = data;
6012 bool changed;
6013 int err;
6014
6015 BT_DBG("%s", hdev->name);
6016
6017 if (hdev_is_powered(hdev))
6018 return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
6019 MGMT_STATUS_REJECTED);
6020
6021 if (!bacmp(&cp->bdaddr, BDADDR_ANY))
6022 return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
6023 MGMT_STATUS_INVALID_PARAMS);
6024
6025 if (!hdev->set_bdaddr)
6026 return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
6027 MGMT_STATUS_NOT_SUPPORTED);
6028
6029 hci_dev_lock(hdev);
6030
6031 changed = !!bacmp(&hdev->public_addr, &cp->bdaddr);
6032 bacpy(&hdev->public_addr, &cp->bdaddr);
6033
6034 err = send_options_rsp(sk, MGMT_OP_SET_PUBLIC_ADDRESS, hdev);
6035 if (err < 0)
6036 goto unlock;
6037
6038 if (!changed)
6039 goto unlock;
6040
6041 if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
6042 err = new_options(hdev, sk);
6043
6044 if (is_configured(hdev)) {
6045 mgmt_index_removed(hdev);
6046
6047 clear_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
6048
6049 set_bit(HCI_CONFIG, &hdev->dev_flags);
6050 set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
6051
6052 queue_work(hdev->req_workqueue, &hdev->power_on);
6053 }
6054
6055unlock:
6056 hci_dev_unlock(hdev);
6057 return err;
6058}
6059
Andrei Emeltchenko2e3c35e2012-03-14 18:54:15 +02006060static const struct mgmt_handler {
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006061 int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
6062 u16 data_len);
Johan Hedbergbe22b542012-03-01 22:24:41 +02006063 bool var_len;
6064 size_t data_len;
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02006065} mgmt_handlers[] = {
6066 { NULL }, /* 0x0000 (no command) */
Johan Hedbergbe22b542012-03-01 22:24:41 +02006067 { read_version, false, MGMT_READ_VERSION_SIZE },
6068 { read_commands, false, MGMT_READ_COMMANDS_SIZE },
6069 { read_index_list, false, MGMT_READ_INDEX_LIST_SIZE },
6070 { read_controller_info, false, MGMT_READ_INFO_SIZE },
6071 { set_powered, false, MGMT_SETTING_SIZE },
6072 { set_discoverable, false, MGMT_SET_DISCOVERABLE_SIZE },
6073 { set_connectable, false, MGMT_SETTING_SIZE },
6074 { set_fast_connectable, false, MGMT_SETTING_SIZE },
Johan Hedbergb2939472014-07-30 09:22:23 +03006075 { set_bondable, false, MGMT_SETTING_SIZE },
Johan Hedbergbe22b542012-03-01 22:24:41 +02006076 { set_link_security, false, MGMT_SETTING_SIZE },
6077 { set_ssp, false, MGMT_SETTING_SIZE },
6078 { set_hs, false, MGMT_SETTING_SIZE },
6079 { set_le, false, MGMT_SETTING_SIZE },
6080 { set_dev_class, false, MGMT_SET_DEV_CLASS_SIZE },
6081 { set_local_name, false, MGMT_SET_LOCAL_NAME_SIZE },
6082 { add_uuid, false, MGMT_ADD_UUID_SIZE },
6083 { remove_uuid, false, MGMT_REMOVE_UUID_SIZE },
6084 { load_link_keys, true, MGMT_LOAD_LINK_KEYS_SIZE },
6085 { load_long_term_keys, true, MGMT_LOAD_LONG_TERM_KEYS_SIZE },
6086 { disconnect, false, MGMT_DISCONNECT_SIZE },
6087 { get_connections, false, MGMT_GET_CONNECTIONS_SIZE },
6088 { pin_code_reply, false, MGMT_PIN_CODE_REPLY_SIZE },
6089 { pin_code_neg_reply, false, MGMT_PIN_CODE_NEG_REPLY_SIZE },
6090 { set_io_capability, false, MGMT_SET_IO_CAPABILITY_SIZE },
6091 { pair_device, false, MGMT_PAIR_DEVICE_SIZE },
6092 { cancel_pair_device, false, MGMT_CANCEL_PAIR_DEVICE_SIZE },
6093 { unpair_device, false, MGMT_UNPAIR_DEVICE_SIZE },
6094 { user_confirm_reply, false, MGMT_USER_CONFIRM_REPLY_SIZE },
6095 { user_confirm_neg_reply, false, MGMT_USER_CONFIRM_NEG_REPLY_SIZE },
6096 { user_passkey_reply, false, MGMT_USER_PASSKEY_REPLY_SIZE },
6097 { user_passkey_neg_reply, false, MGMT_USER_PASSKEY_NEG_REPLY_SIZE },
6098 { read_local_oob_data, false, MGMT_READ_LOCAL_OOB_DATA_SIZE },
Marcel Holtmannec109112014-01-10 02:07:30 -08006099 { add_remote_oob_data, true, MGMT_ADD_REMOTE_OOB_DATA_SIZE },
Johan Hedbergbe22b542012-03-01 22:24:41 +02006100 { remove_remote_oob_data, false, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE },
6101 { start_discovery, false, MGMT_START_DISCOVERY_SIZE },
6102 { stop_discovery, false, MGMT_STOP_DISCOVERY_SIZE },
6103 { confirm_name, false, MGMT_CONFIRM_NAME_SIZE },
6104 { block_device, false, MGMT_BLOCK_DEVICE_SIZE },
6105 { unblock_device, false, MGMT_UNBLOCK_DEVICE_SIZE },
Marcel Holtmanncdbaccc2012-03-11 20:00:29 -07006106 { set_device_id, false, MGMT_SET_DEVICE_ID_SIZE },
Johan Hedberg4375f102013-09-25 13:26:10 +03006107 { set_advertising, false, MGMT_SETTING_SIZE },
Johan Hedberg0663ca22013-10-02 13:43:14 +03006108 { set_bredr, false, MGMT_SETTING_SIZE },
Marcel Holtmannd13eafc2013-10-02 04:41:30 -07006109 { set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE },
Marcel Holtmann14b49b92013-10-11 08:23:20 -07006110 { set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE },
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08006111 { set_secure_conn, false, MGMT_SETTING_SIZE },
Marcel Holtmann4e39ac82014-01-31 11:55:22 -08006112 { set_debug_keys, false, MGMT_SETTING_SIZE },
Johan Hedberg62b04cd2014-02-23 19:42:27 +02006113 { set_privacy, false, MGMT_SET_PRIVACY_SIZE },
Johan Hedberg41edf162014-02-18 10:19:35 +02006114 { load_irks, true, MGMT_LOAD_IRKS_SIZE },
Andrzej Kaczmarekdd983802014-05-14 13:43:03 +02006115 { get_conn_info, false, MGMT_GET_CONN_INFO_SIZE },
Johan Hedberg95868422014-06-28 17:54:07 +03006116 { get_clock_info, false, MGMT_GET_CLOCK_INFO_SIZE },
Marcel Holtmann2faade52014-06-29 19:44:03 +02006117 { add_device, false, MGMT_ADD_DEVICE_SIZE },
6118 { remove_device, false, MGMT_REMOVE_DEVICE_SIZE },
Marcel Holtmann73d1df22014-07-02 22:10:52 +02006119 { load_conn_param, true, MGMT_LOAD_CONN_PARAM_SIZE },
6120 { read_unconf_index_list, false, MGMT_READ_UNCONF_INDEX_LIST_SIZE },
Marcel Holtmann9fc3bfb2014-07-04 00:46:56 +02006121 { read_config_info, false, MGMT_READ_CONFIG_INFO_SIZE },
Marcel Holtmanndbece372014-07-04 18:11:55 +02006122 { set_external_config, false, MGMT_SET_EXTERNAL_CONFIG_SIZE },
Marcel Holtmann9713c172014-07-06 12:11:15 +02006123 { set_public_address, false, MGMT_SET_PUBLIC_ADDRESS_SIZE },
Jakub Pawlowski66ea9422014-12-05 10:55:59 +01006124 { start_service_discovery,true, MGMT_START_SERVICE_DISCOVERY_SIZE },
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02006125};
6126
Johan Hedberg03811012010-12-08 00:21:06 +02006127int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
6128{
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03006129 void *buf;
6130 u8 *cp;
Johan Hedberg03811012010-12-08 00:21:06 +02006131 struct mgmt_hdr *hdr;
Szymon Janc4e51eae2011-02-25 19:05:48 +01006132 u16 opcode, index, len;
Johan Hedbergbdb6d972012-02-28 06:13:32 +02006133 struct hci_dev *hdev = NULL;
Andrei Emeltchenko2e3c35e2012-03-14 18:54:15 +02006134 const struct mgmt_handler *handler;
Johan Hedberg03811012010-12-08 00:21:06 +02006135 int err;
6136
6137 BT_DBG("got %zu bytes", msglen);
6138
6139 if (msglen < sizeof(*hdr))
6140 return -EINVAL;
6141
Gustavo F. Padovane63a15e2011-04-04 18:56:53 -03006142 buf = kmalloc(msglen, GFP_KERNEL);
Johan Hedberg03811012010-12-08 00:21:06 +02006143 if (!buf)
6144 return -ENOMEM;
6145
Al Viro6ce8e9c2014-04-06 21:25:44 -04006146 if (memcpy_from_msg(buf, msg, msglen)) {
Johan Hedberg03811012010-12-08 00:21:06 +02006147 err = -EFAULT;
6148 goto done;
6149 }
6150
Vinicius Costa Gomes650f7262012-02-02 21:07:59 -03006151 hdr = buf;
Marcel Holtmann1f350c82012-03-12 20:31:08 -07006152 opcode = __le16_to_cpu(hdr->opcode);
6153 index = __le16_to_cpu(hdr->index);
6154 len = __le16_to_cpu(hdr->len);
Johan Hedberg03811012010-12-08 00:21:06 +02006155
6156 if (len != msglen - sizeof(*hdr)) {
6157 err = -EINVAL;
6158 goto done;
6159 }
6160
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02006161 if (index != MGMT_INDEX_NONE) {
Johan Hedbergbdb6d972012-02-28 06:13:32 +02006162 hdev = hci_dev_get(index);
6163 if (!hdev) {
6164 err = cmd_status(sk, index, opcode,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006165 MGMT_STATUS_INVALID_INDEX);
Johan Hedbergbdb6d972012-02-28 06:13:32 +02006166 goto done;
6167 }
Marcel Holtmann0736cfa2013-08-26 21:40:51 -07006168
Johan Hedbergcebf4cf2013-10-10 18:06:04 +02006169 if (test_bit(HCI_SETUP, &hdev->dev_flags) ||
Marcel Holtmannd603b762014-07-06 12:11:14 +02006170 test_bit(HCI_CONFIG, &hdev->dev_flags) ||
Marcel Holtmann4a964402014-07-02 19:10:33 +02006171 test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
Marcel Holtmann0736cfa2013-08-26 21:40:51 -07006172 err = cmd_status(sk, index, opcode,
6173 MGMT_STATUS_INVALID_INDEX);
6174 goto done;
6175 }
Marcel Holtmann42a9bc142014-07-04 16:54:40 +02006176
6177 if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
Marcel Holtmanndbece372014-07-04 18:11:55 +02006178 opcode != MGMT_OP_READ_CONFIG_INFO &&
Marcel Holtmann9713c172014-07-06 12:11:15 +02006179 opcode != MGMT_OP_SET_EXTERNAL_CONFIG &&
6180 opcode != MGMT_OP_SET_PUBLIC_ADDRESS) {
Marcel Holtmann42a9bc142014-07-04 16:54:40 +02006181 err = cmd_status(sk, index, opcode,
6182 MGMT_STATUS_INVALID_INDEX);
6183 goto done;
6184 }
Johan Hedbergbdb6d972012-02-28 06:13:32 +02006185 }
6186
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02006187 if (opcode >= ARRAY_SIZE(mgmt_handlers) ||
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03006188 mgmt_handlers[opcode].func == NULL) {
Johan Hedberg03811012010-12-08 00:21:06 +02006189 BT_DBG("Unknown op %u", opcode);
Johan Hedbergca69b792011-11-11 18:10:00 +02006190 err = cmd_status(sk, index, opcode,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006191 MGMT_STATUS_UNKNOWN_COMMAND);
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02006192 goto done;
Johan Hedberg03811012010-12-08 00:21:06 +02006193 }
6194
Marcel Holtmann73d1df22014-07-02 22:10:52 +02006195 if (hdev && (opcode <= MGMT_OP_READ_INDEX_LIST ||
6196 opcode == MGMT_OP_READ_UNCONF_INDEX_LIST)) {
6197 err = cmd_status(sk, index, opcode,
6198 MGMT_STATUS_INVALID_INDEX);
6199 goto done;
6200 }
6201
6202 if (!hdev && (opcode > MGMT_OP_READ_INDEX_LIST &&
6203 opcode != MGMT_OP_READ_UNCONF_INDEX_LIST)) {
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02006204 err = cmd_status(sk, index, opcode,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006205 MGMT_STATUS_INVALID_INDEX);
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02006206 goto done;
6207 }
6208
Johan Hedbergbe22b542012-03-01 22:24:41 +02006209 handler = &mgmt_handlers[opcode];
6210
6211 if ((handler->var_len && len < handler->data_len) ||
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03006212 (!handler->var_len && len != handler->data_len)) {
Johan Hedbergbe22b542012-03-01 22:24:41 +02006213 err = cmd_status(sk, index, opcode,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006214 MGMT_STATUS_INVALID_PARAMS);
Johan Hedbergbe22b542012-03-01 22:24:41 +02006215 goto done;
6216 }
6217
Johan Hedberg0f4e68c2012-02-28 17:18:30 +02006218 if (hdev)
6219 mgmt_init_hdev(sk, hdev);
6220
6221 cp = buf + sizeof(*hdr);
6222
Johan Hedbergbe22b542012-03-01 22:24:41 +02006223 err = handler->func(sk, hdev, cp, len);
Johan Hedberge41d8b42010-12-13 21:07:03 +02006224 if (err < 0)
6225 goto done;
6226
Johan Hedberg03811012010-12-08 00:21:06 +02006227 err = msglen;
6228
6229done:
Johan Hedbergbdb6d972012-02-28 06:13:32 +02006230 if (hdev)
6231 hci_dev_put(hdev);
6232
Johan Hedberg03811012010-12-08 00:21:06 +02006233 kfree(buf);
6234 return err;
6235}
Johan Hedbergc71e97b2010-12-13 21:07:07 +02006236
Marcel Holtmannbf6b56d2013-10-06 23:55:45 -07006237void mgmt_index_added(struct hci_dev *hdev)
Johan Hedbergc71e97b2010-12-13 21:07:07 +02006238{
Marcel Holtmann1514b892013-10-06 08:25:01 -07006239 if (hdev->dev_type != HCI_BREDR)
Marcel Holtmannbf6b56d2013-10-06 23:55:45 -07006240 return;
Andrei Emeltchenkobb4b2a92012-07-19 17:03:40 +03006241
Marcel Holtmann0602a8a2014-07-02 21:30:54 +02006242 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6243 return;
6244
6245 if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
6246 mgmt_event(MGMT_EV_UNCONF_INDEX_ADDED, hdev, NULL, 0, NULL);
6247 else
6248 mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
Johan Hedbergc71e97b2010-12-13 21:07:07 +02006249}
6250
Marcel Holtmannbf6b56d2013-10-06 23:55:45 -07006251void mgmt_index_removed(struct hci_dev *hdev)
Johan Hedbergc71e97b2010-12-13 21:07:07 +02006252{
Johan Hedberg5f159032012-03-02 03:13:19 +02006253 u8 status = MGMT_STATUS_INVALID_INDEX;
Johan Hedbergb24752f2011-11-03 14:40:33 +02006254
Marcel Holtmann1514b892013-10-06 08:25:01 -07006255 if (hdev->dev_type != HCI_BREDR)
Marcel Holtmannbf6b56d2013-10-06 23:55:45 -07006256 return;
Andrei Emeltchenkobb4b2a92012-07-19 17:03:40 +03006257
Marcel Holtmann0602a8a2014-07-02 21:30:54 +02006258 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6259 return;
6260
Johan Hedberg1b9b5ee2014-12-05 13:36:00 +02006261 mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status);
Johan Hedbergb24752f2011-11-03 14:40:33 +02006262
Marcel Holtmannedd38962014-07-02 21:30:55 +02006263 if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
6264 mgmt_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, NULL);
6265 else
6266 mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02006267}
6268
Andre Guedes6046dc32014-02-26 20:21:51 -03006269/* This function requires the caller holds hdev->lock */
Johan Hedberg2cf22212014-12-19 22:26:00 +02006270static void restart_le_actions(struct hci_request *req)
Andre Guedes6046dc32014-02-26 20:21:51 -03006271{
Johan Hedberg2cf22212014-12-19 22:26:00 +02006272 struct hci_dev *hdev = req->hdev;
Andre Guedes6046dc32014-02-26 20:21:51 -03006273 struct hci_conn_params *p;
6274
6275 list_for_each_entry(p, &hdev->le_conn_params, list) {
Johan Hedbergd7347f32014-07-04 12:37:23 +03006276 /* Needed for AUTO_OFF case where might not "really"
6277 * have been powered off.
6278 */
6279 list_del_init(&p->action);
6280
6281 switch (p->auto_connect) {
Marcel Holtmann4b9e7e72014-07-23 21:55:23 +02006282 case HCI_AUTO_CONN_DIRECT:
Johan Hedbergd7347f32014-07-04 12:37:23 +03006283 case HCI_AUTO_CONN_ALWAYS:
6284 list_add(&p->action, &hdev->pend_le_conns);
6285 break;
6286 case HCI_AUTO_CONN_REPORT:
6287 list_add(&p->action, &hdev->pend_le_reports);
6288 break;
6289 default:
6290 break;
Marcel Holtmannc83ed192014-07-01 19:28:24 +02006291 }
Andre Guedes6046dc32014-02-26 20:21:51 -03006292 }
Marcel Holtmannc83ed192014-07-01 19:28:24 +02006293
Johan Hedberg2cf22212014-12-19 22:26:00 +02006294 __hci_update_background_scan(req);
Andre Guedes6046dc32014-02-26 20:21:51 -03006295}
6296
Marcel Holtmann1904a852015-01-11 13:50:44 -08006297static void powered_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Johan Hedberg229ab392013-03-15 17:06:53 -05006298{
6299 struct cmd_lookup match = { NULL, hdev };
6300
6301 BT_DBG("status 0x%02x", status);
6302
Marcel Holtmann162a3ba2015-01-14 15:43:11 -08006303 if (!status) {
6304 /* Register the available SMP channels (BR/EDR and LE) only
6305 * when successfully powering on the controller. This late
6306 * registration is required so that LE SMP can clearly
6307 * decide if the public address or static address is used.
6308 */
6309 smp_register(hdev);
6310 }
6311
Johan Hedberg229ab392013-03-15 17:06:53 -05006312 hci_dev_lock(hdev);
6313
6314 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
6315
6316 new_settings(hdev, match.sk);
6317
6318 hci_dev_unlock(hdev);
6319
6320 if (match.sk)
6321 sock_put(match.sk);
6322}
6323
Johan Hedberg70da6242013-03-15 17:06:51 -05006324static int powered_update_hci(struct hci_dev *hdev)
6325{
Johan Hedberg890ea892013-03-15 17:06:52 -05006326 struct hci_request req;
Johan Hedberg70da6242013-03-15 17:06:51 -05006327 u8 link_sec;
6328
Johan Hedberg890ea892013-03-15 17:06:52 -05006329 hci_req_init(&req, hdev);
6330
Johan Hedberg70da6242013-03-15 17:06:51 -05006331 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
6332 !lmp_host_ssp_capable(hdev)) {
Marcel Holtmann574ea3c2015-01-22 11:15:20 -08006333 u8 mode = 0x01;
Johan Hedberg70da6242013-03-15 17:06:51 -05006334
Marcel Holtmann574ea3c2015-01-22 11:15:20 -08006335 hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
Johan Hedberg70da6242013-03-15 17:06:51 -05006336
Marcel Holtmann574ea3c2015-01-22 11:15:20 -08006337 if (bredr_sc_enabled(hdev) && !lmp_host_sc_capable(hdev)) {
6338 u8 support = 0x01;
6339
6340 hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT,
6341 sizeof(support), &support);
6342 }
Johan Hedbergec6f99b2014-12-12 13:30:11 +02006343 }
6344
Johan Hedbergc73eee92013-04-19 18:35:21 +03006345 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
6346 lmp_bredr_capable(hdev)) {
Johan Hedberg70da6242013-03-15 17:06:51 -05006347 struct hci_cp_write_le_host_supported cp;
6348
Marcel Holtmann32226e42014-07-24 20:04:16 +02006349 cp.le = 0x01;
6350 cp.simul = 0x00;
Johan Hedberg70da6242013-03-15 17:06:51 -05006351
6352 /* Check first if we already have the right
6353 * host state (host features set)
6354 */
6355 if (cp.le != lmp_host_le_capable(hdev) ||
6356 cp.simul != lmp_host_le_br_capable(hdev))
Johan Hedberg890ea892013-03-15 17:06:52 -05006357 hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED,
6358 sizeof(cp), &cp);
Johan Hedberg70da6242013-03-15 17:06:51 -05006359 }
6360
Marcel Holtmannd13eafc2013-10-02 04:41:30 -07006361 if (lmp_le_capable(hdev)) {
Marcel Holtmann441ad2d2013-10-15 06:33:52 -07006362 /* Make sure the controller has a good default for
6363 * advertising data. This also applies to the case
6364 * where BR/EDR was toggled during the AUTO_OFF phase.
6365 */
Marcel Holtmannf14d8f62013-10-16 00:16:48 -07006366 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Marcel Holtmann5947f4b2013-10-16 00:16:50 -07006367 update_adv_data(&req);
Marcel Holtmannf14d8f62013-10-16 00:16:48 -07006368 update_scan_rsp_data(&req);
6369 }
Marcel Holtmann441ad2d2013-10-15 06:33:52 -07006370
Marcel Holtmannbba3aa52013-10-06 02:55:21 -07006371 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
6372 enable_advertising(&req);
Johan Hedberg2cf22212014-12-19 22:26:00 +02006373
6374 restart_le_actions(&req);
Johan Hedbergeeca6f82013-09-25 13:26:09 +03006375 }
6376
Johan Hedberg70da6242013-03-15 17:06:51 -05006377 link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
6378 if (link_sec != test_bit(HCI_AUTH, &hdev->flags))
Johan Hedberg890ea892013-03-15 17:06:52 -05006379 hci_req_add(&req, HCI_OP_WRITE_AUTH_ENABLE,
6380 sizeof(link_sec), &link_sec);
Johan Hedberg70da6242013-03-15 17:06:51 -05006381
6382 if (lmp_bredr_capable(hdev)) {
Johan Hedberg432df052014-08-01 11:13:31 +03006383 write_fast_connectable(&req, false);
Johan Hedberg1d2dc5b2014-12-19 13:40:19 +02006384 __hci_update_page_scan(&req);
Johan Hedberg890ea892013-03-15 17:06:52 -05006385 update_class(&req);
Johan Hedberg13928972013-03-15 17:07:00 -05006386 update_name(&req);
Johan Hedberg890ea892013-03-15 17:06:52 -05006387 update_eir(&req);
Johan Hedberg70da6242013-03-15 17:06:51 -05006388 }
6389
Johan Hedberg229ab392013-03-15 17:06:53 -05006390 return hci_req_run(&req, powered_complete);
Johan Hedberg70da6242013-03-15 17:06:51 -05006391}
6392
Johan Hedberg744cf192011-11-08 20:40:14 +02006393int mgmt_powered(struct hci_dev *hdev, u8 powered)
Johan Hedberg5add6af2010-12-16 10:00:37 +02006394{
Johan Hedberg76a7f3a2012-02-17 00:34:40 +02006395 struct cmd_lookup match = { NULL, hdev };
Johan Hedberg98459042014-12-12 11:15:21 +02006396 u8 status, zero_cod[] = { 0, 0, 0 };
Johan Hedberg7bb895d2012-02-17 01:20:00 +02006397 int err;
Johan Hedberg5add6af2010-12-16 10:00:37 +02006398
Johan Hedberg5e5282b2012-02-21 16:01:30 +02006399 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
6400 return 0;
6401
Johan Hedberg5e5282b2012-02-21 16:01:30 +02006402 if (powered) {
Johan Hedberg229ab392013-03-15 17:06:53 -05006403 if (powered_update_hci(hdev) == 0)
6404 return 0;
Johan Hedbergfe038882013-01-16 16:15:34 +02006405
Johan Hedberg229ab392013-03-15 17:06:53 -05006406 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp,
6407 &match);
6408 goto new_settings;
Johan Hedbergb24752f2011-11-03 14:40:33 +02006409 }
6410
Johan Hedberg229ab392013-03-15 17:06:53 -05006411 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
Johan Hedberg98459042014-12-12 11:15:21 +02006412
6413 /* If the power off is because of hdev unregistration let
6414 * use the appropriate INVALID_INDEX status. Otherwise use
6415 * NOT_POWERED. We cover both scenarios here since later in
6416 * mgmt_index_removed() any hci_conn callbacks will have already
6417 * been triggered, potentially causing misleading DISCONNECTED
6418 * status responses.
6419 */
6420 if (test_bit(HCI_UNREGISTER, &hdev->dev_flags))
6421 status = MGMT_STATUS_INVALID_INDEX;
6422 else
6423 status = MGMT_STATUS_NOT_POWERED;
6424
6425 mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status);
Johan Hedberg229ab392013-03-15 17:06:53 -05006426
6427 if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0)
6428 mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
6429 zero_cod, sizeof(zero_cod), NULL);
6430
6431new_settings:
Johan Hedbergbeadb2b2012-02-21 16:55:31 +02006432 err = new_settings(hdev, match.sk);
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02006433
6434 if (match.sk)
6435 sock_put(match.sk);
6436
Johan Hedberg7bb895d2012-02-17 01:20:00 +02006437 return err;
Johan Hedberg5add6af2010-12-16 10:00:37 +02006438}
Johan Hedberg73f22f62010-12-29 16:00:25 +02006439
Marcel Holtmann3eec7052013-10-06 23:55:46 -07006440void mgmt_set_powered_failed(struct hci_dev *hdev, int err)
Johan Hedberg96570ff2013-05-29 09:51:29 +03006441{
6442 struct pending_cmd *cmd;
6443 u8 status;
6444
6445 cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
6446 if (!cmd)
Marcel Holtmann3eec7052013-10-06 23:55:46 -07006447 return;
Johan Hedberg96570ff2013-05-29 09:51:29 +03006448
6449 if (err == -ERFKILL)
6450 status = MGMT_STATUS_RFKILLED;
6451 else
6452 status = MGMT_STATUS_FAILED;
6453
Marcel Holtmann3eec7052013-10-06 23:55:46 -07006454 cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status);
Johan Hedberg96570ff2013-05-29 09:51:29 +03006455
6456 mgmt_pending_remove(cmd);
Johan Hedberg96570ff2013-05-29 09:51:29 +03006457}
6458
Marcel Holtmannd1967ff2013-10-15 10:57:40 -07006459void mgmt_discoverable_timeout(struct hci_dev *hdev)
6460{
6461 struct hci_request req;
Marcel Holtmannd1967ff2013-10-15 10:57:40 -07006462
6463 hci_dev_lock(hdev);
6464
6465 /* When discoverable timeout triggers, then just make sure
6466 * the limited discoverable flag is cleared. Even in the case
6467 * of a timeout triggered from general discoverable, it is
6468 * safe to unconditionally clear the flag.
6469 */
6470 clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
Johan Hedberg9a43e252013-10-20 19:00:07 +03006471 clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
Marcel Holtmannd1967ff2013-10-15 10:57:40 -07006472
6473 hci_req_init(&req, hdev);
Johan Hedberg4b580612013-10-19 23:38:21 +03006474 if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
6475 u8 scan = SCAN_PAGE;
6476 hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE,
6477 sizeof(scan), &scan);
6478 }
Marcel Holtmannd1967ff2013-10-15 10:57:40 -07006479 update_class(&req);
Johan Hedberg9a43e252013-10-20 19:00:07 +03006480 update_adv_data(&req);
Marcel Holtmannd1967ff2013-10-15 10:57:40 -07006481 hci_req_run(&req, NULL);
6482
6483 hdev->discov_timeout = 0;
6484
Johan Hedberg9a43e252013-10-20 19:00:07 +03006485 new_settings(hdev, NULL);
6486
Marcel Holtmannd1967ff2013-10-15 10:57:40 -07006487 hci_dev_unlock(hdev);
6488}
6489
Marcel Holtmanndc4a5ee2013-10-15 10:15:57 -07006490void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
6491 bool persistent)
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02006492{
Johan Hedberg86742e12011-11-07 23:13:38 +02006493 struct mgmt_ev_new_link_key ev;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02006494
Vinicius Costa Gomesa492cd52011-08-25 20:02:29 -03006495 memset(&ev, 0, sizeof(ev));
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02006496
Vinicius Costa Gomesa492cd52011-08-25 20:02:29 -03006497 ev.store_hint = persistent;
Johan Hedbergd753fdc2012-02-17 14:06:34 +02006498 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
Andre Guedes591f47f2012-04-24 21:02:49 -03006499 ev.key.addr.type = BDADDR_BREDR;
Vinicius Costa Gomesa492cd52011-08-25 20:02:29 -03006500 ev.key.type = key->type;
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03006501 memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE);
Vinicius Costa Gomesa492cd52011-08-25 20:02:29 -03006502 ev.key.pin_len = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02006503
Marcel Holtmanndc4a5ee2013-10-15 10:15:57 -07006504 mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02006505}
Johan Hedbergf7520542011-01-20 12:34:39 +02006506
Johan Hedbergd7b25452014-05-23 13:19:53 +03006507static u8 mgmt_ltk_type(struct smp_ltk *ltk)
6508{
Johan Hedberg23fb8de2014-05-23 13:15:37 +03006509 switch (ltk->type) {
6510 case SMP_LTK:
6511 case SMP_LTK_SLAVE:
6512 if (ltk->authenticated)
6513 return MGMT_LTK_AUTHENTICATED;
6514 return MGMT_LTK_UNAUTHENTICATED;
6515 case SMP_LTK_P256:
6516 if (ltk->authenticated)
6517 return MGMT_LTK_P256_AUTH;
6518 return MGMT_LTK_P256_UNAUTH;
6519 case SMP_LTK_P256_DEBUG:
6520 return MGMT_LTK_P256_DEBUG;
6521 }
Johan Hedbergd7b25452014-05-23 13:19:53 +03006522
6523 return MGMT_LTK_UNAUTHENTICATED;
6524}
6525
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07006526void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03006527{
6528 struct mgmt_ev_new_long_term_key ev;
6529
6530 memset(&ev, 0, sizeof(ev));
6531
Marcel Holtmann5192d302014-02-19 17:11:58 -08006532 /* Devices using resolvable or non-resolvable random addresses
6533 * without providing an indentity resolving key don't require
6534 * to store long term keys. Their addresses will change the
6535 * next time around.
6536 *
6537 * Only when a remote device provides an identity address
6538 * make sure the long term key is stored. If the remote
6539 * identity is known, the long term keys are internally
6540 * mapped to the identity address. So allow static random
6541 * and public addresses here.
6542 */
Johan Hedbergba74b662014-02-19 14:57:45 +02006543 if (key->bdaddr_type == ADDR_LE_DEV_RANDOM &&
6544 (key->bdaddr.b[5] & 0xc0) != 0xc0)
6545 ev.store_hint = 0x00;
6546 else
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07006547 ev.store_hint = persistent;
Johan Hedbergba74b662014-02-19 14:57:45 +02006548
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03006549 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
Andre Guedes57c14772012-04-24 21:02:50 -03006550 ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
Johan Hedbergd7b25452014-05-23 13:19:53 +03006551 ev.key.type = mgmt_ltk_type(key);
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03006552 ev.key.enc_size = key->enc_size;
6553 ev.key.ediv = key->ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08006554 ev.key.rand = key->rand;
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03006555
Johan Hedberg2ceba532014-06-16 19:25:16 +03006556 if (key->type == SMP_LTK)
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03006557 ev.key.master = 1;
6558
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03006559 memcpy(ev.key.val, key->val, sizeof(key->val));
6560
Marcel Holtmann083368f2013-10-15 14:26:29 -07006561 mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), NULL);
Vinicius Costa Gomes346af672012-02-02 21:08:02 -03006562}
6563
Johan Hedberg95fbac82014-02-19 15:18:31 +02006564void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk)
6565{
6566 struct mgmt_ev_new_irk ev;
6567
6568 memset(&ev, 0, sizeof(ev));
6569
Marcel Holtmannbab6d1e2014-02-19 11:51:54 -08006570 /* For identity resolving keys from devices that are already
6571 * using a public address or static random address, do not
6572 * ask for storing this key. The identity resolving key really
6573 * is only mandatory for devices using resovlable random
6574 * addresses.
6575 *
6576 * Storing all identity resolving keys has the downside that
6577 * they will be also loaded on next boot of they system. More
6578 * identity resolving keys, means more time during scanning is
6579 * needed to actually resolve these addresses.
6580 */
6581 if (bacmp(&irk->rpa, BDADDR_ANY))
6582 ev.store_hint = 0x01;
6583 else
6584 ev.store_hint = 0x00;
6585
Johan Hedberg95fbac82014-02-19 15:18:31 +02006586 bacpy(&ev.rpa, &irk->rpa);
6587 bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr);
6588 ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type);
6589 memcpy(ev.irk.val, irk->val, sizeof(irk->val));
6590
6591 mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
6592}
6593
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07006594void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
6595 bool persistent)
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07006596{
6597 struct mgmt_ev_new_csrk ev;
6598
6599 memset(&ev, 0, sizeof(ev));
6600
6601 /* Devices using resolvable or non-resolvable random addresses
6602 * without providing an indentity resolving key don't require
6603 * to store signature resolving keys. Their addresses will change
6604 * the next time around.
6605 *
6606 * Only when a remote device provides an identity address
6607 * make sure the signature resolving key is stored. So allow
6608 * static random and public addresses here.
6609 */
6610 if (csrk->bdaddr_type == ADDR_LE_DEV_RANDOM &&
6611 (csrk->bdaddr.b[5] & 0xc0) != 0xc0)
6612 ev.store_hint = 0x00;
6613 else
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07006614 ev.store_hint = persistent;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07006615
6616 bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr);
6617 ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type);
6618 ev.key.master = csrk->master;
6619 memcpy(ev.key.val, csrk->val, sizeof(csrk->val));
6620
6621 mgmt_event(MGMT_EV_NEW_CSRK, hdev, &ev, sizeof(ev), NULL);
6622}
6623
Andre Guedesffb5a8272014-07-01 18:10:11 -03006624void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
Johan Hedbergf4869e22014-07-02 17:37:32 +03006625 u8 bdaddr_type, u8 store_hint, u16 min_interval,
6626 u16 max_interval, u16 latency, u16 timeout)
Andre Guedesffb5a8272014-07-01 18:10:11 -03006627{
6628 struct mgmt_ev_new_conn_param ev;
6629
Johan Hedbergc103aea2014-07-02 17:37:34 +03006630 if (!hci_is_identity_address(bdaddr, bdaddr_type))
6631 return;
6632
Andre Guedesffb5a8272014-07-01 18:10:11 -03006633 memset(&ev, 0, sizeof(ev));
6634 bacpy(&ev.addr.bdaddr, bdaddr);
6635 ev.addr.type = link_to_bdaddr(LE_LINK, bdaddr_type);
Johan Hedbergf4869e22014-07-02 17:37:32 +03006636 ev.store_hint = store_hint;
Andre Guedesffb5a8272014-07-01 18:10:11 -03006637 ev.min_interval = cpu_to_le16(min_interval);
6638 ev.max_interval = cpu_to_le16(max_interval);
6639 ev.latency = cpu_to_le16(latency);
6640 ev.timeout = cpu_to_le16(timeout);
6641
6642 mgmt_event(MGMT_EV_NEW_CONN_PARAM, hdev, &ev, sizeof(ev), NULL);
6643}
6644
Marcel Holtmann94933992013-10-15 10:26:39 -07006645static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
6646 u8 data_len)
6647{
6648 eir[eir_len++] = sizeof(type) + data_len;
6649 eir[eir_len++] = type;
6650 memcpy(&eir[eir_len], data, data_len);
6651 eir_len += data_len;
6652
6653 return eir_len;
6654}
6655
Alfonso Acosta48ec92f2014-10-07 08:44:10 +00006656void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
6657 u32 flags, u8 *name, u8 name_len)
Johan Hedbergf7520542011-01-20 12:34:39 +02006658{
Johan Hedbergb644ba32012-01-17 21:48:47 +02006659 char buf[512];
6660 struct mgmt_ev_device_connected *ev = (void *) buf;
6661 u16 eir_len = 0;
Johan Hedbergf7520542011-01-20 12:34:39 +02006662
Alfonso Acosta48ec92f2014-10-07 08:44:10 +00006663 bacpy(&ev->addr.bdaddr, &conn->dst);
6664 ev->addr.type = link_to_bdaddr(conn->type, conn->dst_type);
Johan Hedbergf7520542011-01-20 12:34:39 +02006665
Johan Hedbergc95f0ba2012-02-23 22:54:38 +02006666 ev->flags = __cpu_to_le32(flags);
Johan Hedberg08c79b62012-02-23 22:31:51 +02006667
Alfonso Acostafd45ada2014-10-07 08:44:11 +00006668 /* We must ensure that the EIR Data fields are ordered and
6669 * unique. Keep it simple for now and avoid the problem by not
6670 * adding any BR/EDR data to the LE adv.
6671 */
6672 if (conn->le_adv_data_len > 0) {
6673 memcpy(&ev->eir[eir_len],
6674 conn->le_adv_data, conn->le_adv_data_len);
6675 eir_len = conn->le_adv_data_len;
6676 } else {
6677 if (name_len > 0)
6678 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
6679 name, name_len);
Johan Hedbergb644ba32012-01-17 21:48:47 +02006680
Alfonso Acostaddbea5c2014-10-07 08:44:12 +00006681 if (memcmp(conn->dev_class, "\0\0\0", 3) != 0)
Alfonso Acostafd45ada2014-10-07 08:44:11 +00006682 eir_len = eir_append_data(ev->eir, eir_len,
6683 EIR_CLASS_OF_DEV,
6684 conn->dev_class, 3);
6685 }
Johan Hedbergb644ba32012-01-17 21:48:47 +02006686
Marcel Holtmanneb55ef02012-03-14 18:08:46 +02006687 ev->eir_len = cpu_to_le16(eir_len);
Johan Hedbergb644ba32012-01-17 21:48:47 +02006688
Marcel Holtmannecd90ae2013-10-06 23:55:49 -07006689 mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, buf,
6690 sizeof(*ev) + eir_len, NULL);
Johan Hedbergf7520542011-01-20 12:34:39 +02006691}
6692
Johan Hedberg8962ee72011-01-20 12:40:27 +02006693static void disconnect_rsp(struct pending_cmd *cmd, void *data)
6694{
Johan Hedberg8962ee72011-01-20 12:40:27 +02006695 struct sock **sk = data;
Johan Hedberg8962ee72011-01-20 12:40:27 +02006696
Johan Hedbergf5818c22014-12-05 13:36:02 +02006697 cmd->cmd_complete(cmd, 0);
Johan Hedberg8962ee72011-01-20 12:40:27 +02006698
6699 *sk = cmd->sk;
6700 sock_hold(*sk);
6701
Johan Hedberga664b5b2011-02-19 12:06:02 -03006702 mgmt_pending_remove(cmd);
Johan Hedberg8962ee72011-01-20 12:40:27 +02006703}
6704
Johan Hedberg124f6e32012-02-09 13:50:12 +02006705static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
Johan Hedberga8a1d192011-11-10 15:54:38 +02006706{
Johan Hedbergb1078ad2012-02-09 17:21:16 +02006707 struct hci_dev *hdev = data;
Johan Hedberg124f6e32012-02-09 13:50:12 +02006708 struct mgmt_cp_unpair_device *cp = cmd->param;
Johan Hedberga8a1d192011-11-10 15:54:38 +02006709
Johan Hedbergb1078ad2012-02-09 17:21:16 +02006710 device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
6711
Johan Hedbergd8b7b1e2014-12-05 13:36:05 +02006712 cmd->cmd_complete(cmd, 0);
Johan Hedberga8a1d192011-11-10 15:54:38 +02006713 mgmt_pending_remove(cmd);
6714}
6715
Johan Hedberg84c61d92014-08-01 11:13:30 +03006716bool mgmt_powering_down(struct hci_dev *hdev)
6717{
6718 struct pending_cmd *cmd;
6719 struct mgmt_mode *cp;
6720
6721 cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
6722 if (!cmd)
6723 return false;
6724
6725 cp = cmd->param;
6726 if (!cp->val)
6727 return true;
6728
6729 return false;
6730}
6731
Marcel Holtmann9b80ec52013-10-06 23:55:50 -07006732void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02006733 u8 link_type, u8 addr_type, u8 reason,
6734 bool mgmt_connected)
Johan Hedbergf7520542011-01-20 12:34:39 +02006735{
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02006736 struct mgmt_ev_device_disconnected ev;
Johan Hedberg8962ee72011-01-20 12:40:27 +02006737 struct sock *sk = NULL;
Johan Hedberg8962ee72011-01-20 12:40:27 +02006738
Johan Hedberg84c61d92014-08-01 11:13:30 +03006739 /* The connection is still in hci_conn_hash so test for 1
6740 * instead of 0 to know if this is the last one.
6741 */
6742 if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) {
6743 cancel_delayed_work(&hdev->power_off);
6744 queue_work(hdev->req_workqueue, &hdev->power_off.work);
Johan Hedberg8b064a32014-02-24 14:52:22 +02006745 }
6746
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02006747 if (!mgmt_connected)
6748 return;
6749
Andre Guedes57eb7762013-10-30 19:01:41 -03006750 if (link_type != ACL_LINK && link_type != LE_LINK)
6751 return;
6752
Johan Hedberg744cf192011-11-08 20:40:14 +02006753 mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);
Johan Hedbergf7520542011-01-20 12:34:39 +02006754
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02006755 bacpy(&ev.addr.bdaddr, bdaddr);
6756 ev.addr.type = link_to_bdaddr(link_type, addr_type);
6757 ev.reason = reason;
Johan Hedbergf7520542011-01-20 12:34:39 +02006758
Marcel Holtmann9b80ec52013-10-06 23:55:50 -07006759 mgmt_event(MGMT_EV_DEVICE_DISCONNECTED, hdev, &ev, sizeof(ev), sk);
Johan Hedberg8962ee72011-01-20 12:40:27 +02006760
6761 if (sk)
Szymon Jancd97dcb62012-03-16 16:02:56 +01006762 sock_put(sk);
Johan Hedberg8962ee72011-01-20 12:40:27 +02006763
Johan Hedberg124f6e32012-02-09 13:50:12 +02006764 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006765 hdev);
Johan Hedberg8962ee72011-01-20 12:40:27 +02006766}
6767
Marcel Holtmann78929242013-10-06 23:55:47 -07006768void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
6769 u8 link_type, u8 addr_type, u8 status)
Johan Hedberg8962ee72011-01-20 12:40:27 +02006770{
Andre Guedes3655bba2013-10-30 19:01:40 -03006771 u8 bdaddr_type = link_to_bdaddr(link_type, addr_type);
6772 struct mgmt_cp_disconnect *cp;
Johan Hedberg8962ee72011-01-20 12:40:27 +02006773 struct pending_cmd *cmd;
Johan Hedberg8962ee72011-01-20 12:40:27 +02006774
Jefferson Delfes36a75f12012-09-18 13:36:54 -04006775 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
6776 hdev);
6777
Johan Hedberg2e58ef32011-11-08 20:40:15 +02006778 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev);
Johan Hedberg8962ee72011-01-20 12:40:27 +02006779 if (!cmd)
Marcel Holtmann78929242013-10-06 23:55:47 -07006780 return;
Johan Hedberg8962ee72011-01-20 12:40:27 +02006781
Andre Guedes3655bba2013-10-30 19:01:40 -03006782 cp = cmd->param;
6783
6784 if (bacmp(bdaddr, &cp->addr.bdaddr))
6785 return;
6786
6787 if (cp->addr.type != bdaddr_type)
6788 return;
6789
Johan Hedbergf5818c22014-12-05 13:36:02 +02006790 cmd->cmd_complete(cmd, mgmt_status(status));
Johan Hedberga664b5b2011-02-19 12:06:02 -03006791 mgmt_pending_remove(cmd);
Johan Hedbergf7520542011-01-20 12:34:39 +02006792}
Johan Hedberg17d5c042011-01-22 06:09:08 +02006793
Marcel Holtmann445608d2013-10-06 23:55:48 -07006794void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
6795 u8 addr_type, u8 status)
Johan Hedberg17d5c042011-01-22 06:09:08 +02006796{
6797 struct mgmt_ev_connect_failed ev;
Johan Hedbergc9910d02014-02-27 14:35:12 +02006798
Johan Hedberg84c61d92014-08-01 11:13:30 +03006799 /* The connection is still in hci_conn_hash so test for 1
6800 * instead of 0 to know if this is the last one.
6801 */
6802 if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) {
6803 cancel_delayed_work(&hdev->power_off);
6804 queue_work(hdev->req_workqueue, &hdev->power_off.work);
Johan Hedbergc9910d02014-02-27 14:35:12 +02006805 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02006806
Johan Hedberg4c659c32011-11-07 23:13:39 +02006807 bacpy(&ev.addr.bdaddr, bdaddr);
Andre Guedes57c14772012-04-24 21:02:50 -03006808 ev.addr.type = link_to_bdaddr(link_type, addr_type);
Johan Hedbergca69b792011-11-11 18:10:00 +02006809 ev.status = mgmt_status(status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02006810
Marcel Holtmann445608d2013-10-06 23:55:48 -07006811 mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL);
Johan Hedberg17d5c042011-01-22 06:09:08 +02006812}
Johan Hedberg980e1a52011-01-22 06:10:07 +02006813
Marcel Holtmannce0e4a02013-10-15 14:26:20 -07006814void mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure)
Johan Hedberg980e1a52011-01-22 06:10:07 +02006815{
6816 struct mgmt_ev_pin_code_request ev;
6817
Johan Hedbergd8457692012-02-17 14:24:57 +02006818 bacpy(&ev.addr.bdaddr, bdaddr);
Andre Guedes591f47f2012-04-24 21:02:49 -03006819 ev.addr.type = BDADDR_BREDR;
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02006820 ev.secure = secure;
Johan Hedberg980e1a52011-01-22 06:10:07 +02006821
Marcel Holtmannce0e4a02013-10-15 14:26:20 -07006822 mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev), NULL);
Johan Hedberg980e1a52011-01-22 06:10:07 +02006823}
6824
Marcel Holtmanne669cf82013-10-15 14:26:21 -07006825void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
6826 u8 status)
Johan Hedberg980e1a52011-01-22 06:10:07 +02006827{
6828 struct pending_cmd *cmd;
Johan Hedberg980e1a52011-01-22 06:10:07 +02006829
Johan Hedberg2e58ef32011-11-08 20:40:15 +02006830 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +02006831 if (!cmd)
Marcel Holtmanne669cf82013-10-15 14:26:21 -07006832 return;
Johan Hedberg980e1a52011-01-22 06:10:07 +02006833
Johan Hedberg7776d1d2014-12-05 13:36:03 +02006834 cmd->cmd_complete(cmd, mgmt_status(status));
Johan Hedberga664b5b2011-02-19 12:06:02 -03006835 mgmt_pending_remove(cmd);
Johan Hedberg980e1a52011-01-22 06:10:07 +02006836}
6837
Marcel Holtmann3eb38522013-10-15 14:26:22 -07006838void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
6839 u8 status)
Johan Hedberg980e1a52011-01-22 06:10:07 +02006840{
6841 struct pending_cmd *cmd;
Johan Hedberg980e1a52011-01-22 06:10:07 +02006842
Johan Hedberg2e58ef32011-11-08 20:40:15 +02006843 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +02006844 if (!cmd)
Marcel Holtmann3eb38522013-10-15 14:26:22 -07006845 return;
Johan Hedberg980e1a52011-01-22 06:10:07 +02006846
Johan Hedberg7776d1d2014-12-05 13:36:03 +02006847 cmd->cmd_complete(cmd, mgmt_status(status));
Johan Hedberga664b5b2011-02-19 12:06:02 -03006848 mgmt_pending_remove(cmd);
Johan Hedberg980e1a52011-01-22 06:10:07 +02006849}
Johan Hedberga5c29682011-02-19 12:05:57 -03006850
Johan Hedberg744cf192011-11-08 20:40:14 +02006851int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
Johan Hedberg39adbff2014-03-20 08:18:14 +02006852 u8 link_type, u8 addr_type, u32 value,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006853 u8 confirm_hint)
Johan Hedberga5c29682011-02-19 12:05:57 -03006854{
6855 struct mgmt_ev_user_confirm_request ev;
6856
Johan Hedberg744cf192011-11-08 20:40:14 +02006857 BT_DBG("%s", hdev->name);
Johan Hedberga5c29682011-02-19 12:05:57 -03006858
Johan Hedberg272d90d2012-02-09 15:26:12 +02006859 bacpy(&ev.addr.bdaddr, bdaddr);
Andre Guedes57c14772012-04-24 21:02:50 -03006860 ev.addr.type = link_to_bdaddr(link_type, addr_type);
Johan Hedberg55bc1a32011-04-28 11:28:56 -07006861 ev.confirm_hint = confirm_hint;
Johan Hedberg39adbff2014-03-20 08:18:14 +02006862 ev.value = cpu_to_le32(value);
Johan Hedberga5c29682011-02-19 12:05:57 -03006863
Johan Hedberg744cf192011-11-08 20:40:14 +02006864 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev),
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006865 NULL);
Johan Hedberga5c29682011-02-19 12:05:57 -03006866}
6867
Johan Hedberg272d90d2012-02-09 15:26:12 +02006868int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03006869 u8 link_type, u8 addr_type)
Brian Gix604086b2011-11-23 08:28:33 -08006870{
6871 struct mgmt_ev_user_passkey_request ev;
6872
6873 BT_DBG("%s", hdev->name);
6874
Johan Hedberg272d90d2012-02-09 15:26:12 +02006875 bacpy(&ev.addr.bdaddr, bdaddr);
Andre Guedes57c14772012-04-24 21:02:50 -03006876 ev.addr.type = link_to_bdaddr(link_type, addr_type);
Brian Gix604086b2011-11-23 08:28:33 -08006877
6878 return mgmt_event(MGMT_EV_USER_PASSKEY_REQUEST, hdev, &ev, sizeof(ev),
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006879 NULL);
Brian Gix604086b2011-11-23 08:28:33 -08006880}
6881
Brian Gix0df4c182011-11-16 13:53:13 -08006882static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
Gustavo Padovan8ce8e2b2012-05-17 00:36:20 -03006883 u8 link_type, u8 addr_type, u8 status,
6884 u8 opcode)
Johan Hedberga5c29682011-02-19 12:05:57 -03006885{
6886 struct pending_cmd *cmd;
Johan Hedberga5c29682011-02-19 12:05:57 -03006887
Johan Hedberg2e58ef32011-11-08 20:40:15 +02006888 cmd = mgmt_pending_find(opcode, hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03006889 if (!cmd)
6890 return -ENOENT;
6891
Johan Hedberg7776d1d2014-12-05 13:36:03 +02006892 cmd->cmd_complete(cmd, mgmt_status(status));
Johan Hedberga664b5b2011-02-19 12:06:02 -03006893 mgmt_pending_remove(cmd);
Johan Hedberga5c29682011-02-19 12:05:57 -03006894
Johan Hedberg7776d1d2014-12-05 13:36:03 +02006895 return 0;
Johan Hedberga5c29682011-02-19 12:05:57 -03006896}
6897
Johan Hedberg744cf192011-11-08 20:40:14 +02006898int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006899 u8 link_type, u8 addr_type, u8 status)
Johan Hedberga5c29682011-02-19 12:05:57 -03006900{
Johan Hedberg272d90d2012-02-09 15:26:12 +02006901 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006902 status, MGMT_OP_USER_CONFIRM_REPLY);
Johan Hedberga5c29682011-02-19 12:05:57 -03006903}
6904
Johan Hedberg272d90d2012-02-09 15:26:12 +02006905int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006906 u8 link_type, u8 addr_type, u8 status)
Johan Hedberga5c29682011-02-19 12:05:57 -03006907{
Johan Hedberg272d90d2012-02-09 15:26:12 +02006908 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03006909 status,
6910 MGMT_OP_USER_CONFIRM_NEG_REPLY);
Johan Hedberga5c29682011-02-19 12:05:57 -03006911}
Johan Hedberg2a611692011-02-19 12:06:00 -03006912
Brian Gix604086b2011-11-23 08:28:33 -08006913int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006914 u8 link_type, u8 addr_type, u8 status)
Brian Gix604086b2011-11-23 08:28:33 -08006915{
Johan Hedberg272d90d2012-02-09 15:26:12 +02006916 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006917 status, MGMT_OP_USER_PASSKEY_REPLY);
Brian Gix604086b2011-11-23 08:28:33 -08006918}
6919
Johan Hedberg272d90d2012-02-09 15:26:12 +02006920int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006921 u8 link_type, u8 addr_type, u8 status)
Brian Gix604086b2011-11-23 08:28:33 -08006922{
Johan Hedberg272d90d2012-02-09 15:26:12 +02006923 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03006924 status,
6925 MGMT_OP_USER_PASSKEY_NEG_REPLY);
Brian Gix604086b2011-11-23 08:28:33 -08006926}
6927
Johan Hedberg92a25252012-09-06 18:39:26 +03006928int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr,
6929 u8 link_type, u8 addr_type, u32 passkey,
6930 u8 entered)
6931{
6932 struct mgmt_ev_passkey_notify ev;
6933
6934 BT_DBG("%s", hdev->name);
6935
6936 bacpy(&ev.addr.bdaddr, bdaddr);
6937 ev.addr.type = link_to_bdaddr(link_type, addr_type);
6938 ev.passkey = __cpu_to_le32(passkey);
6939 ev.entered = entered;
6940
6941 return mgmt_event(MGMT_EV_PASSKEY_NOTIFY, hdev, &ev, sizeof(ev), NULL);
6942}
6943
Johan Hedberge1e930f2014-09-08 17:09:49 -07006944void mgmt_auth_failed(struct hci_conn *conn, u8 hci_status)
Johan Hedberg2a611692011-02-19 12:06:00 -03006945{
6946 struct mgmt_ev_auth_failed ev;
Johan Hedberge1e930f2014-09-08 17:09:49 -07006947 struct pending_cmd *cmd;
6948 u8 status = mgmt_status(hci_status);
Johan Hedberg2a611692011-02-19 12:06:00 -03006949
Johan Hedberge1e930f2014-09-08 17:09:49 -07006950 bacpy(&ev.addr.bdaddr, &conn->dst);
6951 ev.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
6952 ev.status = status;
Johan Hedberg2a611692011-02-19 12:06:00 -03006953
Johan Hedberge1e930f2014-09-08 17:09:49 -07006954 cmd = find_pairing(conn);
6955
6956 mgmt_event(MGMT_EV_AUTH_FAILED, conn->hdev, &ev, sizeof(ev),
6957 cmd ? cmd->sk : NULL);
6958
Johan Hedberga511b352014-12-11 21:45:45 +02006959 if (cmd) {
6960 cmd->cmd_complete(cmd, status);
6961 mgmt_pending_remove(cmd);
6962 }
Johan Hedberg2a611692011-02-19 12:06:00 -03006963}
Johan Hedbergb312b1612011-03-16 14:29:37 +02006964
Marcel Holtmann464996a2013-10-15 14:26:24 -07006965void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
Johan Hedberg33ef95e2012-02-16 23:56:27 +02006966{
6967 struct cmd_lookup match = { NULL, hdev };
Marcel Holtmann464996a2013-10-15 14:26:24 -07006968 bool changed;
Johan Hedberg33ef95e2012-02-16 23:56:27 +02006969
6970 if (status) {
6971 u8 mgmt_err = mgmt_status(status);
6972 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006973 cmd_status_rsp, &mgmt_err);
Marcel Holtmann464996a2013-10-15 14:26:24 -07006974 return;
Johan Hedberg33ef95e2012-02-16 23:56:27 +02006975 }
6976
Marcel Holtmann464996a2013-10-15 14:26:24 -07006977 if (test_bit(HCI_AUTH, &hdev->flags))
6978 changed = !test_and_set_bit(HCI_LINK_SECURITY,
6979 &hdev->dev_flags);
6980 else
6981 changed = test_and_clear_bit(HCI_LINK_SECURITY,
6982 &hdev->dev_flags);
Johan Hedberg47990ea2012-02-22 11:58:37 +02006983
Johan Hedberg33ef95e2012-02-16 23:56:27 +02006984 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03006985 &match);
Johan Hedberg33ef95e2012-02-16 23:56:27 +02006986
Johan Hedberg47990ea2012-02-22 11:58:37 +02006987 if (changed)
Marcel Holtmann464996a2013-10-15 14:26:24 -07006988 new_settings(hdev, match.sk);
Johan Hedberg33ef95e2012-02-16 23:56:27 +02006989
6990 if (match.sk)
6991 sock_put(match.sk);
Johan Hedberg33ef95e2012-02-16 23:56:27 +02006992}
6993
Johan Hedberg890ea892013-03-15 17:06:52 -05006994static void clear_eir(struct hci_request *req)
Johan Hedbergcacaf522012-02-21 00:52:42 +02006995{
Johan Hedberg890ea892013-03-15 17:06:52 -05006996 struct hci_dev *hdev = req->hdev;
Johan Hedbergcacaf522012-02-21 00:52:42 +02006997 struct hci_cp_write_eir cp;
6998
Johan Hedberg976eb202012-10-24 21:12:01 +03006999 if (!lmp_ext_inq_capable(hdev))
Johan Hedberg890ea892013-03-15 17:06:52 -05007000 return;
Johan Hedbergcacaf522012-02-21 00:52:42 +02007001
Johan Hedbergc80da272012-02-22 15:38:48 +02007002 memset(hdev->eir, 0, sizeof(hdev->eir));
7003
Johan Hedbergcacaf522012-02-21 00:52:42 +02007004 memset(&cp, 0, sizeof(cp));
7005
Johan Hedberg890ea892013-03-15 17:06:52 -05007006 hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
Johan Hedbergcacaf522012-02-21 00:52:42 +02007007}
7008
Marcel Holtmann3e248562013-10-15 14:26:25 -07007009void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
Johan Hedberged2c4ee2012-02-17 00:56:28 +02007010{
7011 struct cmd_lookup match = { NULL, hdev };
Johan Hedberg890ea892013-03-15 17:06:52 -05007012 struct hci_request req;
Johan Hedbergc0ecddc2012-02-22 12:38:31 +02007013 bool changed = false;
Johan Hedberged2c4ee2012-02-17 00:56:28 +02007014
7015 if (status) {
7016 u8 mgmt_err = mgmt_status(status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +02007017
7018 if (enable && test_and_clear_bit(HCI_SSP_ENABLED,
Marcel Holtmann9ecb3e22013-10-10 03:08:11 -07007019 &hdev->dev_flags)) {
7020 clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
Marcel Holtmann3e248562013-10-15 14:26:25 -07007021 new_settings(hdev, NULL);
Marcel Holtmann9ecb3e22013-10-10 03:08:11 -07007022 }
Johan Hedbergc0ecddc2012-02-22 12:38:31 +02007023
Gustavo F. Padovan04124682012-03-08 01:25:00 -03007024 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp,
7025 &mgmt_err);
Marcel Holtmann3e248562013-10-15 14:26:25 -07007026 return;
Johan Hedbergc0ecddc2012-02-22 12:38:31 +02007027 }
7028
7029 if (enable) {
Marcel Holtmann9ecb3e22013-10-10 03:08:11 -07007030 changed = !test_and_set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +02007031 } else {
Marcel Holtmann9ecb3e22013-10-10 03:08:11 -07007032 changed = test_and_clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
7033 if (!changed)
7034 changed = test_and_clear_bit(HCI_HS_ENABLED,
7035 &hdev->dev_flags);
7036 else
7037 clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
Johan Hedberged2c4ee2012-02-17 00:56:28 +02007038 }
7039
7040 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);
7041
Johan Hedbergc0ecddc2012-02-22 12:38:31 +02007042 if (changed)
Marcel Holtmann3e248562013-10-15 14:26:25 -07007043 new_settings(hdev, match.sk);
Johan Hedberged2c4ee2012-02-17 00:56:28 +02007044
Johan Hedberg5fc6ebb2012-02-22 15:10:59 +02007045 if (match.sk)
Johan Hedberged2c4ee2012-02-17 00:56:28 +02007046 sock_put(match.sk);
7047
Johan Hedberg890ea892013-03-15 17:06:52 -05007048 hci_req_init(&req, hdev);
7049
Johan Hedberg37699722014-06-24 14:00:27 +03007050 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
7051 if (test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags))
7052 hci_req_add(&req, HCI_OP_WRITE_SSP_DEBUG_MODE,
7053 sizeof(enable), &enable);
Johan Hedberg890ea892013-03-15 17:06:52 -05007054 update_eir(&req);
Johan Hedberg37699722014-06-24 14:00:27 +03007055 } else {
Johan Hedberg890ea892013-03-15 17:06:52 -05007056 clear_eir(&req);
Johan Hedberg37699722014-06-24 14:00:27 +03007057 }
Johan Hedberg890ea892013-03-15 17:06:52 -05007058
7059 hci_req_run(&req, NULL);
Johan Hedberged2c4ee2012-02-17 00:56:28 +02007060}
7061
Johan Hedberg92da6092013-03-15 17:06:55 -05007062static void sk_lookup(struct pending_cmd *cmd, void *data)
Johan Hedberg90e70452012-02-23 23:09:40 +02007063{
7064 struct cmd_lookup *match = data;
7065
Johan Hedberg90e70452012-02-23 23:09:40 +02007066 if (match->sk == NULL) {
7067 match->sk = cmd->sk;
7068 sock_hold(match->sk);
7069 }
Johan Hedberg90e70452012-02-23 23:09:40 +02007070}
7071
Marcel Holtmann4e1b0242013-10-15 14:26:26 -07007072void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
7073 u8 status)
Marcel Holtmann7f9a9032012-02-22 18:38:01 +01007074{
Johan Hedberg90e70452012-02-23 23:09:40 +02007075 struct cmd_lookup match = { NULL, hdev, mgmt_status(status) };
Marcel Holtmann7f9a9032012-02-22 18:38:01 +01007076
Johan Hedberg92da6092013-03-15 17:06:55 -05007077 mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match);
7078 mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match);
7079 mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match);
Johan Hedberg90e70452012-02-23 23:09:40 +02007080
7081 if (!status)
Marcel Holtmann4e1b0242013-10-15 14:26:26 -07007082 mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, 3,
7083 NULL);
Johan Hedberg90e70452012-02-23 23:09:40 +02007084
7085 if (match.sk)
7086 sock_put(match.sk);
Marcel Holtmann7f9a9032012-02-22 18:38:01 +01007087}
7088
Marcel Holtmann7667da32013-10-15 14:26:27 -07007089void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
Johan Hedbergb312b1612011-03-16 14:29:37 +02007090{
Johan Hedbergb312b1612011-03-16 14:29:37 +02007091 struct mgmt_cp_set_local_name ev;
Johan Hedberg13928972013-03-15 17:07:00 -05007092 struct pending_cmd *cmd;
Johan Hedberg28cc7bd2012-02-22 21:06:55 +02007093
Johan Hedberg13928972013-03-15 17:07:00 -05007094 if (status)
Marcel Holtmann7667da32013-10-15 14:26:27 -07007095 return;
Johan Hedbergb312b1612011-03-16 14:29:37 +02007096
7097 memset(&ev, 0, sizeof(ev));
7098 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +02007099 memcpy(ev.short_name, hdev->short_name, HCI_MAX_SHORT_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +02007100
Johan Hedberg2e58ef32011-11-08 20:40:15 +02007101 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev);
Johan Hedberg13928972013-03-15 17:07:00 -05007102 if (!cmd) {
7103 memcpy(hdev->dev_name, name, sizeof(hdev->dev_name));
Johan Hedbergb312b1612011-03-16 14:29:37 +02007104
Johan Hedberg13928972013-03-15 17:07:00 -05007105 /* If this is a HCI command related to powering on the
7106 * HCI dev don't send any mgmt signals.
7107 */
7108 if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
Marcel Holtmann7667da32013-10-15 14:26:27 -07007109 return;
Johan Hedbergb312b1612011-03-16 14:29:37 +02007110 }
7111
Marcel Holtmann7667da32013-10-15 14:26:27 -07007112 mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev),
7113 cmd ? cmd->sk : NULL);
Johan Hedbergb312b1612011-03-16 14:29:37 +02007114}
Szymon Jancc35938b2011-03-22 13:12:21 +01007115
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08007116void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
Johan Hedberg38da1702014-11-17 20:52:20 +02007117 u8 *rand192, u8 *hash256, u8 *rand256,
7118 u8 status)
Szymon Jancc35938b2011-03-22 13:12:21 +01007119{
7120 struct pending_cmd *cmd;
Szymon Jancc35938b2011-03-22 13:12:21 +01007121
Johan Hedberg744cf192011-11-08 20:40:14 +02007122 BT_DBG("%s status %u", hdev->name, status);
Szymon Jancc35938b2011-03-22 13:12:21 +01007123
Johan Hedberg2e58ef32011-11-08 20:40:15 +02007124 cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01007125 if (!cmd)
Marcel Holtmann3edaf092013-10-15 14:26:28 -07007126 return;
Szymon Jancc35938b2011-03-22 13:12:21 +01007127
7128 if (status) {
Marcel Holtmann3edaf092013-10-15 14:26:28 -07007129 cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
7130 mgmt_status(status));
Szymon Jancc35938b2011-03-22 13:12:21 +01007131 } else {
Johan Hedberg710f11c2014-05-26 11:21:22 +03007132 if (bredr_sc_enabled(hdev) && hash256 && rand256) {
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08007133 struct mgmt_rp_read_local_oob_ext_data rp;
Szymon Jancc35938b2011-03-22 13:12:21 +01007134
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08007135 memcpy(rp.hash192, hash192, sizeof(rp.hash192));
Johan Hedberg38da1702014-11-17 20:52:20 +02007136 memcpy(rp.rand192, rand192, sizeof(rp.rand192));
Szymon Jancc35938b2011-03-22 13:12:21 +01007137
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08007138 memcpy(rp.hash256, hash256, sizeof(rp.hash256));
Johan Hedberg38da1702014-11-17 20:52:20 +02007139 memcpy(rp.rand256, rand256, sizeof(rp.rand256));
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08007140
7141 cmd_complete(cmd->sk, hdev->id,
7142 MGMT_OP_READ_LOCAL_OOB_DATA, 0,
7143 &rp, sizeof(rp));
7144 } else {
7145 struct mgmt_rp_read_local_oob_data rp;
7146
7147 memcpy(rp.hash, hash192, sizeof(rp.hash));
Johan Hedberg38da1702014-11-17 20:52:20 +02007148 memcpy(rp.rand, rand192, sizeof(rp.rand));
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08007149
7150 cmd_complete(cmd->sk, hdev->id,
7151 MGMT_OP_READ_LOCAL_OOB_DATA, 0,
7152 &rp, sizeof(rp));
7153 }
Szymon Jancc35938b2011-03-22 13:12:21 +01007154 }
7155
7156 mgmt_pending_remove(cmd);
Szymon Jancc35938b2011-03-22 13:12:21 +01007157}
Johan Hedberge17acd42011-03-30 23:57:16 +03007158
Jakub Pawlowski799ce932014-12-05 10:55:58 +01007159static inline bool has_uuid(u8 *uuid, u16 uuid_count, u8 (*uuids)[16])
7160{
7161 int i;
7162
7163 for (i = 0; i < uuid_count; i++) {
7164 if (!memcmp(uuid, uuids[i], 16))
7165 return true;
7166 }
7167
7168 return false;
7169}
7170
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007171static bool eir_has_uuids(u8 *eir, u16 eir_len, u16 uuid_count, u8 (*uuids)[16])
7172{
Jakub Pawlowski799ce932014-12-05 10:55:58 +01007173 u16 parsed = 0;
7174
7175 while (parsed < eir_len) {
7176 u8 field_len = eir[0];
7177 u8 uuid[16];
7178 int i;
7179
7180 if (field_len == 0)
7181 break;
7182
7183 if (eir_len - parsed < field_len + 1)
7184 break;
7185
7186 switch (eir[1]) {
7187 case EIR_UUID16_ALL:
7188 case EIR_UUID16_SOME:
7189 for (i = 0; i + 3 <= field_len; i += 2) {
Johan Hedberg189f6ad2014-12-05 13:40:01 +02007190 memcpy(uuid, bluetooth_base_uuid, 16);
Jakub Pawlowski799ce932014-12-05 10:55:58 +01007191 uuid[13] = eir[i + 3];
7192 uuid[12] = eir[i + 2];
7193 if (has_uuid(uuid, uuid_count, uuids))
7194 return true;
7195 }
7196 break;
7197 case EIR_UUID32_ALL:
7198 case EIR_UUID32_SOME:
7199 for (i = 0; i + 5 <= field_len; i += 4) {
Johan Hedberg189f6ad2014-12-05 13:40:01 +02007200 memcpy(uuid, bluetooth_base_uuid, 16);
Jakub Pawlowski799ce932014-12-05 10:55:58 +01007201 uuid[15] = eir[i + 5];
7202 uuid[14] = eir[i + 4];
7203 uuid[13] = eir[i + 3];
7204 uuid[12] = eir[i + 2];
7205 if (has_uuid(uuid, uuid_count, uuids))
7206 return true;
7207 }
7208 break;
7209 case EIR_UUID128_ALL:
7210 case EIR_UUID128_SOME:
7211 for (i = 0; i + 17 <= field_len; i += 16) {
7212 memcpy(uuid, eir + i + 2, 16);
7213 if (has_uuid(uuid, uuid_count, uuids))
7214 return true;
7215 }
7216 break;
7217 }
7218
7219 parsed += field_len + 1;
7220 eir += field_len + 1;
7221 }
7222
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007223 return false;
7224}
7225
Marcel Holtmann901801b2013-10-06 23:55:51 -07007226void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
Marcel Holtmannaf589252014-07-01 14:11:20 +02007227 u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
7228 u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
Johan Hedberge17acd42011-03-30 23:57:16 +03007229{
Johan Hedberge319d2e2012-01-15 19:51:59 +02007230 char buf[512];
7231 struct mgmt_ev_device_found *ev = (void *) buf;
Johan Hedberg1dc06092012-01-15 21:01:23 +02007232 size_t ev_size;
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007233 bool match;
Johan Hedberge17acd42011-03-30 23:57:16 +03007234
Johan Hedberg75ce2082014-07-02 22:42:01 +03007235 /* Don't send events for a non-kernel initiated discovery. With
7236 * LE one exception is if we have pend_le_reports > 0 in which
7237 * case we're doing passive scanning and want these events.
7238 */
7239 if (!hci_discovery_active(hdev)) {
7240 if (link_type == ACL_LINK)
7241 return;
Johan Hedberg66f84552014-07-04 12:37:18 +03007242 if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports))
Johan Hedberg75ce2082014-07-02 22:42:01 +03007243 return;
7244 }
Andre Guedes12602d02013-04-30 15:29:40 -03007245
Marcel Holtmannbda157a2014-12-05 10:55:56 +01007246 /* When using service discovery with a RSSI threshold, then check
7247 * if such a RSSI threshold is specified. If a RSSI threshold has
7248 * been specified, then all results with a RSSI smaller than the
7249 * RSSI threshold will be dropped.
Marcel Holtmannefb25132014-12-05 13:03:34 +01007250 *
7251 * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry,
7252 * the results are also dropped.
Marcel Holtmannbda157a2014-12-05 10:55:56 +01007253 */
7254 if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
Marcel Holtmannefb25132014-12-05 13:03:34 +01007255 (rssi < hdev->discovery.rssi || rssi == HCI_RSSI_INVALID))
Marcel Holtmannbda157a2014-12-05 10:55:56 +01007256 return;
7257
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02007258 /* Make sure that the buffer is big enough. The 5 extra bytes
7259 * are for the potential CoD field.
7260 */
7261 if (sizeof(*ev) + eir_len + scan_rsp_len + 5 > sizeof(buf))
Marcel Holtmann901801b2013-10-06 23:55:51 -07007262 return;
Andre Guedes7d262f82012-01-10 18:20:49 -03007263
Johan Hedberg1dc06092012-01-15 21:01:23 +02007264 memset(buf, 0, sizeof(buf));
7265
Marcel Holtmannda25cf62014-12-05 13:03:35 +01007266 /* In case of device discovery with BR/EDR devices (pre 1.2), the
7267 * RSSI value was reported as 0 when not available. This behavior
7268 * is kept when using device discovery. This is required for full
7269 * backwards compatibility with the API.
7270 *
7271 * However when using service discovery, the value 127 will be
7272 * returned when the RSSI is not available.
7273 */
Szymon Janc91200e92015-01-22 16:57:05 +01007274 if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi &&
7275 link_type == ACL_LINK)
Marcel Holtmannefb25132014-12-05 13:03:34 +01007276 rssi = 0;
7277
Johan Hedberg841c5642014-07-07 12:45:54 +03007278 bacpy(&ev->addr.bdaddr, bdaddr);
7279 ev->addr.type = link_to_bdaddr(link_type, addr_type);
Johan Hedberge319d2e2012-01-15 19:51:59 +02007280 ev->rssi = rssi;
Marcel Holtmannaf589252014-07-01 14:11:20 +02007281 ev->flags = cpu_to_le32(flags);
Johan Hedberge17acd42011-03-30 23:57:16 +03007282
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007283 if (eir_len > 0) {
7284 /* When using service discovery and a list of UUID is
7285 * provided, results with no matching UUID should be
7286 * dropped. In case there is a match the result is
7287 * kept and checking possible scan response data
7288 * will be skipped.
7289 */
Marcel Holtmannea8ae252014-12-17 18:18:08 +01007290 if (hdev->discovery.uuid_count > 0)
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007291 match = eir_has_uuids(eir, eir_len,
7292 hdev->discovery.uuid_count,
7293 hdev->discovery.uuids);
Marcel Holtmannea8ae252014-12-17 18:18:08 +01007294 else
7295 match = true;
7296
7297 if (!match && !scan_rsp_len)
7298 return;
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007299
7300 /* Copy EIR or advertising data into event */
Johan Hedberge319d2e2012-01-15 19:51:59 +02007301 memcpy(ev->eir, eir, eir_len);
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007302 } else {
7303 /* When using service discovery and a list of UUID is
7304 * provided, results with empty EIR or advertising data
7305 * should be dropped since they do not match any UUID.
7306 */
Marcel Holtmannea8ae252014-12-17 18:18:08 +01007307 if (hdev->discovery.uuid_count > 0 && !scan_rsp_len)
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007308 return;
Marcel Holtmannea8ae252014-12-17 18:18:08 +01007309
7310 match = false;
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007311 }
Johan Hedberge17acd42011-03-30 23:57:16 +03007312
Johan Hedberg1dc06092012-01-15 21:01:23 +02007313 if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
7314 eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03007315 dev_class, 3);
Johan Hedberg1dc06092012-01-15 21:01:23 +02007316
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007317 if (scan_rsp_len > 0) {
7318 /* When using service discovery and a list of UUID is
7319 * provided, results with no matching UUID should be
7320 * dropped if there is no previous match from the
7321 * advertising data.
7322 */
7323 if (hdev->discovery.uuid_count > 0) {
7324 if (!match && !eir_has_uuids(scan_rsp, scan_rsp_len,
7325 hdev->discovery.uuid_count,
7326 hdev->discovery.uuids))
7327 return;
7328 }
7329
7330 /* Append scan response data to event */
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02007331 memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len);
Marcel Holtmannb487b9c2014-12-05 10:55:57 +01007332 } else {
7333 /* When using service discovery and a list of UUID is
7334 * provided, results with empty scan response and no
7335 * previous matched advertising data should be dropped.
7336 */
7337 if (hdev->discovery.uuid_count > 0 && !match)
7338 return;
7339 }
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02007340
7341 ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len);
7342 ev_size = sizeof(*ev) + eir_len + scan_rsp_len;
Andre Guedesf8523592011-09-09 18:56:26 -03007343
Marcel Holtmann901801b2013-10-06 23:55:51 -07007344 mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL);
Johan Hedberge17acd42011-03-30 23:57:16 +03007345}
Johan Hedberga88a9652011-03-30 13:18:12 +03007346
Marcel Holtmann9cf12ae2013-10-06 23:55:52 -07007347void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
7348 u8 addr_type, s8 rssi, u8 *name, u8 name_len)
Johan Hedberga88a9652011-03-30 13:18:12 +03007349{
Johan Hedbergb644ba32012-01-17 21:48:47 +02007350 struct mgmt_ev_device_found *ev;
7351 char buf[sizeof(*ev) + HCI_MAX_NAME_LENGTH + 2];
7352 u16 eir_len;
Johan Hedberga88a9652011-03-30 13:18:12 +03007353
Johan Hedbergb644ba32012-01-17 21:48:47 +02007354 ev = (struct mgmt_ev_device_found *) buf;
Johan Hedberga88a9652011-03-30 13:18:12 +03007355
Johan Hedbergb644ba32012-01-17 21:48:47 +02007356 memset(buf, 0, sizeof(buf));
Johan Hedberga88a9652011-03-30 13:18:12 +03007357
Johan Hedbergb644ba32012-01-17 21:48:47 +02007358 bacpy(&ev->addr.bdaddr, bdaddr);
Andre Guedes57c14772012-04-24 21:02:50 -03007359 ev->addr.type = link_to_bdaddr(link_type, addr_type);
Johan Hedbergb644ba32012-01-17 21:48:47 +02007360 ev->rssi = rssi;
7361
7362 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03007363 name_len);
Johan Hedbergb644ba32012-01-17 21:48:47 +02007364
Marcel Holtmanneb55ef02012-03-14 18:08:46 +02007365 ev->eir_len = cpu_to_le16(eir_len);
Johan Hedbergb644ba32012-01-17 21:48:47 +02007366
Marcel Holtmann9cf12ae2013-10-06 23:55:52 -07007367 mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, sizeof(*ev) + eir_len, NULL);
Johan Hedberga88a9652011-03-30 13:18:12 +03007368}
Johan Hedberg314b2382011-04-27 10:29:57 -04007369
Marcel Holtmann2f1e0632013-10-06 23:55:53 -07007370void mgmt_discovering(struct hci_dev *hdev, u8 discovering)
Johan Hedberg314b2382011-04-27 10:29:57 -04007371{
Johan Hedbergf963e8e2012-02-20 23:30:44 +02007372 struct mgmt_ev_discovering ev;
Johan Hedberg164a6e72011-11-01 17:06:44 +02007373
Andre Guedes343fb142011-11-22 17:14:19 -03007374 BT_DBG("%s discovering %u", hdev->name, discovering);
7375
Johan Hedbergf963e8e2012-02-20 23:30:44 +02007376 memset(&ev, 0, sizeof(ev));
7377 ev.type = hdev->discovery.type;
7378 ev.discovering = discovering;
7379
Marcel Holtmann2f1e0632013-10-06 23:55:53 -07007380 mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL);
Johan Hedberg314b2382011-04-27 10:29:57 -04007381}
Antti Julku5e762442011-08-25 16:48:02 +03007382
Marcel Holtmann1904a852015-01-11 13:50:44 -08007383static void adv_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
Marcel Holtmann5976e602013-10-06 04:08:14 -07007384{
7385 BT_DBG("%s status %u", hdev->name, status);
Marcel Holtmann5976e602013-10-06 04:08:14 -07007386}
7387
7388void mgmt_reenable_advertising(struct hci_dev *hdev)
7389{
7390 struct hci_request req;
7391
Marcel Holtmann5976e602013-10-06 04:08:14 -07007392 if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
7393 return;
7394
7395 hci_req_init(&req, hdev);
7396 enable_advertising(&req);
Johan Hedberg0ec5ae82014-07-08 15:07:50 +03007397 hci_req_run(&req, adv_enable_complete);
Marcel Holtmann5976e602013-10-06 04:08:14 -07007398}