Merge lp:~timchen119/ubuntu/utopic/bluez/lp1035431 into lp:ubuntu/utopic/bluez
- Utopic (14.10)
- lp1035431
- Merge into utopic
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Mathieu Trudel-Lapierre | ||||
Approved revision: | 116 | ||||
Merge reported by: | Mathieu Trudel-Lapierre | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~timchen119/ubuntu/utopic/bluez/lp1035431 | ||||
Merge into: | lp:ubuntu/utopic/bluez | ||||
Diff against target: |
15522 lines (+15164/-63) 28 files modified
.pc/applied-patches (+1/-0) .pc/ssp_parameter.patch/doc/agent-api.txt (+123/-0) .pc/ssp_parameter.patch/lib/hci.h (+2391/-0) .pc/ssp_parameter.patch/lib/mgmt.h (+554/-0) .pc/ssp_parameter.patch/plugins/hciops.c (+3943/-0) .pc/ssp_parameter.patch/plugins/mgmtops.c (+2523/-0) .pc/ssp_parameter.patch/src/agent.c (+844/-0) .pc/ssp_parameter.patch/src/agent.h (+80/-0) .pc/ssp_parameter.patch/src/device.c (+3164/-0) .pc/ssp_parameter.patch/src/device.h (+128/-0) .pc/ssp_parameter.patch/src/event.c (+571/-0) .pc/ssp_parameter.patch/src/event.h (+49/-0) .pc/ssp_parameter.patch/test/simple-agent (+144/-0) debian/changelog (+19/-0) debian/patches/series (+1/-0) debian/patches/ssp_parameter.patch (+439/-0) doc/agent-api.txt (+2/-1) lib/hci.h (+2/-1) lib/mgmt.h (+7/-0) plugins/hciops.c (+1/-1) plugins/mgmtops.c (+37/-0) src/agent.c (+4/-1) src/agent.h (+1/-1) src/device.c (+116/-40) src/device.h (+9/-2) src/event.c (+7/-12) src/event.h (+1/-1) test/simple-agent (+3/-3) |
||||
To merge this branch: | bzr merge lp:~timchen119/ubuntu/utopic/bluez/lp1035431 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mathieu Trudel-Lapierre | Approve | ||
Review via email: mp+219626@code.launchpad.net |
Commit message
Description of the change
This fixed the issue for the paring issue on Logitech K810 and HP bluetooth keyboard K4000 and should also fixed any ssp paired bluetooth keyboard.
The root problem here is that in bluez4, the doc (agent-api.txt), specific that the
function
void DisplayPasskey(
however in bluez4's src/agent.c agent_display_
didn't pass the entered correct "enter" parameter,
and most of client implementation in linux (at least gnome-bluetooth, bluedevil, blueman) follows the specification in the api document so they never receive correct parameter.
This is already fixed in bluez5,
however due to the compatibility issue between bluez4 and bluez5
this never being backported in bluez4.
Another related merge is at https:/
gnome-bluetooth do follow the doc and, but still have issues when display the number,
the number will not correctly display in current implementation,
however gnome-bluetooth is being removed in recent gnome upstream, so we need to maintain a ubuntu distro patch here.
This request is from our OEM so please help to review these patch and see if there's things I can improve this patch. If the patch is accepted I'll send SRUs to trusty (OEM shipping image is LTS based, so it will be trusty right now).
Mathieu Trudel-Lapierre (cyphermox) wrote : | # |
Tim Chen (timchen119) wrote : | # |
@Mathieu
Thanks for the review and bring this up,
the reason behind this inconsistency is because it's how bluez5 doing it and I don't plan to modify too much upstream code when porting, upstream commit 6a394b2c7f19b53
=======
commit 6a394b2c7f19b53
Author: Johan Hedberg <email address hidden>
Date: Tue Sep 4 13:49:58 2012 +0300
agent-api: DisplayPasskey: D-Bus doesn't have a uint8 type
#git-upstream/
agent.c-
agent.c-int agent_display_
agent.c: uint32_t passkey, uint16_t entered)
agent.c-{
agent.c- DBusMessage *message;
--
agent.h-
agent.h-int agent_display_
agent.h: uint32_t passkey, uint16_t entered);
agent.h-
agent.h-int agent_display_
--
device.c-
device.c-int device_
device.c: uint8_t entered)
device.c-{
device.c- struct authentication_req *auth;
--
device.h- uint8_t confirm_hint);
device.h-int device_
device.h: uint8_t entered);
device.h-int device_
device.h- const char *pincode);
Mathieu Trudel-Lapierre (cyphermox) wrote : | # |
Alright, let's land this.
Preview Diff
1 | === modified file '.pc/applied-patches' |
2 | --- .pc/applied-patches 2014-04-08 10:54:11 +0000 |
3 | +++ .pc/applied-patches 2014-05-15 03:26:22 +0000 |
4 | @@ -14,3 +14,4 @@ |
5 | telephony_ofono_add_watch.patch |
6 | 12_check_device_before_removing_from_devices.patch |
7 | 13_reset_default_adapter_id.patch |
8 | +ssp_parameter.patch |
9 | |
10 | === added directory '.pc/ssp_parameter.patch' |
11 | === added directory '.pc/ssp_parameter.patch/doc' |
12 | === added file '.pc/ssp_parameter.patch/doc/agent-api.txt' |
13 | --- .pc/ssp_parameter.patch/doc/agent-api.txt 1970-01-01 00:00:00 +0000 |
14 | +++ .pc/ssp_parameter.patch/doc/agent-api.txt 2014-05-15 03:26:22 +0000 |
15 | @@ -0,0 +1,123 @@ |
16 | +BlueZ D-Bus Agent API description |
17 | +********************************** |
18 | + |
19 | +Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> |
20 | +Copyright (C) 2005-2006 Johan Hedberg <johan.hedberg@nokia.com> |
21 | + |
22 | + |
23 | +Agent hierarchy |
24 | +=============== |
25 | + |
26 | +Service unique name |
27 | +Interface org.bluez.Agent |
28 | +Object path freely definable |
29 | + |
30 | +Methods void Release() |
31 | + |
32 | + This method gets called when the service daemon |
33 | + unregisters the agent. An agent can use it to do |
34 | + cleanup tasks. There is no need to unregister the |
35 | + agent, because when this method gets called it has |
36 | + already been unregistered. |
37 | + |
38 | + string RequestPinCode(object device) |
39 | + |
40 | + This method gets called when the service daemon |
41 | + needs to get the passkey for an authentication. |
42 | + |
43 | + The return value should be a string of 1-16 characters |
44 | + length. The string can be alphanumeric. |
45 | + |
46 | + Possible errors: org.bluez.Error.Rejected |
47 | + org.bluez.Error.Canceled |
48 | + |
49 | + uint32 RequestPasskey(object device) |
50 | + |
51 | + This method gets called when the service daemon |
52 | + needs to get the passkey for an authentication. |
53 | + |
54 | + The return value should be a numeric value |
55 | + between 0-999999. |
56 | + |
57 | + Possible errors: org.bluez.Error.Rejected |
58 | + org.bluez.Error.Canceled |
59 | + |
60 | + void DisplayPasskey(object device, uint32 passkey, uint8 entered) |
61 | + |
62 | + This method gets called when the service daemon |
63 | + needs to display a passkey for an authentication. |
64 | + |
65 | + The entered parameter indicates the number of already |
66 | + typed keys on the remote side. |
67 | + |
68 | + An empty reply should be returned. When the passkey |
69 | + needs no longer to be displayed, the Cancel method |
70 | + of the agent will be called. |
71 | + |
72 | + During the pairing process this method might be |
73 | + called multiple times to update the entered value. |
74 | + |
75 | + Note that the passkey will always be a 6-digit number, |
76 | + so the display should be zero-padded at the start if |
77 | + the value contains less than 6 digits. |
78 | + |
79 | + void DisplayPinCode(object device, string pincode) |
80 | + |
81 | + This method gets called when the service daemon |
82 | + needs to display a pincode for an authentication. |
83 | + |
84 | + An empty reply should be returned. When the pincode |
85 | + needs no longer to be displayed, the Cancel method |
86 | + of the agent will be called. |
87 | + |
88 | + If this method is not implemented the RequestPinCode |
89 | + method will be used instead. |
90 | + |
91 | + This is used during the pairing process of keyboards |
92 | + that don't support Bluetooth 2.1 Secure Simple Pairing, |
93 | + in contrast to DisplayPasskey which is used for those |
94 | + that do. |
95 | + |
96 | + This method will only ever be called once since |
97 | + older keyboards do not support typing notification. |
98 | + |
99 | + Note that the PIN will always be a 6-digit number, |
100 | + zero-padded to 6 digits. This is for harmony with |
101 | + the later specification. |
102 | + |
103 | + void RequestConfirmation(object device, uint32 passkey) |
104 | + |
105 | + This method gets called when the service daemon |
106 | + needs to confirm a passkey for an authentication. |
107 | + |
108 | + To confirm the value it should return an empty reply |
109 | + or an error in case the passkey is invalid. |
110 | + |
111 | + Note that the passkey will always be a 6-digit number, |
112 | + so the display should be zero-padded at the start if |
113 | + the value contains less than 6 digits. |
114 | + |
115 | + Possible errors: org.bluez.Error.Rejected |
116 | + org.bluez.Error.Canceled |
117 | + |
118 | + void Authorize(object device, string uuid) |
119 | + |
120 | + This method gets called when the service daemon |
121 | + needs to authorize a connection/service request. |
122 | + |
123 | + Possible errors: org.bluez.Error.Rejected |
124 | + org.bluez.Error.Canceled |
125 | + |
126 | + void ConfirmModeChange(string mode) |
127 | + |
128 | + This method gets called if a mode change is requested |
129 | + that needs to be confirmed by the user. An example |
130 | + would be leaving flight mode. |
131 | + |
132 | + Possible errors: org.bluez.Error.Rejected |
133 | + org.bluez.Error.Canceled |
134 | + |
135 | + void Cancel() |
136 | + |
137 | + This method gets called to indicate that the agent |
138 | + request failed before a reply was returned. |
139 | |
140 | === added directory '.pc/ssp_parameter.patch/lib' |
141 | === added file '.pc/ssp_parameter.patch/lib/hci.h' |
142 | --- .pc/ssp_parameter.patch/lib/hci.h 1970-01-01 00:00:00 +0000 |
143 | +++ .pc/ssp_parameter.patch/lib/hci.h 2014-05-15 03:26:22 +0000 |
144 | @@ -0,0 +1,2391 @@ |
145 | +/* |
146 | + * |
147 | + * BlueZ - Bluetooth protocol stack for Linux |
148 | + * |
149 | + * Copyright (C) 2000-2001 Qualcomm Incorporated |
150 | + * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> |
151 | + * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org> |
152 | + * |
153 | + * |
154 | + * This program is free software; you can redistribute it and/or modify |
155 | + * it under the terms of the GNU General Public License as published by |
156 | + * the Free Software Foundation; either version 2 of the License, or |
157 | + * (at your option) any later version. |
158 | + * |
159 | + * This program is distributed in the hope that it will be useful, |
160 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
161 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
162 | + * GNU General Public License for more details. |
163 | + * |
164 | + * You should have received a copy of the GNU General Public License |
165 | + * along with this program; if not, write to the Free Software |
166 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
167 | + * |
168 | + */ |
169 | + |
170 | +#ifndef __HCI_H |
171 | +#define __HCI_H |
172 | + |
173 | +#ifdef __cplusplus |
174 | +extern "C" { |
175 | +#endif |
176 | + |
177 | +#include <sys/socket.h> |
178 | + |
179 | +#define HCI_MAX_DEV 16 |
180 | + |
181 | +#define HCI_MAX_ACL_SIZE 1024 |
182 | +#define HCI_MAX_SCO_SIZE 255 |
183 | +#define HCI_MAX_EVENT_SIZE 260 |
184 | +#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) |
185 | + |
186 | +/* HCI dev events */ |
187 | +#define HCI_DEV_REG 1 |
188 | +#define HCI_DEV_UNREG 2 |
189 | +#define HCI_DEV_UP 3 |
190 | +#define HCI_DEV_DOWN 4 |
191 | +#define HCI_DEV_SUSPEND 5 |
192 | +#define HCI_DEV_RESUME 6 |
193 | + |
194 | +/* HCI bus types */ |
195 | +#define HCI_VIRTUAL 0 |
196 | +#define HCI_USB 1 |
197 | +#define HCI_PCCARD 2 |
198 | +#define HCI_UART 3 |
199 | +#define HCI_RS232 4 |
200 | +#define HCI_PCI 5 |
201 | +#define HCI_SDIO 6 |
202 | + |
203 | +/* HCI controller types */ |
204 | +#define HCI_BREDR 0x00 |
205 | +#define HCI_AMP 0x01 |
206 | + |
207 | +/* HCI device flags */ |
208 | +enum { |
209 | + HCI_UP, |
210 | + HCI_INIT, |
211 | + HCI_RUNNING, |
212 | + |
213 | + HCI_PSCAN, |
214 | + HCI_ISCAN, |
215 | + HCI_AUTH, |
216 | + HCI_ENCRYPT, |
217 | + HCI_INQUIRY, |
218 | + |
219 | + HCI_RAW, |
220 | +}; |
221 | + |
222 | +/* LE address type */ |
223 | +enum { |
224 | + LE_PUBLIC_ADDRESS = 0x00, |
225 | + LE_RANDOM_ADDRESS = 0x01 |
226 | +}; |
227 | + |
228 | +/* HCI ioctl defines */ |
229 | +#define HCIDEVUP _IOW('H', 201, int) |
230 | +#define HCIDEVDOWN _IOW('H', 202, int) |
231 | +#define HCIDEVRESET _IOW('H', 203, int) |
232 | +#define HCIDEVRESTAT _IOW('H', 204, int) |
233 | + |
234 | +#define HCIGETDEVLIST _IOR('H', 210, int) |
235 | +#define HCIGETDEVINFO _IOR('H', 211, int) |
236 | +#define HCIGETCONNLIST _IOR('H', 212, int) |
237 | +#define HCIGETCONNINFO _IOR('H', 213, int) |
238 | +#define HCIGETAUTHINFO _IOR('H', 215, int) |
239 | + |
240 | +#define HCISETRAW _IOW('H', 220, int) |
241 | +#define HCISETSCAN _IOW('H', 221, int) |
242 | +#define HCISETAUTH _IOW('H', 222, int) |
243 | +#define HCISETENCRYPT _IOW('H', 223, int) |
244 | +#define HCISETPTYPE _IOW('H', 224, int) |
245 | +#define HCISETLINKPOL _IOW('H', 225, int) |
246 | +#define HCISETLINKMODE _IOW('H', 226, int) |
247 | +#define HCISETACLMTU _IOW('H', 227, int) |
248 | +#define HCISETSCOMTU _IOW('H', 228, int) |
249 | + |
250 | +#define HCIBLOCKADDR _IOW('H', 230, int) |
251 | +#define HCIUNBLOCKADDR _IOW('H', 231, int) |
252 | + |
253 | +#define HCIINQUIRY _IOR('H', 240, int) |
254 | + |
255 | +#ifndef __NO_HCI_DEFS |
256 | + |
257 | +/* HCI Packet types */ |
258 | +#define HCI_COMMAND_PKT 0x01 |
259 | +#define HCI_ACLDATA_PKT 0x02 |
260 | +#define HCI_SCODATA_PKT 0x03 |
261 | +#define HCI_EVENT_PKT 0x04 |
262 | +#define HCI_VENDOR_PKT 0xff |
263 | + |
264 | +/* HCI Packet types */ |
265 | +#define HCI_2DH1 0x0002 |
266 | +#define HCI_3DH1 0x0004 |
267 | +#define HCI_DM1 0x0008 |
268 | +#define HCI_DH1 0x0010 |
269 | +#define HCI_2DH3 0x0100 |
270 | +#define HCI_3DH3 0x0200 |
271 | +#define HCI_DM3 0x0400 |
272 | +#define HCI_DH3 0x0800 |
273 | +#define HCI_2DH5 0x1000 |
274 | +#define HCI_3DH5 0x2000 |
275 | +#define HCI_DM5 0x4000 |
276 | +#define HCI_DH5 0x8000 |
277 | + |
278 | +#define HCI_HV1 0x0020 |
279 | +#define HCI_HV2 0x0040 |
280 | +#define HCI_HV3 0x0080 |
281 | + |
282 | +#define HCI_EV3 0x0008 |
283 | +#define HCI_EV4 0x0010 |
284 | +#define HCI_EV5 0x0020 |
285 | +#define HCI_2EV3 0x0040 |
286 | +#define HCI_3EV3 0x0080 |
287 | +#define HCI_2EV5 0x0100 |
288 | +#define HCI_3EV5 0x0200 |
289 | + |
290 | +#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3) |
291 | +#define ACL_PTYPE_MASK (HCI_DM1 | HCI_DH1 | HCI_DM3 | HCI_DH3 | HCI_DM5 | HCI_DH5) |
292 | + |
293 | +/* HCI Error codes */ |
294 | +#define HCI_UNKNOWN_COMMAND 0x01 |
295 | +#define HCI_NO_CONNECTION 0x02 |
296 | +#define HCI_HARDWARE_FAILURE 0x03 |
297 | +#define HCI_PAGE_TIMEOUT 0x04 |
298 | +#define HCI_AUTHENTICATION_FAILURE 0x05 |
299 | +#define HCI_PIN_OR_KEY_MISSING 0x06 |
300 | +#define HCI_MEMORY_FULL 0x07 |
301 | +#define HCI_CONNECTION_TIMEOUT 0x08 |
302 | +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 |
303 | +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a |
304 | +#define HCI_ACL_CONNECTION_EXISTS 0x0b |
305 | +#define HCI_COMMAND_DISALLOWED 0x0c |
306 | +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d |
307 | +#define HCI_REJECTED_SECURITY 0x0e |
308 | +#define HCI_REJECTED_PERSONAL 0x0f |
309 | +#define HCI_HOST_TIMEOUT 0x10 |
310 | +#define HCI_UNSUPPORTED_FEATURE 0x11 |
311 | +#define HCI_INVALID_PARAMETERS 0x12 |
312 | +#define HCI_OE_USER_ENDED_CONNECTION 0x13 |
313 | +#define HCI_OE_LOW_RESOURCES 0x14 |
314 | +#define HCI_OE_POWER_OFF 0x15 |
315 | +#define HCI_CONNECTION_TERMINATED 0x16 |
316 | +#define HCI_REPEATED_ATTEMPTS 0x17 |
317 | +#define HCI_PAIRING_NOT_ALLOWED 0x18 |
318 | +#define HCI_UNKNOWN_LMP_PDU 0x19 |
319 | +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a |
320 | +#define HCI_SCO_OFFSET_REJECTED 0x1b |
321 | +#define HCI_SCO_INTERVAL_REJECTED 0x1c |
322 | +#define HCI_AIR_MODE_REJECTED 0x1d |
323 | +#define HCI_INVALID_LMP_PARAMETERS 0x1e |
324 | +#define HCI_UNSPECIFIED_ERROR 0x1f |
325 | +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 |
326 | +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 |
327 | +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 |
328 | +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 |
329 | +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 |
330 | +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 |
331 | +#define HCI_UNIT_LINK_KEY_USED 0x26 |
332 | +#define HCI_QOS_NOT_SUPPORTED 0x27 |
333 | +#define HCI_INSTANT_PASSED 0x28 |
334 | +#define HCI_PAIRING_NOT_SUPPORTED 0x29 |
335 | +#define HCI_TRANSACTION_COLLISION 0x2a |
336 | +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c |
337 | +#define HCI_QOS_REJECTED 0x2d |
338 | +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e |
339 | +#define HCI_INSUFFICIENT_SECURITY 0x2f |
340 | +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 |
341 | +#define HCI_ROLE_SWITCH_PENDING 0x32 |
342 | +#define HCI_SLOT_VIOLATION 0x34 |
343 | +#define HCI_ROLE_SWITCH_FAILED 0x35 |
344 | +#define HCI_EIR_TOO_LARGE 0x36 |
345 | +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 |
346 | +#define HCI_HOST_BUSY_PAIRING 0x38 |
347 | + |
348 | +/* ACL flags */ |
349 | +#define ACL_START_NO_FLUSH 0x00 |
350 | +#define ACL_CONT 0x01 |
351 | +#define ACL_START 0x02 |
352 | +#define ACL_ACTIVE_BCAST 0x04 |
353 | +#define ACL_PICO_BCAST 0x08 |
354 | + |
355 | +/* Baseband links */ |
356 | +#define SCO_LINK 0x00 |
357 | +#define ACL_LINK 0x01 |
358 | +#define ESCO_LINK 0x02 |
359 | + |
360 | +/* LMP features */ |
361 | +#define LMP_3SLOT 0x01 |
362 | +#define LMP_5SLOT 0x02 |
363 | +#define LMP_ENCRYPT 0x04 |
364 | +#define LMP_SOFFSET 0x08 |
365 | +#define LMP_TACCURACY 0x10 |
366 | +#define LMP_RSWITCH 0x20 |
367 | +#define LMP_HOLD 0x40 |
368 | +#define LMP_SNIFF 0x80 |
369 | + |
370 | +#define LMP_PARK 0x01 |
371 | +#define LMP_RSSI 0x02 |
372 | +#define LMP_QUALITY 0x04 |
373 | +#define LMP_SCO 0x08 |
374 | +#define LMP_HV2 0x10 |
375 | +#define LMP_HV3 0x20 |
376 | +#define LMP_ULAW 0x40 |
377 | +#define LMP_ALAW 0x80 |
378 | + |
379 | +#define LMP_CVSD 0x01 |
380 | +#define LMP_PSCHEME 0x02 |
381 | +#define LMP_PCONTROL 0x04 |
382 | +#define LMP_TRSP_SCO 0x08 |
383 | +#define LMP_BCAST_ENC 0x80 |
384 | + |
385 | +#define LMP_EDR_ACL_2M 0x02 |
386 | +#define LMP_EDR_ACL_3M 0x04 |
387 | +#define LMP_ENH_ISCAN 0x08 |
388 | +#define LMP_ILACE_ISCAN 0x10 |
389 | +#define LMP_ILACE_PSCAN 0x20 |
390 | +#define LMP_RSSI_INQ 0x40 |
391 | +#define LMP_ESCO 0x80 |
392 | + |
393 | +#define LMP_EV4 0x01 |
394 | +#define LMP_EV5 0x02 |
395 | +#define LMP_AFH_CAP_SLV 0x08 |
396 | +#define LMP_AFH_CLS_SLV 0x10 |
397 | +#define LMP_NO_BREDR 0x20 |
398 | +#define LMP_LE 0x40 |
399 | +#define LMP_EDR_3SLOT 0x80 |
400 | + |
401 | +#define LMP_EDR_5SLOT 0x01 |
402 | +#define LMP_SNIFF_SUBR 0x02 |
403 | +#define LMP_PAUSE_ENC 0x04 |
404 | +#define LMP_AFH_CAP_MST 0x08 |
405 | +#define LMP_AFH_CLS_MST 0x10 |
406 | +#define LMP_EDR_ESCO_2M 0x20 |
407 | +#define LMP_EDR_ESCO_3M 0x40 |
408 | +#define LMP_EDR_3S_ESCO 0x80 |
409 | + |
410 | +#define LMP_EXT_INQ 0x01 |
411 | +#define LMP_LE_BREDR 0x02 |
412 | +#define LMP_SIMPLE_PAIR 0x08 |
413 | +#define LMP_ENCAPS_PDU 0x10 |
414 | +#define LMP_ERR_DAT_REP 0x20 |
415 | +#define LMP_NFLUSH_PKTS 0x40 |
416 | + |
417 | +#define LMP_LSTO 0x01 |
418 | +#define LMP_INQ_TX_PWR 0x02 |
419 | +#define LMP_EPC 0x04 |
420 | +#define LMP_EXT_FEAT 0x80 |
421 | + |
422 | +/* Extended LMP features */ |
423 | +#define LMP_HOST_SSP 0x01 |
424 | +#define LMP_HOST_LE 0x02 |
425 | +#define LMP_HOST_LE_BREDR 0x04 |
426 | + |
427 | +/* Link policies */ |
428 | +#define HCI_LP_RSWITCH 0x0001 |
429 | +#define HCI_LP_HOLD 0x0002 |
430 | +#define HCI_LP_SNIFF 0x0004 |
431 | +#define HCI_LP_PARK 0x0008 |
432 | + |
433 | +/* Link mode */ |
434 | +#define HCI_LM_ACCEPT 0x8000 |
435 | +#define HCI_LM_MASTER 0x0001 |
436 | +#define HCI_LM_AUTH 0x0002 |
437 | +#define HCI_LM_ENCRYPT 0x0004 |
438 | +#define HCI_LM_TRUSTED 0x0008 |
439 | +#define HCI_LM_RELIABLE 0x0010 |
440 | +#define HCI_LM_SECURE 0x0020 |
441 | + |
442 | +/* Link Key types */ |
443 | +#define HCI_LK_COMBINATION 0x00 |
444 | +#define HCI_LK_LOCAL_UNIT 0x01 |
445 | +#define HCI_LK_REMOTE_UNIT 0x02 |
446 | +#define HCI_LK_DEBUG_COMBINATION 0x03 |
447 | +#define HCI_LK_UNAUTH_COMBINATION 0x04 |
448 | +#define HCI_LK_AUTH_COMBINATION 0x05 |
449 | +#define HCI_LK_CHANGED_COMBINATION 0x06 |
450 | +#define HCI_LK_INVALID 0xFF |
451 | + |
452 | +/* ----- HCI Commands ----- */ |
453 | + |
454 | +/* Link Control */ |
455 | +#define OGF_LINK_CTL 0x01 |
456 | + |
457 | +#define OCF_INQUIRY 0x0001 |
458 | +typedef struct { |
459 | + uint8_t lap[3]; |
460 | + uint8_t length; /* 1.28s units */ |
461 | + uint8_t num_rsp; |
462 | +} __attribute__ ((packed)) inquiry_cp; |
463 | +#define INQUIRY_CP_SIZE 5 |
464 | + |
465 | +typedef struct { |
466 | + uint8_t status; |
467 | + bdaddr_t bdaddr; |
468 | +} __attribute__ ((packed)) status_bdaddr_rp; |
469 | +#define STATUS_BDADDR_RP_SIZE 7 |
470 | + |
471 | +#define OCF_INQUIRY_CANCEL 0x0002 |
472 | + |
473 | +#define OCF_PERIODIC_INQUIRY 0x0003 |
474 | +typedef struct { |
475 | + uint16_t max_period; /* 1.28s units */ |
476 | + uint16_t min_period; /* 1.28s units */ |
477 | + uint8_t lap[3]; |
478 | + uint8_t length; /* 1.28s units */ |
479 | + uint8_t num_rsp; |
480 | +} __attribute__ ((packed)) periodic_inquiry_cp; |
481 | +#define PERIODIC_INQUIRY_CP_SIZE 9 |
482 | + |
483 | +#define OCF_EXIT_PERIODIC_INQUIRY 0x0004 |
484 | + |
485 | +#define OCF_CREATE_CONN 0x0005 |
486 | +typedef struct { |
487 | + bdaddr_t bdaddr; |
488 | + uint16_t pkt_type; |
489 | + uint8_t pscan_rep_mode; |
490 | + uint8_t pscan_mode; |
491 | + uint16_t clock_offset; |
492 | + uint8_t role_switch; |
493 | +} __attribute__ ((packed)) create_conn_cp; |
494 | +#define CREATE_CONN_CP_SIZE 13 |
495 | + |
496 | +#define OCF_DISCONNECT 0x0006 |
497 | +typedef struct { |
498 | + uint16_t handle; |
499 | + uint8_t reason; |
500 | +} __attribute__ ((packed)) disconnect_cp; |
501 | +#define DISCONNECT_CP_SIZE 3 |
502 | + |
503 | +#define OCF_ADD_SCO 0x0007 |
504 | +typedef struct { |
505 | + uint16_t handle; |
506 | + uint16_t pkt_type; |
507 | +} __attribute__ ((packed)) add_sco_cp; |
508 | +#define ADD_SCO_CP_SIZE 4 |
509 | + |
510 | +#define OCF_CREATE_CONN_CANCEL 0x0008 |
511 | +typedef struct { |
512 | + bdaddr_t bdaddr; |
513 | +} __attribute__ ((packed)) create_conn_cancel_cp; |
514 | +#define CREATE_CONN_CANCEL_CP_SIZE 6 |
515 | + |
516 | +#define OCF_ACCEPT_CONN_REQ 0x0009 |
517 | +typedef struct { |
518 | + bdaddr_t bdaddr; |
519 | + uint8_t role; |
520 | +} __attribute__ ((packed)) accept_conn_req_cp; |
521 | +#define ACCEPT_CONN_REQ_CP_SIZE 7 |
522 | + |
523 | +#define OCF_REJECT_CONN_REQ 0x000A |
524 | +typedef struct { |
525 | + bdaddr_t bdaddr; |
526 | + uint8_t reason; |
527 | +} __attribute__ ((packed)) reject_conn_req_cp; |
528 | +#define REJECT_CONN_REQ_CP_SIZE 7 |
529 | + |
530 | +#define OCF_LINK_KEY_REPLY 0x000B |
531 | +typedef struct { |
532 | + bdaddr_t bdaddr; |
533 | + uint8_t link_key[16]; |
534 | +} __attribute__ ((packed)) link_key_reply_cp; |
535 | +#define LINK_KEY_REPLY_CP_SIZE 22 |
536 | + |
537 | +#define OCF_LINK_KEY_NEG_REPLY 0x000C |
538 | + |
539 | +#define OCF_PIN_CODE_REPLY 0x000D |
540 | +typedef struct { |
541 | + bdaddr_t bdaddr; |
542 | + uint8_t pin_len; |
543 | + uint8_t pin_code[16]; |
544 | +} __attribute__ ((packed)) pin_code_reply_cp; |
545 | +#define PIN_CODE_REPLY_CP_SIZE 23 |
546 | + |
547 | +#define OCF_PIN_CODE_NEG_REPLY 0x000E |
548 | + |
549 | +#define OCF_SET_CONN_PTYPE 0x000F |
550 | +typedef struct { |
551 | + uint16_t handle; |
552 | + uint16_t pkt_type; |
553 | +} __attribute__ ((packed)) set_conn_ptype_cp; |
554 | +#define SET_CONN_PTYPE_CP_SIZE 4 |
555 | + |
556 | +#define OCF_AUTH_REQUESTED 0x0011 |
557 | +typedef struct { |
558 | + uint16_t handle; |
559 | +} __attribute__ ((packed)) auth_requested_cp; |
560 | +#define AUTH_REQUESTED_CP_SIZE 2 |
561 | + |
562 | +#define OCF_SET_CONN_ENCRYPT 0x0013 |
563 | +typedef struct { |
564 | + uint16_t handle; |
565 | + uint8_t encrypt; |
566 | +} __attribute__ ((packed)) set_conn_encrypt_cp; |
567 | +#define SET_CONN_ENCRYPT_CP_SIZE 3 |
568 | + |
569 | +#define OCF_CHANGE_CONN_LINK_KEY 0x0015 |
570 | +typedef struct { |
571 | + uint16_t handle; |
572 | +} __attribute__ ((packed)) change_conn_link_key_cp; |
573 | +#define CHANGE_CONN_LINK_KEY_CP_SIZE 2 |
574 | + |
575 | +#define OCF_MASTER_LINK_KEY 0x0017 |
576 | +typedef struct { |
577 | + uint8_t key_flag; |
578 | +} __attribute__ ((packed)) master_link_key_cp; |
579 | +#define MASTER_LINK_KEY_CP_SIZE 1 |
580 | + |
581 | +#define OCF_REMOTE_NAME_REQ 0x0019 |
582 | +typedef struct { |
583 | + bdaddr_t bdaddr; |
584 | + uint8_t pscan_rep_mode; |
585 | + uint8_t pscan_mode; |
586 | + uint16_t clock_offset; |
587 | +} __attribute__ ((packed)) remote_name_req_cp; |
588 | +#define REMOTE_NAME_REQ_CP_SIZE 10 |
589 | + |
590 | +#define OCF_REMOTE_NAME_REQ_CANCEL 0x001A |
591 | +typedef struct { |
592 | + bdaddr_t bdaddr; |
593 | +} __attribute__ ((packed)) remote_name_req_cancel_cp; |
594 | +#define REMOTE_NAME_REQ_CANCEL_CP_SIZE 6 |
595 | + |
596 | +#define OCF_READ_REMOTE_FEATURES 0x001B |
597 | +typedef struct { |
598 | + uint16_t handle; |
599 | +} __attribute__ ((packed)) read_remote_features_cp; |
600 | +#define READ_REMOTE_FEATURES_CP_SIZE 2 |
601 | + |
602 | +#define OCF_READ_REMOTE_EXT_FEATURES 0x001C |
603 | +typedef struct { |
604 | + uint16_t handle; |
605 | + uint8_t page_num; |
606 | +} __attribute__ ((packed)) read_remote_ext_features_cp; |
607 | +#define READ_REMOTE_EXT_FEATURES_CP_SIZE 3 |
608 | + |
609 | +#define OCF_READ_REMOTE_VERSION 0x001D |
610 | +typedef struct { |
611 | + uint16_t handle; |
612 | +} __attribute__ ((packed)) read_remote_version_cp; |
613 | +#define READ_REMOTE_VERSION_CP_SIZE 2 |
614 | + |
615 | +#define OCF_READ_CLOCK_OFFSET 0x001F |
616 | +typedef struct { |
617 | + uint16_t handle; |
618 | +} __attribute__ ((packed)) read_clock_offset_cp; |
619 | +#define READ_CLOCK_OFFSET_CP_SIZE 2 |
620 | + |
621 | +#define OCF_READ_LMP_HANDLE 0x0020 |
622 | + |
623 | +#define OCF_SETUP_SYNC_CONN 0x0028 |
624 | +typedef struct { |
625 | + uint16_t handle; |
626 | + uint32_t tx_bandwith; |
627 | + uint32_t rx_bandwith; |
628 | + uint16_t max_latency; |
629 | + uint16_t voice_setting; |
630 | + uint8_t retrans_effort; |
631 | + uint16_t pkt_type; |
632 | +} __attribute__ ((packed)) setup_sync_conn_cp; |
633 | +#define SETUP_SYNC_CONN_CP_SIZE 17 |
634 | + |
635 | +#define OCF_ACCEPT_SYNC_CONN_REQ 0x0029 |
636 | +typedef struct { |
637 | + bdaddr_t bdaddr; |
638 | + uint32_t tx_bandwith; |
639 | + uint32_t rx_bandwith; |
640 | + uint16_t max_latency; |
641 | + uint16_t voice_setting; |
642 | + uint8_t retrans_effort; |
643 | + uint16_t pkt_type; |
644 | +} __attribute__ ((packed)) accept_sync_conn_req_cp; |
645 | +#define ACCEPT_SYNC_CONN_REQ_CP_SIZE 21 |
646 | + |
647 | +#define OCF_REJECT_SYNC_CONN_REQ 0x002A |
648 | +typedef struct { |
649 | + bdaddr_t bdaddr; |
650 | + uint8_t reason; |
651 | +} __attribute__ ((packed)) reject_sync_conn_req_cp; |
652 | +#define REJECT_SYNC_CONN_REQ_CP_SIZE 7 |
653 | + |
654 | +#define OCF_IO_CAPABILITY_REPLY 0x002B |
655 | +typedef struct { |
656 | + bdaddr_t bdaddr; |
657 | + uint8_t capability; |
658 | + uint8_t oob_data; |
659 | + uint8_t authentication; |
660 | +} __attribute__ ((packed)) io_capability_reply_cp; |
661 | +#define IO_CAPABILITY_REPLY_CP_SIZE 9 |
662 | + |
663 | +#define OCF_USER_CONFIRM_REPLY 0x002C |
664 | +typedef struct { |
665 | + bdaddr_t bdaddr; |
666 | +} __attribute__ ((packed)) user_confirm_reply_cp; |
667 | +#define USER_CONFIRM_REPLY_CP_SIZE 6 |
668 | + |
669 | +#define OCF_USER_CONFIRM_NEG_REPLY 0x002D |
670 | + |
671 | +#define OCF_USER_PASSKEY_REPLY 0x002E |
672 | +typedef struct { |
673 | + bdaddr_t bdaddr; |
674 | + uint32_t passkey; |
675 | +} __attribute__ ((packed)) user_passkey_reply_cp; |
676 | +#define USER_PASSKEY_REPLY_CP_SIZE 10 |
677 | + |
678 | +#define OCF_USER_PASSKEY_NEG_REPLY 0x002F |
679 | + |
680 | +#define OCF_REMOTE_OOB_DATA_REPLY 0x0030 |
681 | +typedef struct { |
682 | + bdaddr_t bdaddr; |
683 | + uint8_t hash[16]; |
684 | + uint8_t randomizer[16]; |
685 | +} __attribute__ ((packed)) remote_oob_data_reply_cp; |
686 | +#define REMOTE_OOB_DATA_REPLY_CP_SIZE 38 |
687 | + |
688 | +#define OCF_REMOTE_OOB_DATA_NEG_REPLY 0x0033 |
689 | + |
690 | +#define OCF_IO_CAPABILITY_NEG_REPLY 0x0034 |
691 | +typedef struct { |
692 | + bdaddr_t bdaddr; |
693 | + uint8_t reason; |
694 | +} __attribute__ ((packed)) io_capability_neg_reply_cp; |
695 | +#define IO_CAPABILITY_NEG_REPLY_CP_SIZE 7 |
696 | + |
697 | +#define OCF_CREATE_PHYSICAL_LINK 0x0035 |
698 | +typedef struct { |
699 | + uint8_t handle; |
700 | + uint8_t key_length; |
701 | + uint8_t key_type; |
702 | + uint8_t key[32]; |
703 | +} __attribute__ ((packed)) create_physical_link_cp; |
704 | +#define CREATE_PHYSICAL_LINK_CP_SIZE 35 |
705 | + |
706 | +#define OCF_ACCEPT_PHYSICAL_LINK 0x0036 |
707 | + |
708 | +#define OCF_DISCONNECT_PHYSICAL_LINK 0x0037 |
709 | +typedef struct { |
710 | + uint8_t handle; |
711 | + uint8_t reason; |
712 | +} __attribute__ ((packed)) disconnect_physical_link_cp; |
713 | +#define DISCONNECT_PHYSICAL_LINK_CP_SIZE 2 |
714 | + |
715 | +#define OCF_CREATE_LOGICAL_LINK 0x0038 |
716 | +typedef struct { |
717 | + uint8_t handle; |
718 | + uint8_t tx_flow[16]; |
719 | + uint8_t rx_flow[16]; |
720 | +} __attribute__ ((packed)) create_logical_link_cp; |
721 | +#define CREATE_LOGICAL_LINK_CP_SIZE 33 |
722 | + |
723 | +#define OCF_ACCEPT_LOGICAL_LINK 0x0039 |
724 | + |
725 | +#define OCF_DISCONNECT_LOGICAL_LINK 0x003A |
726 | +typedef struct { |
727 | + uint16_t handle; |
728 | +} __attribute__ ((packed)) disconnect_logical_link_cp; |
729 | +#define DISCONNECT_LOGICAL_LINK_CP_SIZE 2 |
730 | + |
731 | +#define OCF_LOGICAL_LINK_CANCEL 0x003B |
732 | +typedef struct { |
733 | + uint8_t handle; |
734 | + uint8_t tx_flow_id; |
735 | +} __attribute__ ((packed)) cancel_logical_link_cp; |
736 | +#define LOGICAL_LINK_CANCEL_CP_SIZE 2 |
737 | +typedef struct { |
738 | + uint8_t status; |
739 | + uint8_t handle; |
740 | + uint8_t tx_flow_id; |
741 | +} __attribute__ ((packed)) cancel_logical_link_rp; |
742 | +#define LOGICAL_LINK_CANCEL_RP_SIZE 3 |
743 | + |
744 | +#define OCF_FLOW_SPEC_MODIFY 0x003C |
745 | + |
746 | +/* Link Policy */ |
747 | +#define OGF_LINK_POLICY 0x02 |
748 | + |
749 | +#define OCF_HOLD_MODE 0x0001 |
750 | +typedef struct { |
751 | + uint16_t handle; |
752 | + uint16_t max_interval; |
753 | + uint16_t min_interval; |
754 | +} __attribute__ ((packed)) hold_mode_cp; |
755 | +#define HOLD_MODE_CP_SIZE 6 |
756 | + |
757 | +#define OCF_SNIFF_MODE 0x0003 |
758 | +typedef struct { |
759 | + uint16_t handle; |
760 | + uint16_t max_interval; |
761 | + uint16_t min_interval; |
762 | + uint16_t attempt; |
763 | + uint16_t timeout; |
764 | +} __attribute__ ((packed)) sniff_mode_cp; |
765 | +#define SNIFF_MODE_CP_SIZE 10 |
766 | + |
767 | +#define OCF_EXIT_SNIFF_MODE 0x0004 |
768 | +typedef struct { |
769 | + uint16_t handle; |
770 | +} __attribute__ ((packed)) exit_sniff_mode_cp; |
771 | +#define EXIT_SNIFF_MODE_CP_SIZE 2 |
772 | + |
773 | +#define OCF_PARK_MODE 0x0005 |
774 | +typedef struct { |
775 | + uint16_t handle; |
776 | + uint16_t max_interval; |
777 | + uint16_t min_interval; |
778 | +} __attribute__ ((packed)) park_mode_cp; |
779 | +#define PARK_MODE_CP_SIZE 6 |
780 | + |
781 | +#define OCF_EXIT_PARK_MODE 0x0006 |
782 | +typedef struct { |
783 | + uint16_t handle; |
784 | +} __attribute__ ((packed)) exit_park_mode_cp; |
785 | +#define EXIT_PARK_MODE_CP_SIZE 2 |
786 | + |
787 | +#define OCF_QOS_SETUP 0x0007 |
788 | +typedef struct { |
789 | + uint8_t service_type; /* 1 = best effort */ |
790 | + uint32_t token_rate; /* Byte per seconds */ |
791 | + uint32_t peak_bandwidth; /* Byte per seconds */ |
792 | + uint32_t latency; /* Microseconds */ |
793 | + uint32_t delay_variation; /* Microseconds */ |
794 | +} __attribute__ ((packed)) hci_qos; |
795 | +#define HCI_QOS_CP_SIZE 17 |
796 | +typedef struct { |
797 | + uint16_t handle; |
798 | + uint8_t flags; /* Reserved */ |
799 | + hci_qos qos; |
800 | +} __attribute__ ((packed)) qos_setup_cp; |
801 | +#define QOS_SETUP_CP_SIZE (3 + HCI_QOS_CP_SIZE) |
802 | + |
803 | +#define OCF_ROLE_DISCOVERY 0x0009 |
804 | +typedef struct { |
805 | + uint16_t handle; |
806 | +} __attribute__ ((packed)) role_discovery_cp; |
807 | +#define ROLE_DISCOVERY_CP_SIZE 2 |
808 | +typedef struct { |
809 | + uint8_t status; |
810 | + uint16_t handle; |
811 | + uint8_t role; |
812 | +} __attribute__ ((packed)) role_discovery_rp; |
813 | +#define ROLE_DISCOVERY_RP_SIZE 4 |
814 | + |
815 | +#define OCF_SWITCH_ROLE 0x000B |
816 | +typedef struct { |
817 | + bdaddr_t bdaddr; |
818 | + uint8_t role; |
819 | +} __attribute__ ((packed)) switch_role_cp; |
820 | +#define SWITCH_ROLE_CP_SIZE 7 |
821 | + |
822 | +#define OCF_READ_LINK_POLICY 0x000C |
823 | +typedef struct { |
824 | + uint16_t handle; |
825 | +} __attribute__ ((packed)) read_link_policy_cp; |
826 | +#define READ_LINK_POLICY_CP_SIZE 2 |
827 | +typedef struct { |
828 | + uint8_t status; |
829 | + uint16_t handle; |
830 | + uint16_t policy; |
831 | +} __attribute__ ((packed)) read_link_policy_rp; |
832 | +#define READ_LINK_POLICY_RP_SIZE 5 |
833 | + |
834 | +#define OCF_WRITE_LINK_POLICY 0x000D |
835 | +typedef struct { |
836 | + uint16_t handle; |
837 | + uint16_t policy; |
838 | +} __attribute__ ((packed)) write_link_policy_cp; |
839 | +#define WRITE_LINK_POLICY_CP_SIZE 4 |
840 | +typedef struct { |
841 | + uint8_t status; |
842 | + uint16_t handle; |
843 | +} __attribute__ ((packed)) write_link_policy_rp; |
844 | +#define WRITE_LINK_POLICY_RP_SIZE 3 |
845 | + |
846 | +#define OCF_READ_DEFAULT_LINK_POLICY 0x000E |
847 | + |
848 | +#define OCF_WRITE_DEFAULT_LINK_POLICY 0x000F |
849 | + |
850 | +#define OCF_FLOW_SPECIFICATION 0x0010 |
851 | + |
852 | +#define OCF_SNIFF_SUBRATING 0x0011 |
853 | +typedef struct { |
854 | + uint16_t handle; |
855 | + uint16_t max_latency; |
856 | + uint16_t min_remote_timeout; |
857 | + uint16_t min_local_timeout; |
858 | +} __attribute__ ((packed)) sniff_subrating_cp; |
859 | +#define SNIFF_SUBRATING_CP_SIZE 8 |
860 | + |
861 | +/* Host Controller and Baseband */ |
862 | +#define OGF_HOST_CTL 0x03 |
863 | + |
864 | +#define OCF_SET_EVENT_MASK 0x0001 |
865 | +typedef struct { |
866 | + uint8_t mask[8]; |
867 | +} __attribute__ ((packed)) set_event_mask_cp; |
868 | +#define SET_EVENT_MASK_CP_SIZE 8 |
869 | + |
870 | +#define OCF_RESET 0x0003 |
871 | + |
872 | +#define OCF_SET_EVENT_FLT 0x0005 |
873 | +typedef struct { |
874 | + uint8_t flt_type; |
875 | + uint8_t cond_type; |
876 | + uint8_t condition[0]; |
877 | +} __attribute__ ((packed)) set_event_flt_cp; |
878 | +#define SET_EVENT_FLT_CP_SIZE 2 |
879 | + |
880 | +/* Filter types */ |
881 | +#define FLT_CLEAR_ALL 0x00 |
882 | +#define FLT_INQ_RESULT 0x01 |
883 | +#define FLT_CONN_SETUP 0x02 |
884 | +/* INQ_RESULT Condition types */ |
885 | +#define INQ_RESULT_RETURN_ALL 0x00 |
886 | +#define INQ_RESULT_RETURN_CLASS 0x01 |
887 | +#define INQ_RESULT_RETURN_BDADDR 0x02 |
888 | +/* CONN_SETUP Condition types */ |
889 | +#define CONN_SETUP_ALLOW_ALL 0x00 |
890 | +#define CONN_SETUP_ALLOW_CLASS 0x01 |
891 | +#define CONN_SETUP_ALLOW_BDADDR 0x02 |
892 | +/* CONN_SETUP Conditions */ |
893 | +#define CONN_SETUP_AUTO_OFF 0x01 |
894 | +#define CONN_SETUP_AUTO_ON 0x02 |
895 | + |
896 | +#define OCF_FLUSH 0x0008 |
897 | + |
898 | +#define OCF_READ_PIN_TYPE 0x0009 |
899 | +typedef struct { |
900 | + uint8_t status; |
901 | + uint8_t pin_type; |
902 | +} __attribute__ ((packed)) read_pin_type_rp; |
903 | +#define READ_PIN_TYPE_RP_SIZE 2 |
904 | + |
905 | +#define OCF_WRITE_PIN_TYPE 0x000A |
906 | +typedef struct { |
907 | + uint8_t pin_type; |
908 | +} __attribute__ ((packed)) write_pin_type_cp; |
909 | +#define WRITE_PIN_TYPE_CP_SIZE 1 |
910 | + |
911 | +#define OCF_CREATE_NEW_UNIT_KEY 0x000B |
912 | + |
913 | +#define OCF_READ_STORED_LINK_KEY 0x000D |
914 | +typedef struct { |
915 | + bdaddr_t bdaddr; |
916 | + uint8_t read_all; |
917 | +} __attribute__ ((packed)) read_stored_link_key_cp; |
918 | +#define READ_STORED_LINK_KEY_CP_SIZE 7 |
919 | +typedef struct { |
920 | + uint8_t status; |
921 | + uint16_t max_keys; |
922 | + uint16_t num_keys; |
923 | +} __attribute__ ((packed)) read_stored_link_key_rp; |
924 | +#define READ_STORED_LINK_KEY_RP_SIZE 5 |
925 | + |
926 | +#define OCF_WRITE_STORED_LINK_KEY 0x0011 |
927 | +typedef struct { |
928 | + uint8_t num_keys; |
929 | + /* variable length part */ |
930 | +} __attribute__ ((packed)) write_stored_link_key_cp; |
931 | +#define WRITE_STORED_LINK_KEY_CP_SIZE 1 |
932 | +typedef struct { |
933 | + uint8_t status; |
934 | + uint8_t num_keys; |
935 | +} __attribute__ ((packed)) write_stored_link_key_rp; |
936 | +#define READ_WRITE_LINK_KEY_RP_SIZE 2 |
937 | + |
938 | +#define OCF_DELETE_STORED_LINK_KEY 0x0012 |
939 | +typedef struct { |
940 | + bdaddr_t bdaddr; |
941 | + uint8_t delete_all; |
942 | +} __attribute__ ((packed)) delete_stored_link_key_cp; |
943 | +#define DELETE_STORED_LINK_KEY_CP_SIZE 7 |
944 | +typedef struct { |
945 | + uint8_t status; |
946 | + uint16_t num_keys; |
947 | +} __attribute__ ((packed)) delete_stored_link_key_rp; |
948 | +#define DELETE_STORED_LINK_KEY_RP_SIZE 3 |
949 | + |
950 | +#define HCI_MAX_NAME_LENGTH 248 |
951 | + |
952 | +#define OCF_CHANGE_LOCAL_NAME 0x0013 |
953 | +typedef struct { |
954 | + uint8_t name[HCI_MAX_NAME_LENGTH]; |
955 | +} __attribute__ ((packed)) change_local_name_cp; |
956 | +#define CHANGE_LOCAL_NAME_CP_SIZE 248 |
957 | + |
958 | +#define OCF_READ_LOCAL_NAME 0x0014 |
959 | +typedef struct { |
960 | + uint8_t status; |
961 | + uint8_t name[HCI_MAX_NAME_LENGTH]; |
962 | +} __attribute__ ((packed)) read_local_name_rp; |
963 | +#define READ_LOCAL_NAME_RP_SIZE 249 |
964 | + |
965 | +#define OCF_READ_CONN_ACCEPT_TIMEOUT 0x0015 |
966 | +typedef struct { |
967 | + uint8_t status; |
968 | + uint16_t timeout; |
969 | +} __attribute__ ((packed)) read_conn_accept_timeout_rp; |
970 | +#define READ_CONN_ACCEPT_TIMEOUT_RP_SIZE 3 |
971 | + |
972 | +#define OCF_WRITE_CONN_ACCEPT_TIMEOUT 0x0016 |
973 | +typedef struct { |
974 | + uint16_t timeout; |
975 | +} __attribute__ ((packed)) write_conn_accept_timeout_cp; |
976 | +#define WRITE_CONN_ACCEPT_TIMEOUT_CP_SIZE 2 |
977 | + |
978 | +#define OCF_READ_PAGE_TIMEOUT 0x0017 |
979 | +typedef struct { |
980 | + uint8_t status; |
981 | + uint16_t timeout; |
982 | +} __attribute__ ((packed)) read_page_timeout_rp; |
983 | +#define READ_PAGE_TIMEOUT_RP_SIZE 3 |
984 | + |
985 | +#define OCF_WRITE_PAGE_TIMEOUT 0x0018 |
986 | +typedef struct { |
987 | + uint16_t timeout; |
988 | +} __attribute__ ((packed)) write_page_timeout_cp; |
989 | +#define WRITE_PAGE_TIMEOUT_CP_SIZE 2 |
990 | + |
991 | +#define OCF_READ_SCAN_ENABLE 0x0019 |
992 | +typedef struct { |
993 | + uint8_t status; |
994 | + uint8_t enable; |
995 | +} __attribute__ ((packed)) read_scan_enable_rp; |
996 | +#define READ_SCAN_ENABLE_RP_SIZE 2 |
997 | + |
998 | +#define OCF_WRITE_SCAN_ENABLE 0x001A |
999 | + #define SCAN_DISABLED 0x00 |
1000 | + #define SCAN_INQUIRY 0x01 |
1001 | + #define SCAN_PAGE 0x02 |
1002 | + |
1003 | +#define OCF_READ_PAGE_ACTIVITY 0x001B |
1004 | +typedef struct { |
1005 | + uint8_t status; |
1006 | + uint16_t interval; |
1007 | + uint16_t window; |
1008 | +} __attribute__ ((packed)) read_page_activity_rp; |
1009 | +#define READ_PAGE_ACTIVITY_RP_SIZE 5 |
1010 | + |
1011 | +#define OCF_WRITE_PAGE_ACTIVITY 0x001C |
1012 | +typedef struct { |
1013 | + uint16_t interval; |
1014 | + uint16_t window; |
1015 | +} __attribute__ ((packed)) write_page_activity_cp; |
1016 | +#define WRITE_PAGE_ACTIVITY_CP_SIZE 4 |
1017 | + |
1018 | +#define OCF_READ_INQ_ACTIVITY 0x001D |
1019 | +typedef struct { |
1020 | + uint8_t status; |
1021 | + uint16_t interval; |
1022 | + uint16_t window; |
1023 | +} __attribute__ ((packed)) read_inq_activity_rp; |
1024 | +#define READ_INQ_ACTIVITY_RP_SIZE 5 |
1025 | + |
1026 | +#define OCF_WRITE_INQ_ACTIVITY 0x001E |
1027 | +typedef struct { |
1028 | + uint16_t interval; |
1029 | + uint16_t window; |
1030 | +} __attribute__ ((packed)) write_inq_activity_cp; |
1031 | +#define WRITE_INQ_ACTIVITY_CP_SIZE 4 |
1032 | + |
1033 | +#define OCF_READ_AUTH_ENABLE 0x001F |
1034 | + |
1035 | +#define OCF_WRITE_AUTH_ENABLE 0x0020 |
1036 | + #define AUTH_DISABLED 0x00 |
1037 | + #define AUTH_ENABLED 0x01 |
1038 | + |
1039 | +#define OCF_READ_ENCRYPT_MODE 0x0021 |
1040 | + |
1041 | +#define OCF_WRITE_ENCRYPT_MODE 0x0022 |
1042 | + #define ENCRYPT_DISABLED 0x00 |
1043 | + #define ENCRYPT_P2P 0x01 |
1044 | + #define ENCRYPT_BOTH 0x02 |
1045 | + |
1046 | +#define OCF_READ_CLASS_OF_DEV 0x0023 |
1047 | +typedef struct { |
1048 | + uint8_t status; |
1049 | + uint8_t dev_class[3]; |
1050 | +} __attribute__ ((packed)) read_class_of_dev_rp; |
1051 | +#define READ_CLASS_OF_DEV_RP_SIZE 4 |
1052 | + |
1053 | +#define OCF_WRITE_CLASS_OF_DEV 0x0024 |
1054 | +typedef struct { |
1055 | + uint8_t dev_class[3]; |
1056 | +} __attribute__ ((packed)) write_class_of_dev_cp; |
1057 | +#define WRITE_CLASS_OF_DEV_CP_SIZE 3 |
1058 | + |
1059 | +#define OCF_READ_VOICE_SETTING 0x0025 |
1060 | +typedef struct { |
1061 | + uint8_t status; |
1062 | + uint16_t voice_setting; |
1063 | +} __attribute__ ((packed)) read_voice_setting_rp; |
1064 | +#define READ_VOICE_SETTING_RP_SIZE 3 |
1065 | + |
1066 | +#define OCF_WRITE_VOICE_SETTING 0x0026 |
1067 | +typedef struct { |
1068 | + uint16_t voice_setting; |
1069 | +} __attribute__ ((packed)) write_voice_setting_cp; |
1070 | +#define WRITE_VOICE_SETTING_CP_SIZE 2 |
1071 | + |
1072 | +#define OCF_READ_AUTOMATIC_FLUSH_TIMEOUT 0x0027 |
1073 | + |
1074 | +#define OCF_WRITE_AUTOMATIC_FLUSH_TIMEOUT 0x0028 |
1075 | + |
1076 | +#define OCF_READ_NUM_BROADCAST_RETRANS 0x0029 |
1077 | + |
1078 | +#define OCF_WRITE_NUM_BROADCAST_RETRANS 0x002A |
1079 | + |
1080 | +#define OCF_READ_HOLD_MODE_ACTIVITY 0x002B |
1081 | + |
1082 | +#define OCF_WRITE_HOLD_MODE_ACTIVITY 0x002C |
1083 | + |
1084 | +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D |
1085 | +typedef struct { |
1086 | + uint16_t handle; |
1087 | + uint8_t type; |
1088 | +} __attribute__ ((packed)) read_transmit_power_level_cp; |
1089 | +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 |
1090 | +typedef struct { |
1091 | + uint8_t status; |
1092 | + uint16_t handle; |
1093 | + int8_t level; |
1094 | +} __attribute__ ((packed)) read_transmit_power_level_rp; |
1095 | +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 |
1096 | + |
1097 | +#define OCF_READ_SYNC_FLOW_ENABLE 0x002E |
1098 | + |
1099 | +#define OCF_WRITE_SYNC_FLOW_ENABLE 0x002F |
1100 | + |
1101 | +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 |
1102 | + |
1103 | +#define OCF_HOST_BUFFER_SIZE 0x0033 |
1104 | +typedef struct { |
1105 | + uint16_t acl_mtu; |
1106 | + uint8_t sco_mtu; |
1107 | + uint16_t acl_max_pkt; |
1108 | + uint16_t sco_max_pkt; |
1109 | +} __attribute__ ((packed)) host_buffer_size_cp; |
1110 | +#define HOST_BUFFER_SIZE_CP_SIZE 7 |
1111 | + |
1112 | +#define OCF_HOST_NUM_COMP_PKTS 0x0035 |
1113 | +typedef struct { |
1114 | + uint8_t num_hndl; |
1115 | + /* variable length part */ |
1116 | +} __attribute__ ((packed)) host_num_comp_pkts_cp; |
1117 | +#define HOST_NUM_COMP_PKTS_CP_SIZE 1 |
1118 | + |
1119 | +#define OCF_READ_LINK_SUPERVISION_TIMEOUT 0x0036 |
1120 | +typedef struct { |
1121 | + uint8_t status; |
1122 | + uint16_t handle; |
1123 | + uint16_t timeout; |
1124 | +} __attribute__ ((packed)) read_link_supervision_timeout_rp; |
1125 | +#define READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE 5 |
1126 | + |
1127 | +#define OCF_WRITE_LINK_SUPERVISION_TIMEOUT 0x0037 |
1128 | +typedef struct { |
1129 | + uint16_t handle; |
1130 | + uint16_t timeout; |
1131 | +} __attribute__ ((packed)) write_link_supervision_timeout_cp; |
1132 | +#define WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE 4 |
1133 | +typedef struct { |
1134 | + uint8_t status; |
1135 | + uint16_t handle; |
1136 | +} __attribute__ ((packed)) write_link_supervision_timeout_rp; |
1137 | +#define WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE 3 |
1138 | + |
1139 | +#define OCF_READ_NUM_SUPPORTED_IAC 0x0038 |
1140 | + |
1141 | +#define MAX_IAC_LAP 0x40 |
1142 | +#define OCF_READ_CURRENT_IAC_LAP 0x0039 |
1143 | +typedef struct { |
1144 | + uint8_t status; |
1145 | + uint8_t num_current_iac; |
1146 | + uint8_t lap[MAX_IAC_LAP][3]; |
1147 | +} __attribute__ ((packed)) read_current_iac_lap_rp; |
1148 | +#define READ_CURRENT_IAC_LAP_RP_SIZE 2+3*MAX_IAC_LAP |
1149 | + |
1150 | +#define OCF_WRITE_CURRENT_IAC_LAP 0x003A |
1151 | +typedef struct { |
1152 | + uint8_t num_current_iac; |
1153 | + uint8_t lap[MAX_IAC_LAP][3]; |
1154 | +} __attribute__ ((packed)) write_current_iac_lap_cp; |
1155 | +#define WRITE_CURRENT_IAC_LAP_CP_SIZE 1+3*MAX_IAC_LAP |
1156 | + |
1157 | +#define OCF_READ_PAGE_SCAN_PERIOD_MODE 0x003B |
1158 | + |
1159 | +#define OCF_WRITE_PAGE_SCAN_PERIOD_MODE 0x003C |
1160 | + |
1161 | +#define OCF_READ_PAGE_SCAN_MODE 0x003D |
1162 | + |
1163 | +#define OCF_WRITE_PAGE_SCAN_MODE 0x003E |
1164 | + |
1165 | +#define OCF_SET_AFH_CLASSIFICATION 0x003F |
1166 | +typedef struct { |
1167 | + uint8_t map[10]; |
1168 | +} __attribute__ ((packed)) set_afh_classification_cp; |
1169 | +#define SET_AFH_CLASSIFICATION_CP_SIZE 10 |
1170 | +typedef struct { |
1171 | + uint8_t status; |
1172 | +} __attribute__ ((packed)) set_afh_classification_rp; |
1173 | +#define SET_AFH_CLASSIFICATION_RP_SIZE 1 |
1174 | + |
1175 | +#define OCF_READ_INQUIRY_SCAN_TYPE 0x0042 |
1176 | +typedef struct { |
1177 | + uint8_t status; |
1178 | + uint8_t type; |
1179 | +} __attribute__ ((packed)) read_inquiry_scan_type_rp; |
1180 | +#define READ_INQUIRY_SCAN_TYPE_RP_SIZE 2 |
1181 | + |
1182 | +#define OCF_WRITE_INQUIRY_SCAN_TYPE 0x0043 |
1183 | +typedef struct { |
1184 | + uint8_t type; |
1185 | +} __attribute__ ((packed)) write_inquiry_scan_type_cp; |
1186 | +#define WRITE_INQUIRY_SCAN_TYPE_CP_SIZE 1 |
1187 | +typedef struct { |
1188 | + uint8_t status; |
1189 | +} __attribute__ ((packed)) write_inquiry_scan_type_rp; |
1190 | +#define WRITE_INQUIRY_SCAN_TYPE_RP_SIZE 1 |
1191 | + |
1192 | +#define OCF_READ_INQUIRY_MODE 0x0044 |
1193 | +typedef struct { |
1194 | + uint8_t status; |
1195 | + uint8_t mode; |
1196 | +} __attribute__ ((packed)) read_inquiry_mode_rp; |
1197 | +#define READ_INQUIRY_MODE_RP_SIZE 2 |
1198 | + |
1199 | +#define OCF_WRITE_INQUIRY_MODE 0x0045 |
1200 | +typedef struct { |
1201 | + uint8_t mode; |
1202 | +} __attribute__ ((packed)) write_inquiry_mode_cp; |
1203 | +#define WRITE_INQUIRY_MODE_CP_SIZE 1 |
1204 | +typedef struct { |
1205 | + uint8_t status; |
1206 | +} __attribute__ ((packed)) write_inquiry_mode_rp; |
1207 | +#define WRITE_INQUIRY_MODE_RP_SIZE 1 |
1208 | + |
1209 | +#define OCF_READ_PAGE_SCAN_TYPE 0x0046 |
1210 | + |
1211 | +#define OCF_WRITE_PAGE_SCAN_TYPE 0x0047 |
1212 | + #define PAGE_SCAN_TYPE_STANDARD 0x00 |
1213 | + #define PAGE_SCAN_TYPE_INTERLACED 0x01 |
1214 | + |
1215 | +#define OCF_READ_AFH_MODE 0x0048 |
1216 | +typedef struct { |
1217 | + uint8_t status; |
1218 | + uint8_t mode; |
1219 | +} __attribute__ ((packed)) read_afh_mode_rp; |
1220 | +#define READ_AFH_MODE_RP_SIZE 2 |
1221 | + |
1222 | +#define OCF_WRITE_AFH_MODE 0x0049 |
1223 | +typedef struct { |
1224 | + uint8_t mode; |
1225 | +} __attribute__ ((packed)) write_afh_mode_cp; |
1226 | +#define WRITE_AFH_MODE_CP_SIZE 1 |
1227 | +typedef struct { |
1228 | + uint8_t status; |
1229 | +} __attribute__ ((packed)) write_afh_mode_rp; |
1230 | +#define WRITE_AFH_MODE_RP_SIZE 1 |
1231 | + |
1232 | +#define HCI_MAX_EIR_LENGTH 240 |
1233 | + |
1234 | +#define OCF_READ_EXT_INQUIRY_RESPONSE 0x0051 |
1235 | +typedef struct { |
1236 | + uint8_t status; |
1237 | + uint8_t fec; |
1238 | + uint8_t data[HCI_MAX_EIR_LENGTH]; |
1239 | +} __attribute__ ((packed)) read_ext_inquiry_response_rp; |
1240 | +#define READ_EXT_INQUIRY_RESPONSE_RP_SIZE 242 |
1241 | + |
1242 | +#define OCF_WRITE_EXT_INQUIRY_RESPONSE 0x0052 |
1243 | +typedef struct { |
1244 | + uint8_t fec; |
1245 | + uint8_t data[HCI_MAX_EIR_LENGTH]; |
1246 | +} __attribute__ ((packed)) write_ext_inquiry_response_cp; |
1247 | +#define WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE 241 |
1248 | +typedef struct { |
1249 | + uint8_t status; |
1250 | +} __attribute__ ((packed)) write_ext_inquiry_response_rp; |
1251 | +#define WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE 1 |
1252 | + |
1253 | +#define OCF_REFRESH_ENCRYPTION_KEY 0x0053 |
1254 | +typedef struct { |
1255 | + uint16_t handle; |
1256 | +} __attribute__ ((packed)) refresh_encryption_key_cp; |
1257 | +#define REFRESH_ENCRYPTION_KEY_CP_SIZE 2 |
1258 | +typedef struct { |
1259 | + uint8_t status; |
1260 | +} __attribute__ ((packed)) refresh_encryption_key_rp; |
1261 | +#define REFRESH_ENCRYPTION_KEY_RP_SIZE 1 |
1262 | + |
1263 | +#define OCF_READ_SIMPLE_PAIRING_MODE 0x0055 |
1264 | +typedef struct { |
1265 | + uint8_t status; |
1266 | + uint8_t mode; |
1267 | +} __attribute__ ((packed)) read_simple_pairing_mode_rp; |
1268 | +#define READ_SIMPLE_PAIRING_MODE_RP_SIZE 2 |
1269 | + |
1270 | +#define OCF_WRITE_SIMPLE_PAIRING_MODE 0x0056 |
1271 | +typedef struct { |
1272 | + uint8_t mode; |
1273 | +} __attribute__ ((packed)) write_simple_pairing_mode_cp; |
1274 | +#define WRITE_SIMPLE_PAIRING_MODE_CP_SIZE 1 |
1275 | +typedef struct { |
1276 | + uint8_t status; |
1277 | +} __attribute__ ((packed)) write_simple_pairing_mode_rp; |
1278 | +#define WRITE_SIMPLE_PAIRING_MODE_RP_SIZE 1 |
1279 | + |
1280 | +#define OCF_READ_LOCAL_OOB_DATA 0x0057 |
1281 | +typedef struct { |
1282 | + uint8_t status; |
1283 | + uint8_t hash[16]; |
1284 | + uint8_t randomizer[16]; |
1285 | +} __attribute__ ((packed)) read_local_oob_data_rp; |
1286 | +#define READ_LOCAL_OOB_DATA_RP_SIZE 33 |
1287 | + |
1288 | +#define OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL 0x0058 |
1289 | +typedef struct { |
1290 | + uint8_t status; |
1291 | + int8_t level; |
1292 | +} __attribute__ ((packed)) read_inq_response_tx_power_level_rp; |
1293 | +#define READ_INQ_RESPONSE_TX_POWER_LEVEL_RP_SIZE 2 |
1294 | + |
1295 | +#define OCF_READ_INQUIRY_TRANSMIT_POWER_LEVEL 0x0058 |
1296 | +typedef struct { |
1297 | + uint8_t status; |
1298 | + int8_t level; |
1299 | +} __attribute__ ((packed)) read_inquiry_transmit_power_level_rp; |
1300 | +#define READ_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE 2 |
1301 | + |
1302 | +#define OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL 0x0059 |
1303 | +typedef struct { |
1304 | + int8_t level; |
1305 | +} __attribute__ ((packed)) write_inquiry_transmit_power_level_cp; |
1306 | +#define WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_CP_SIZE 1 |
1307 | +typedef struct { |
1308 | + uint8_t status; |
1309 | +} __attribute__ ((packed)) write_inquiry_transmit_power_level_rp; |
1310 | +#define WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE 1 |
1311 | + |
1312 | +#define OCF_READ_DEFAULT_ERROR_DATA_REPORTING 0x005A |
1313 | +typedef struct { |
1314 | + uint8_t status; |
1315 | + uint8_t reporting; |
1316 | +} __attribute__ ((packed)) read_default_error_data_reporting_rp; |
1317 | +#define READ_DEFAULT_ERROR_DATA_REPORTING_RP_SIZE 2 |
1318 | + |
1319 | +#define OCF_WRITE_DEFAULT_ERROR_DATA_REPORTING 0x005B |
1320 | +typedef struct { |
1321 | + uint8_t reporting; |
1322 | +} __attribute__ ((packed)) write_default_error_data_reporting_cp; |
1323 | +#define WRITE_DEFAULT_ERROR_DATA_REPORTING_CP_SIZE 1 |
1324 | +typedef struct { |
1325 | + uint8_t status; |
1326 | +} __attribute__ ((packed)) write_default_error_data_reporting_rp; |
1327 | +#define WRITE_DEFAULT_ERROR_DATA_REPORTING_RP_SIZE 1 |
1328 | + |
1329 | +#define OCF_ENHANCED_FLUSH 0x005F |
1330 | +typedef struct { |
1331 | + uint16_t handle; |
1332 | + uint8_t type; |
1333 | +} __attribute__ ((packed)) enhanced_flush_cp; |
1334 | +#define ENHANCED_FLUSH_CP_SIZE 3 |
1335 | + |
1336 | +#define OCF_SEND_KEYPRESS_NOTIFY 0x0060 |
1337 | +typedef struct { |
1338 | + bdaddr_t bdaddr; |
1339 | + uint8_t type; |
1340 | +} __attribute__ ((packed)) send_keypress_notify_cp; |
1341 | +#define SEND_KEYPRESS_NOTIFY_CP_SIZE 7 |
1342 | +typedef struct { |
1343 | + uint8_t status; |
1344 | +} __attribute__ ((packed)) send_keypress_notify_rp; |
1345 | +#define SEND_KEYPRESS_NOTIFY_RP_SIZE 1 |
1346 | + |
1347 | +#define OCF_READ_LOGICAL_LINK_ACCEPT_TIMEOUT 0x0061 |
1348 | +typedef struct { |
1349 | + uint8_t status; |
1350 | + uint16_t timeout; |
1351 | +} __attribute__ ((packed)) read_log_link_accept_timeout_rp; |
1352 | +#define READ_LOGICAL_LINK_ACCEPT_TIMEOUT_RP_SIZE 3 |
1353 | + |
1354 | +#define OCF_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT 0x0062 |
1355 | +typedef struct { |
1356 | + uint16_t timeout; |
1357 | +} __attribute__ ((packed)) write_log_link_accept_timeout_cp; |
1358 | +#define WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CP_SIZE 2 |
1359 | + |
1360 | +#define OCF_SET_EVENT_MASK_PAGE_2 0x0063 |
1361 | + |
1362 | +#define OCF_READ_LOCATION_DATA 0x0064 |
1363 | + |
1364 | +#define OCF_WRITE_LOCATION_DATA 0x0065 |
1365 | + |
1366 | +#define OCF_READ_FLOW_CONTROL_MODE 0x0066 |
1367 | + |
1368 | +#define OCF_WRITE_FLOW_CONTROL_MODE 0x0067 |
1369 | + |
1370 | +#define OCF_READ_ENHANCED_TRANSMIT_POWER_LEVEL 0x0068 |
1371 | +typedef struct { |
1372 | + uint8_t status; |
1373 | + uint16_t handle; |
1374 | + int8_t level_gfsk; |
1375 | + int8_t level_dqpsk; |
1376 | + int8_t level_8dpsk; |
1377 | +} __attribute__ ((packed)) read_enhanced_transmit_power_level_rp; |
1378 | +#define READ_ENHANCED_TRANSMIT_POWER_LEVEL_RP_SIZE 6 |
1379 | + |
1380 | +#define OCF_READ_BEST_EFFORT_FLUSH_TIMEOUT 0x0069 |
1381 | +typedef struct { |
1382 | + uint8_t status; |
1383 | + uint32_t timeout; |
1384 | +} __attribute__ ((packed)) read_best_effort_flush_timeout_rp; |
1385 | +#define READ_BEST_EFFORT_FLUSH_TIMEOUT_RP_SIZE 5 |
1386 | + |
1387 | +#define OCF_WRITE_BEST_EFFORT_FLUSH_TIMEOUT 0x006A |
1388 | +typedef struct { |
1389 | + uint16_t handle; |
1390 | + uint32_t timeout; |
1391 | +} __attribute__ ((packed)) write_best_effort_flush_timeout_cp; |
1392 | +#define WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CP_SIZE 6 |
1393 | +typedef struct { |
1394 | + uint8_t status; |
1395 | +} __attribute__ ((packed)) write_best_effort_flush_timeout_rp; |
1396 | +#define WRITE_BEST_EFFORT_FLUSH_TIMEOUT_RP_SIZE 1 |
1397 | + |
1398 | +#define OCF_READ_LE_HOST_SUPPORTED 0x006C |
1399 | +typedef struct { |
1400 | + uint8_t status; |
1401 | + uint8_t le; |
1402 | + uint8_t simul; |
1403 | +} __attribute__ ((packed)) read_le_host_supported_rp; |
1404 | +#define READ_LE_HOST_SUPPORTED_RP_SIZE 3 |
1405 | + |
1406 | +#define OCF_WRITE_LE_HOST_SUPPORTED 0x006D |
1407 | +typedef struct { |
1408 | + uint8_t le; |
1409 | + uint8_t simul; |
1410 | +} __attribute__ ((packed)) write_le_host_supported_cp; |
1411 | +#define WRITE_LE_HOST_SUPPORTED_CP_SIZE 2 |
1412 | + |
1413 | +/* Informational Parameters */ |
1414 | +#define OGF_INFO_PARAM 0x04 |
1415 | + |
1416 | +#define OCF_READ_LOCAL_VERSION 0x0001 |
1417 | +typedef struct { |
1418 | + uint8_t status; |
1419 | + uint8_t hci_ver; |
1420 | + uint16_t hci_rev; |
1421 | + uint8_t lmp_ver; |
1422 | + uint16_t manufacturer; |
1423 | + uint16_t lmp_subver; |
1424 | +} __attribute__ ((packed)) read_local_version_rp; |
1425 | +#define READ_LOCAL_VERSION_RP_SIZE 9 |
1426 | + |
1427 | +#define OCF_READ_LOCAL_COMMANDS 0x0002 |
1428 | +typedef struct { |
1429 | + uint8_t status; |
1430 | + uint8_t commands[64]; |
1431 | +} __attribute__ ((packed)) read_local_commands_rp; |
1432 | +#define READ_LOCAL_COMMANDS_RP_SIZE 65 |
1433 | + |
1434 | +#define OCF_READ_LOCAL_FEATURES 0x0003 |
1435 | +typedef struct { |
1436 | + uint8_t status; |
1437 | + uint8_t features[8]; |
1438 | +} __attribute__ ((packed)) read_local_features_rp; |
1439 | +#define READ_LOCAL_FEATURES_RP_SIZE 9 |
1440 | + |
1441 | +#define OCF_READ_LOCAL_EXT_FEATURES 0x0004 |
1442 | +typedef struct { |
1443 | + uint8_t page_num; |
1444 | +} __attribute__ ((packed)) read_local_ext_features_cp; |
1445 | +#define READ_LOCAL_EXT_FEATURES_CP_SIZE 1 |
1446 | +typedef struct { |
1447 | + uint8_t status; |
1448 | + uint8_t page_num; |
1449 | + uint8_t max_page_num; |
1450 | + uint8_t features[8]; |
1451 | +} __attribute__ ((packed)) read_local_ext_features_rp; |
1452 | +#define READ_LOCAL_EXT_FEATURES_RP_SIZE 11 |
1453 | + |
1454 | +#define OCF_READ_BUFFER_SIZE 0x0005 |
1455 | +typedef struct { |
1456 | + uint8_t status; |
1457 | + uint16_t acl_mtu; |
1458 | + uint8_t sco_mtu; |
1459 | + uint16_t acl_max_pkt; |
1460 | + uint16_t sco_max_pkt; |
1461 | +} __attribute__ ((packed)) read_buffer_size_rp; |
1462 | +#define READ_BUFFER_SIZE_RP_SIZE 8 |
1463 | + |
1464 | +#define OCF_READ_COUNTRY_CODE 0x0007 |
1465 | + |
1466 | +#define OCF_READ_BD_ADDR 0x0009 |
1467 | +typedef struct { |
1468 | + uint8_t status; |
1469 | + bdaddr_t bdaddr; |
1470 | +} __attribute__ ((packed)) read_bd_addr_rp; |
1471 | +#define READ_BD_ADDR_RP_SIZE 7 |
1472 | + |
1473 | +/* Status params */ |
1474 | +#define OGF_STATUS_PARAM 0x05 |
1475 | + |
1476 | +#define OCF_READ_FAILED_CONTACT_COUNTER 0x0001 |
1477 | +typedef struct { |
1478 | + uint8_t status; |
1479 | + uint16_t handle; |
1480 | + uint8_t counter; |
1481 | +} __attribute__ ((packed)) read_failed_contact_counter_rp; |
1482 | +#define READ_FAILED_CONTACT_COUNTER_RP_SIZE 4 |
1483 | + |
1484 | +#define OCF_RESET_FAILED_CONTACT_COUNTER 0x0002 |
1485 | +typedef struct { |
1486 | + uint8_t status; |
1487 | + uint16_t handle; |
1488 | +} __attribute__ ((packed)) reset_failed_contact_counter_rp; |
1489 | +#define RESET_FAILED_CONTACT_COUNTER_RP_SIZE 4 |
1490 | + |
1491 | +#define OCF_READ_LINK_QUALITY 0x0003 |
1492 | +typedef struct { |
1493 | + uint8_t status; |
1494 | + uint16_t handle; |
1495 | + uint8_t link_quality; |
1496 | +} __attribute__ ((packed)) read_link_quality_rp; |
1497 | +#define READ_LINK_QUALITY_RP_SIZE 4 |
1498 | + |
1499 | +#define OCF_READ_RSSI 0x0005 |
1500 | +typedef struct { |
1501 | + uint8_t status; |
1502 | + uint16_t handle; |
1503 | + int8_t rssi; |
1504 | +} __attribute__ ((packed)) read_rssi_rp; |
1505 | +#define READ_RSSI_RP_SIZE 4 |
1506 | + |
1507 | +#define OCF_READ_AFH_MAP 0x0006 |
1508 | +typedef struct { |
1509 | + uint8_t status; |
1510 | + uint16_t handle; |
1511 | + uint8_t mode; |
1512 | + uint8_t map[10]; |
1513 | +} __attribute__ ((packed)) read_afh_map_rp; |
1514 | +#define READ_AFH_MAP_RP_SIZE 14 |
1515 | + |
1516 | +#define OCF_READ_CLOCK 0x0007 |
1517 | +typedef struct { |
1518 | + uint16_t handle; |
1519 | + uint8_t which_clock; |
1520 | +} __attribute__ ((packed)) read_clock_cp; |
1521 | +#define READ_CLOCK_CP_SIZE 3 |
1522 | +typedef struct { |
1523 | + uint8_t status; |
1524 | + uint16_t handle; |
1525 | + uint32_t clock; |
1526 | + uint16_t accuracy; |
1527 | +} __attribute__ ((packed)) read_clock_rp; |
1528 | +#define READ_CLOCK_RP_SIZE 9 |
1529 | + |
1530 | +#define OCF_READ_LOCAL_AMP_INFO 0x0009 |
1531 | +typedef struct { |
1532 | + uint8_t status; |
1533 | + uint8_t amp_status; |
1534 | + uint32_t total_bandwidth; |
1535 | + uint32_t max_guaranteed_bandwidth; |
1536 | + uint32_t min_latency; |
1537 | + uint32_t max_pdu_size; |
1538 | + uint8_t controller_type; |
1539 | + uint16_t pal_caps; |
1540 | + uint16_t max_amp_assoc_length; |
1541 | + uint32_t max_flush_timeout; |
1542 | + uint32_t best_effort_flush_timeout; |
1543 | +} __attribute__ ((packed)) read_local_amp_info_rp; |
1544 | +#define READ_LOCAL_AMP_INFO_RP_SIZE 31 |
1545 | + |
1546 | +#define OCF_READ_LOCAL_AMP_ASSOC 0x000A |
1547 | +typedef struct { |
1548 | + uint8_t handle; |
1549 | + uint16_t len_so_far; |
1550 | + uint16_t max_len; |
1551 | +} __attribute__ ((packed)) read_local_amp_assoc_cp; |
1552 | + |
1553 | +typedef struct { |
1554 | + uint8_t status; |
1555 | + uint8_t handle; |
1556 | + uint16_t rem_len; |
1557 | + uint8_t frag[0]; |
1558 | +} __attribute__ ((packed)) read_local_amp_assoc_rp; |
1559 | + |
1560 | +#define OCF_WRITE_REMOTE_AMP_ASSOC 0x000B |
1561 | +typedef struct { |
1562 | + uint8_t handle; |
1563 | + uint16_t length_so_far; |
1564 | + uint16_t assoc_length; |
1565 | + uint8_t fragment[HCI_MAX_NAME_LENGTH]; |
1566 | +} __attribute__ ((packed)) write_remote_amp_assoc_cp; |
1567 | +#define WRITE_REMOTE_AMP_ASSOC_CP_SIZE 253 |
1568 | +typedef struct { |
1569 | + uint8_t status; |
1570 | + uint8_t handle; |
1571 | +} __attribute__ ((packed)) write_remote_amp_assoc_rp; |
1572 | +#define WRITE_REMOTE_AMP_ASSOC_RP_SIZE 2 |
1573 | + |
1574 | +/* Testing commands */ |
1575 | +#define OGF_TESTING_CMD 0x3e |
1576 | + |
1577 | +#define OCF_READ_LOOPBACK_MODE 0x0001 |
1578 | + |
1579 | +#define OCF_WRITE_LOOPBACK_MODE 0x0002 |
1580 | + |
1581 | +#define OCF_ENABLE_DEVICE_UNDER_TEST_MODE 0x0003 |
1582 | + |
1583 | +#define OCF_WRITE_SIMPLE_PAIRING_DEBUG_MODE 0x0004 |
1584 | +typedef struct { |
1585 | + uint8_t mode; |
1586 | +} __attribute__ ((packed)) write_simple_pairing_debug_mode_cp; |
1587 | +#define WRITE_SIMPLE_PAIRING_DEBUG_MODE_CP_SIZE 1 |
1588 | +typedef struct { |
1589 | + uint8_t status; |
1590 | +} __attribute__ ((packed)) write_simple_pairing_debug_mode_rp; |
1591 | +#define WRITE_SIMPLE_PAIRING_DEBUG_MODE_RP_SIZE 1 |
1592 | + |
1593 | +/* LE commands */ |
1594 | +#define OGF_LE_CTL 0x08 |
1595 | + |
1596 | +#define OCF_LE_SET_EVENT_MASK 0x0001 |
1597 | +typedef struct { |
1598 | + uint8_t mask[8]; |
1599 | +} __attribute__ ((packed)) le_set_event_mask_cp; |
1600 | +#define LE_SET_EVENT_MASK_CP_SIZE 8 |
1601 | + |
1602 | +#define OCF_LE_READ_BUFFER_SIZE 0x0002 |
1603 | +typedef struct { |
1604 | + uint8_t status; |
1605 | + uint16_t pkt_len; |
1606 | + uint8_t max_pkt; |
1607 | +} __attribute__ ((packed)) le_read_buffer_size_rp; |
1608 | +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 |
1609 | + |
1610 | +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 |
1611 | +typedef struct { |
1612 | + uint8_t status; |
1613 | + uint8_t features[8]; |
1614 | +} __attribute__ ((packed)) le_read_local_supported_features_rp; |
1615 | +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 |
1616 | + |
1617 | +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 |
1618 | +typedef struct { |
1619 | + bdaddr_t bdaddr; |
1620 | +} __attribute__ ((packed)) le_set_random_address_cp; |
1621 | +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 |
1622 | + |
1623 | +#define OCF_LE_SET_ADVERTISING_PARAMETERS 0x0006 |
1624 | +typedef struct { |
1625 | + uint16_t min_interval; |
1626 | + uint16_t max_interval; |
1627 | + uint8_t advtype; |
1628 | + uint8_t own_bdaddr_type; |
1629 | + uint8_t direct_bdaddr_type; |
1630 | + bdaddr_t direct_bdaddr; |
1631 | + uint8_t chan_map; |
1632 | + uint8_t filter; |
1633 | +} __attribute__ ((packed)) le_set_advertising_parameters_cp; |
1634 | +#define LE_SET_ADVERTISING_PARAMETERS_CP_SIZE 15 |
1635 | + |
1636 | +#define OCF_LE_READ_ADVERTISING_CHANNEL_TX_POWER 0x0007 |
1637 | +typedef struct { |
1638 | + uint8_t status; |
1639 | + uint8_t level; |
1640 | +} __attribute__ ((packed)) le_read_advertising_channel_tx_power_rp; |
1641 | +#define LE_READ_ADVERTISING_CHANNEL_TX_POWER_RP_SIZE 2 |
1642 | + |
1643 | +#define OCF_LE_SET_ADVERTISING_DATA 0x0008 |
1644 | +typedef struct { |
1645 | + uint8_t length; |
1646 | + uint8_t data[31]; |
1647 | +} __attribute__ ((packed)) le_set_advertising_data_cp; |
1648 | +#define LE_SET_ADVERTISING_DATA_CP_SIZE 32 |
1649 | + |
1650 | +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 |
1651 | +typedef struct { |
1652 | + uint8_t length; |
1653 | + uint8_t data[31]; |
1654 | +} __attribute__ ((packed)) le_set_scan_response_data_cp; |
1655 | +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 |
1656 | + |
1657 | +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A |
1658 | +typedef struct { |
1659 | + uint8_t enable; |
1660 | +} __attribute__ ((packed)) le_set_advertise_enable_cp; |
1661 | +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 |
1662 | + |
1663 | +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B |
1664 | +typedef struct { |
1665 | + uint8_t type; |
1666 | + uint16_t interval; |
1667 | + uint16_t window; |
1668 | + uint8_t own_bdaddr_type; |
1669 | + uint8_t filter; |
1670 | +} __attribute__ ((packed)) le_set_scan_parameters_cp; |
1671 | +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 |
1672 | + |
1673 | +#define OCF_LE_SET_SCAN_ENABLE 0x000C |
1674 | +typedef struct { |
1675 | + uint8_t enable; |
1676 | + uint8_t filter_dup; |
1677 | +} __attribute__ ((packed)) le_set_scan_enable_cp; |
1678 | +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 |
1679 | + |
1680 | +#define OCF_LE_CREATE_CONN 0x000D |
1681 | +typedef struct { |
1682 | + uint16_t interval; |
1683 | + uint16_t window; |
1684 | + uint8_t initiator_filter; |
1685 | + uint8_t peer_bdaddr_type; |
1686 | + bdaddr_t peer_bdaddr; |
1687 | + uint8_t own_bdaddr_type; |
1688 | + uint16_t min_interval; |
1689 | + uint16_t max_interval; |
1690 | + uint16_t latency; |
1691 | + uint16_t supervision_timeout; |
1692 | + uint16_t min_ce_length; |
1693 | + uint16_t max_ce_length; |
1694 | +} __attribute__ ((packed)) le_create_connection_cp; |
1695 | +#define LE_CREATE_CONN_CP_SIZE 25 |
1696 | + |
1697 | +#define OCF_LE_CREATE_CONN_CANCEL 0x000E |
1698 | + |
1699 | +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F |
1700 | +typedef struct { |
1701 | + uint8_t status; |
1702 | + uint8_t size; |
1703 | +} __attribute__ ((packed)) le_read_white_list_size_rp; |
1704 | +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 |
1705 | + |
1706 | +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 |
1707 | + |
1708 | +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 |
1709 | +typedef struct { |
1710 | + uint8_t bdaddr_type; |
1711 | + bdaddr_t bdaddr; |
1712 | +} __attribute__ ((packed)) le_add_device_to_white_list_cp; |
1713 | +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 |
1714 | + |
1715 | +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 |
1716 | +typedef struct { |
1717 | + uint8_t bdaddr_type; |
1718 | + bdaddr_t bdaddr; |
1719 | +} __attribute__ ((packed)) le_remove_device_from_white_list_cp; |
1720 | +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 |
1721 | + |
1722 | +#define OCF_LE_CONN_UPDATE 0x0013 |
1723 | +typedef struct { |
1724 | + uint16_t handle; |
1725 | + uint16_t min_interval; |
1726 | + uint16_t max_interval; |
1727 | + uint16_t latency; |
1728 | + uint16_t supervision_timeout; |
1729 | + uint16_t min_ce_length; |
1730 | + uint16_t max_ce_length; |
1731 | +} __attribute__ ((packed)) le_connection_update_cp; |
1732 | +#define LE_CONN_UPDATE_CP_SIZE 14 |
1733 | + |
1734 | +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 |
1735 | +typedef struct { |
1736 | + uint8_t map[5]; |
1737 | +} __attribute__ ((packed)) le_set_host_channel_classification_cp; |
1738 | +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 |
1739 | + |
1740 | +#define OCF_LE_READ_CHANNEL_MAP 0x0015 |
1741 | +typedef struct { |
1742 | + uint16_t handle; |
1743 | +} __attribute__ ((packed)) le_read_channel_map_cp; |
1744 | +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 |
1745 | +typedef struct { |
1746 | + uint8_t status; |
1747 | + uint16_t handle; |
1748 | + uint8_t map[5]; |
1749 | +} __attribute__ ((packed)) le_read_channel_map_rp; |
1750 | +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 |
1751 | + |
1752 | +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 |
1753 | +typedef struct { |
1754 | + uint16_t handle; |
1755 | +} __attribute__ ((packed)) le_read_remote_used_features_cp; |
1756 | +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 |
1757 | + |
1758 | +#define OCF_LE_ENCRYPT 0x0017 |
1759 | +typedef struct { |
1760 | + uint8_t key[16]; |
1761 | + uint8_t plaintext[16]; |
1762 | +} __attribute__ ((packed)) le_encrypt_cp; |
1763 | +#define LE_ENCRYPT_CP_SIZE 32 |
1764 | +typedef struct { |
1765 | + uint8_t status; |
1766 | + uint8_t data[16]; |
1767 | +} __attribute__ ((packed)) le_encrypt_rp; |
1768 | +#define LE_ENCRYPT_RP_SIZE 17 |
1769 | + |
1770 | +#define OCF_LE_RAND 0x0018 |
1771 | +typedef struct { |
1772 | + uint8_t status; |
1773 | + uint64_t random; |
1774 | +} __attribute__ ((packed)) le_rand_rp; |
1775 | +#define LE_RAND_RP_SIZE 9 |
1776 | + |
1777 | +#define OCF_LE_START_ENCRYPTION 0x0019 |
1778 | +typedef struct { |
1779 | + uint16_t handle; |
1780 | + uint64_t random; |
1781 | + uint16_t diversifier; |
1782 | + uint8_t key[16]; |
1783 | +} __attribute__ ((packed)) le_start_encryption_cp; |
1784 | +#define LE_START_ENCRYPTION_CP_SIZE 28 |
1785 | + |
1786 | +#define OCF_LE_LTK_REPLY 0x001A |
1787 | +typedef struct { |
1788 | + uint16_t handle; |
1789 | + uint8_t key[16]; |
1790 | +} __attribute__ ((packed)) le_ltk_reply_cp; |
1791 | +#define LE_LTK_REPLY_CP_SIZE 18 |
1792 | +typedef struct { |
1793 | + uint8_t status; |
1794 | + uint16_t handle; |
1795 | +} __attribute__ ((packed)) le_ltk_reply_rp; |
1796 | +#define LE_LTK_REPLY_RP_SIZE 3 |
1797 | + |
1798 | +#define OCF_LE_LTK_NEG_REPLY 0x001B |
1799 | +typedef struct { |
1800 | + uint16_t handle; |
1801 | +} __attribute__ ((packed)) le_ltk_neg_reply_cp; |
1802 | +#define LE_LTK_NEG_REPLY_CP_SIZE 2 |
1803 | +typedef struct { |
1804 | + uint8_t status; |
1805 | + uint16_t handle; |
1806 | +} __attribute__ ((packed)) le_ltk_neg_reply_rp; |
1807 | +#define LE_LTK_NEG_REPLY_RP_SIZE 3 |
1808 | + |
1809 | +#define OCF_LE_READ_SUPPORTED_STATES 0x001C |
1810 | +typedef struct { |
1811 | + uint8_t status; |
1812 | + uint64_t states; |
1813 | +} __attribute__ ((packed)) le_read_supported_states_rp; |
1814 | +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 |
1815 | + |
1816 | +#define OCF_LE_RECEIVER_TEST 0x001D |
1817 | +typedef struct { |
1818 | + uint8_t frequency; |
1819 | +} __attribute__ ((packed)) le_receiver_test_cp; |
1820 | +#define LE_RECEIVER_TEST_CP_SIZE 1 |
1821 | + |
1822 | +#define OCF_LE_TRANSMITTER_TEST 0x001E |
1823 | +typedef struct { |
1824 | + uint8_t frequency; |
1825 | + uint8_t length; |
1826 | + uint8_t payload; |
1827 | +} __attribute__ ((packed)) le_transmitter_test_cp; |
1828 | +#define LE_TRANSMITTER_TEST_CP_SIZE 3 |
1829 | + |
1830 | +#define OCF_LE_TEST_END 0x001F |
1831 | +typedef struct { |
1832 | + uint8_t status; |
1833 | + uint16_t num_pkts; |
1834 | +} __attribute__ ((packed)) le_test_end_rp; |
1835 | +#define LE_TEST_END_RP_SIZE 3 |
1836 | + |
1837 | +/* Vendor specific commands */ |
1838 | +#define OGF_VENDOR_CMD 0x3f |
1839 | + |
1840 | +/* ---- HCI Events ---- */ |
1841 | + |
1842 | +#define EVT_INQUIRY_COMPLETE 0x01 |
1843 | + |
1844 | +#define EVT_INQUIRY_RESULT 0x02 |
1845 | +typedef struct { |
1846 | + bdaddr_t bdaddr; |
1847 | + uint8_t pscan_rep_mode; |
1848 | + uint8_t pscan_period_mode; |
1849 | + uint8_t pscan_mode; |
1850 | + uint8_t dev_class[3]; |
1851 | + uint16_t clock_offset; |
1852 | +} __attribute__ ((packed)) inquiry_info; |
1853 | +#define INQUIRY_INFO_SIZE 14 |
1854 | + |
1855 | +#define EVT_CONN_COMPLETE 0x03 |
1856 | +typedef struct { |
1857 | + uint8_t status; |
1858 | + uint16_t handle; |
1859 | + bdaddr_t bdaddr; |
1860 | + uint8_t link_type; |
1861 | + uint8_t encr_mode; |
1862 | +} __attribute__ ((packed)) evt_conn_complete; |
1863 | +#define EVT_CONN_COMPLETE_SIZE 13 |
1864 | + |
1865 | +#define EVT_CONN_REQUEST 0x04 |
1866 | +typedef struct { |
1867 | + bdaddr_t bdaddr; |
1868 | + uint8_t dev_class[3]; |
1869 | + uint8_t link_type; |
1870 | +} __attribute__ ((packed)) evt_conn_request; |
1871 | +#define EVT_CONN_REQUEST_SIZE 10 |
1872 | + |
1873 | +#define EVT_DISCONN_COMPLETE 0x05 |
1874 | +typedef struct { |
1875 | + uint8_t status; |
1876 | + uint16_t handle; |
1877 | + uint8_t reason; |
1878 | +} __attribute__ ((packed)) evt_disconn_complete; |
1879 | +#define EVT_DISCONN_COMPLETE_SIZE 4 |
1880 | + |
1881 | +#define EVT_AUTH_COMPLETE 0x06 |
1882 | +typedef struct { |
1883 | + uint8_t status; |
1884 | + uint16_t handle; |
1885 | +} __attribute__ ((packed)) evt_auth_complete; |
1886 | +#define EVT_AUTH_COMPLETE_SIZE 3 |
1887 | + |
1888 | +#define EVT_REMOTE_NAME_REQ_COMPLETE 0x07 |
1889 | +typedef struct { |
1890 | + uint8_t status; |
1891 | + bdaddr_t bdaddr; |
1892 | + uint8_t name[HCI_MAX_NAME_LENGTH]; |
1893 | +} __attribute__ ((packed)) evt_remote_name_req_complete; |
1894 | +#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255 |
1895 | + |
1896 | +#define EVT_ENCRYPT_CHANGE 0x08 |
1897 | +typedef struct { |
1898 | + uint8_t status; |
1899 | + uint16_t handle; |
1900 | + uint8_t encrypt; |
1901 | +} __attribute__ ((packed)) evt_encrypt_change; |
1902 | +#define EVT_ENCRYPT_CHANGE_SIZE 5 |
1903 | + |
1904 | +#define EVT_CHANGE_CONN_LINK_KEY_COMPLETE 0x09 |
1905 | +typedef struct { |
1906 | + uint8_t status; |
1907 | + uint16_t handle; |
1908 | +} __attribute__ ((packed)) evt_change_conn_link_key_complete; |
1909 | +#define EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE 3 |
1910 | + |
1911 | +#define EVT_MASTER_LINK_KEY_COMPLETE 0x0A |
1912 | +typedef struct { |
1913 | + uint8_t status; |
1914 | + uint16_t handle; |
1915 | + uint8_t key_flag; |
1916 | +} __attribute__ ((packed)) evt_master_link_key_complete; |
1917 | +#define EVT_MASTER_LINK_KEY_COMPLETE_SIZE 4 |
1918 | + |
1919 | +#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B |
1920 | +typedef struct { |
1921 | + uint8_t status; |
1922 | + uint16_t handle; |
1923 | + uint8_t features[8]; |
1924 | +} __attribute__ ((packed)) evt_read_remote_features_complete; |
1925 | +#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11 |
1926 | + |
1927 | +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C |
1928 | +typedef struct { |
1929 | + uint8_t status; |
1930 | + uint16_t handle; |
1931 | + uint8_t lmp_ver; |
1932 | + uint16_t manufacturer; |
1933 | + uint16_t lmp_subver; |
1934 | +} __attribute__ ((packed)) evt_read_remote_version_complete; |
1935 | +#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8 |
1936 | + |
1937 | +#define EVT_QOS_SETUP_COMPLETE 0x0D |
1938 | +typedef struct { |
1939 | + uint8_t status; |
1940 | + uint16_t handle; |
1941 | + uint8_t flags; /* Reserved */ |
1942 | + hci_qos qos; |
1943 | +} __attribute__ ((packed)) evt_qos_setup_complete; |
1944 | +#define EVT_QOS_SETUP_COMPLETE_SIZE (4 + HCI_QOS_CP_SIZE) |
1945 | + |
1946 | +#define EVT_CMD_COMPLETE 0x0E |
1947 | +typedef struct { |
1948 | + uint8_t ncmd; |
1949 | + uint16_t opcode; |
1950 | +} __attribute__ ((packed)) evt_cmd_complete; |
1951 | +#define EVT_CMD_COMPLETE_SIZE 3 |
1952 | + |
1953 | +#define EVT_CMD_STATUS 0x0F |
1954 | +typedef struct { |
1955 | + uint8_t status; |
1956 | + uint8_t ncmd; |
1957 | + uint16_t opcode; |
1958 | +} __attribute__ ((packed)) evt_cmd_status; |
1959 | +#define EVT_CMD_STATUS_SIZE 4 |
1960 | + |
1961 | +#define EVT_HARDWARE_ERROR 0x10 |
1962 | +typedef struct { |
1963 | + uint8_t code; |
1964 | +} __attribute__ ((packed)) evt_hardware_error; |
1965 | +#define EVT_HARDWARE_ERROR_SIZE 1 |
1966 | + |
1967 | +#define EVT_FLUSH_OCCURRED 0x11 |
1968 | +typedef struct { |
1969 | + uint16_t handle; |
1970 | +} __attribute__ ((packed)) evt_flush_occured; |
1971 | +#define EVT_FLUSH_OCCURRED_SIZE 2 |
1972 | + |
1973 | +#define EVT_ROLE_CHANGE 0x12 |
1974 | +typedef struct { |
1975 | + uint8_t status; |
1976 | + bdaddr_t bdaddr; |
1977 | + uint8_t role; |
1978 | +} __attribute__ ((packed)) evt_role_change; |
1979 | +#define EVT_ROLE_CHANGE_SIZE 8 |
1980 | + |
1981 | +#define EVT_NUM_COMP_PKTS 0x13 |
1982 | +typedef struct { |
1983 | + uint8_t num_hndl; |
1984 | + /* variable length part */ |
1985 | +} __attribute__ ((packed)) evt_num_comp_pkts; |
1986 | +#define EVT_NUM_COMP_PKTS_SIZE 1 |
1987 | + |
1988 | +#define EVT_MODE_CHANGE 0x14 |
1989 | +typedef struct { |
1990 | + uint8_t status; |
1991 | + uint16_t handle; |
1992 | + uint8_t mode; |
1993 | + uint16_t interval; |
1994 | +} __attribute__ ((packed)) evt_mode_change; |
1995 | +#define EVT_MODE_CHANGE_SIZE 6 |
1996 | + |
1997 | +#define EVT_RETURN_LINK_KEYS 0x15 |
1998 | +typedef struct { |
1999 | + uint8_t num_keys; |
2000 | + /* variable length part */ |
2001 | +} __attribute__ ((packed)) evt_return_link_keys; |
2002 | +#define EVT_RETURN_LINK_KEYS_SIZE 1 |
2003 | + |
2004 | +#define EVT_PIN_CODE_REQ 0x16 |
2005 | +typedef struct { |
2006 | + bdaddr_t bdaddr; |
2007 | +} __attribute__ ((packed)) evt_pin_code_req; |
2008 | +#define EVT_PIN_CODE_REQ_SIZE 6 |
2009 | + |
2010 | +#define EVT_LINK_KEY_REQ 0x17 |
2011 | +typedef struct { |
2012 | + bdaddr_t bdaddr; |
2013 | +} __attribute__ ((packed)) evt_link_key_req; |
2014 | +#define EVT_LINK_KEY_REQ_SIZE 6 |
2015 | + |
2016 | +#define EVT_LINK_KEY_NOTIFY 0x18 |
2017 | +typedef struct { |
2018 | + bdaddr_t bdaddr; |
2019 | + uint8_t link_key[16]; |
2020 | + uint8_t key_type; |
2021 | +} __attribute__ ((packed)) evt_link_key_notify; |
2022 | +#define EVT_LINK_KEY_NOTIFY_SIZE 23 |
2023 | + |
2024 | +#define EVT_LOOPBACK_COMMAND 0x19 |
2025 | + |
2026 | +#define EVT_DATA_BUFFER_OVERFLOW 0x1A |
2027 | +typedef struct { |
2028 | + uint8_t link_type; |
2029 | +} __attribute__ ((packed)) evt_data_buffer_overflow; |
2030 | +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 |
2031 | + |
2032 | +#define EVT_MAX_SLOTS_CHANGE 0x1B |
2033 | +typedef struct { |
2034 | + uint16_t handle; |
2035 | + uint8_t max_slots; |
2036 | +} __attribute__ ((packed)) evt_max_slots_change; |
2037 | +#define EVT_MAX_SLOTS_CHANGE_SIZE 3 |
2038 | + |
2039 | +#define EVT_READ_CLOCK_OFFSET_COMPLETE 0x1C |
2040 | +typedef struct { |
2041 | + uint8_t status; |
2042 | + uint16_t handle; |
2043 | + uint16_t clock_offset; |
2044 | +} __attribute__ ((packed)) evt_read_clock_offset_complete; |
2045 | +#define EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE 5 |
2046 | + |
2047 | +#define EVT_CONN_PTYPE_CHANGED 0x1D |
2048 | +typedef struct { |
2049 | + uint8_t status; |
2050 | + uint16_t handle; |
2051 | + uint16_t ptype; |
2052 | +} __attribute__ ((packed)) evt_conn_ptype_changed; |
2053 | +#define EVT_CONN_PTYPE_CHANGED_SIZE 5 |
2054 | + |
2055 | +#define EVT_QOS_VIOLATION 0x1E |
2056 | +typedef struct { |
2057 | + uint16_t handle; |
2058 | +} __attribute__ ((packed)) evt_qos_violation; |
2059 | +#define EVT_QOS_VIOLATION_SIZE 2 |
2060 | + |
2061 | +#define EVT_PSCAN_REP_MODE_CHANGE 0x20 |
2062 | +typedef struct { |
2063 | + bdaddr_t bdaddr; |
2064 | + uint8_t pscan_rep_mode; |
2065 | +} __attribute__ ((packed)) evt_pscan_rep_mode_change; |
2066 | +#define EVT_PSCAN_REP_MODE_CHANGE_SIZE 7 |
2067 | + |
2068 | +#define EVT_FLOW_SPEC_COMPLETE 0x21 |
2069 | +typedef struct { |
2070 | + uint8_t status; |
2071 | + uint16_t handle; |
2072 | + uint8_t flags; |
2073 | + uint8_t direction; |
2074 | + hci_qos qos; |
2075 | +} __attribute__ ((packed)) evt_flow_spec_complete; |
2076 | +#define EVT_FLOW_SPEC_COMPLETE_SIZE (5 + HCI_QOS_CP_SIZE) |
2077 | + |
2078 | +#define EVT_INQUIRY_RESULT_WITH_RSSI 0x22 |
2079 | +typedef struct { |
2080 | + bdaddr_t bdaddr; |
2081 | + uint8_t pscan_rep_mode; |
2082 | + uint8_t pscan_period_mode; |
2083 | + uint8_t dev_class[3]; |
2084 | + uint16_t clock_offset; |
2085 | + int8_t rssi; |
2086 | +} __attribute__ ((packed)) inquiry_info_with_rssi; |
2087 | +#define INQUIRY_INFO_WITH_RSSI_SIZE 14 |
2088 | +typedef struct { |
2089 | + bdaddr_t bdaddr; |
2090 | + uint8_t pscan_rep_mode; |
2091 | + uint8_t pscan_period_mode; |
2092 | + uint8_t pscan_mode; |
2093 | + uint8_t dev_class[3]; |
2094 | + uint16_t clock_offset; |
2095 | + int8_t rssi; |
2096 | +} __attribute__ ((packed)) inquiry_info_with_rssi_and_pscan_mode; |
2097 | +#define INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE 15 |
2098 | + |
2099 | +#define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE 0x23 |
2100 | +typedef struct { |
2101 | + uint8_t status; |
2102 | + uint16_t handle; |
2103 | + uint8_t page_num; |
2104 | + uint8_t max_page_num; |
2105 | + uint8_t features[8]; |
2106 | +} __attribute__ ((packed)) evt_read_remote_ext_features_complete; |
2107 | +#define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE 13 |
2108 | + |
2109 | +#define EVT_SYNC_CONN_COMPLETE 0x2C |
2110 | +typedef struct { |
2111 | + uint8_t status; |
2112 | + uint16_t handle; |
2113 | + bdaddr_t bdaddr; |
2114 | + uint8_t link_type; |
2115 | + uint8_t trans_interval; |
2116 | + uint8_t retrans_window; |
2117 | + uint16_t rx_pkt_len; |
2118 | + uint16_t tx_pkt_len; |
2119 | + uint8_t air_mode; |
2120 | +} __attribute__ ((packed)) evt_sync_conn_complete; |
2121 | +#define EVT_SYNC_CONN_COMPLETE_SIZE 17 |
2122 | + |
2123 | +#define EVT_SYNC_CONN_CHANGED 0x2D |
2124 | +typedef struct { |
2125 | + uint8_t status; |
2126 | + uint16_t handle; |
2127 | + uint8_t trans_interval; |
2128 | + uint8_t retrans_window; |
2129 | + uint16_t rx_pkt_len; |
2130 | + uint16_t tx_pkt_len; |
2131 | +} __attribute__ ((packed)) evt_sync_conn_changed; |
2132 | +#define EVT_SYNC_CONN_CHANGED_SIZE 9 |
2133 | + |
2134 | +#define EVT_SNIFF_SUBRATING 0x2E |
2135 | +typedef struct { |
2136 | + uint8_t status; |
2137 | + uint16_t handle; |
2138 | + uint16_t max_tx_latency; |
2139 | + uint16_t max_rx_latency; |
2140 | + uint16_t min_remote_timeout; |
2141 | + uint16_t min_local_timeout; |
2142 | +} __attribute__ ((packed)) evt_sniff_subrating; |
2143 | +#define EVT_SNIFF_SUBRATING_SIZE 11 |
2144 | + |
2145 | +#define EVT_EXTENDED_INQUIRY_RESULT 0x2F |
2146 | +typedef struct { |
2147 | + bdaddr_t bdaddr; |
2148 | + uint8_t pscan_rep_mode; |
2149 | + uint8_t pscan_period_mode; |
2150 | + uint8_t dev_class[3]; |
2151 | + uint16_t clock_offset; |
2152 | + int8_t rssi; |
2153 | + uint8_t data[HCI_MAX_EIR_LENGTH]; |
2154 | +} __attribute__ ((packed)) extended_inquiry_info; |
2155 | +#define EXTENDED_INQUIRY_INFO_SIZE 254 |
2156 | + |
2157 | +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 |
2158 | +typedef struct { |
2159 | + uint8_t status; |
2160 | + uint16_t handle; |
2161 | +} __attribute__ ((packed)) evt_encryption_key_refresh_complete; |
2162 | +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 |
2163 | + |
2164 | +#define EVT_IO_CAPABILITY_REQUEST 0x31 |
2165 | +typedef struct { |
2166 | + bdaddr_t bdaddr; |
2167 | +} __attribute__ ((packed)) evt_io_capability_request; |
2168 | +#define EVT_IO_CAPABILITY_REQUEST_SIZE 6 |
2169 | + |
2170 | +#define EVT_IO_CAPABILITY_RESPONSE 0x32 |
2171 | +typedef struct { |
2172 | + bdaddr_t bdaddr; |
2173 | + uint8_t capability; |
2174 | + uint8_t oob_data; |
2175 | + uint8_t authentication; |
2176 | +} __attribute__ ((packed)) evt_io_capability_response; |
2177 | +#define EVT_IO_CAPABILITY_RESPONSE_SIZE 9 |
2178 | + |
2179 | +#define EVT_USER_CONFIRM_REQUEST 0x33 |
2180 | +typedef struct { |
2181 | + bdaddr_t bdaddr; |
2182 | + uint32_t passkey; |
2183 | +} __attribute__ ((packed)) evt_user_confirm_request; |
2184 | +#define EVT_USER_CONFIRM_REQUEST_SIZE 10 |
2185 | + |
2186 | +#define EVT_USER_PASSKEY_REQUEST 0x34 |
2187 | +typedef struct { |
2188 | + bdaddr_t bdaddr; |
2189 | +} __attribute__ ((packed)) evt_user_passkey_request; |
2190 | +#define EVT_USER_PASSKEY_REQUEST_SIZE 6 |
2191 | + |
2192 | +#define EVT_REMOTE_OOB_DATA_REQUEST 0x35 |
2193 | +typedef struct { |
2194 | + bdaddr_t bdaddr; |
2195 | +} __attribute__ ((packed)) evt_remote_oob_data_request; |
2196 | +#define EVT_REMOTE_OOB_DATA_REQUEST_SIZE 6 |
2197 | + |
2198 | +#define EVT_SIMPLE_PAIRING_COMPLETE 0x36 |
2199 | +typedef struct { |
2200 | + uint8_t status; |
2201 | + bdaddr_t bdaddr; |
2202 | +} __attribute__ ((packed)) evt_simple_pairing_complete; |
2203 | +#define EVT_SIMPLE_PAIRING_COMPLETE_SIZE 7 |
2204 | + |
2205 | +#define EVT_LINK_SUPERVISION_TIMEOUT_CHANGED 0x38 |
2206 | +typedef struct { |
2207 | + uint16_t handle; |
2208 | + uint16_t timeout; |
2209 | +} __attribute__ ((packed)) evt_link_supervision_timeout_changed; |
2210 | +#define EVT_LINK_SUPERVISION_TIMEOUT_CHANGED_SIZE 4 |
2211 | + |
2212 | +#define EVT_ENHANCED_FLUSH_COMPLETE 0x39 |
2213 | +typedef struct { |
2214 | + uint16_t handle; |
2215 | +} __attribute__ ((packed)) evt_enhanced_flush_complete; |
2216 | +#define EVT_ENHANCED_FLUSH_COMPLETE_SIZE 2 |
2217 | + |
2218 | +#define EVT_USER_PASSKEY_NOTIFY 0x3B |
2219 | +typedef struct { |
2220 | + bdaddr_t bdaddr; |
2221 | + uint32_t passkey; |
2222 | +} __attribute__ ((packed)) evt_user_passkey_notify; |
2223 | +#define EVT_USER_PASSKEY_NOTIFY_SIZE 10 |
2224 | + |
2225 | +#define EVT_KEYPRESS_NOTIFY 0x3C |
2226 | +typedef struct { |
2227 | + bdaddr_t bdaddr; |
2228 | + uint8_t type; |
2229 | +} __attribute__ ((packed)) evt_keypress_notify; |
2230 | +#define EVT_KEYPRESS_NOTIFY_SIZE 7 |
2231 | + |
2232 | +#define EVT_REMOTE_HOST_FEATURES_NOTIFY 0x3D |
2233 | +typedef struct { |
2234 | + bdaddr_t bdaddr; |
2235 | + uint8_t features[8]; |
2236 | +} __attribute__ ((packed)) evt_remote_host_features_notify; |
2237 | +#define EVT_REMOTE_HOST_FEATURES_NOTIFY_SIZE 14 |
2238 | + |
2239 | +#define EVT_LE_META_EVENT 0x3E |
2240 | +typedef struct { |
2241 | + uint8_t subevent; |
2242 | + uint8_t data[0]; |
2243 | +} __attribute__ ((packed)) evt_le_meta_event; |
2244 | +#define EVT_LE_META_EVENT_SIZE 1 |
2245 | + |
2246 | +#define EVT_LE_CONN_COMPLETE 0x01 |
2247 | +typedef struct { |
2248 | + uint8_t status; |
2249 | + uint16_t handle; |
2250 | + uint8_t role; |
2251 | + uint8_t peer_bdaddr_type; |
2252 | + bdaddr_t peer_bdaddr; |
2253 | + uint16_t interval; |
2254 | + uint16_t latency; |
2255 | + uint16_t supervision_timeout; |
2256 | + uint8_t master_clock_accuracy; |
2257 | +} __attribute__ ((packed)) evt_le_connection_complete; |
2258 | +#define EVT_LE_CONN_COMPLETE_SIZE 18 |
2259 | + |
2260 | +#define EVT_LE_ADVERTISING_REPORT 0x02 |
2261 | +typedef struct { |
2262 | + uint8_t evt_type; |
2263 | + uint8_t bdaddr_type; |
2264 | + bdaddr_t bdaddr; |
2265 | + uint8_t length; |
2266 | + uint8_t data[0]; |
2267 | +} __attribute__ ((packed)) le_advertising_info; |
2268 | +#define LE_ADVERTISING_INFO_SIZE 9 |
2269 | + |
2270 | +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 |
2271 | +typedef struct { |
2272 | + uint8_t status; |
2273 | + uint16_t handle; |
2274 | + uint16_t interval; |
2275 | + uint16_t latency; |
2276 | + uint16_t supervision_timeout; |
2277 | +} __attribute__ ((packed)) evt_le_connection_update_complete; |
2278 | +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 |
2279 | + |
2280 | +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 |
2281 | +typedef struct { |
2282 | + uint8_t status; |
2283 | + uint16_t handle; |
2284 | + uint8_t features[8]; |
2285 | +} __attribute__ ((packed)) evt_le_read_remote_used_features_complete; |
2286 | +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 |
2287 | + |
2288 | +#define EVT_LE_LTK_REQUEST 0x05 |
2289 | +typedef struct { |
2290 | + uint16_t handle; |
2291 | + uint64_t random; |
2292 | + uint16_t diversifier; |
2293 | +} __attribute__ ((packed)) evt_le_long_term_key_request; |
2294 | +#define EVT_LE_LTK_REQUEST_SIZE 12 |
2295 | + |
2296 | +#define EVT_PHYSICAL_LINK_COMPLETE 0x40 |
2297 | +typedef struct { |
2298 | + uint8_t status; |
2299 | + uint8_t handle; |
2300 | +} __attribute__ ((packed)) evt_physical_link_complete; |
2301 | +#define EVT_PHYSICAL_LINK_COMPLETE_SIZE 2 |
2302 | + |
2303 | +#define EVT_CHANNEL_SELECTED 0x41 |
2304 | + |
2305 | +#define EVT_DISCONNECT_PHYSICAL_LINK_COMPLETE 0x42 |
2306 | +typedef struct { |
2307 | + uint8_t status; |
2308 | + uint8_t handle; |
2309 | + uint8_t reason; |
2310 | +} __attribute__ ((packed)) evt_disconn_physical_link_complete; |
2311 | +#define EVT_DISCONNECT_PHYSICAL_LINK_COMPLETE_SIZE 3 |
2312 | + |
2313 | +#define EVT_PHYSICAL_LINK_LOSS_EARLY_WARNING 0x43 |
2314 | +typedef struct { |
2315 | + uint8_t handle; |
2316 | + uint8_t reason; |
2317 | +} __attribute__ ((packed)) evt_physical_link_loss_warning; |
2318 | +#define EVT_PHYSICAL_LINK_LOSS_WARNING_SIZE 2 |
2319 | + |
2320 | +#define EVT_PHYSICAL_LINK_RECOVERY 0x44 |
2321 | +typedef struct { |
2322 | + uint8_t handle; |
2323 | +} __attribute__ ((packed)) evt_physical_link_recovery; |
2324 | +#define EVT_PHYSICAL_LINK_RECOVERY_SIZE 1 |
2325 | + |
2326 | +#define EVT_LOGICAL_LINK_COMPLETE 0x45 |
2327 | +typedef struct { |
2328 | + uint8_t status; |
2329 | + uint16_t log_handle; |
2330 | + uint8_t handle; |
2331 | + uint8_t tx_flow_id; |
2332 | +} __attribute__ ((packed)) evt_logical_link_complete; |
2333 | +#define EVT_LOGICAL_LINK_COMPLETE_SIZE 5 |
2334 | + |
2335 | +#define EVT_DISCONNECT_LOGICAL_LINK_COMPLETE 0x46 |
2336 | + |
2337 | +#define EVT_FLOW_SPEC_MODIFY_COMPLETE 0x47 |
2338 | +typedef struct { |
2339 | + uint8_t status; |
2340 | + uint16_t handle; |
2341 | +} __attribute__ ((packed)) evt_flow_spec_modify_complete; |
2342 | +#define EVT_FLOW_SPEC_MODIFY_COMPLETE_SIZE 3 |
2343 | + |
2344 | +#define EVT_NUMBER_COMPLETED_BLOCKS 0x48 |
2345 | + |
2346 | +#define EVT_AMP_STATUS_CHANGE 0x4D |
2347 | +typedef struct { |
2348 | + uint8_t status; |
2349 | + uint8_t amp_status; |
2350 | +} __attribute__ ((packed)) evt_amp_status_change; |
2351 | +#define EVT_AMP_STATUS_CHANGE_SIZE 2 |
2352 | + |
2353 | +#define EVT_TESTING 0xFE |
2354 | + |
2355 | +#define EVT_VENDOR 0xFF |
2356 | + |
2357 | +/* Internal events generated by BlueZ stack */ |
2358 | +#define EVT_STACK_INTERNAL 0xFD |
2359 | +typedef struct { |
2360 | + uint16_t type; |
2361 | + uint8_t data[0]; |
2362 | +} __attribute__ ((packed)) evt_stack_internal; |
2363 | +#define EVT_STACK_INTERNAL_SIZE 2 |
2364 | + |
2365 | +#define EVT_SI_DEVICE 0x01 |
2366 | +typedef struct { |
2367 | + uint16_t event; |
2368 | + uint16_t dev_id; |
2369 | +} __attribute__ ((packed)) evt_si_device; |
2370 | +#define EVT_SI_DEVICE_SIZE 4 |
2371 | + |
2372 | +/* -------- HCI Packet structures -------- */ |
2373 | +#define HCI_TYPE_LEN 1 |
2374 | + |
2375 | +typedef struct { |
2376 | + uint16_t opcode; /* OCF & OGF */ |
2377 | + uint8_t plen; |
2378 | +} __attribute__ ((packed)) hci_command_hdr; |
2379 | +#define HCI_COMMAND_HDR_SIZE 3 |
2380 | + |
2381 | +typedef struct { |
2382 | + uint8_t evt; |
2383 | + uint8_t plen; |
2384 | +} __attribute__ ((packed)) hci_event_hdr; |
2385 | +#define HCI_EVENT_HDR_SIZE 2 |
2386 | + |
2387 | +typedef struct { |
2388 | + uint16_t handle; /* Handle & Flags(PB, BC) */ |
2389 | + uint16_t dlen; |
2390 | +} __attribute__ ((packed)) hci_acl_hdr; |
2391 | +#define HCI_ACL_HDR_SIZE 4 |
2392 | + |
2393 | +typedef struct { |
2394 | + uint16_t handle; |
2395 | + uint8_t dlen; |
2396 | +} __attribute__ ((packed)) hci_sco_hdr; |
2397 | +#define HCI_SCO_HDR_SIZE 3 |
2398 | + |
2399 | +typedef struct { |
2400 | + uint16_t device; |
2401 | + uint16_t type; |
2402 | + uint16_t plen; |
2403 | +} __attribute__ ((packed)) hci_msg_hdr; |
2404 | +#define HCI_MSG_HDR_SIZE 6 |
2405 | + |
2406 | +/* Command opcode pack/unpack */ |
2407 | +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) |
2408 | +#define cmd_opcode_ogf(op) (op >> 10) |
2409 | +#define cmd_opcode_ocf(op) (op & 0x03ff) |
2410 | + |
2411 | +/* ACL handle and flags pack/unpack */ |
2412 | +#define acl_handle_pack(h, f) (uint16_t)((h & 0x0fff)|(f << 12)) |
2413 | +#define acl_handle(h) (h & 0x0fff) |
2414 | +#define acl_flags(h) (h >> 12) |
2415 | + |
2416 | +#endif /* _NO_HCI_DEFS */ |
2417 | + |
2418 | +/* HCI Socket options */ |
2419 | +#define HCI_DATA_DIR 1 |
2420 | +#define HCI_FILTER 2 |
2421 | +#define HCI_TIME_STAMP 3 |
2422 | + |
2423 | +/* HCI CMSG flags */ |
2424 | +#define HCI_CMSG_DIR 0x0001 |
2425 | +#define HCI_CMSG_TSTAMP 0x0002 |
2426 | + |
2427 | +struct sockaddr_hci { |
2428 | + sa_family_t hci_family; |
2429 | + unsigned short hci_dev; |
2430 | + unsigned short hci_channel; |
2431 | +}; |
2432 | +#define HCI_DEV_NONE 0xffff |
2433 | + |
2434 | +#define HCI_CHANNEL_RAW 0 |
2435 | +#define HCI_CHANNEL_MONITOR 2 |
2436 | +#define HCI_CHANNEL_CONTROL 3 |
2437 | + |
2438 | +struct hci_filter { |
2439 | + uint32_t type_mask; |
2440 | + uint32_t event_mask[2]; |
2441 | + uint16_t opcode; |
2442 | +}; |
2443 | + |
2444 | +#define HCI_FLT_TYPE_BITS 31 |
2445 | +#define HCI_FLT_EVENT_BITS 63 |
2446 | +#define HCI_FLT_OGF_BITS 63 |
2447 | +#define HCI_FLT_OCF_BITS 127 |
2448 | + |
2449 | +/* Ioctl requests structures */ |
2450 | +struct hci_dev_stats { |
2451 | + uint32_t err_rx; |
2452 | + uint32_t err_tx; |
2453 | + uint32_t cmd_tx; |
2454 | + uint32_t evt_rx; |
2455 | + uint32_t acl_tx; |
2456 | + uint32_t acl_rx; |
2457 | + uint32_t sco_tx; |
2458 | + uint32_t sco_rx; |
2459 | + uint32_t byte_rx; |
2460 | + uint32_t byte_tx; |
2461 | +}; |
2462 | + |
2463 | +struct hci_dev_info { |
2464 | + uint16_t dev_id; |
2465 | + char name[8]; |
2466 | + |
2467 | + bdaddr_t bdaddr; |
2468 | + |
2469 | + uint32_t flags; |
2470 | + uint8_t type; |
2471 | + |
2472 | + uint8_t features[8]; |
2473 | + |
2474 | + uint32_t pkt_type; |
2475 | + uint32_t link_policy; |
2476 | + uint32_t link_mode; |
2477 | + |
2478 | + uint16_t acl_mtu; |
2479 | + uint16_t acl_pkts; |
2480 | + uint16_t sco_mtu; |
2481 | + uint16_t sco_pkts; |
2482 | + |
2483 | + struct hci_dev_stats stat; |
2484 | +}; |
2485 | + |
2486 | +struct hci_conn_info { |
2487 | + uint16_t handle; |
2488 | + bdaddr_t bdaddr; |
2489 | + uint8_t type; |
2490 | + uint8_t out; |
2491 | + uint16_t state; |
2492 | + uint32_t link_mode; |
2493 | +}; |
2494 | + |
2495 | +struct hci_dev_req { |
2496 | + uint16_t dev_id; |
2497 | + uint32_t dev_opt; |
2498 | +}; |
2499 | + |
2500 | +struct hci_dev_list_req { |
2501 | + uint16_t dev_num; |
2502 | + struct hci_dev_req dev_req[0]; /* hci_dev_req structures */ |
2503 | +}; |
2504 | + |
2505 | +struct hci_conn_list_req { |
2506 | + uint16_t dev_id; |
2507 | + uint16_t conn_num; |
2508 | + struct hci_conn_info conn_info[0]; |
2509 | +}; |
2510 | + |
2511 | +struct hci_conn_info_req { |
2512 | + bdaddr_t bdaddr; |
2513 | + uint8_t type; |
2514 | + struct hci_conn_info conn_info[0]; |
2515 | +}; |
2516 | + |
2517 | +struct hci_auth_info_req { |
2518 | + bdaddr_t bdaddr; |
2519 | + uint8_t type; |
2520 | +}; |
2521 | + |
2522 | +struct hci_inquiry_req { |
2523 | + uint16_t dev_id; |
2524 | + uint16_t flags; |
2525 | + uint8_t lap[3]; |
2526 | + uint8_t length; |
2527 | + uint8_t num_rsp; |
2528 | +}; |
2529 | +#define IREQ_CACHE_FLUSH 0x0001 |
2530 | + |
2531 | +#ifdef __cplusplus |
2532 | +} |
2533 | +#endif |
2534 | + |
2535 | +#endif /* __HCI_H */ |
2536 | |
2537 | === added file '.pc/ssp_parameter.patch/lib/mgmt.h' |
2538 | --- .pc/ssp_parameter.patch/lib/mgmt.h 1970-01-01 00:00:00 +0000 |
2539 | +++ .pc/ssp_parameter.patch/lib/mgmt.h 2014-05-15 03:26:22 +0000 |
2540 | @@ -0,0 +1,554 @@ |
2541 | +/* |
2542 | + * BlueZ - Bluetooth protocol stack for Linux |
2543 | + * |
2544 | + * Copyright (C) 2010 Nokia Corporation |
2545 | + * Copyright (C) 2010 Marcel Holtmann <marcel@holtmann.org> |
2546 | + * |
2547 | + * |
2548 | + * This program is free software; you can redistribute it and/or modify |
2549 | + * it under the terms of the GNU General Public License as published by |
2550 | + * the Free Software Foundation; either version 2 of the License, or |
2551 | + * (at your option) any later version. |
2552 | + * |
2553 | + * This program is distributed in the hope that it will be useful, |
2554 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2555 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2556 | + * GNU General Public License for more details. |
2557 | + * |
2558 | + * You should have received a copy of the GNU General Public License |
2559 | + * along with this program; if not, write to the Free Software |
2560 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
2561 | + * |
2562 | + */ |
2563 | + |
2564 | +#ifndef __packed |
2565 | +#define __packed __attribute__((packed)) |
2566 | +#endif |
2567 | + |
2568 | +#define MGMT_INDEX_NONE 0xFFFF |
2569 | + |
2570 | +#define MGMT_STATUS_SUCCESS 0x00 |
2571 | +#define MGMT_STATUS_UNKNOWN_COMMAND 0x01 |
2572 | +#define MGMT_STATUS_NOT_CONNECTED 0x02 |
2573 | +#define MGMT_STATUS_FAILED 0x03 |
2574 | +#define MGMT_STATUS_CONNECT_FAILED 0x04 |
2575 | +#define MGMT_STATUS_AUTH_FAILED 0x05 |
2576 | +#define MGMT_STATUS_NOT_PAIRED 0x06 |
2577 | +#define MGMT_STATUS_NO_RESOURCES 0x07 |
2578 | +#define MGMT_STATUS_TIMEOUT 0x08 |
2579 | +#define MGMT_STATUS_ALREADY_CONNECTED 0x09 |
2580 | +#define MGMT_STATUS_BUSY 0x0a |
2581 | +#define MGMT_STATUS_REJECTED 0x0b |
2582 | +#define MGMT_STATUS_NOT_SUPPORTED 0x0c |
2583 | +#define MGMT_STATUS_INVALID_PARAMS 0x0d |
2584 | +#define MGMT_STATUS_DISCONNECTED 0x0e |
2585 | +#define MGMT_STATUS_NOT_POWERED 0x0f |
2586 | +#define MGMT_STATUS_CANCELLED 0x10 |
2587 | +#define MGMT_STATUS_INVALID_INDEX 0x11 |
2588 | + |
2589 | +struct mgmt_hdr { |
2590 | + uint16_t opcode; |
2591 | + uint16_t index; |
2592 | + uint16_t len; |
2593 | +} __packed; |
2594 | +#define MGMT_HDR_SIZE 6 |
2595 | + |
2596 | +struct mgmt_addr_info { |
2597 | + bdaddr_t bdaddr; |
2598 | + uint8_t type; |
2599 | +} __packed; |
2600 | + |
2601 | +#define MGMT_OP_READ_VERSION 0x0001 |
2602 | +struct mgmt_rp_read_version { |
2603 | + uint8_t version; |
2604 | + uint16_t revision; |
2605 | +} __packed; |
2606 | + |
2607 | +#define MGMT_OP_READ_COMMANDS 0x0002 |
2608 | +struct mgmt_rp_read_commands { |
2609 | + uint16_t num_commands; |
2610 | + uint16_t num_events; |
2611 | + uint16_t opcodes[0]; |
2612 | +} __packed; |
2613 | + |
2614 | +#define MGMT_OP_READ_INDEX_LIST 0x0003 |
2615 | +struct mgmt_rp_read_index_list { |
2616 | + uint16_t num_controllers; |
2617 | + uint16_t index[0]; |
2618 | +} __packed; |
2619 | + |
2620 | +/* Reserve one extra byte for names in management messages so that they |
2621 | + * are always guaranteed to be nul-terminated */ |
2622 | +#define MGMT_MAX_NAME_LENGTH (HCI_MAX_NAME_LENGTH + 1) |
2623 | +#define MGMT_MAX_SHORT_NAME_LENGTH (10 + 1) |
2624 | + |
2625 | +#define MGMT_SETTING_POWERED 0x00000001 |
2626 | +#define MGMT_SETTING_CONNECTABLE 0x00000002 |
2627 | +#define MGMT_SETTING_FAST_CONNECTABLE 0x00000004 |
2628 | +#define MGMT_SETTING_DISCOVERABLE 0x00000008 |
2629 | +#define MGMT_SETTING_PAIRABLE 0x00000010 |
2630 | +#define MGMT_SETTING_LINK_SECURITY 0x00000020 |
2631 | +#define MGMT_SETTING_SSP 0x00000040 |
2632 | +#define MGMT_SETTING_BREDR 0x00000080 |
2633 | +#define MGMT_SETTING_HS 0x00000100 |
2634 | +#define MGMT_SETTING_LE 0x00000200 |
2635 | + |
2636 | +#define MGMT_OP_READ_INFO 0x0004 |
2637 | +struct mgmt_rp_read_info { |
2638 | + bdaddr_t bdaddr; |
2639 | + uint8_t version; |
2640 | + uint16_t manufacturer; |
2641 | + uint32_t supported_settings; |
2642 | + uint32_t current_settings; |
2643 | + uint8_t dev_class[3]; |
2644 | + uint8_t name[MGMT_MAX_NAME_LENGTH]; |
2645 | + uint8_t short_name[MGMT_MAX_SHORT_NAME_LENGTH]; |
2646 | +} __packed; |
2647 | + |
2648 | +struct mgmt_mode { |
2649 | + uint8_t val; |
2650 | +} __packed; |
2651 | + |
2652 | +#define MGMT_OP_SET_POWERED 0x0005 |
2653 | + |
2654 | +#define MGMT_OP_SET_DISCOVERABLE 0x0006 |
2655 | +struct mgmt_cp_set_discoverable { |
2656 | + uint8_t val; |
2657 | + uint16_t timeout; |
2658 | +} __packed; |
2659 | + |
2660 | +#define MGMT_OP_SET_CONNECTABLE 0x0007 |
2661 | + |
2662 | +#define MGMT_OP_SET_FAST_CONNECTABLE 0x0008 |
2663 | + |
2664 | +#define MGMT_OP_SET_PAIRABLE 0x0009 |
2665 | + |
2666 | +#define MGMT_OP_SET_LINK_SECURITY 0x000A |
2667 | + |
2668 | +#define MGMT_OP_SET_SSP 0x000B |
2669 | + |
2670 | +#define MGMT_OP_SET_HS 0x000C |
2671 | + |
2672 | +#define MGMT_OP_SET_LE 0x000D |
2673 | + |
2674 | +#define MGMT_OP_SET_DEV_CLASS 0x000E |
2675 | +struct mgmt_cp_set_dev_class { |
2676 | + uint8_t major; |
2677 | + uint8_t minor; |
2678 | +} __packed; |
2679 | + |
2680 | +#define MGMT_OP_SET_LOCAL_NAME 0x000F |
2681 | +struct mgmt_cp_set_local_name { |
2682 | + uint8_t name[MGMT_MAX_NAME_LENGTH]; |
2683 | + uint8_t short_name[MGMT_MAX_SHORT_NAME_LENGTH]; |
2684 | +} __packed; |
2685 | + |
2686 | +#define MGMT_OP_ADD_UUID 0x0010 |
2687 | +struct mgmt_cp_add_uuid { |
2688 | + uint8_t uuid[16]; |
2689 | + uint8_t svc_hint; |
2690 | +} __packed; |
2691 | + |
2692 | +#define MGMT_OP_REMOVE_UUID 0x0011 |
2693 | +struct mgmt_cp_remove_uuid { |
2694 | + uint8_t uuid[16]; |
2695 | +} __packed; |
2696 | + |
2697 | +struct mgmt_link_key_info { |
2698 | + struct mgmt_addr_info addr; |
2699 | + uint8_t type; |
2700 | + uint8_t val[16]; |
2701 | + uint8_t pin_len; |
2702 | +} __packed; |
2703 | + |
2704 | +#define MGMT_OP_LOAD_LINK_KEYS 0x0012 |
2705 | +struct mgmt_cp_load_link_keys { |
2706 | + uint8_t debug_keys; |
2707 | + uint16_t key_count; |
2708 | + struct mgmt_link_key_info keys[0]; |
2709 | +} __packed; |
2710 | + |
2711 | +struct mgmt_ltk_info { |
2712 | + struct mgmt_addr_info addr; |
2713 | + uint8_t authenticated; |
2714 | + uint8_t master; |
2715 | + uint8_t enc_size; |
2716 | + uint16_t ediv; |
2717 | + uint8_t rand[8]; |
2718 | + uint8_t val[16]; |
2719 | +} __packed; |
2720 | + |
2721 | +#define MGMT_OP_LOAD_LONG_TERM_KEYS 0x0013 |
2722 | +struct mgmt_cp_load_long_term_keys { |
2723 | + uint16_t key_count; |
2724 | + struct mgmt_ltk_info keys[0]; |
2725 | +} __packed; |
2726 | + |
2727 | +#define MGMT_OP_DISCONNECT 0x0014 |
2728 | +struct mgmt_cp_disconnect { |
2729 | + struct mgmt_addr_info addr; |
2730 | +} __packed; |
2731 | +struct mgmt_rp_disconnect { |
2732 | + struct mgmt_addr_info addr; |
2733 | +} __packed; |
2734 | + |
2735 | +#define MGMT_OP_GET_CONNECTIONS 0x0015 |
2736 | +struct mgmt_rp_get_connections { |
2737 | + uint16_t conn_count; |
2738 | + struct mgmt_addr_info addr[0]; |
2739 | +} __packed; |
2740 | + |
2741 | +#define MGMT_OP_PIN_CODE_REPLY 0x0016 |
2742 | +struct mgmt_cp_pin_code_reply { |
2743 | + struct mgmt_addr_info addr; |
2744 | + uint8_t pin_len; |
2745 | + uint8_t pin_code[16]; |
2746 | +} __packed; |
2747 | + |
2748 | +#define MGMT_OP_PIN_CODE_NEG_REPLY 0x0017 |
2749 | +struct mgmt_cp_pin_code_neg_reply { |
2750 | + struct mgmt_addr_info addr; |
2751 | +} __packed; |
2752 | + |
2753 | +#define MGMT_OP_SET_IO_CAPABILITY 0x0018 |
2754 | +struct mgmt_cp_set_io_capability { |
2755 | + uint8_t io_capability; |
2756 | +} __packed; |
2757 | + |
2758 | +#define MGMT_OP_PAIR_DEVICE 0x0019 |
2759 | +struct mgmt_cp_pair_device { |
2760 | + struct mgmt_addr_info addr; |
2761 | + uint8_t io_cap; |
2762 | +} __packed; |
2763 | +struct mgmt_rp_pair_device { |
2764 | + struct mgmt_addr_info addr; |
2765 | +} __packed; |
2766 | + |
2767 | +#define MGMT_OP_CANCEL_PAIR_DEVICE 0x001A |
2768 | + |
2769 | +#define MGMT_OP_UNPAIR_DEVICE 0x001B |
2770 | +struct mgmt_cp_unpair_device { |
2771 | + struct mgmt_addr_info addr; |
2772 | + uint8_t disconnect; |
2773 | +} __packed; |
2774 | +struct mgmt_rp_unpair_device { |
2775 | + struct mgmt_addr_info addr; |
2776 | +} __packed; |
2777 | + |
2778 | +#define MGMT_OP_USER_CONFIRM_REPLY 0x001C |
2779 | +struct mgmt_cp_user_confirm_reply { |
2780 | + struct mgmt_addr_info addr; |
2781 | +} __packed; |
2782 | +struct mgmt_rp_user_confirm_reply { |
2783 | + struct mgmt_addr_info addr; |
2784 | +} __packed; |
2785 | + |
2786 | +#define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x001D |
2787 | + |
2788 | +#define MGMT_OP_USER_PASSKEY_REPLY 0x001E |
2789 | +struct mgmt_cp_user_passkey_reply { |
2790 | + struct mgmt_addr_info addr; |
2791 | + uint32_t passkey; |
2792 | +} __packed; |
2793 | +struct mgmt_rp_user_passkey_reply { |
2794 | + struct mgmt_addr_info addr; |
2795 | +} __packed; |
2796 | + |
2797 | +#define MGMT_OP_USER_PASSKEY_NEG_REPLY 0x001F |
2798 | +struct mgmt_cp_user_passkey_neg_reply { |
2799 | + struct mgmt_addr_info addr; |
2800 | +} __packed; |
2801 | + |
2802 | +#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0020 |
2803 | +struct mgmt_rp_read_local_oob_data { |
2804 | + uint8_t hash[16]; |
2805 | + uint8_t randomizer[16]; |
2806 | +} __packed; |
2807 | + |
2808 | +#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0021 |
2809 | +struct mgmt_cp_add_remote_oob_data { |
2810 | + struct mgmt_addr_info addr; |
2811 | + uint8_t hash[16]; |
2812 | + uint8_t randomizer[16]; |
2813 | +} __packed; |
2814 | + |
2815 | +#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x0022 |
2816 | +struct mgmt_cp_remove_remote_oob_data { |
2817 | + struct mgmt_addr_info addr; |
2818 | +} __packed; |
2819 | + |
2820 | +#define MGMT_OP_START_DISCOVERY 0x0023 |
2821 | +struct mgmt_cp_start_discovery { |
2822 | + uint8_t type; |
2823 | +} __packed; |
2824 | + |
2825 | +#define MGMT_OP_STOP_DISCOVERY 0x0024 |
2826 | +struct mgmt_cp_stop_discovery { |
2827 | + uint8_t type; |
2828 | +} __packed; |
2829 | + |
2830 | +#define MGMT_OP_CONFIRM_NAME 0x0025 |
2831 | +struct mgmt_cp_confirm_name { |
2832 | + struct mgmt_addr_info addr; |
2833 | + uint8_t name_known; |
2834 | +} __packed; |
2835 | +struct mgmt_rp_confirm_name { |
2836 | + struct mgmt_addr_info addr; |
2837 | +} __packed; |
2838 | + |
2839 | +#define MGMT_OP_BLOCK_DEVICE 0x0026 |
2840 | +struct mgmt_cp_block_device { |
2841 | + struct mgmt_addr_info addr; |
2842 | +} __packed; |
2843 | + |
2844 | +#define MGMT_OP_UNBLOCK_DEVICE 0x0027 |
2845 | +struct mgmt_cp_unblock_device { |
2846 | + struct mgmt_addr_info addr; |
2847 | +} __packed; |
2848 | + |
2849 | +#define MGMT_OP_SET_DEVICE_ID 0x0028 |
2850 | +struct mgmt_cp_set_device_id { |
2851 | + uint16_t source; |
2852 | + uint16_t vendor; |
2853 | + uint16_t product; |
2854 | + uint16_t version; |
2855 | +} __packed; |
2856 | + |
2857 | +#define MGMT_EV_CMD_COMPLETE 0x0001 |
2858 | +struct mgmt_ev_cmd_complete { |
2859 | + uint16_t opcode; |
2860 | + uint8_t status; |
2861 | + uint8_t data[0]; |
2862 | +} __packed; |
2863 | + |
2864 | +#define MGMT_EV_CMD_STATUS 0x0002 |
2865 | +struct mgmt_ev_cmd_status { |
2866 | + uint16_t opcode; |
2867 | + uint8_t status; |
2868 | +} __packed; |
2869 | + |
2870 | +#define MGMT_EV_CONTROLLER_ERROR 0x0003 |
2871 | +struct mgmt_ev_controller_error { |
2872 | + uint8_t error_code; |
2873 | +} __packed; |
2874 | + |
2875 | +#define MGMT_EV_INDEX_ADDED 0x0004 |
2876 | + |
2877 | +#define MGMT_EV_INDEX_REMOVED 0x0005 |
2878 | + |
2879 | +#define MGMT_EV_NEW_SETTINGS 0x0006 |
2880 | + |
2881 | +#define MGMT_EV_CLASS_OF_DEV_CHANGED 0x0007 |
2882 | +struct mgmt_ev_class_of_dev_changed { |
2883 | + uint8_t class_of_dev[3]; |
2884 | +} __packed; |
2885 | + |
2886 | +#define MGMT_EV_LOCAL_NAME_CHANGED 0x0008 |
2887 | +struct mgmt_ev_local_name_changed { |
2888 | + uint8_t name[MGMT_MAX_NAME_LENGTH]; |
2889 | + uint8_t short_name[MGMT_MAX_SHORT_NAME_LENGTH]; |
2890 | +} __packed; |
2891 | + |
2892 | +#define MGMT_EV_NEW_LINK_KEY 0x0009 |
2893 | +struct mgmt_ev_new_link_key { |
2894 | + uint8_t store_hint; |
2895 | + struct mgmt_link_key_info key; |
2896 | +} __packed; |
2897 | + |
2898 | +#define MGMT_EV_NEW_LONG_TERM_KEY 0x000A |
2899 | +struct mgmt_ev_new_long_term_key { |
2900 | + uint8_t store_hint; |
2901 | + struct mgmt_ltk_info key; |
2902 | +} __packed; |
2903 | + |
2904 | +#define MGMT_EV_DEVICE_CONNECTED 0x000B |
2905 | +struct mgmt_ev_device_connected { |
2906 | + struct mgmt_addr_info addr; |
2907 | + uint32_t flags; |
2908 | + uint16_t eir_len; |
2909 | + uint8_t eir[0]; |
2910 | +} __packed; |
2911 | + |
2912 | +#define MGMT_EV_DEVICE_DISCONNECTED 0x000C |
2913 | +struct mgmt_ev_device_disconnected { |
2914 | + struct mgmt_addr_info addr; |
2915 | +} __packed; |
2916 | + |
2917 | +#define MGMT_EV_CONNECT_FAILED 0x000D |
2918 | +struct mgmt_ev_connect_failed { |
2919 | + struct mgmt_addr_info addr; |
2920 | + uint8_t status; |
2921 | +} __packed; |
2922 | + |
2923 | +#define MGMT_EV_PIN_CODE_REQUEST 0x000E |
2924 | +struct mgmt_ev_pin_code_request { |
2925 | + struct mgmt_addr_info addr; |
2926 | + uint8_t secure; |
2927 | +} __packed; |
2928 | + |
2929 | +#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F |
2930 | +struct mgmt_ev_user_confirm_request { |
2931 | + struct mgmt_addr_info addr; |
2932 | + uint8_t confirm_hint; |
2933 | + uint32_t value; |
2934 | +} __packed; |
2935 | + |
2936 | +#define MGMT_EV_USER_PASSKEY_REQUEST 0x0010 |
2937 | +struct mgmt_ev_user_passkey_request { |
2938 | + struct mgmt_addr_info addr; |
2939 | +} __packed; |
2940 | + |
2941 | +#define MGMT_EV_AUTH_FAILED 0x0011 |
2942 | +struct mgmt_ev_auth_failed { |
2943 | + struct mgmt_addr_info addr; |
2944 | + uint8_t status; |
2945 | +} __packed; |
2946 | + |
2947 | +#define MGMT_DEV_FOUND_CONFIRM_NAME 0x01 |
2948 | +#define MGMT_DEV_FOUND_LEGACY_PAIRING 0x02 |
2949 | + |
2950 | +#define MGMT_EV_DEVICE_FOUND 0x0012 |
2951 | +struct mgmt_ev_device_found { |
2952 | + struct mgmt_addr_info addr; |
2953 | + int8_t rssi; |
2954 | + uint32_t flags; |
2955 | + uint16_t eir_len; |
2956 | + uint8_t eir[0]; |
2957 | +} __packed; |
2958 | + |
2959 | +#define MGMT_EV_DISCOVERING 0x0013 |
2960 | +struct mgmt_ev_discovering { |
2961 | + uint8_t type; |
2962 | + uint8_t discovering; |
2963 | +} __packed; |
2964 | + |
2965 | +#define MGMT_EV_DEVICE_BLOCKED 0x0014 |
2966 | +struct mgmt_ev_device_blocked { |
2967 | + struct mgmt_addr_info addr; |
2968 | +} __packed; |
2969 | + |
2970 | +#define MGMT_EV_DEVICE_UNBLOCKED 0x0015 |
2971 | +struct mgmt_ev_device_unblocked { |
2972 | + struct mgmt_addr_info addr; |
2973 | +} __packed; |
2974 | + |
2975 | +#define MGMT_EV_DEVICE_UNPAIRED 0x0016 |
2976 | +struct mgmt_ev_device_unpaired { |
2977 | + struct mgmt_addr_info addr; |
2978 | +} __packed; |
2979 | + |
2980 | +static const char *mgmt_op[] = { |
2981 | + "<0x0000>", |
2982 | + "Read Version", |
2983 | + "Read Commands", |
2984 | + "Read Index List", |
2985 | + "Read Controller Info", |
2986 | + "Set Powered", |
2987 | + "Set Discoverable", |
2988 | + "Set Connectable", |
2989 | + "Set Fast Connectable", /* 0x0008 */ |
2990 | + "Set Pairable", |
2991 | + "Set Link Security", |
2992 | + "Set Secure Simple Pairing", |
2993 | + "Set High Speed", |
2994 | + "Set Low Energy", |
2995 | + "Set Dev Class", |
2996 | + "Set Local Name", |
2997 | + "Add UUID", /* 0x0010 */ |
2998 | + "Remove UUID", |
2999 | + "Load Link Keys", |
3000 | + "Load Long Term Keys", |
3001 | + "Disconnect", |
3002 | + "Get Connections", |
3003 | + "PIN Code Reply", |
3004 | + "PIN Code Neg Reply", |
3005 | + "Set IO Capability", /* 0x0018 */ |
3006 | + "Pair Device", |
3007 | + "Cancel Pair Device", |
3008 | + "Unpair Device", |
3009 | + "User Confirm Reply", |
3010 | + "User Confirm Neg Reply", |
3011 | + "User Passkey Reply", |
3012 | + "User Passkey Neg Reply", |
3013 | + "Read Local OOB Data", /* 0x0020 */ |
3014 | + "Add Remote OOB Data", |
3015 | + "Remove Remove OOB Data", |
3016 | + "Start Discovery", |
3017 | + "Stop Discovery", |
3018 | + "Confirm Name", |
3019 | + "Block Device", |
3020 | + "Unblock Device", |
3021 | + "Set Device ID", |
3022 | +}; |
3023 | + |
3024 | +static const char *mgmt_ev[] = { |
3025 | + "<0x0000>", |
3026 | + "Command Complete", |
3027 | + "Command Status", |
3028 | + "Controller Error", |
3029 | + "Index Added", |
3030 | + "Index Removed", |
3031 | + "New Settings", |
3032 | + "Class of Device Changed", |
3033 | + "Local Name Changed", /* 0x0008 */ |
3034 | + "New Link Key", |
3035 | + "New Long Term Key", |
3036 | + "Device Connected", |
3037 | + "Device Disconnected", |
3038 | + "Connect Failed", |
3039 | + "PIN Code Request", |
3040 | + "User Confirm Request", |
3041 | + "User Passkey Request", /* 0x0010 */ |
3042 | + "Authentication Failed", |
3043 | + "Device Found", |
3044 | + "Discovering", |
3045 | + "Device Blocked", |
3046 | + "Device Unblocked", |
3047 | + "Device Unpaired", |
3048 | +}; |
3049 | + |
3050 | +static const char *mgmt_status[] = { |
3051 | + "Success", |
3052 | + "Unknown Command", |
3053 | + "Not Connected", |
3054 | + "Failed", |
3055 | + "Connect Failed", |
3056 | + "Authentication Failed", |
3057 | + "Not Paired", |
3058 | + "No Resources", |
3059 | + "Timeout", |
3060 | + "Already Connected", |
3061 | + "Busy", |
3062 | + "Rejected", |
3063 | + "Not Supported", |
3064 | + "Invalid Parameters", |
3065 | + "Disconnected", |
3066 | + "Not Powered", |
3067 | + "Cancelled", |
3068 | + "Invalid Index", |
3069 | +}; |
3070 | + |
3071 | +#ifndef NELEM |
3072 | +#define NELEM(x) (sizeof(x) / sizeof((x)[0])) |
3073 | +#endif |
3074 | + |
3075 | +static inline const char *mgmt_opstr(uint16_t op) |
3076 | +{ |
3077 | + if (op >= NELEM(mgmt_op)) |
3078 | + return "<unknown opcode>"; |
3079 | + return mgmt_op[op]; |
3080 | +} |
3081 | + |
3082 | +static inline const char *mgmt_evstr(uint16_t ev) |
3083 | +{ |
3084 | + if (ev >= NELEM(mgmt_ev)) |
3085 | + return "<unknown event>"; |
3086 | + return mgmt_ev[ev]; |
3087 | +} |
3088 | + |
3089 | +static inline const char *mgmt_errstr(uint8_t status) |
3090 | +{ |
3091 | + if (status >= NELEM(mgmt_status)) |
3092 | + return "<unknown status>"; |
3093 | + return mgmt_status[status]; |
3094 | +} |
3095 | |
3096 | === added directory '.pc/ssp_parameter.patch/plugins' |
3097 | === added file '.pc/ssp_parameter.patch/plugins/hciops.c' |
3098 | --- .pc/ssp_parameter.patch/plugins/hciops.c 1970-01-01 00:00:00 +0000 |
3099 | +++ .pc/ssp_parameter.patch/plugins/hciops.c 2014-05-15 03:26:22 +0000 |
3100 | @@ -0,0 +1,3943 @@ |
3101 | +/* |
3102 | + * |
3103 | + * BlueZ - Bluetooth protocol stack for Linux |
3104 | + * |
3105 | + * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> |
3106 | + * |
3107 | + * This program is free software; you can redistribute it and/or modify |
3108 | + * it under the terms of the GNU General Public License as published by |
3109 | + * the Free Software Foundation; either version 2 of the License, or |
3110 | + * (at your option) any later version. |
3111 | + * |
3112 | + * This program is distributed in the hope that it will be useful, |
3113 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3114 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3115 | + * GNU General Public License for more details. |
3116 | + * |
3117 | + * You should have received a copy of the GNU General Public License |
3118 | + * along with this program; if not, write to the Free Software |
3119 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
3120 | + * |
3121 | + */ |
3122 | + |
3123 | +#ifdef HAVE_CONFIG_H |
3124 | +#include <config.h> |
3125 | +#endif |
3126 | + |
3127 | +#include <stdio.h> |
3128 | +#include <errno.h> |
3129 | +#include <unistd.h> |
3130 | +#include <stdlib.h> |
3131 | +#include <sys/types.h> |
3132 | +#include <sys/ioctl.h> |
3133 | +#include <sys/wait.h> |
3134 | + |
3135 | +#include <bluetooth/bluetooth.h> |
3136 | +#include <bluetooth/hci.h> |
3137 | +#include <bluetooth/hci_lib.h> |
3138 | +#include <bluetooth/sdp.h> |
3139 | +#include <bluetooth/sdp_lib.h> |
3140 | + |
3141 | +#include <glib.h> |
3142 | + |
3143 | +#include "hcid.h" |
3144 | +#include "sdpd.h" |
3145 | +#include "btio.h" |
3146 | +#include "adapter.h" |
3147 | +#include "device.h" |
3148 | +#include "plugin.h" |
3149 | +#include "log.h" |
3150 | +#include "storage.h" |
3151 | +#include "event.h" |
3152 | +#include "manager.h" |
3153 | +#include "oob.h" |
3154 | +#include "eir.h" |
3155 | + |
3156 | +#define DISCOV_HALTED 0 |
3157 | +#define DISCOV_INQ 1 |
3158 | +#define DISCOV_SCAN 2 |
3159 | +#define DISCOV_NAMES 3 |
3160 | + |
3161 | +#define TIMEOUT_BR_LE_SCAN 5120 /* TGAP(100)/2 */ |
3162 | +#define TIMEOUT_LE_SCAN 10240 /* TGAP(gen_disc_scan_min) */ |
3163 | + |
3164 | +#define LENGTH_BR_INQ 0x08 |
3165 | +#define LENGTH_BR_LE_INQ 0x04 |
3166 | + |
3167 | +static int start_scanning(int index, int timeout); |
3168 | + |
3169 | +static int child_pipe[2] = { -1, -1 }; |
3170 | + |
3171 | +static guint child_io_id = 0; |
3172 | +static guint ctl_io_id = 0; |
3173 | + |
3174 | +enum adapter_type { |
3175 | + BR_EDR, |
3176 | + LE_ONLY, |
3177 | + BR_EDR_LE, |
3178 | + UNKNOWN, |
3179 | +}; |
3180 | + |
3181 | +/* Commands sent by kernel on starting an adapter */ |
3182 | +enum { |
3183 | + PENDING_BDADDR, |
3184 | + PENDING_VERSION, |
3185 | + PENDING_FEATURES, |
3186 | + PENDING_NAME, |
3187 | +}; |
3188 | + |
3189 | +struct bt_conn { |
3190 | + struct dev_info *dev; |
3191 | + bdaddr_t bdaddr; |
3192 | + uint16_t handle; |
3193 | + uint8_t loc_cap; |
3194 | + uint8_t loc_auth; |
3195 | + uint8_t rem_cap; |
3196 | + uint8_t rem_auth; |
3197 | + uint8_t rem_oob_data; |
3198 | + gboolean bonding_initiator; |
3199 | + gboolean secmode3; |
3200 | + GIOChannel *io; /* For raw L2CAP socket (bonding) */ |
3201 | +}; |
3202 | + |
3203 | +struct oob_data { |
3204 | + bdaddr_t bdaddr; |
3205 | + uint8_t hash[16]; |
3206 | + uint8_t randomizer[16]; |
3207 | +}; |
3208 | + |
3209 | +enum name_state { |
3210 | + NAME_UNKNOWN, |
3211 | + NAME_NEEDED, |
3212 | + NAME_NOT_NEEDED, |
3213 | + NAME_PENDING, |
3214 | +}; |
3215 | + |
3216 | +struct found_dev { |
3217 | + bdaddr_t bdaddr; |
3218 | + int8_t rssi; |
3219 | + enum name_state name_state; |
3220 | +}; |
3221 | + |
3222 | +static int max_dev = -1; |
3223 | +static struct dev_info { |
3224 | + int id; |
3225 | + int sk; |
3226 | + bdaddr_t bdaddr; |
3227 | + char name[249]; |
3228 | + uint8_t eir[HCI_MAX_EIR_LENGTH]; |
3229 | + uint8_t features[8]; |
3230 | + uint8_t extfeatures[8]; |
3231 | + uint8_t ssp_mode; |
3232 | + |
3233 | + int8_t tx_power; |
3234 | + |
3235 | + int discov_state; |
3236 | + |
3237 | + uint32_t current_cod; |
3238 | + uint32_t wanted_cod; |
3239 | + uint32_t pending_cod; |
3240 | + gboolean cache_enable; |
3241 | + gboolean already_up; |
3242 | + gboolean registered; |
3243 | + gboolean pairable; |
3244 | + |
3245 | + uint8_t io_capability; |
3246 | + |
3247 | + struct hci_version ver; |
3248 | + |
3249 | + uint16_t did_source; |
3250 | + uint16_t did_vendor; |
3251 | + uint16_t did_product; |
3252 | + uint16_t did_version; |
3253 | + |
3254 | + gboolean up; |
3255 | + uint32_t pending; |
3256 | + |
3257 | + GIOChannel *io; |
3258 | + guint watch_id; |
3259 | + |
3260 | + gboolean debug_keys; |
3261 | + GSList *keys; |
3262 | + uint8_t pin_length; |
3263 | + |
3264 | + GSList *oob_data; |
3265 | + |
3266 | + GSList *uuids; |
3267 | + |
3268 | + GSList *connections; |
3269 | + |
3270 | + GSList *found_devs; |
3271 | + GSList *need_name; |
3272 | + |
3273 | + guint stop_scan_id; |
3274 | + |
3275 | + uint16_t discoverable_timeout; |
3276 | + guint discoverable_id; |
3277 | +} *devs = NULL; |
3278 | + |
3279 | +static int found_dev_rssi_cmp(gconstpointer a, gconstpointer b) |
3280 | +{ |
3281 | + const struct found_dev *d1 = a, *d2 = b; |
3282 | + int rssi1, rssi2; |
3283 | + |
3284 | + if (d2->name_state == NAME_NOT_NEEDED) |
3285 | + return -1; |
3286 | + |
3287 | + rssi1 = d1->rssi < 0 ? -d1->rssi : d1->rssi; |
3288 | + rssi2 = d2->rssi < 0 ? -d2->rssi : d2->rssi; |
3289 | + |
3290 | + return rssi1 - rssi2; |
3291 | +} |
3292 | + |
3293 | +static int found_dev_bda_cmp(gconstpointer a, gconstpointer b) |
3294 | +{ |
3295 | + const struct found_dev *d1 = a, *d2 = b; |
3296 | + |
3297 | + return bacmp(&d1->bdaddr, &d2->bdaddr); |
3298 | +} |
3299 | + |
3300 | +static void found_dev_cleanup(struct dev_info *info) |
3301 | +{ |
3302 | + g_slist_free_full(info->found_devs, g_free); |
3303 | + info->found_devs = NULL; |
3304 | + |
3305 | + g_slist_free_full(info->need_name, g_free); |
3306 | + info->need_name = NULL; |
3307 | +} |
3308 | + |
3309 | +static int resolve_name(struct dev_info *info, bdaddr_t *bdaddr) |
3310 | +{ |
3311 | + remote_name_req_cp cp; |
3312 | + char addr[18]; |
3313 | + |
3314 | + ba2str(bdaddr, addr); |
3315 | + DBG("hci%d dba %s", info->id, addr); |
3316 | + |
3317 | + memset(&cp, 0, sizeof(cp)); |
3318 | + bacpy(&cp.bdaddr, bdaddr); |
3319 | + cp.pscan_rep_mode = 0x02; |
3320 | + |
3321 | + if (hci_send_cmd(info->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ, |
3322 | + REMOTE_NAME_REQ_CP_SIZE, &cp) < 0) |
3323 | + return -errno; |
3324 | + |
3325 | + return 0; |
3326 | +} |
3327 | + |
3328 | +static int resolve_names(struct dev_info *info, struct btd_adapter *adapter) |
3329 | +{ |
3330 | + struct found_dev *dev; |
3331 | + |
3332 | + DBG("found_dev %u need_name %u", g_slist_length(info->found_devs), |
3333 | + g_slist_length(info->need_name)); |
3334 | + |
3335 | + if (g_slist_length(info->need_name) == 0) |
3336 | + return -ENOENT; |
3337 | + |
3338 | + dev = info->need_name->data; |
3339 | + resolve_name(info, &dev->bdaddr); |
3340 | + dev->name_state = NAME_PENDING; |
3341 | + |
3342 | + return 0; |
3343 | +} |
3344 | + |
3345 | +static void set_state(int index, int state) |
3346 | +{ |
3347 | + struct btd_adapter *adapter; |
3348 | + struct dev_info *dev = &devs[index]; |
3349 | + |
3350 | + if (dev->discov_state == state) |
3351 | + return; |
3352 | + |
3353 | + adapter = manager_find_adapter_by_id(index); |
3354 | + if (!adapter) { |
3355 | + error("No matching adapter found"); |
3356 | + return; |
3357 | + } |
3358 | + |
3359 | + dev->discov_state = state; |
3360 | + |
3361 | + DBG("hci%d: new state %d", index, dev->discov_state); |
3362 | + |
3363 | + switch (dev->discov_state) { |
3364 | + case DISCOV_HALTED: |
3365 | + found_dev_cleanup(dev); |
3366 | + adapter_set_discovering(adapter, FALSE); |
3367 | + break; |
3368 | + case DISCOV_INQ: |
3369 | + case DISCOV_SCAN: |
3370 | + adapter_set_discovering(adapter, TRUE); |
3371 | + break; |
3372 | + case DISCOV_NAMES: |
3373 | + if (resolve_names(dev, adapter) < 0) |
3374 | + set_state(index, DISCOV_HALTED); |
3375 | + break; |
3376 | + } |
3377 | +} |
3378 | + |
3379 | +static inline gboolean is_le_capable(int index) |
3380 | +{ |
3381 | + struct dev_info *dev = &devs[index]; |
3382 | + |
3383 | + return (dev->features[4] & LMP_LE && |
3384 | + dev->extfeatures[0] & LMP_HOST_LE) ? TRUE : FALSE; |
3385 | +} |
3386 | + |
3387 | +static inline gboolean is_bredr_capable(int index) |
3388 | +{ |
3389 | + struct dev_info *dev = &devs[index]; |
3390 | + |
3391 | + return (dev->features[4] & LMP_NO_BREDR) == 0 ? TRUE : FALSE; |
3392 | +} |
3393 | + |
3394 | +static int get_adapter_type(int index) |
3395 | +{ |
3396 | + if (is_le_capable(index) && is_bredr_capable(index)) |
3397 | + return BR_EDR_LE; |
3398 | + else if (is_le_capable(index)) |
3399 | + return LE_ONLY; |
3400 | + else if (is_bredr_capable(index)) |
3401 | + return BR_EDR; |
3402 | + |
3403 | + return UNKNOWN; |
3404 | +} |
3405 | + |
3406 | +static int ignore_device(struct hci_dev_info *di) |
3407 | +{ |
3408 | + return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR; |
3409 | +} |
3410 | + |
3411 | +static struct dev_info *init_dev_info(int index, int sk, gboolean registered, |
3412 | + gboolean already_up) |
3413 | +{ |
3414 | + struct dev_info *dev = &devs[index]; |
3415 | + |
3416 | + memset(dev, 0, sizeof(*dev)); |
3417 | + |
3418 | + dev->id = index; |
3419 | + dev->sk = sk; |
3420 | + dev->cache_enable = TRUE; |
3421 | + dev->registered = registered; |
3422 | + dev->already_up = already_up; |
3423 | + dev->io_capability = 0x03; /* No Input No Output */ |
3424 | + dev->discov_state = DISCOV_HALTED; |
3425 | + |
3426 | + return dev; |
3427 | +} |
3428 | + |
3429 | +/* Async HCI command handling with callback support */ |
3430 | + |
3431 | +struct hci_cmd_data { |
3432 | + bt_hci_result_t cb; |
3433 | + uint16_t handle; |
3434 | + uint16_t ocf; |
3435 | + gpointer caller_data; |
3436 | +}; |
3437 | + |
3438 | +static gboolean hci_event_watch(GIOChannel *io, |
3439 | + GIOCondition cond, gpointer user_data) |
3440 | +{ |
3441 | + unsigned char buf[HCI_MAX_EVENT_SIZE], *body; |
3442 | + struct hci_cmd_data *cmd = user_data; |
3443 | + evt_cmd_status *evt_status; |
3444 | + evt_auth_complete *evt_auth; |
3445 | + evt_encrypt_change *evt_enc; |
3446 | + hci_event_hdr *hdr; |
3447 | + set_conn_encrypt_cp cp; |
3448 | + int dd; |
3449 | + uint16_t ocf; |
3450 | + uint8_t status = HCI_OE_POWER_OFF; |
3451 | + |
3452 | + if (cond & G_IO_NVAL) { |
3453 | + cmd->cb(status, cmd->caller_data); |
3454 | + return FALSE; |
3455 | + } |
3456 | + |
3457 | + if (cond & (G_IO_ERR | G_IO_HUP)) |
3458 | + goto failed; |
3459 | + |
3460 | + dd = g_io_channel_unix_get_fd(io); |
3461 | + |
3462 | + if (read(dd, buf, sizeof(buf)) < 0) |
3463 | + goto failed; |
3464 | + |
3465 | + hdr = (hci_event_hdr *) (buf + 1); |
3466 | + body = buf + (1 + HCI_EVENT_HDR_SIZE); |
3467 | + |
3468 | + switch (hdr->evt) { |
3469 | + case EVT_CMD_STATUS: |
3470 | + evt_status = (evt_cmd_status *) body; |
3471 | + ocf = cmd_opcode_ocf(evt_status->opcode); |
3472 | + if (ocf != cmd->ocf) |
3473 | + return TRUE; |
3474 | + switch (ocf) { |
3475 | + case OCF_AUTH_REQUESTED: |
3476 | + case OCF_SET_CONN_ENCRYPT: |
3477 | + if (evt_status->status != 0) { |
3478 | + /* Baseband rejected command */ |
3479 | + status = evt_status->status; |
3480 | + goto failed; |
3481 | + } |
3482 | + break; |
3483 | + default: |
3484 | + return TRUE; |
3485 | + } |
3486 | + /* Wait for the next event */ |
3487 | + return TRUE; |
3488 | + case EVT_AUTH_COMPLETE: |
3489 | + evt_auth = (evt_auth_complete *) body; |
3490 | + if (evt_auth->handle != cmd->handle) { |
3491 | + /* Skipping */ |
3492 | + return TRUE; |
3493 | + } |
3494 | + |
3495 | + if (evt_auth->status != 0x00) { |
3496 | + status = evt_auth->status; |
3497 | + /* Abort encryption */ |
3498 | + goto failed; |
3499 | + } |
3500 | + |
3501 | + memset(&cp, 0, sizeof(cp)); |
3502 | + cp.handle = cmd->handle; |
3503 | + cp.encrypt = 1; |
3504 | + |
3505 | + cmd->ocf = OCF_SET_CONN_ENCRYPT; |
3506 | + |
3507 | + if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, |
3508 | + SET_CONN_ENCRYPT_CP_SIZE, &cp) < 0) { |
3509 | + status = HCI_COMMAND_DISALLOWED; |
3510 | + goto failed; |
3511 | + } |
3512 | + /* Wait for encrypt change event */ |
3513 | + return TRUE; |
3514 | + case EVT_ENCRYPT_CHANGE: |
3515 | + evt_enc = (evt_encrypt_change *) body; |
3516 | + if (evt_enc->handle != cmd->handle) |
3517 | + return TRUE; |
3518 | + |
3519 | + /* Procedure finished: reporting status */ |
3520 | + status = evt_enc->status; |
3521 | + break; |
3522 | + default: |
3523 | + /* Skipping */ |
3524 | + return TRUE; |
3525 | + } |
3526 | + |
3527 | +failed: |
3528 | + cmd->cb(status, cmd->caller_data); |
3529 | + g_io_channel_shutdown(io, TRUE, NULL); |
3530 | + |
3531 | + return FALSE; |
3532 | +} |
3533 | + |
3534 | +static int write_inq_mode(int index, uint8_t mode) |
3535 | +{ |
3536 | + struct dev_info *dev = &devs[index]; |
3537 | + write_inquiry_mode_cp cp; |
3538 | + |
3539 | + memset(&cp, 0, sizeof(cp)); |
3540 | + cp.mode = mode; |
3541 | + |
3542 | + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, |
3543 | + WRITE_INQUIRY_MODE_CP_SIZE, &cp) < 0) |
3544 | + return -errno; |
3545 | + |
3546 | + return 0; |
3547 | +} |
3548 | + |
3549 | +static uint8_t get_inquiry_mode(int index) |
3550 | +{ |
3551 | + struct dev_info *dev = &devs[index]; |
3552 | + |
3553 | + if (dev->features[6] & LMP_EXT_INQ) |
3554 | + return 2; |
3555 | + |
3556 | + if (dev->features[3] & LMP_RSSI_INQ) |
3557 | + return 1; |
3558 | + |
3559 | + if (dev->ver.manufacturer == 11 && dev->ver.hci_rev == 0x00 && |
3560 | + dev->ver.lmp_subver == 0x0757) |
3561 | + return 1; |
3562 | + |
3563 | + if (dev->ver.manufacturer == 15) { |
3564 | + if (dev->ver.hci_rev == 0x03 && |
3565 | + dev->ver.lmp_subver == 0x6963) |
3566 | + return 1; |
3567 | + if (dev->ver.hci_rev == 0x09 && |
3568 | + dev->ver.lmp_subver == 0x6963) |
3569 | + return 1; |
3570 | + if (dev->ver.hci_rev == 0x00 && |
3571 | + dev->ver.lmp_subver == 0x6965) |
3572 | + return 1; |
3573 | + } |
3574 | + |
3575 | + if (dev->ver.manufacturer == 31 && dev->ver.hci_rev == 0x2005 && |
3576 | + dev->ver.lmp_subver == 0x1805) |
3577 | + return 1; |
3578 | + |
3579 | + return 0; |
3580 | +} |
3581 | + |
3582 | +static int init_ssp_mode(int index) |
3583 | +{ |
3584 | + struct dev_info *dev = &devs[index]; |
3585 | + write_simple_pairing_mode_cp cp; |
3586 | + |
3587 | + if (ioctl(dev->sk, HCIGETAUTHINFO, NULL) < 0 && errno == EINVAL) |
3588 | + return 0; |
3589 | + |
3590 | + memset(&cp, 0, sizeof(cp)); |
3591 | + cp.mode = 0x01; |
3592 | + |
3593 | + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, |
3594 | + OCF_WRITE_SIMPLE_PAIRING_MODE, |
3595 | + WRITE_SIMPLE_PAIRING_MODE_CP_SIZE, &cp) < 0) |
3596 | + return -errno; |
3597 | + |
3598 | + return 0; |
3599 | +} |
3600 | + |
3601 | +static int hciops_set_discoverable(int index, gboolean discoverable, |
3602 | + uint16_t timeout) |
3603 | +{ |
3604 | + struct dev_info *dev = &devs[index]; |
3605 | + uint8_t mode; |
3606 | + |
3607 | + if (discoverable) |
3608 | + mode = (SCAN_PAGE | SCAN_INQUIRY); |
3609 | + else |
3610 | + mode = SCAN_PAGE; |
3611 | + |
3612 | + DBG("hci%d discoverable %d", index, discoverable); |
3613 | + |
3614 | + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, |
3615 | + 1, &mode) < 0) |
3616 | + return -errno; |
3617 | + |
3618 | + dev->discoverable_timeout = timeout; |
3619 | + |
3620 | + return 0; |
3621 | +} |
3622 | + |
3623 | +static int hciops_set_pairable(int index, gboolean pairable) |
3624 | +{ |
3625 | + struct btd_adapter *adapter; |
3626 | + |
3627 | + DBG("hci%d pairable %d", index, pairable); |
3628 | + |
3629 | + adapter = manager_find_adapter(&devs[index].bdaddr); |
3630 | + if (adapter) |
3631 | + btd_adapter_pairable_changed(adapter, pairable); |
3632 | + |
3633 | + devs[index].pairable = pairable; |
3634 | + |
3635 | + return 0; |
3636 | +} |
3637 | + |
3638 | +static int hciops_power_off(int index) |
3639 | +{ |
3640 | + struct dev_info *dev = &devs[index]; |
3641 | + |
3642 | + DBG("hci%d", index); |
3643 | + |
3644 | + if (ioctl(dev->sk, HCIDEVDOWN, index) < 0 && errno != EALREADY) |
3645 | + return -errno; |
3646 | + |
3647 | + return 0; |
3648 | +} |
3649 | + |
3650 | +static void set_event_mask(int index) |
3651 | +{ |
3652 | + struct dev_info *dev = &devs[index]; |
3653 | + /* The second byte is 0xff instead of 0x9f (two reserved bits |
3654 | + * disabled) since a Broadcom 1.2 dongle doesn't respond to the |
3655 | + * command otherwise */ |
3656 | + uint8_t events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; |
3657 | + |
3658 | + /* Events for 1.2 and newer controllers */ |
3659 | + if (dev->ver.lmp_ver > 1) { |
3660 | + events[4] |= 0x01; /* Flow Specification Complete */ |
3661 | + events[4] |= 0x02; /* Inquiry Result with RSSI */ |
3662 | + events[4] |= 0x04; /* Read Remote Extended Features Complete */ |
3663 | + events[5] |= 0x08; /* Synchronous Connection Complete */ |
3664 | + events[5] |= 0x10; /* Synchronous Connection Changed */ |
3665 | + } |
3666 | + |
3667 | + if (dev->features[3] & LMP_RSSI_INQ) |
3668 | + events[4] |= 0x02; /* Inquiry Result with RSSI */ |
3669 | + |
3670 | + if (dev->features[5] & LMP_SNIFF_SUBR) |
3671 | + events[5] |= 0x20; /* Sniff Subrating */ |
3672 | + |
3673 | + if (dev->features[5] & LMP_PAUSE_ENC) |
3674 | + events[5] |= 0x80; /* Encryption Key Refresh Complete */ |
3675 | + |
3676 | + if (dev->features[6] & LMP_EXT_INQ) |
3677 | + events[5] |= 0x40; /* Extended Inquiry Result */ |
3678 | + |
3679 | + if (dev->features[6] & LMP_NFLUSH_PKTS) |
3680 | + events[7] |= 0x01; /* Enhanced Flush Complete */ |
3681 | + |
3682 | + if (dev->features[7] & LMP_LSTO) |
3683 | + events[6] |= 0x80; /* Link Supervision Timeout Changed */ |
3684 | + |
3685 | + if (dev->features[6] & LMP_SIMPLE_PAIR) { |
3686 | + events[6] |= 0x01; /* IO Capability Request */ |
3687 | + events[6] |= 0x02; /* IO Capability Response */ |
3688 | + events[6] |= 0x04; /* User Confirmation Request */ |
3689 | + events[6] |= 0x08; /* User Passkey Request */ |
3690 | + events[6] |= 0x10; /* Remote OOB Data Request */ |
3691 | + events[6] |= 0x20; /* Simple Pairing Complete */ |
3692 | + events[7] |= 0x04; /* User Passkey Notification */ |
3693 | + events[7] |= 0x08; /* Keypress Notification */ |
3694 | + events[7] |= 0x10; /* Remote Host Supported |
3695 | + * Features Notification */ |
3696 | + } |
3697 | + |
3698 | + if (dev->features[4] & LMP_LE) |
3699 | + events[7] |= 0x20; /* LE Meta-Event */ |
3700 | + |
3701 | + hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_SET_EVENT_MASK, |
3702 | + sizeof(events), events); |
3703 | +} |
3704 | + |
3705 | +static void start_adapter(int index) |
3706 | +{ |
3707 | + struct dev_info *dev = &devs[index]; |
3708 | + uint8_t inqmode; |
3709 | + uint16_t link_policy; |
3710 | + |
3711 | + set_event_mask(index); |
3712 | + |
3713 | + if (dev->features[6] & LMP_SIMPLE_PAIR) |
3714 | + init_ssp_mode(index); |
3715 | + |
3716 | + inqmode = get_inquiry_mode(index); |
3717 | + if (inqmode) |
3718 | + write_inq_mode(index, inqmode); |
3719 | + |
3720 | + if (dev->features[7] & LMP_INQ_TX_PWR) |
3721 | + hci_send_cmd(dev->sk, OGF_HOST_CTL, |
3722 | + OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL, 0, NULL); |
3723 | + |
3724 | + /* Set default link policy */ |
3725 | + link_policy = main_opts.link_policy; |
3726 | + |
3727 | + if (!(dev->features[0] & LMP_RSWITCH)) |
3728 | + link_policy &= ~HCI_LP_RSWITCH; |
3729 | + if (!(dev->features[0] & LMP_HOLD)) |
3730 | + link_policy &= ~HCI_LP_HOLD; |
3731 | + if (!(dev->features[0] & LMP_SNIFF)) |
3732 | + link_policy &= ~HCI_LP_SNIFF; |
3733 | + if (!(dev->features[1] & LMP_PARK)) |
3734 | + link_policy &= ~HCI_LP_PARK; |
3735 | + |
3736 | + link_policy = htobs(link_policy); |
3737 | + hci_send_cmd(dev->sk, OGF_LINK_POLICY, OCF_WRITE_DEFAULT_LINK_POLICY, |
3738 | + sizeof(link_policy), &link_policy); |
3739 | + |
3740 | + dev->current_cod = 0; |
3741 | + memset(dev->eir, 0, sizeof(dev->eir)); |
3742 | +} |
3743 | + |
3744 | +static int hciops_stop_inquiry(int index) |
3745 | +{ |
3746 | + struct dev_info *dev = &devs[index]; |
3747 | + |
3748 | + DBG("hci%d", index); |
3749 | + |
3750 | + if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_INQUIRY_CANCEL, 0, 0) < 0) |
3751 | + return -errno; |
3752 | + |
3753 | + return 0; |
3754 | +} |
3755 | + |
3756 | +static void update_ext_inquiry_response(int index) |
3757 | +{ |
3758 | + struct dev_info *dev = &devs[index]; |
3759 | + write_ext_inquiry_response_cp cp; |
3760 | + |
3761 | + DBG("hci%d", index); |
3762 | + |
3763 | + if (!(dev->features[6] & LMP_EXT_INQ)) |
3764 | + return; |
3765 | + |
3766 | + if (dev->ssp_mode == 0) |
3767 | + return; |
3768 | + |
3769 | + if (dev->cache_enable) |
3770 | + return; |
3771 | + |
3772 | + memset(&cp, 0, sizeof(cp)); |
3773 | + |
3774 | + eir_create(dev->name, dev->tx_power, dev->did_vendor, dev->did_product, |
3775 | + dev->did_version, dev->did_source, dev->uuids, |
3776 | + cp.data); |
3777 | + |
3778 | + if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0) |
3779 | + return; |
3780 | + |
3781 | + memcpy(dev->eir, cp.data, sizeof(cp.data)); |
3782 | + |
3783 | + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, |
3784 | + OCF_WRITE_EXT_INQUIRY_RESPONSE, |
3785 | + WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &cp) < 0) |
3786 | + error("Unable to write EIR data: %s (%d)", |
3787 | + strerror(errno), errno); |
3788 | +} |
3789 | + |
3790 | +static int hciops_set_name(int index, const char *name) |
3791 | +{ |
3792 | + struct dev_info *dev = &devs[index]; |
3793 | + change_local_name_cp cp; |
3794 | + |
3795 | + DBG("hci%d, name %s", index, name); |
3796 | + |
3797 | + memset(&cp, 0, sizeof(cp)); |
3798 | + strncpy((char *) cp.name, name, sizeof(cp.name)); |
3799 | + |
3800 | + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, |
3801 | + CHANGE_LOCAL_NAME_CP_SIZE, &cp) < 0) |
3802 | + return -errno; |
3803 | + |
3804 | + memcpy(dev->name, cp.name, 248); |
3805 | + update_ext_inquiry_response(index); |
3806 | + |
3807 | + return 0; |
3808 | +} |
3809 | + |
3810 | +static int write_class(int index, uint32_t class) |
3811 | +{ |
3812 | + struct dev_info *dev = &devs[index]; |
3813 | + write_class_of_dev_cp cp; |
3814 | + |
3815 | + DBG("hci%d class 0x%06x", index, class); |
3816 | + |
3817 | + memcpy(cp.dev_class, &class, 3); |
3818 | + |
3819 | + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, |
3820 | + WRITE_CLASS_OF_DEV_CP_SIZE, &cp) < 0) |
3821 | + return -errno; |
3822 | + |
3823 | + dev->pending_cod = class; |
3824 | + |
3825 | + return 0; |
3826 | +} |
3827 | + |
3828 | +static int hciops_set_dev_class(int index, uint8_t major, uint8_t minor) |
3829 | +{ |
3830 | + struct dev_info *dev = &devs[index]; |
3831 | + int err; |
3832 | + |
3833 | + DBG("hci%d major %u minor %u", index, major, minor); |
3834 | + |
3835 | + /* Update only the major and minor class bits keeping remaining bits |
3836 | + * intact*/ |
3837 | + dev->wanted_cod &= 0xffe000; |
3838 | + dev->wanted_cod |= ((major & 0x1f) << 8) | minor; |
3839 | + |
3840 | + if (dev->wanted_cod == dev->current_cod || |
3841 | + dev->cache_enable || dev->pending_cod) |
3842 | + return 0; |
3843 | + |
3844 | + DBG("Changing Major/Minor class to 0x%06x", dev->wanted_cod); |
3845 | + |
3846 | + err = write_class(index, dev->wanted_cod); |
3847 | + if (err < 0) |
3848 | + error("Adapter class update failed: %s (%d)", |
3849 | + strerror(-err), -err); |
3850 | + |
3851 | + return err; |
3852 | +} |
3853 | + |
3854 | +static gboolean init_adapter(int index) |
3855 | +{ |
3856 | + struct dev_info *dev = &devs[index]; |
3857 | + struct btd_adapter *adapter = NULL; |
3858 | + gboolean existing_adapter = dev->registered; |
3859 | + uint8_t mode, on_mode, major, minor; |
3860 | + gboolean pairable, discoverable; |
3861 | + const char *name; |
3862 | + uint16_t discoverable_timeout; |
3863 | + |
3864 | + if (!dev->registered) { |
3865 | + adapter = btd_manager_register_adapter(index, TRUE); |
3866 | + if (adapter) |
3867 | + dev->registered = TRUE; |
3868 | + } else { |
3869 | + adapter = manager_find_adapter(&dev->bdaddr); |
3870 | + /* FIXME: manager_find_adapter should return a new ref */ |
3871 | + btd_adapter_ref(adapter); |
3872 | + } |
3873 | + |
3874 | + if (adapter == NULL) |
3875 | + return FALSE; |
3876 | + |
3877 | + btd_adapter_get_mode(adapter, &mode, &on_mode, |
3878 | + &discoverable_timeout, |
3879 | + &pairable); |
3880 | + |
3881 | + if (existing_adapter) |
3882 | + mode = on_mode; |
3883 | + |
3884 | + if (mode == MODE_OFF) { |
3885 | + hciops_power_off(index); |
3886 | + goto done; |
3887 | + } |
3888 | + |
3889 | + start_adapter(index); |
3890 | + |
3891 | + name = btd_adapter_get_name(adapter); |
3892 | + if (name) |
3893 | + hciops_set_name(index, name); |
3894 | + |
3895 | + btd_adapter_get_class(adapter, &major, &minor); |
3896 | + hciops_set_dev_class(index, major, minor); |
3897 | + |
3898 | + btd_adapter_start(adapter); |
3899 | + |
3900 | + discoverable = (mode == MODE_DISCOVERABLE); |
3901 | + |
3902 | + hciops_set_discoverable(index, discoverable, discoverable_timeout); |
3903 | + hciops_set_pairable(index, pairable); |
3904 | + |
3905 | + if (dev->already_up) |
3906 | + hciops_stop_inquiry(index); |
3907 | + |
3908 | +done: |
3909 | + btd_adapter_unref(adapter); |
3910 | + return TRUE; |
3911 | +} |
3912 | + |
3913 | +static int hciops_encrypt_link(int index, bdaddr_t *dst, bt_hci_result_t cb, |
3914 | + gpointer user_data) |
3915 | +{ |
3916 | + GIOChannel *io; |
3917 | + struct hci_cmd_data *cmd; |
3918 | + struct hci_conn_info_req *cr; |
3919 | + auth_requested_cp cp; |
3920 | + struct hci_filter nf; |
3921 | + int dd, err; |
3922 | + uint32_t link_mode; |
3923 | + uint16_t handle; |
3924 | + |
3925 | + dd = hci_open_dev(index); |
3926 | + if (dd < 0) |
3927 | + return -errno; |
3928 | + |
3929 | + cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); |
3930 | + cr->type = ACL_LINK; |
3931 | + bacpy(&cr->bdaddr, dst); |
3932 | + |
3933 | + err = ioctl(dd, HCIGETCONNINFO, cr); |
3934 | + link_mode = cr->conn_info->link_mode; |
3935 | + handle = cr->conn_info->handle; |
3936 | + g_free(cr); |
3937 | + |
3938 | + if (err < 0) { |
3939 | + err = -errno; |
3940 | + goto fail; |
3941 | + } |
3942 | + |
3943 | + if (link_mode & HCI_LM_ENCRYPT) { |
3944 | + err = -EALREADY; |
3945 | + goto fail; |
3946 | + } |
3947 | + |
3948 | + memset(&cp, 0, sizeof(cp)); |
3949 | + cp.handle = htobs(handle); |
3950 | + |
3951 | + if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_AUTH_REQUESTED, |
3952 | + AUTH_REQUESTED_CP_SIZE, &cp) < 0) { |
3953 | + err = -errno; |
3954 | + goto fail; |
3955 | + } |
3956 | + |
3957 | + cmd = g_new0(struct hci_cmd_data, 1); |
3958 | + cmd->handle = handle; |
3959 | + cmd->ocf = OCF_AUTH_REQUESTED; |
3960 | + cmd->cb = cb; |
3961 | + cmd->caller_data = user_data; |
3962 | + |
3963 | + hci_filter_clear(&nf); |
3964 | + hci_filter_set_ptype(HCI_EVENT_PKT, &nf); |
3965 | + hci_filter_set_event(EVT_CMD_STATUS, &nf); |
3966 | + hci_filter_set_event(EVT_AUTH_COMPLETE, &nf); |
3967 | + hci_filter_set_event(EVT_ENCRYPT_CHANGE, &nf); |
3968 | + |
3969 | + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) { |
3970 | + err = -errno; |
3971 | + g_free(cmd); |
3972 | + goto fail; |
3973 | + } |
3974 | + |
3975 | + io = g_io_channel_unix_new(dd); |
3976 | + g_io_channel_set_close_on_unref(io, FALSE); |
3977 | + g_io_add_watch_full(io, G_PRIORITY_DEFAULT, |
3978 | + G_IO_HUP | G_IO_ERR | G_IO_NVAL | G_IO_IN, |
3979 | + hci_event_watch, cmd, g_free); |
3980 | + g_io_channel_unref(io); |
3981 | + |
3982 | + return 0; |
3983 | + |
3984 | +fail: |
3985 | + close(dd); |
3986 | + return err; |
3987 | +} |
3988 | + |
3989 | +static int hciops_set_did(int index, uint16_t vendor, uint16_t product, |
3990 | + uint16_t version, uint16_t source) |
3991 | +{ |
3992 | + struct dev_info *dev = &devs[index]; |
3993 | + |
3994 | + dev->did_vendor = vendor; |
3995 | + dev->did_product = product; |
3996 | + dev->did_version = version; |
3997 | + dev->did_source = source; |
3998 | + |
3999 | + return 0; |
4000 | +} |
4001 | + |
4002 | +/* End async HCI command handling */ |
4003 | + |
4004 | +/* Start of HCI event callbacks */ |
4005 | + |
4006 | +static gint conn_handle_cmp(gconstpointer a, gconstpointer b) |
4007 | +{ |
4008 | + const struct bt_conn *conn = a; |
4009 | + uint16_t handle = *((const uint16_t *) b); |
4010 | + |
4011 | + return (int) conn->handle - (int) handle; |
4012 | +} |
4013 | + |
4014 | +static struct bt_conn *find_conn_by_handle(struct dev_info *dev, |
4015 | + uint16_t handle) |
4016 | +{ |
4017 | + GSList *match; |
4018 | + |
4019 | + match = g_slist_find_custom(dev->connections, &handle, |
4020 | + conn_handle_cmp); |
4021 | + if (match) |
4022 | + return match->data; |
4023 | + |
4024 | + return NULL; |
4025 | +} |
4026 | + |
4027 | +static gint conn_bdaddr_cmp(gconstpointer a, gconstpointer b) |
4028 | +{ |
4029 | + const struct bt_conn *conn = a; |
4030 | + const bdaddr_t *bdaddr = b; |
4031 | + |
4032 | + return bacmp(&conn->bdaddr, bdaddr); |
4033 | +} |
4034 | + |
4035 | +static struct bt_conn *find_connection(struct dev_info *dev, bdaddr_t *bdaddr) |
4036 | +{ |
4037 | + GSList *match; |
4038 | + |
4039 | + match = g_slist_find_custom(dev->connections, bdaddr, conn_bdaddr_cmp); |
4040 | + if (match) |
4041 | + return match->data; |
4042 | + |
4043 | + return NULL; |
4044 | +} |
4045 | + |
4046 | +static struct bt_conn *get_connection(struct dev_info *dev, bdaddr_t *bdaddr) |
4047 | +{ |
4048 | + struct bt_conn *conn; |
4049 | + |
4050 | + conn = find_connection(dev, bdaddr); |
4051 | + if (conn) |
4052 | + return conn; |
4053 | + |
4054 | + conn = g_new0(struct bt_conn, 1); |
4055 | + |
4056 | + conn->dev = dev; |
4057 | + conn->loc_cap = dev->io_capability; |
4058 | + conn->loc_auth = 0xff; |
4059 | + conn->rem_auth = 0xff; |
4060 | + bacpy(&conn->bdaddr, bdaddr); |
4061 | + |
4062 | + dev->connections = g_slist_append(dev->connections, conn); |
4063 | + |
4064 | + return conn; |
4065 | +} |
4066 | + |
4067 | +static int get_handle(int index, bdaddr_t *bdaddr, uint16_t *handle) |
4068 | +{ |
4069 | + struct dev_info *dev = &devs[index]; |
4070 | + struct bt_conn *conn; |
4071 | + char addr[18]; |
4072 | + |
4073 | + ba2str(bdaddr, addr); |
4074 | + DBG("hci%d dba %s", index, addr); |
4075 | + |
4076 | + conn = find_connection(dev, bdaddr); |
4077 | + if (conn == NULL) |
4078 | + return -ENOENT; |
4079 | + |
4080 | + *handle = conn->handle; |
4081 | + |
4082 | + return 0; |
4083 | +} |
4084 | + |
4085 | +static int disconnect_addr(int index, bdaddr_t *dba, uint8_t reason) |
4086 | +{ |
4087 | + disconnect_cp cp; |
4088 | + uint16_t handle; |
4089 | + int err; |
4090 | + |
4091 | + err = get_handle(index, dba, &handle); |
4092 | + if (err < 0) |
4093 | + return err; |
4094 | + |
4095 | + memset(&cp, 0, sizeof(cp)); |
4096 | + cp.handle = htobs(handle); |
4097 | + cp.reason = reason; |
4098 | + |
4099 | + if (hci_send_cmd(devs[index].sk, OGF_LINK_CTL, OCF_DISCONNECT, |
4100 | + DISCONNECT_CP_SIZE, &cp) < 0) |
4101 | + return -errno; |
4102 | + |
4103 | + return 0; |
4104 | +} |
4105 | + |
4106 | +static void bonding_complete(struct dev_info *dev, struct bt_conn *conn, |
4107 | + uint8_t status) |
4108 | +{ |
4109 | + struct btd_adapter *adapter; |
4110 | + |
4111 | + DBG("status 0x%02x", status); |
4112 | + |
4113 | + if (conn->io != NULL) { |
4114 | + /* bonding_connect_cb takes care of the successul case */ |
4115 | + if (status != 0) |
4116 | + g_io_channel_shutdown(conn->io, TRUE, NULL); |
4117 | + g_io_channel_unref(conn->io); |
4118 | + conn->io = NULL; |
4119 | + } |
4120 | + |
4121 | + conn->bonding_initiator = FALSE; |
4122 | + |
4123 | + adapter = manager_find_adapter(&dev->bdaddr); |
4124 | + if (adapter) |
4125 | + adapter_bonding_complete(adapter, &conn->bdaddr, status); |
4126 | +} |
4127 | + |
4128 | +static int get_auth_info(int index, bdaddr_t *bdaddr, uint8_t *auth) |
4129 | +{ |
4130 | + struct dev_info *dev = &devs[index]; |
4131 | + struct hci_auth_info_req req; |
4132 | + char addr[18]; |
4133 | + |
4134 | + ba2str(bdaddr, addr); |
4135 | + DBG("hci%d dba %s", index, addr); |
4136 | + |
4137 | + memset(&req, 0, sizeof(req)); |
4138 | + bacpy(&req.bdaddr, bdaddr); |
4139 | + |
4140 | + if (ioctl(dev->sk, HCIGETAUTHINFO, (unsigned long) &req) < 0) |
4141 | + return -errno; |
4142 | + |
4143 | + if (auth) |
4144 | + *auth = req.type; |
4145 | + |
4146 | + return 0; |
4147 | +} |
4148 | + |
4149 | +/* Link Key handling */ |
4150 | + |
4151 | +static void link_key_request(int index, bdaddr_t *dba) |
4152 | +{ |
4153 | + struct dev_info *dev = &devs[index]; |
4154 | + struct link_key_info *key_info; |
4155 | + struct bt_conn *conn; |
4156 | + GSList *match; |
4157 | + char da[18]; |
4158 | + |
4159 | + ba2str(dba, da); |
4160 | + DBG("hci%d dba %s", index, da); |
4161 | + |
4162 | + conn = get_connection(dev, dba); |
4163 | + if (conn->handle == 0) |
4164 | + conn->secmode3 = TRUE; |
4165 | + |
4166 | + get_auth_info(index, dba, &conn->loc_auth); |
4167 | + |
4168 | + DBG("kernel auth requirements = 0x%02x", conn->loc_auth); |
4169 | + |
4170 | + match = g_slist_find_custom(dev->keys, dba, (GCompareFunc) bacmp); |
4171 | + if (match) |
4172 | + key_info = match->data; |
4173 | + else |
4174 | + key_info = NULL; |
4175 | + |
4176 | + DBG("Matching key %s", key_info ? "found" : "not found"); |
4177 | + |
4178 | + if (key_info == NULL || (!dev->debug_keys && key_info->type == 0x03)) { |
4179 | + /* Link key not found */ |
4180 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, |
4181 | + 6, dba); |
4182 | + return; |
4183 | + } |
4184 | + |
4185 | + /* Link key found */ |
4186 | + |
4187 | + DBG("link key type 0x%02x", key_info->type); |
4188 | + |
4189 | + /* Don't use unauthenticated combination keys if MITM is |
4190 | + * required */ |
4191 | + if (key_info->type == 0x04 && conn->loc_auth != 0xff && |
4192 | + (conn->loc_auth & 0x01)) |
4193 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, |
4194 | + 6, dba); |
4195 | + else { |
4196 | + link_key_reply_cp lr; |
4197 | + |
4198 | + memcpy(lr.link_key, key_info->key, 16); |
4199 | + bacpy(&lr.bdaddr, dba); |
4200 | + |
4201 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, |
4202 | + LINK_KEY_REPLY_CP_SIZE, &lr); |
4203 | + } |
4204 | +} |
4205 | + |
4206 | +static void link_key_notify(int index, void *ptr) |
4207 | +{ |
4208 | + struct dev_info *dev = &devs[index]; |
4209 | + evt_link_key_notify *evt = ptr; |
4210 | + bdaddr_t *dba = &evt->bdaddr; |
4211 | + struct link_key_info *key_info; |
4212 | + uint8_t old_key_type, key_type; |
4213 | + struct bt_conn *conn; |
4214 | + GSList *match; |
4215 | + char da[18]; |
4216 | + uint8_t status = 0; |
4217 | + |
4218 | + ba2str(dba, da); |
4219 | + DBG("hci%d dba %s type %d", index, da, evt->key_type); |
4220 | + |
4221 | + conn = get_connection(dev, &evt->bdaddr); |
4222 | + |
4223 | + match = g_slist_find_custom(dev->keys, dba, (GCompareFunc) bacmp); |
4224 | + if (match) |
4225 | + key_info = match->data; |
4226 | + else |
4227 | + key_info = NULL; |
4228 | + |
4229 | + if (key_info == NULL) { |
4230 | + key_info = g_new0(struct link_key_info, 1); |
4231 | + bacpy(&key_info->bdaddr, &evt->bdaddr); |
4232 | + old_key_type = 0xff; |
4233 | + } else { |
4234 | + dev->keys = g_slist_remove(dev->keys, key_info); |
4235 | + old_key_type = key_info->type; |
4236 | + } |
4237 | + |
4238 | + memcpy(key_info->key, evt->link_key, sizeof(evt->link_key)); |
4239 | + key_info->type = evt->key_type; |
4240 | + key_info->pin_len = dev->pin_length; |
4241 | + |
4242 | + key_type = evt->key_type; |
4243 | + |
4244 | + DBG("key type 0x%02x old key type 0x%02x", key_type, old_key_type); |
4245 | + DBG("local auth 0x%02x and remote auth 0x%02x", |
4246 | + conn->loc_auth, conn->rem_auth); |
4247 | + |
4248 | + if (key_type == HCI_LK_CHANGED_COMBINATION) { |
4249 | + /* Some buggy controller combinations generate a changed |
4250 | + * combination key for legacy pairing even when there's no |
4251 | + * previous key */ |
4252 | + if (conn->rem_auth == 0xff && old_key_type == 0xff) |
4253 | + key_type = HCI_LK_COMBINATION; |
4254 | + else if (old_key_type != 0xff) |
4255 | + key_type = old_key_type; |
4256 | + else |
4257 | + /* This is Changed Combination Link Key for |
4258 | + * a temporary link key.*/ |
4259 | + goto done; |
4260 | + } |
4261 | + |
4262 | + key_info->type = key_type; |
4263 | + |
4264 | + /* Skip the storage check if this is a debug key */ |
4265 | + if (key_type == HCI_LK_DEBUG_COMBINATION) |
4266 | + goto done; |
4267 | + |
4268 | + /* Store the link key persistently if one of the following is true: |
4269 | + * 1. this is a legacy link key |
4270 | + * 2. this is a changed combination key and there was a previously |
4271 | + * stored one |
4272 | + * 3. neither local nor remote side had no-bonding as a requirement |
4273 | + * 4. the local side had dedicated bonding as a requirement |
4274 | + * 5. the remote side is using dedicated bonding since in that case |
4275 | + * also the local requirements are set to dedicated bonding |
4276 | + * If none of the above match only keep the link key around for |
4277 | + * this connection and set the temporary flag for the device. |
4278 | + */ |
4279 | + if (key_type < HCI_LK_DEBUG_COMBINATION || |
4280 | + (key_type == HCI_LK_CHANGED_COMBINATION |
4281 | + && old_key_type != HCI_LK_INVALID) || |
4282 | + (conn->loc_auth > 0x01 && conn->rem_auth > 0x01) || |
4283 | + (conn->loc_auth == 0x02 || conn->loc_auth == 0x03) || |
4284 | + (conn->rem_auth == 0x02 || conn->rem_auth == 0x03)) { |
4285 | + int err; |
4286 | + |
4287 | + err = btd_event_link_key_notify(&dev->bdaddr, dba, |
4288 | + evt->link_key, key_type, |
4289 | + dev->pin_length); |
4290 | + |
4291 | + if (err == -ENODEV) |
4292 | + status = HCI_OE_LOW_RESOURCES; |
4293 | + else if (err < 0) |
4294 | + status = HCI_MEMORY_FULL; |
4295 | + |
4296 | + goto done; |
4297 | + } |
4298 | + |
4299 | +done: |
4300 | + dev->pin_length = 0; |
4301 | + |
4302 | + if (status != 0) { |
4303 | + g_free(key_info); |
4304 | + bonding_complete(dev, conn, status); |
4305 | + disconnect_addr(index, dba, status); |
4306 | + return; |
4307 | + } |
4308 | + |
4309 | + dev->keys = g_slist_prepend(dev->keys, key_info); |
4310 | + |
4311 | + /* If we're connected and not dedicated bonding initiators we're |
4312 | + * done with the bonding process */ |
4313 | + if (!conn->bonding_initiator && conn->handle != 0) |
4314 | + bonding_complete(dev, conn, 0); |
4315 | +} |
4316 | + |
4317 | +static void return_link_keys(int index, void *ptr) |
4318 | +{ |
4319 | + struct dev_info *dev = &devs[index]; |
4320 | + evt_return_link_keys *evt = ptr; |
4321 | + uint8_t num = evt->num_keys; |
4322 | + unsigned char key[16]; |
4323 | + char da[18]; |
4324 | + bdaddr_t dba; |
4325 | + int i; |
4326 | + |
4327 | + DBG("hci%d num_keys %u", index, num); |
4328 | + |
4329 | + ptr++; |
4330 | + |
4331 | + for (i = 0; i < num; i++) { |
4332 | + bacpy(&dba, ptr); ba2str(&dba, da); |
4333 | + memcpy(key, ptr + 6, 16); |
4334 | + |
4335 | + DBG("hci%d returned key for %s", index, da); |
4336 | + |
4337 | + btd_event_returned_link_key(&dev->bdaddr, &dba); |
4338 | + |
4339 | + ptr += 22; |
4340 | + } |
4341 | +} |
4342 | + |
4343 | +/* Simple Pairing handling */ |
4344 | + |
4345 | +static int hciops_confirm_reply(int index, bdaddr_t *bdaddr, uint8_t bdaddr_type, |
4346 | + gboolean success) |
4347 | +{ |
4348 | + struct dev_info *dev = &devs[index]; |
4349 | + user_confirm_reply_cp cp; |
4350 | + char addr[18]; |
4351 | + int err; |
4352 | + |
4353 | + ba2str(bdaddr, addr); |
4354 | + DBG("hci%d dba %s success %d", index, addr, success); |
4355 | + |
4356 | + memset(&cp, 0, sizeof(cp)); |
4357 | + bacpy(&cp.bdaddr, bdaddr); |
4358 | + |
4359 | + if (success) |
4360 | + err = hci_send_cmd(dev->sk, OGF_LINK_CTL, |
4361 | + OCF_USER_CONFIRM_REPLY, |
4362 | + USER_CONFIRM_REPLY_CP_SIZE, &cp); |
4363 | + else |
4364 | + err = hci_send_cmd(dev->sk, OGF_LINK_CTL, |
4365 | + OCF_USER_CONFIRM_NEG_REPLY, |
4366 | + USER_CONFIRM_REPLY_CP_SIZE, &cp); |
4367 | + |
4368 | + if (err < 0) |
4369 | + err = -errno; |
4370 | + |
4371 | + return err; |
4372 | +} |
4373 | + |
4374 | +static void user_confirm_request(int index, void *ptr) |
4375 | +{ |
4376 | + struct dev_info *dev = &devs[index]; |
4377 | + evt_user_confirm_request *req = ptr; |
4378 | + gboolean loc_mitm, rem_mitm; |
4379 | + struct bt_conn *conn; |
4380 | + |
4381 | + DBG("hci%d", index); |
4382 | + |
4383 | + conn = find_connection(dev, &req->bdaddr); |
4384 | + if (conn == NULL) |
4385 | + return; |
4386 | + |
4387 | + loc_mitm = (conn->loc_auth & 0x01) ? TRUE : FALSE; |
4388 | + rem_mitm = (conn->rem_auth & 0x01) ? TRUE : FALSE; |
4389 | + |
4390 | + /* If we require MITM but the remote device can't provide that |
4391 | + * (it has NoInputNoOutput) then reject the confirmation |
4392 | + * request. The only exception is when we're dedicated bonding |
4393 | + * initiators since then we always have the MITM bit set. */ |
4394 | + if (!conn->bonding_initiator && loc_mitm && conn->rem_cap == 0x03) { |
4395 | + error("Rejecting request: remote device can't provide MITM"); |
4396 | + goto fail; |
4397 | + } |
4398 | + |
4399 | + /* If no side requires MITM protection; auto-accept */ |
4400 | + if ((conn->loc_auth == 0xff || !loc_mitm || conn->rem_cap == 0x03) && |
4401 | + (!rem_mitm || conn->loc_cap == 0x03)) { |
4402 | + DBG("auto accept of confirmation"); |
4403 | + |
4404 | + /* Wait 5 milliseconds before doing auto-accept */ |
4405 | + usleep(5000); |
4406 | + |
4407 | + if (hciops_confirm_reply(index, &req->bdaddr, |
4408 | + BDADDR_BREDR, TRUE) < 0) |
4409 | + goto fail; |
4410 | + |
4411 | + return; |
4412 | + } |
4413 | + |
4414 | + if (btd_event_user_confirm(&dev->bdaddr, &req->bdaddr, |
4415 | + btohl(req->passkey)) == 0) |
4416 | + return; |
4417 | + |
4418 | +fail: |
4419 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY, |
4420 | + 6, ptr); |
4421 | +} |
4422 | + |
4423 | +static void user_passkey_request(int index, void *ptr) |
4424 | +{ |
4425 | + struct dev_info *dev = &devs[index]; |
4426 | + evt_user_passkey_request *req = ptr; |
4427 | + |
4428 | + DBG("hci%d", index); |
4429 | + |
4430 | + if (btd_event_user_passkey(&dev->bdaddr, &req->bdaddr) < 0) |
4431 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, |
4432 | + OCF_USER_PASSKEY_NEG_REPLY, 6, ptr); |
4433 | +} |
4434 | + |
4435 | +static void user_passkey_notify(int index, void *ptr) |
4436 | +{ |
4437 | + struct dev_info *dev = &devs[index]; |
4438 | + evt_user_passkey_notify *req = ptr; |
4439 | + |
4440 | + DBG("hci%d", index); |
4441 | + |
4442 | + btd_event_user_notify(&dev->bdaddr, &req->bdaddr, |
4443 | + btohl(req->passkey)); |
4444 | +} |
4445 | + |
4446 | +static gint oob_bdaddr_cmp(gconstpointer a, gconstpointer b) |
4447 | +{ |
4448 | + const struct oob_data *data = a; |
4449 | + const bdaddr_t *bdaddr = b; |
4450 | + |
4451 | + return bacmp(&data->bdaddr, bdaddr); |
4452 | +} |
4453 | + |
4454 | +static void remote_oob_data_request(int index, bdaddr_t *bdaddr) |
4455 | +{ |
4456 | + struct dev_info *dev = &devs[index]; |
4457 | + GSList *match; |
4458 | + |
4459 | + DBG("hci%d", index); |
4460 | + |
4461 | + match = g_slist_find_custom(dev->oob_data, bdaddr, oob_bdaddr_cmp); |
4462 | + |
4463 | + if (match) { |
4464 | + struct oob_data *data; |
4465 | + remote_oob_data_reply_cp cp; |
4466 | + |
4467 | + data = match->data; |
4468 | + |
4469 | + bacpy(&cp.bdaddr, &data->bdaddr); |
4470 | + memcpy(cp.hash, data->hash, sizeof(cp.hash)); |
4471 | + memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer)); |
4472 | + |
4473 | + dev->oob_data = g_slist_delete_link(dev->oob_data, match); |
4474 | + |
4475 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY, |
4476 | + REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp); |
4477 | + |
4478 | + } else { |
4479 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, |
4480 | + OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, bdaddr); |
4481 | + } |
4482 | +} |
4483 | + |
4484 | +static int get_io_cap(int index, bdaddr_t *bdaddr, uint8_t *cap, uint8_t *auth) |
4485 | +{ |
4486 | + struct dev_info *dev = &devs[index]; |
4487 | + struct bt_conn *conn; |
4488 | + int err; |
4489 | + |
4490 | + conn = find_connection(dev, bdaddr); |
4491 | + if (conn == NULL) |
4492 | + return -ENOENT; |
4493 | + |
4494 | + err = get_auth_info(index, bdaddr, &conn->loc_auth); |
4495 | + if (err < 0) |
4496 | + return err; |
4497 | + |
4498 | + DBG("initial authentication requirement is 0x%02x", conn->loc_auth); |
4499 | + |
4500 | + if (!dev->pairable && !conn->bonding_initiator) { |
4501 | + if (conn->rem_auth < 0x02) { |
4502 | + DBG("Allowing no bonding in non-bondable mode"); |
4503 | + /* Kernel defaults to general bonding and so |
4504 | + * overwrite for this special case. Otherwise |
4505 | + * non-pairable test cases will fail. */ |
4506 | + conn->loc_auth = conn->rem_auth; |
4507 | + goto done; |
4508 | + } |
4509 | + |
4510 | + return -EPERM; |
4511 | + } |
4512 | + |
4513 | + /* If the kernel doesn't know the local requirement just mirror |
4514 | + * the remote one */ |
4515 | + if (conn->loc_auth == 0xff) |
4516 | + conn->loc_auth = conn->rem_auth; |
4517 | + |
4518 | + if (conn->loc_auth == 0x00 || conn->loc_auth == 0x04) { |
4519 | + /* If remote requests dedicated bonding follow that lead */ |
4520 | + if (conn->rem_auth == 0x02 || conn->rem_auth == 0x03) { |
4521 | + |
4522 | + /* If both remote and local IO capabilities allow MITM |
4523 | + * then require it, otherwise don't */ |
4524 | + if (conn->rem_cap == 0x03 || conn->loc_cap == 0x03) |
4525 | + conn->loc_auth = 0x02; |
4526 | + else |
4527 | + conn->loc_auth = 0x03; |
4528 | + } |
4529 | + |
4530 | + /* If remote indicates no bonding then follow that. This |
4531 | + * is important since the kernel might give general bonding |
4532 | + * as default. */ |
4533 | + if (conn->rem_auth == 0x00 || conn->rem_auth == 0x01) |
4534 | + conn->loc_auth = 0x00; |
4535 | + |
4536 | + /* If remote requires MITM then also require it, unless |
4537 | + * our IO capability is NoInputNoOutput (so some |
4538 | + * just-works security cases can be tested) */ |
4539 | + if (conn->rem_auth != 0xff && (conn->rem_auth & 0x01) && |
4540 | + conn->loc_cap != 0x03) |
4541 | + conn->loc_auth |= 0x01; |
4542 | + } |
4543 | + |
4544 | +done: |
4545 | + *cap = conn->loc_cap; |
4546 | + *auth = conn->loc_auth; |
4547 | + |
4548 | + DBG("final authentication requirement is 0x%02x", *auth); |
4549 | + |
4550 | + return 0; |
4551 | +} |
4552 | + |
4553 | +static void io_capa_request(int index, void *ptr) |
4554 | +{ |
4555 | + struct dev_info *dev = &devs[index]; |
4556 | + bdaddr_t *dba = ptr; |
4557 | + uint8_t cap, auth = 0xff; |
4558 | + char da[18]; |
4559 | + int err; |
4560 | + |
4561 | + ba2str(dba, da); |
4562 | + DBG("hci%d IO capability request for %s", index, da); |
4563 | + |
4564 | + err = get_io_cap(index, dba, &cap, &auth); |
4565 | + if (err < 0) { |
4566 | + io_capability_neg_reply_cp cp; |
4567 | + |
4568 | + error("Getting IO capability failed: %s (%d)", |
4569 | + strerror(-err), -err); |
4570 | + |
4571 | + memset(&cp, 0, sizeof(cp)); |
4572 | + bacpy(&cp.bdaddr, dba); |
4573 | + cp.reason = HCI_PAIRING_NOT_ALLOWED; |
4574 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, |
4575 | + OCF_IO_CAPABILITY_NEG_REPLY, |
4576 | + IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp); |
4577 | + } else { |
4578 | + io_capability_reply_cp cp; |
4579 | + struct bt_conn *conn; |
4580 | + GSList *match; |
4581 | + |
4582 | + memset(&cp, 0, sizeof(cp)); |
4583 | + bacpy(&cp.bdaddr, dba); |
4584 | + cp.capability = cap; |
4585 | + cp.authentication = auth; |
4586 | + |
4587 | + conn = find_connection(dev, dba); |
4588 | + match = g_slist_find_custom(dev->oob_data, dba, oob_bdaddr_cmp); |
4589 | + |
4590 | + if ((conn->bonding_initiator || conn->rem_oob_data == 0x01) && |
4591 | + match) |
4592 | + cp.oob_data = 0x01; |
4593 | + else |
4594 | + cp.oob_data = 0x00; |
4595 | + |
4596 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY, |
4597 | + IO_CAPABILITY_REPLY_CP_SIZE, &cp); |
4598 | + } |
4599 | +} |
4600 | + |
4601 | +static void io_capa_response(int index, void *ptr) |
4602 | +{ |
4603 | + struct dev_info *dev = &devs[index]; |
4604 | + evt_io_capability_response *evt = ptr; |
4605 | + struct bt_conn *conn; |
4606 | + char da[18]; |
4607 | + |
4608 | + ba2str(&evt->bdaddr, da); |
4609 | + DBG("hci%d IO capability response from %s", index, da); |
4610 | + |
4611 | + conn = find_connection(dev, &evt->bdaddr); |
4612 | + if (conn) { |
4613 | + conn->rem_cap = evt->capability; |
4614 | + conn->rem_auth = evt->authentication; |
4615 | + conn->rem_oob_data = evt->oob_data; |
4616 | + } |
4617 | +} |
4618 | + |
4619 | +/* PIN code handling */ |
4620 | + |
4621 | +static void pin_code_request(int index, bdaddr_t *dba) |
4622 | +{ |
4623 | + struct dev_info *dev = &devs[index]; |
4624 | + struct bt_conn *conn; |
4625 | + char addr[18]; |
4626 | + int err; |
4627 | + |
4628 | + ba2str(dba, addr); |
4629 | + DBG("hci%d PIN request for %s", index, addr); |
4630 | + |
4631 | + conn = get_connection(dev, dba); |
4632 | + if (conn->handle == 0) |
4633 | + conn->secmode3 = TRUE; |
4634 | + |
4635 | + /* Check if the adapter is not pairable and if there isn't a bonding in |
4636 | + * progress */ |
4637 | + if (!dev->pairable && !conn->bonding_initiator) { |
4638 | + DBG("Rejecting PIN request in non-pairable mode"); |
4639 | + goto reject; |
4640 | + } |
4641 | + |
4642 | + err = btd_event_request_pin(&dev->bdaddr, dba, FALSE); |
4643 | + if (err < 0) { |
4644 | + error("PIN code negative reply: %s", strerror(-err)); |
4645 | + goto reject; |
4646 | + } |
4647 | + |
4648 | + return; |
4649 | + |
4650 | +reject: |
4651 | + hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); |
4652 | +} |
4653 | + |
4654 | +static inline void remote_features_notify(int index, void *ptr) |
4655 | +{ |
4656 | + struct dev_info *dev = &devs[index]; |
4657 | + evt_remote_host_features_notify *evt = ptr; |
4658 | + |
4659 | + if (evt->features[0] & 0x01) |
4660 | + btd_event_set_legacy_pairing(&dev->bdaddr, &evt->bdaddr, |
4661 | + FALSE); |
4662 | + else |
4663 | + btd_event_set_legacy_pairing(&dev->bdaddr, &evt->bdaddr, |
4664 | + TRUE); |
4665 | + |
4666 | + write_features_info(&dev->bdaddr, &evt->bdaddr, NULL, evt->features); |
4667 | +} |
4668 | + |
4669 | +static void read_local_version_complete(int index, |
4670 | + const read_local_version_rp *rp) |
4671 | +{ |
4672 | + struct dev_info *dev = &devs[index]; |
4673 | + |
4674 | + if (rp->status) |
4675 | + return; |
4676 | + |
4677 | + dev->ver.manufacturer = btohs(bt_get_unaligned(&rp->manufacturer)); |
4678 | + dev->ver.hci_ver = rp->hci_ver; |
4679 | + dev->ver.hci_rev = btohs(bt_get_unaligned(&rp->hci_rev)); |
4680 | + dev->ver.lmp_ver = rp->lmp_ver; |
4681 | + dev->ver.lmp_subver = btohs(bt_get_unaligned(&rp->lmp_subver)); |
4682 | + |
4683 | + if (!dev->pending) |
4684 | + return; |
4685 | + |
4686 | + hci_clear_bit(PENDING_VERSION, &dev->pending); |
4687 | + |
4688 | + DBG("Got version for hci%d", index); |
4689 | + |
4690 | + if (!dev->pending && dev->up) |
4691 | + init_adapter(index); |
4692 | +} |
4693 | + |
4694 | +static void read_local_features_complete(int index, |
4695 | + const read_local_features_rp *rp) |
4696 | +{ |
4697 | + struct dev_info *dev = &devs[index]; |
4698 | + |
4699 | + if (rp->status) |
4700 | + return; |
4701 | + |
4702 | + memcpy(dev->features, rp->features, 8); |
4703 | + |
4704 | + if (!dev->pending) |
4705 | + return; |
4706 | + |
4707 | + hci_clear_bit(PENDING_FEATURES, &dev->pending); |
4708 | + |
4709 | + DBG("Got features for hci%d", index); |
4710 | + |
4711 | + if (!dev->pending && dev->up) |
4712 | + init_adapter(index); |
4713 | +} |
4714 | + |
4715 | +static void update_name(int index, const char *name) |
4716 | +{ |
4717 | + struct btd_adapter *adapter; |
4718 | + |
4719 | + adapter = manager_find_adapter_by_id(index); |
4720 | + if (adapter) |
4721 | + adapter_name_changed(adapter, name); |
4722 | + |
4723 | + update_ext_inquiry_response(index); |
4724 | +} |
4725 | + |
4726 | +static void read_local_name_complete(int index, read_local_name_rp *rp) |
4727 | +{ |
4728 | + struct dev_info *dev = &devs[index]; |
4729 | + |
4730 | + DBG("hci%d status %u", index, rp->status); |
4731 | + |
4732 | + if (rp->status) |
4733 | + return; |
4734 | + |
4735 | + memcpy(dev->name, rp->name, 248); |
4736 | + |
4737 | + if (!dev->pending) { |
4738 | + update_name(index, (char *) rp->name); |
4739 | + return; |
4740 | + } |
4741 | + |
4742 | + hci_clear_bit(PENDING_NAME, &dev->pending); |
4743 | + |
4744 | + DBG("Got name for hci%d", index); |
4745 | + |
4746 | + if (!dev->pending && dev->up) |
4747 | + init_adapter(index); |
4748 | +} |
4749 | + |
4750 | +static void read_tx_power_complete(int index, void *ptr) |
4751 | +{ |
4752 | + struct dev_info *dev = &devs[index]; |
4753 | + |
4754 | + read_inq_response_tx_power_level_rp *rp = ptr; |
4755 | + |
4756 | + DBG("hci%d status %u", index, rp->status); |
4757 | + |
4758 | + if (rp->status) |
4759 | + return; |
4760 | + |
4761 | + dev->tx_power = rp->level; |
4762 | + update_ext_inquiry_response(index); |
4763 | +} |
4764 | + |
4765 | +static void read_simple_pairing_mode_complete(int index, void *ptr) |
4766 | +{ |
4767 | + struct dev_info *dev = &devs[index]; |
4768 | + read_simple_pairing_mode_rp *rp = ptr; |
4769 | + |
4770 | + DBG("hci%d status %u", index, rp->status); |
4771 | + |
4772 | + if (rp->status) |
4773 | + return; |
4774 | + |
4775 | + dev->ssp_mode = rp->mode; |
4776 | + update_ext_inquiry_response(index); |
4777 | +} |
4778 | + |
4779 | +static void read_local_ext_features_complete(int index, |
4780 | + const read_local_ext_features_rp *rp) |
4781 | +{ |
4782 | + struct dev_info *dev = &devs[index]; |
4783 | + |
4784 | + DBG("hci%d status %u", index, rp->status); |
4785 | + |
4786 | + if (rp->status) |
4787 | + return; |
4788 | + |
4789 | + /* Local Extended feature page number is 1 */ |
4790 | + if (rp->page_num != 1) |
4791 | + return; |
4792 | + |
4793 | + memcpy(dev->extfeatures, rp->features, sizeof(dev->extfeatures)); |
4794 | +} |
4795 | + |
4796 | +static void read_bd_addr_complete(int index, read_bd_addr_rp *rp) |
4797 | +{ |
4798 | + struct dev_info *dev = &devs[index]; |
4799 | + |
4800 | + DBG("hci%d status %u", index, rp->status); |
4801 | + |
4802 | + if (rp->status) |
4803 | + return; |
4804 | + |
4805 | + bacpy(&dev->bdaddr, &rp->bdaddr); |
4806 | + |
4807 | + if (!dev->pending) |
4808 | + return; |
4809 | + |
4810 | + hci_clear_bit(PENDING_BDADDR, &dev->pending); |
4811 | + |
4812 | + DBG("Got bdaddr for hci%d", index); |
4813 | + |
4814 | + if (!dev->pending && dev->up) |
4815 | + init_adapter(index); |
4816 | +} |
4817 | + |
4818 | +static inline void cs_inquiry_evt(int index, uint8_t status) |
4819 | +{ |
4820 | + if (status) { |
4821 | + error("Inquiry Failed with status 0x%02x", status); |
4822 | + return; |
4823 | + } |
4824 | + |
4825 | + set_state(index, DISCOV_INQ); |
4826 | +} |
4827 | + |
4828 | +static inline void cmd_status(int index, void *ptr) |
4829 | +{ |
4830 | + evt_cmd_status *evt = ptr; |
4831 | + uint16_t opcode = btohs(evt->opcode); |
4832 | + |
4833 | + if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) |
4834 | + cs_inquiry_evt(index, evt->status); |
4835 | +} |
4836 | + |
4837 | +static gboolean discoverable_timeout_handler(gpointer user_data) |
4838 | +{ |
4839 | + struct dev_info *dev = user_data; |
4840 | + |
4841 | + hciops_set_discoverable(dev->id, FALSE, 0); |
4842 | + |
4843 | + return FALSE; |
4844 | +} |
4845 | + |
4846 | +/* Limited Discoverable bit mask in CoD */ |
4847 | +#define LIMITED_BIT 0x002000 |
4848 | + |
4849 | +static int hciops_set_limited_discoverable(int index, gboolean limited) |
4850 | +{ |
4851 | + struct dev_info *dev = &devs[index]; |
4852 | + int num = (limited ? 2 : 1); |
4853 | + uint8_t lap[] = { 0x33, 0x8b, 0x9e, 0x00, 0x8b, 0x9e }; |
4854 | + write_current_iac_lap_cp cp; |
4855 | + |
4856 | + DBG("hci%d limited %d", index, limited); |
4857 | + |
4858 | + /* Check if limited bit needs to be set/reset */ |
4859 | + if (limited) |
4860 | + dev->wanted_cod |= LIMITED_BIT; |
4861 | + else |
4862 | + dev->wanted_cod &= ~LIMITED_BIT; |
4863 | + |
4864 | + /* If we dont need the toggling, save an unnecessary CoD write */ |
4865 | + if (dev->pending_cod || dev->wanted_cod == dev->current_cod) |
4866 | + return 0; |
4867 | + |
4868 | + /* |
4869 | + * 1: giac |
4870 | + * 2: giac + liac |
4871 | + */ |
4872 | + memset(&cp, 0, sizeof(cp)); |
4873 | + cp.num_current_iac = num; |
4874 | + memcpy(&cp.lap, lap, num * 3); |
4875 | + |
4876 | + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CURRENT_IAC_LAP, |
4877 | + (num * 3 + 1), &cp) < 0) |
4878 | + return -errno; |
4879 | + |
4880 | + return write_class(index, dev->wanted_cod); |
4881 | +} |
4882 | + |
4883 | +static void reset_discoverable_timeout(int index) |
4884 | +{ |
4885 | + struct dev_info *dev = &devs[index]; |
4886 | + |
4887 | + if (dev->discoverable_id > 0) { |
4888 | + g_source_remove(dev->discoverable_id); |
4889 | + dev->discoverable_id = 0; |
4890 | + } |
4891 | +} |
4892 | + |
4893 | +static void set_discoverable_timeout(int index) |
4894 | +{ |
4895 | + struct dev_info *dev = &devs[index]; |
4896 | + |
4897 | + reset_discoverable_timeout(index); |
4898 | + |
4899 | + if (dev->discoverable_timeout == 0) { |
4900 | + hciops_set_limited_discoverable(index, FALSE); |
4901 | + return; |
4902 | + } |
4903 | + |
4904 | + /* Set limited discoverable if pairable and interval between 0 to 60 |
4905 | + sec */ |
4906 | + if (dev->pairable && dev->discoverable_timeout <= 60) |
4907 | + hciops_set_limited_discoverable(index, TRUE); |
4908 | + else |
4909 | + hciops_set_limited_discoverable(index, FALSE); |
4910 | + |
4911 | + dev->discoverable_id = g_timeout_add_seconds(dev->discoverable_timeout, |
4912 | + discoverable_timeout_handler, |
4913 | + dev); |
4914 | +} |
4915 | + |
4916 | +static void read_scan_complete(int index, uint8_t status, void *ptr) |
4917 | +{ |
4918 | + struct btd_adapter *adapter; |
4919 | + read_scan_enable_rp *rp = ptr; |
4920 | + |
4921 | + DBG("hci%d status %u", index, status); |
4922 | + |
4923 | + switch (rp->enable) { |
4924 | + case (SCAN_PAGE | SCAN_INQUIRY): |
4925 | + case SCAN_INQUIRY: |
4926 | + set_discoverable_timeout(index); |
4927 | + break; |
4928 | + default: |
4929 | + reset_discoverable_timeout(index); |
4930 | + hciops_set_limited_discoverable(index, FALSE); |
4931 | + } |
4932 | + |
4933 | + adapter = manager_find_adapter_by_id(index); |
4934 | + if (!adapter) { |
4935 | + error("Unable to find matching adapter"); |
4936 | + return; |
4937 | + } |
4938 | + |
4939 | + adapter_mode_changed(adapter, rp->enable); |
4940 | +} |
4941 | + |
4942 | +static void write_class_complete(int index, uint8_t status) |
4943 | +{ |
4944 | + struct dev_info *dev = &devs[index]; |
4945 | + struct btd_adapter *adapter; |
4946 | + |
4947 | + if (status) |
4948 | + return; |
4949 | + |
4950 | + if (dev->pending_cod == 0) |
4951 | + return; |
4952 | + |
4953 | + dev->current_cod = dev->pending_cod; |
4954 | + dev->pending_cod = 0; |
4955 | + |
4956 | + adapter = manager_find_adapter(&dev->bdaddr); |
4957 | + if (adapter) |
4958 | + btd_adapter_class_changed(adapter, dev->current_cod); |
4959 | + |
4960 | + update_ext_inquiry_response(index); |
4961 | + |
4962 | + if (dev->wanted_cod == dev->current_cod) |
4963 | + return; |
4964 | + |
4965 | + if (dev->wanted_cod & LIMITED_BIT && |
4966 | + !(dev->current_cod & LIMITED_BIT)) |
4967 | + hciops_set_limited_discoverable(index, TRUE); |
4968 | + else if (!(dev->wanted_cod & LIMITED_BIT) && |
4969 | + (dev->current_cod & LIMITED_BIT)) |
4970 | + hciops_set_limited_discoverable(index, FALSE); |
4971 | + else |
4972 | + write_class(index, dev->wanted_cod); |
4973 | +} |
4974 | + |
4975 | +static void read_local_oob_data_complete(int index, uint8_t status, |
4976 | + read_local_oob_data_rp *rp) |
4977 | +{ |
4978 | + struct btd_adapter *adapter = manager_find_adapter_by_id(index); |
4979 | + |
4980 | + if (!adapter) |
4981 | + return; |
4982 | + |
4983 | + if (status) |
4984 | + oob_read_local_data_complete(adapter, NULL, NULL); |
4985 | + else |
4986 | + oob_read_local_data_complete(adapter, rp->hash, rp->randomizer); |
4987 | +} |
4988 | + |
4989 | +static inline void inquiry_complete_evt(int index, uint8_t status) |
4990 | +{ |
4991 | + int adapter_type; |
4992 | + struct btd_adapter *adapter; |
4993 | + |
4994 | + if (status) { |
4995 | + error("Inquiry Failed with status 0x%02x", status); |
4996 | + return; |
4997 | + } |
4998 | + |
4999 | + adapter = manager_find_adapter_by_id(index); |
5000 | + if (!adapter) { |
Seems to me like the entered property is not consistently either an uint8 or an uint16, I think you'll want to keep it an uint16 everywhere maybe?