CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/hcitools/lib/hci.c
Views: 3959
1
/*
2
*
3
* BlueZ - Bluetooth protocol stack for Linux
4
*
5
* Copyright (C) 2000-2001 Qualcomm Incorporated
6
* Copyright (C) 2002-2003 Maxim Krasnyansky <[email protected]>
7
* Copyright (C) 2002-2010 Marcel Holtmann <[email protected]>
8
*
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
14
*
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
19
*
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
*
24
*/
25
26
#ifdef HAVE_CONFIG_H
27
#include <config.h>
28
#endif
29
30
#include <stdio.h>
31
#include <errno.h>
32
#include <fcntl.h>
33
#include <unistd.h>
34
#include <stdlib.h>
35
#include <string.h>
36
37
#include <sys/param.h>
38
#include <sys/uio.h>
39
#include <sys/poll.h>
40
#include <sys/types.h>
41
#include <sys/ioctl.h>
42
#include <sys/socket.h>
43
44
#include "bluetooth.h"
45
#include "hci.h"
46
#include "hci_lib.h"
47
48
#ifndef MIN
49
#define MIN(x, y) ((x) < (y) ? (x) : (y))
50
#endif
51
52
typedef struct {
53
char *str;
54
unsigned int val;
55
} hci_map;
56
57
static char *hci_bit2str(hci_map *m, unsigned int val)
58
{
59
char *str = malloc(120);
60
char *ptr = str;
61
62
if (!str)
63
return NULL;
64
65
*ptr = 0;
66
while (m->str) {
67
if ((unsigned int) m->val & val)
68
ptr += sprintf(ptr, "%s ", m->str);
69
m++;
70
}
71
return str;
72
}
73
74
static int hci_str2bit(hci_map *map, char *str, unsigned int *val)
75
{
76
char *t, *ptr;
77
hci_map *m;
78
int set;
79
80
if (!str || !(str = ptr = strdup(str)))
81
return 0;
82
83
*val = set = 0;
84
85
while ((t = strsep(&ptr, ","))) {
86
for (m = map; m->str; m++) {
87
if (!strcasecmp(m->str, t)) {
88
*val |= (unsigned int) m->val;
89
set = 1;
90
}
91
}
92
}
93
free(str);
94
95
return set;
96
}
97
98
static char *hci_uint2str(hci_map *m, unsigned int val)
99
{
100
char *str = malloc(50);
101
char *ptr = str;
102
103
if (!str)
104
return NULL;
105
106
*ptr = 0;
107
while (m->str) {
108
if ((unsigned int) m->val == val) {
109
ptr += sprintf(ptr, "%s", m->str);
110
break;
111
}
112
m++;
113
}
114
return str;
115
}
116
117
static int hci_str2uint(hci_map *map, char *str, unsigned int *val)
118
{
119
char *t, *ptr;
120
hci_map *m;
121
int set = 0;
122
123
if (!str)
124
return 0;
125
126
str = ptr = strdup(str);
127
128
while ((t = strsep(&ptr, ","))) {
129
for (m = map; m->str; m++) {
130
if (!strcasecmp(m->str,t)) {
131
*val = (unsigned int) m->val;
132
set = 1;
133
break;
134
}
135
}
136
}
137
free(str);
138
139
return set;
140
}
141
142
char *hci_bustostr(int bus)
143
{
144
switch (bus) {
145
case HCI_VIRTUAL:
146
return "VIRTUAL";
147
case HCI_USB:
148
return "USB";
149
case HCI_PCCARD:
150
return "PCCARD";
151
case HCI_UART:
152
return "UART";
153
case HCI_RS232:
154
return "RS232";
155
case HCI_PCI:
156
return "PCI";
157
case HCI_SDIO:
158
return "SDIO";
159
default:
160
return "UNKNOWN";
161
}
162
}
163
164
char *hci_dtypetostr(int type)
165
{
166
return hci_bustostr(type & 0x0f);
167
}
168
169
char *hci_typetostr(int type)
170
{
171
switch (type) {
172
case HCI_BREDR:
173
return "BR/EDR";
174
case HCI_AMP:
175
return "AMP";
176
default:
177
return "UNKNOWN";
178
}
179
}
180
181
/* HCI dev flags mapping */
182
static hci_map dev_flags_map[] = {
183
{ "UP", HCI_UP },
184
{ "INIT", HCI_INIT },
185
{ "RUNNING", HCI_RUNNING },
186
{ "RAW", HCI_RAW },
187
{ "PSCAN", HCI_PSCAN },
188
{ "ISCAN", HCI_ISCAN },
189
{ "INQUIRY", HCI_INQUIRY },
190
{ "AUTH", HCI_AUTH },
191
{ "ENCRYPT", HCI_ENCRYPT },
192
{ NULL }
193
};
194
195
char *hci_dflagstostr(uint32_t flags)
196
{
197
char *str = bt_malloc(50);
198
char *ptr = str;
199
hci_map *m = dev_flags_map;
200
201
if (!str)
202
return NULL;
203
204
*ptr = 0;
205
206
if (!hci_test_bit(HCI_UP, &flags))
207
ptr += sprintf(ptr, "DOWN ");
208
209
while (m->str) {
210
if (hci_test_bit(m->val, &flags))
211
ptr += sprintf(ptr, "%s ", m->str);
212
m++;
213
}
214
return str;
215
}
216
217
/* HCI packet type mapping */
218
static hci_map pkt_type_map[] = {
219
{ "DM1", HCI_DM1 },
220
{ "DM3", HCI_DM3 },
221
{ "DM5", HCI_DM5 },
222
{ "DH1", HCI_DH1 },
223
{ "DH3", HCI_DH3 },
224
{ "DH5", HCI_DH5 },
225
{ "HV1", HCI_HV1 },
226
{ "HV2", HCI_HV2 },
227
{ "HV3", HCI_HV3 },
228
{ "2-DH1", HCI_2DH1 },
229
{ "2-DH3", HCI_2DH3 },
230
{ "2-DH5", HCI_2DH5 },
231
{ "3-DH1", HCI_3DH1 },
232
{ "3-DH3", HCI_3DH3 },
233
{ "3-DH5", HCI_3DH5 },
234
{ NULL }
235
};
236
237
static hci_map sco_ptype_map[] = {
238
{ "HV1", 0x0001 },
239
{ "HV2", 0x0002 },
240
{ "HV3", 0x0004 },
241
{ "EV3", HCI_EV3 },
242
{ "EV4", HCI_EV4 },
243
{ "EV5", HCI_EV5 },
244
{ "2-EV3", HCI_2EV3 },
245
{ "2-EV5", HCI_2EV5 },
246
{ "3-EV3", HCI_3EV3 },
247
{ "3-EV5", HCI_3EV5 },
248
{ NULL }
249
};
250
251
char *hci_ptypetostr(unsigned int ptype)
252
{
253
return hci_bit2str(pkt_type_map, ptype);
254
}
255
256
int hci_strtoptype(char *str, unsigned int *val)
257
{
258
return hci_str2bit(pkt_type_map, str, val);
259
}
260
261
char *hci_scoptypetostr(unsigned int ptype)
262
{
263
return hci_bit2str(sco_ptype_map, ptype);
264
}
265
266
int hci_strtoscoptype(char *str, unsigned int *val)
267
{
268
return hci_str2bit(sco_ptype_map, str, val);
269
}
270
271
/* Link policy mapping */
272
static hci_map link_policy_map[] = {
273
{ "NONE", 0 },
274
{ "RSWITCH", HCI_LP_RSWITCH },
275
{ "HOLD", HCI_LP_HOLD },
276
{ "SNIFF", HCI_LP_SNIFF },
277
{ "PARK", HCI_LP_PARK },
278
{ NULL }
279
};
280
281
char *hci_lptostr(unsigned int lp)
282
{
283
return hci_bit2str(link_policy_map, lp);
284
}
285
286
int hci_strtolp(char *str, unsigned int *val)
287
{
288
return hci_str2bit(link_policy_map, str, val);
289
}
290
291
/* Link mode mapping */
292
static hci_map link_mode_map[] = {
293
{ "NONE", 0 },
294
{ "ACCEPT", HCI_LM_ACCEPT },
295
{ "MASTER", HCI_LM_MASTER },
296
{ "AUTH", HCI_LM_AUTH },
297
{ "ENCRYPT", HCI_LM_ENCRYPT },
298
{ "TRUSTED", HCI_LM_TRUSTED },
299
{ "RELIABLE", HCI_LM_RELIABLE },
300
{ "SECURE", HCI_LM_SECURE },
301
{ NULL }
302
};
303
304
char *hci_lmtostr(unsigned int lm)
305
{
306
char *s, *str = bt_malloc(50);
307
if (!str)
308
return NULL;
309
310
*str = 0;
311
if (!(lm & HCI_LM_MASTER))
312
strcpy(str, "SLAVE ");
313
314
s = hci_bit2str(link_mode_map, lm);
315
if (!s) {
316
bt_free(str);
317
return NULL;
318
}
319
320
strcat(str, s);
321
free(s);
322
return str;
323
}
324
325
int hci_strtolm(char *str, unsigned int *val)
326
{
327
return hci_str2bit(link_mode_map, str, val);
328
}
329
330
/* Command mapping */
331
static hci_map commands_map[] = {
332
{ "Inquiry", 0 },
333
{ "Inquiry Cancel", 1 },
334
{ "Periodic Inquiry Mode", 2 },
335
{ "Exit Periodic Inquiry Mode", 3 },
336
{ "Create Connection", 4 },
337
{ "Disconnect", 5 },
338
{ "Add SCO Connection", 6 },
339
{ "Cancel Create Connection", 7 },
340
341
{ "Accept Connection Request", 8 },
342
{ "Reject Connection Request", 9 },
343
{ "Link Key Request Reply", 10 },
344
{ "Link Key Request Negative Reply", 11 },
345
{ "PIN Code Request Reply", 12 },
346
{ "PIN Code Request Negative Reply", 13 },
347
{ "Change Connection Packet Type", 14 },
348
{ "Authentication Requested", 15 },
349
350
{ "Set Connection Encryption", 16 },
351
{ "Change Connection Link Key", 17 },
352
{ "Master Link Key", 18 },
353
{ "Remote Name Request", 19 },
354
{ "Cancel Remote Name Request", 20 },
355
{ "Read Remote Supported Features", 21 },
356
{ "Read Remote Extended Features", 22 },
357
{ "Read Remote Version Information", 23 },
358
359
{ "Read Clock Offset", 24 },
360
{ "Read LMP Handle", 25 },
361
{ "Reserved", 26 },
362
{ "Reserved", 27 },
363
{ "Reserved", 28 },
364
{ "Reserved", 29 },
365
{ "Reserved", 30 },
366
{ "Reserved", 31 },
367
368
{ "Reserved", 32 },
369
{ "Hold Mode", 33 },
370
{ "Sniff Mode", 34 },
371
{ "Exit Sniff Mode", 35 },
372
{ "Park State", 36 },
373
{ "Exit Park State", 37 },
374
{ "QoS Setup", 38 },
375
{ "Role Discovery", 39 },
376
377
{ "Switch Role", 40 },
378
{ "Read Link Policy Settings", 41 },
379
{ "Write Link Policy Settings", 42 },
380
{ "Read Default Link Policy Settings", 43 },
381
{ "Write Default Link Policy Settings", 44 },
382
{ "Flow Specification", 45 },
383
{ "Set Event Mask", 46 },
384
{ "Reset", 47 },
385
386
{ "Set Event Filter", 48 },
387
{ "Flush", 49 },
388
{ "Read PIN Type", 50 },
389
{ "Write PIN Type", 51 },
390
{ "Create New Unit Key", 52 },
391
{ "Read Stored Link Key", 53 },
392
{ "Write Stored Link Key", 54 },
393
{ "Delete Stored Link Key", 55 },
394
395
{ "Write Local Name", 56 },
396
{ "Read Local Name", 57 },
397
{ "Read Connection Accept Timeout", 58 },
398
{ "Write Connection Accept Timeout", 59 },
399
{ "Read Page Timeout", 60 },
400
{ "Write Page Timeout", 61 },
401
{ "Read Scan Enable", 62 },
402
{ "Write Scan Enable", 63 },
403
404
{ "Read Page Scan Activity", 64 },
405
{ "Write Page Scan Activity", 65 },
406
{ "Read Inquiry Scan Activity", 66 },
407
{ "Write Inquiry Scan Activity", 67 },
408
{ "Read Authentication Enable", 68 },
409
{ "Write Authentication Enable", 69 },
410
{ "Read Encryption Mode", 70 },
411
{ "Write Encryption Mode", 71 },
412
413
{ "Read Class Of Device", 72 },
414
{ "Write Class Of Device", 73 },
415
{ "Read Voice Setting", 74 },
416
{ "Write Voice Setting", 75 },
417
{ "Read Automatic Flush Timeout", 76 },
418
{ "Write Automatic Flush Timeout", 77 },
419
{ "Read Num Broadcast Retransmissions", 78 },
420
{ "Write Num Broadcast Retransmissions", 79 },
421
422
{ "Read Hold Mode Activity", 80 },
423
{ "Write Hold Mode Activity", 81 },
424
{ "Read Transmit Power Level", 82 },
425
{ "Read Synchronous Flow Control Enable", 83 },
426
{ "Write Synchronous Flow Control Enable", 84 },
427
{ "Set Host Controller To Host Flow Control", 85 },
428
{ "Host Buffer Size", 86 },
429
{ "Host Number Of Completed Packets", 87 },
430
431
{ "Read Link Supervision Timeout", 88 },
432
{ "Write Link Supervision Timeout", 89 },
433
{ "Read Number of Supported IAC", 90 },
434
{ "Read Current IAC LAP", 91 },
435
{ "Write Current IAC LAP", 92 },
436
{ "Read Page Scan Period Mode", 93 },
437
{ "Write Page Scan Period Mode", 94 },
438
{ "Read Page Scan Mode", 95 },
439
440
{ "Write Page Scan Mode", 96 },
441
{ "Set AFH Channel Classification", 97 },
442
{ "Reserved", 98 },
443
{ "Reserved", 99 },
444
{ "Read Inquiry Scan Type", 100 },
445
{ "Write Inquiry Scan Type", 101 },
446
{ "Read Inquiry Mode", 102 },
447
{ "Write Inquiry Mode", 103 },
448
449
{ "Read Page Scan Type", 104 },
450
{ "Write Page Scan Type", 105 },
451
{ "Read AFH Channel Assessment Mode", 106 },
452
{ "Write AFH Channel Assessment Mode", 107 },
453
{ "Reserved", 108 },
454
{ "Reserved", 109 },
455
{ "Reserved", 110 },
456
{ "Reserved", 111 },
457
458
{ "Reserved", 112 },
459
{ "Reserved", 113 },
460
{ "Reserved", 114 },
461
{ "Read Local Version Information", 115 },
462
{ "Read Local Supported Commands", 116 },
463
{ "Read Local Supported Features", 117 },
464
{ "Read Local Extended Features", 118 },
465
{ "Read Buffer Size", 119 },
466
467
{ "Read Country Code", 120 },
468
{ "Read BD ADDR", 121 },
469
{ "Read Failed Contact Counter", 122 },
470
{ "Reset Failed Contact Counter", 123 },
471
{ "Get Link Quality", 124 },
472
{ "Read RSSI", 125 },
473
{ "Read AFH Channel Map", 126 },
474
{ "Read BD Clock", 127 },
475
476
{ "Read Loopback Mode", 128 },
477
{ "Write Loopback Mode", 129 },
478
{ "Enable Device Under Test Mode", 130 },
479
{ "Setup Synchronous Connection", 131 },
480
{ "Accept Synchronous Connection", 132 },
481
{ "Reject Synchronous Connection", 133 },
482
{ "Reserved", 134 },
483
{ "Reserved", 135 },
484
485
{ "Read Extended Inquiry Response", 136 },
486
{ "Write Extended Inquiry Response", 137 },
487
{ "Refresh Encryption Key", 138 },
488
{ "Reserved", 139 },
489
{ "Sniff Subrating", 140 },
490
{ "Read Simple Pairing Mode", 141 },
491
{ "Write Simple Pairing Mode", 142 },
492
{ "Read Local OOB Data", 143 },
493
494
{ "Read Inquiry Response Transmit Power Level", 144 },
495
{ "Write Inquiry Transmit Power Level", 145 },
496
{ "Read Default Erroneous Data Reporting", 146 },
497
{ "Write Default Erroneous Data Reporting", 147 },
498
{ "Reserved", 148 },
499
{ "Reserved", 149 },
500
{ "Reserved", 150 },
501
{ "IO Capability Request Reply", 151 },
502
503
{ "User Confirmation Request Reply", 152 },
504
{ "User Confirmation Request Negative Reply", 153 },
505
{ "User Passkey Request Reply", 154 },
506
{ "User Passkey Request Negative Reply", 155 },
507
{ "Remote OOB Data Request Reply", 156 },
508
{ "Write Simple Pairing Debug Mode", 157 },
509
{ "Enhanced Flush", 158 },
510
{ "Remote OOB Data Request Negative Reply", 159 },
511
512
{ "Reserved", 160 },
513
{ "Reserved", 161 },
514
{ "Send Keypress Notification", 162 },
515
{ "IO Capability Request Negative Reply", 163 },
516
{ "Read Encryption Key Size", 164 },
517
{ "Reserved", 165 },
518
{ "Reserved", 166 },
519
{ "Reserved", 167 },
520
521
{ "Create Physical Link", 168 },
522
{ "Accept Physical Link", 169 },
523
{ "Disconnect Physical Link", 170 },
524
{ "Create Logical Link", 171 },
525
{ "Accept Logical Link", 172 },
526
{ "Disconnect Logical Link", 173 },
527
{ "Logical Link Cancel", 174 },
528
{ "Flow Specification Modify", 175 },
529
530
{ "Read Logical Link Accept Timeout", 176 },
531
{ "Write Logical Link Accept Timeout", 177 },
532
{ "Set Event Mask Page 2", 178 },
533
{ "Read Location Data", 179 },
534
{ "Write Location Data", 180 },
535
{ "Read Local AMP Info", 181 },
536
{ "Read Local AMP_ASSOC", 182 },
537
{ "Write Remote AMP_ASSOC", 183 },
538
539
{ "Read Flow Control Mode", 184 },
540
{ "Write Flow Control Mode", 185 },
541
{ "Read Data Block Size", 186 },
542
{ "Reserved", 187 },
543
{ "Reserved", 188 },
544
{ "Enable AMP Receiver Reports", 189 },
545
{ "AMP Test End", 190 },
546
{ "AMP Test Command", 191 },
547
548
{ "Read Enhanced Transmit Power Level", 192 },
549
{ "Reserved", 193 },
550
{ "Read Best Effort Flush Timeout", 194 },
551
{ "Write Best Effort Flush Timeout", 195 },
552
{ "Short Range Mode", 196 },
553
{ "Read LE Host Support", 197 },
554
{ "Write LE Host Support", 198 },
555
{ "Reserved", 199 },
556
557
{ "LE Set Event Mask", 200 },
558
{ "LE Read Buffer Size", 201 },
559
{ "LE Read Local Supported Features", 202 },
560
{ "Reserved", 203 },
561
{ "LE Set Random Address", 204 },
562
{ "LE Set Advertising Parameters", 205 },
563
{ "LE Read Advertising Channel TX Power", 206 },
564
{ "LE Set Advertising Data", 207 },
565
566
{ "LE Set Scan Response Data", 208 },
567
{ "LE Set Advertise Enable", 209 },
568
{ "LE Set Scan Parameters", 210 },
569
{ "LE Set Scan Enable", 211 },
570
{ "LE Create Connection", 212 },
571
{ "LE Create Connection Cancel", 213 },
572
{ "LE Read White List Size", 214 },
573
{ "LE Clear White List", 215 },
574
575
{ "LE Add Device To White List", 216 },
576
{ "LE Remove Device From White List", 217 },
577
{ "LE Connection Update", 218 },
578
{ "LE Set Host Channel Classification", 219 },
579
{ "LE Read Channel Map", 220 },
580
{ "LE Read Remote Used Features", 221 },
581
{ "LE Encrypt", 222 },
582
{ "LE Rand", 223 },
583
584
{ "LE Start Encryption", 224 },
585
{ "LE Long Term Key Request Reply", 225 },
586
{ "LE Long Term Key Request Negative Reply", 226 },
587
{ "LE Read Supported States", 227 },
588
{ "LE Receiver Test", 228 },
589
{ "LE Transmitter Test", 229 },
590
{ "LE Test End", 230 },
591
{ "Reserved", 231 },
592
593
{ NULL }
594
};
595
596
char *hci_cmdtostr(unsigned int cmd)
597
{
598
return hci_uint2str(commands_map, cmd);
599
}
600
601
char *hci_commandstostr(uint8_t *commands, char *pref, int width)
602
{
603
unsigned int maxwidth = width - 3;
604
hci_map *m;
605
char *off, *ptr, *str;
606
int size = 10;
607
608
m = commands_map;
609
610
while (m->str) {
611
if (commands[m->val / 8] & (1 << (m->val % 8)))
612
size += strlen(m->str) + (pref ? strlen(pref) : 0) + 3;
613
m++;
614
}
615
616
str = bt_malloc(size);
617
if (!str)
618
return NULL;
619
620
ptr = str; *ptr = '\0';
621
622
if (pref)
623
ptr += sprintf(ptr, "%s", pref);
624
625
off = ptr;
626
627
m = commands_map;
628
629
while (m->str) {
630
if (commands[m->val / 8] & (1 << (m->val % 8))) {
631
if (strlen(off) + strlen(m->str) > maxwidth) {
632
ptr += sprintf(ptr, "\n%s", pref ? pref : "");
633
off = ptr;
634
}
635
ptr += sprintf(ptr, "'%s' ", m->str);
636
}
637
m++;
638
}
639
640
return str;
641
}
642
643
/* Version mapping */
644
static hci_map ver_map[] = {
645
{ "1.0b", 0x00 },
646
{ "1.1", 0x01 },
647
{ "1.2", 0x02 },
648
{ "2.0", 0x03 },
649
{ "2.1", 0x04 },
650
{ "3.0", 0x05 },
651
{ "4.0", 0x06 },
652
{ NULL }
653
};
654
655
char *hci_vertostr(unsigned int ver)
656
{
657
return hci_uint2str(ver_map, ver);
658
}
659
660
int hci_strtover(char *str, unsigned int *ver)
661
{
662
return hci_str2uint(ver_map, str, ver);
663
}
664
665
char *lmp_vertostr(unsigned int ver)
666
{
667
return hci_uint2str(ver_map, ver);
668
}
669
670
int lmp_strtover(char *str, unsigned int *ver)
671
{
672
return hci_str2uint(ver_map, str, ver);
673
}
674
675
static hci_map pal_map[] = {
676
{ "3.0", 0x01 },
677
{ NULL }
678
};
679
680
char *pal_vertostr(unsigned int ver)
681
{
682
return hci_uint2str(pal_map, ver);
683
}
684
685
int pal_strtover(char *str, unsigned int *ver)
686
{
687
return hci_str2uint(pal_map, str, ver);
688
}
689
690
/* LMP features mapping */
691
static hci_map lmp_features_map[8][9] = {
692
{ /* Byte 0 */
693
{ "<3-slot packets>", LMP_3SLOT }, /* Bit 0 */
694
{ "<5-slot packets>", LMP_5SLOT }, /* Bit 1 */
695
{ "<encryption>", LMP_ENCRYPT }, /* Bit 2 */
696
{ "<slot offset>", LMP_SOFFSET }, /* Bit 3 */
697
{ "<timing accuracy>", LMP_TACCURACY }, /* Bit 4 */
698
{ "<role switch>", LMP_RSWITCH }, /* Bit 5 */
699
{ "<hold mode>", LMP_HOLD }, /* Bit 6 */
700
{ "<sniff mode>", LMP_SNIFF }, /* Bit 7 */
701
{ NULL }
702
},
703
{ /* Byte 1 */
704
{ "<park state>", LMP_PARK }, /* Bit 0 */
705
{ "<RSSI>", LMP_RSSI }, /* Bit 1 */
706
{ "<channel quality>", LMP_QUALITY }, /* Bit 2 */
707
{ "<SCO link>", LMP_SCO }, /* Bit 3 */
708
{ "<HV2 packets>", LMP_HV2 }, /* Bit 4 */
709
{ "<HV3 packets>", LMP_HV3 }, /* Bit 5 */
710
{ "<u-law log>", LMP_ULAW }, /* Bit 6 */
711
{ "<A-law log>", LMP_ALAW }, /* Bit 7 */
712
{ NULL }
713
},
714
{ /* Byte 2 */
715
{ "<CVSD>", LMP_CVSD }, /* Bit 0 */
716
{ "<paging scheme>", LMP_PSCHEME }, /* Bit 1 */
717
{ "<power control>", LMP_PCONTROL }, /* Bit 2 */
718
{ "<transparent SCO>", LMP_TRSP_SCO }, /* Bit 3 */
719
{ "<broadcast encrypt>",LMP_BCAST_ENC }, /* Bit 7 */
720
{ NULL }
721
},
722
{ /* Byte 3 */
723
{ "<no. 24>", 0x01 }, /* Bit 0 */
724
{ "<EDR ACL 2 Mbps>", LMP_EDR_ACL_2M }, /* Bit 1 */
725
{ "<EDR ACL 3 Mbps>", LMP_EDR_ACL_3M }, /* Bit 2 */
726
{ "<enhanced iscan>", LMP_ENH_ISCAN }, /* Bit 3 */
727
{ "<interlaced iscan>", LMP_ILACE_ISCAN }, /* Bit 4 */
728
{ "<interlaced pscan>", LMP_ILACE_PSCAN }, /* Bit 5 */
729
{ "<inquiry with RSSI>",LMP_RSSI_INQ }, /* Bit 6 */
730
{ "<extended SCO>", LMP_ESCO }, /* Bit 7 */
731
{ NULL }
732
},
733
{ /* Byte 4 */
734
{ "<EV4 packets>", LMP_EV4 }, /* Bit 0 */
735
{ "<EV5 packets>", LMP_EV5 }, /* Bit 1 */
736
{ "<no. 34>", 0x04 }, /* Bit 2 */
737
{ "<AFH cap. slave>", LMP_AFH_CAP_SLV }, /* Bit 3 */
738
{ "<AFH class. slave>", LMP_AFH_CLS_SLV }, /* Bit 4 */
739
{ "<BR/EDR not supp.>", LMP_NO_BREDR }, /* Bit 5 */
740
{ "<LE support>", LMP_LE }, /* Bit 6 */
741
{ "<3-slot EDR ACL>", LMP_EDR_3SLOT }, /* Bit 7 */
742
{ NULL }
743
},
744
{ /* Byte 5 */
745
{ "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */
746
{ "<sniff subrating>", LMP_SNIFF_SUBR }, /* Bit 1 */
747
{ "<pause encryption>", LMP_PAUSE_ENC }, /* Bit 2 */
748
{ "<AFH cap. master>", LMP_AFH_CAP_MST }, /* Bit 3 */
749
{ "<AFH class. master>",LMP_AFH_CLS_MST }, /* Bit 4 */
750
{ "<EDR eSCO 2 Mbps>", LMP_EDR_ESCO_2M }, /* Bit 5 */
751
{ "<EDR eSCO 3 Mbps>", LMP_EDR_ESCO_3M }, /* Bit 6 */
752
{ "<3-slot EDR eSCO>", LMP_EDR_3S_ESCO }, /* Bit 7 */
753
{ NULL }
754
},
755
{ /* Byte 6 */
756
{ "<extended inquiry>", LMP_EXT_INQ }, /* Bit 0 */
757
{ "<LE and BR/EDR>", LMP_LE_BREDR }, /* Bit 1 */
758
{ "<no. 50>", 0x04 }, /* Bit 2 */
759
{ "<simple pairing>", LMP_SIMPLE_PAIR }, /* Bit 3 */
760
{ "<encapsulated PDU>", LMP_ENCAPS_PDU }, /* Bit 4 */
761
{ "<err. data report>", LMP_ERR_DAT_REP }, /* Bit 5 */
762
{ "<non-flush flag>", LMP_NFLUSH_PKTS }, /* Bit 6 */
763
{ "<no. 55>", 0x80 }, /* Bit 7 */
764
{ NULL }
765
},
766
{ /* Byte 7 */
767
{ "<LSTO>", LMP_LSTO }, /* Bit 1 */
768
{ "<inquiry TX power>", LMP_INQ_TX_PWR }, /* Bit 1 */
769
{ "<EPC>", LMP_EPC }, /* Bit 2 */
770
{ "<no. 59>", 0x08 }, /* Bit 3 */
771
{ "<no. 60>", 0x10 }, /* Bit 4 */
772
{ "<no. 61>", 0x20 }, /* Bit 5 */
773
{ "<no. 62>", 0x40 }, /* Bit 6 */
774
{ "<extended features>",LMP_EXT_FEAT }, /* Bit 7 */
775
{ NULL }
776
},
777
};
778
779
char *lmp_featurestostr(uint8_t *features, char *pref, int width)
780
{
781
unsigned int maxwidth = width - 1;
782
char *off, *ptr, *str;
783
int i, size = 10;
784
785
for (i = 0; i < 8; i++) {
786
hci_map *m = lmp_features_map[i];
787
788
while (m->str) {
789
if (m->val & features[i])
790
size += strlen(m->str) +
791
(pref ? strlen(pref) : 0) + 1;
792
m++;
793
}
794
}
795
796
str = bt_malloc(size);
797
if (!str)
798
return NULL;
799
800
ptr = str; *ptr = '\0';
801
802
if (pref)
803
ptr += sprintf(ptr, "%s", pref);
804
805
off = ptr;
806
807
for (i = 0; i < 8; i++) {
808
hci_map *m = lmp_features_map[i];
809
810
while (m->str) {
811
if (m->val & features[i]) {
812
if (strlen(off) + strlen(m->str) > maxwidth) {
813
ptr += sprintf(ptr, "\n%s",
814
pref ? pref : "");
815
off = ptr;
816
}
817
ptr += sprintf(ptr, "%s ", m->str);
818
}
819
m++;
820
}
821
}
822
823
return str;
824
}
825
826
/* HCI functions that do not require open device */
827
int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg),
828
long arg)
829
{
830
struct hci_dev_list_req *dl;
831
struct hci_dev_req *dr;
832
int dev_id = -1;
833
int i, sk, err = 0;
834
835
sk = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);
836
if (sk < 0)
837
return -1;
838
839
dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));
840
if (!dl) {
841
err = errno;
842
goto done;
843
}
844
845
memset(dl, 0, HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));
846
847
dl->dev_num = HCI_MAX_DEV;
848
dr = dl->dev_req;
849
850
if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) {
851
err = errno;
852
goto free;
853
}
854
855
for (i = 0; i < dl->dev_num; i++, dr++) {
856
if (hci_test_bit(flag, &dr->dev_opt))
857
if (!func || func(sk, dr->dev_id, arg)) {
858
dev_id = dr->dev_id;
859
break;
860
}
861
}
862
863
if (dev_id < 0)
864
err = ENODEV;
865
866
free:
867
free(dl);
868
869
done:
870
close(sk);
871
errno = err;
872
873
return dev_id;
874
}
875
876
static int __other_bdaddr(int dd, int dev_id, long arg)
877
{
878
struct hci_dev_info di = { .dev_id = dev_id };
879
880
if (ioctl(dd, HCIGETDEVINFO, (void *) &di))
881
return 0;
882
883
if (hci_test_bit(HCI_RAW, &di.flags))
884
return 0;
885
886
return bacmp((bdaddr_t *) arg, &di.bdaddr);
887
}
888
889
static int __same_bdaddr(int dd, int dev_id, long arg)
890
{
891
struct hci_dev_info di = { .dev_id = dev_id };
892
893
if (ioctl(dd, HCIGETDEVINFO, (void *) &di))
894
return 0;
895
896
return !bacmp((bdaddr_t *) arg, &di.bdaddr);
897
}
898
899
int hci_get_route(bdaddr_t *bdaddr)
900
{
901
return hci_for_each_dev(HCI_UP, __other_bdaddr,
902
(long) (bdaddr ? bdaddr : BDADDR_ANY));
903
}
904
905
int hci_devid(const char *str)
906
{
907
bdaddr_t ba;
908
int id = -1;
909
910
if (!strncmp(str, "hci", 3) && strlen(str) >= 4) {
911
id = atoi(str + 3);
912
if (hci_devba(id, &ba) < 0)
913
return -1;
914
} else {
915
errno = ENODEV;
916
str2ba(str, &ba);
917
id = hci_for_each_dev(HCI_UP, __same_bdaddr, (long) &ba);
918
}
919
920
return id;
921
}
922
923
int hci_devinfo(int dev_id, struct hci_dev_info *di)
924
{
925
int dd, err, ret;
926
927
dd = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);
928
if (dd < 0)
929
return dd;
930
931
memset(di, 0, sizeof(struct hci_dev_info));
932
933
di->dev_id = dev_id;
934
ret = ioctl(dd, HCIGETDEVINFO, (void *) di);
935
936
err = errno;
937
close(dd);
938
errno = err;
939
940
return ret;
941
}
942
943
int hci_devba(int dev_id, bdaddr_t *bdaddr)
944
{
945
struct hci_dev_info di;
946
947
memset(&di, 0, sizeof(di));
948
949
if (hci_devinfo(dev_id, &di))
950
return -1;
951
952
if (!hci_test_bit(HCI_UP, &di.flags)) {
953
errno = ENETDOWN;
954
return -1;
955
}
956
957
bacpy(bdaddr, &di.bdaddr);
958
959
return 0;
960
}
961
962
int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap,
963
inquiry_info **ii, long flags)
964
{
965
struct hci_inquiry_req *ir;
966
uint8_t num_rsp = nrsp;
967
void *buf;
968
int dd, size, err, ret = -1;
969
970
if (nrsp <= 0) {
971
num_rsp = 0;
972
nrsp = 255;
973
}
974
975
if (dev_id < 0) {
976
dev_id = hci_get_route(NULL);
977
if (dev_id < 0) {
978
errno = ENODEV;
979
return -1;
980
}
981
}
982
983
dd = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);
984
if (dd < 0)
985
return dd;
986
987
buf = malloc(sizeof(*ir) + (sizeof(inquiry_info) * (nrsp)));
988
if (!buf)
989
goto done;
990
991
ir = buf;
992
ir->dev_id = dev_id;
993
ir->num_rsp = num_rsp;
994
ir->length = len;
995
ir->flags = flags;
996
997
if (lap) {
998
memcpy(ir->lap, lap, 3);
999
} else {
1000
ir->lap[0] = 0x33;
1001
ir->lap[1] = 0x8b;
1002
ir->lap[2] = 0x9e;
1003
}
1004
1005
ret = ioctl(dd, HCIINQUIRY, (unsigned long) buf);
1006
if (ret < 0)
1007
goto free;
1008
1009
size = sizeof(inquiry_info) * ir->num_rsp;
1010
1011
if (!*ii)
1012
*ii = malloc(size);
1013
1014
if (*ii) {
1015
memcpy((void *) *ii, buf + sizeof(*ir), size);
1016
ret = ir->num_rsp;
1017
} else
1018
ret = -1;
1019
1020
free:
1021
free(buf);
1022
1023
done:
1024
err = errno;
1025
close(dd);
1026
errno = err;
1027
1028
return ret;
1029
}
1030
1031
/* Open HCI device.
1032
* Returns device descriptor (dd). */
1033
int hci_open_dev(int dev_id)
1034
{
1035
struct sockaddr_hci a;
1036
int dd, err;
1037
1038
/* Create HCI socket */
1039
dd = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);
1040
if (dd < 0)
1041
return dd;
1042
1043
/* Bind socket to the HCI device */
1044
memset(&a, 0, sizeof(a));
1045
a.hci_family = AF_BLUETOOTH;
1046
a.hci_dev = dev_id;
1047
if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0)
1048
goto failed;
1049
1050
return dd;
1051
1052
failed:
1053
err = errno;
1054
close(dd);
1055
errno = err;
1056
1057
return -1;
1058
}
1059
1060
int hci_close_dev(int dd)
1061
{
1062
return close(dd);
1063
}
1064
1065
/* HCI functions that require open device
1066
* dd - Device descriptor returned by hci_open_dev. */
1067
1068
int hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param)
1069
{
1070
uint8_t type = HCI_COMMAND_PKT;
1071
hci_command_hdr hc;
1072
struct iovec iv[3];
1073
int ivn;
1074
1075
hc.opcode = htobs(cmd_opcode_pack(ogf, ocf));
1076
hc.plen= plen;
1077
1078
iv[0].iov_base = &type;
1079
iv[0].iov_len = 1;
1080
iv[1].iov_base = &hc;
1081
iv[1].iov_len = HCI_COMMAND_HDR_SIZE;
1082
ivn = 2;
1083
1084
if (plen) {
1085
iv[2].iov_base = param;
1086
iv[2].iov_len = plen;
1087
ivn = 3;
1088
}
1089
1090
while (writev(dd, iv, ivn) < 0) {
1091
if (errno == EAGAIN || errno == EINTR)
1092
continue;
1093
return -1;
1094
}
1095
return 0;
1096
}
1097
1098
int hci_send_req(int dd, struct hci_request *r, int to)
1099
{
1100
unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
1101
uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf));
1102
struct hci_filter nf, of;
1103
socklen_t olen;
1104
hci_event_hdr *hdr;
1105
int err, try;
1106
1107
olen = sizeof(of);
1108
if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &olen) < 0)
1109
return -1;
1110
1111
hci_filter_clear(&nf);
1112
hci_filter_set_ptype(HCI_EVENT_PKT, &nf);
1113
hci_filter_set_event(EVT_CMD_STATUS, &nf);
1114
hci_filter_set_event(EVT_CMD_COMPLETE, &nf);
1115
hci_filter_set_event(EVT_LE_META_EVENT, &nf);
1116
hci_filter_set_event(r->event, &nf);
1117
hci_filter_set_opcode(opcode, &nf);
1118
if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0)
1119
return -1;
1120
1121
if (hci_send_cmd(dd, r->ogf, r->ocf, r->clen, r->cparam) < 0)
1122
goto failed;
1123
1124
try = 10;
1125
while (try--) {
1126
evt_cmd_complete *cc;
1127
evt_cmd_status *cs;
1128
evt_remote_name_req_complete *rn;
1129
evt_le_meta_event *me;
1130
remote_name_req_cp *cp;
1131
int len;
1132
1133
if (to) {
1134
struct pollfd p;
1135
int n;
1136
1137
p.fd = dd; p.events = POLLIN;
1138
while ((n = poll(&p, 1, to)) < 0) {
1139
if (errno == EAGAIN || errno == EINTR)
1140
continue;
1141
goto failed;
1142
}
1143
1144
if (!n) {
1145
errno = ETIMEDOUT;
1146
goto failed;
1147
}
1148
1149
to -= 10;
1150
if (to < 0)
1151
to = 0;
1152
1153
}
1154
1155
while ((len = read(dd, buf, sizeof(buf))) < 0) {
1156
if (errno == EAGAIN || errno == EINTR)
1157
continue;
1158
goto failed;
1159
}
1160
1161
hdr = (void *) (buf + 1);
1162
ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
1163
len -= (1 + HCI_EVENT_HDR_SIZE);
1164
1165
switch (hdr->evt) {
1166
case EVT_CMD_STATUS:
1167
cs = (void *) ptr;
1168
1169
if (cs->opcode != opcode)
1170
continue;
1171
1172
if (r->event != EVT_CMD_STATUS) {
1173
if (cs->status) {
1174
errno = EIO;
1175
goto failed;
1176
}
1177
break;
1178
}
1179
1180
r->rlen = MIN(len, r->rlen);
1181
memcpy(r->rparam, ptr, r->rlen);
1182
goto done;
1183
1184
case EVT_CMD_COMPLETE:
1185
cc = (void *) ptr;
1186
1187
if (cc->opcode != opcode)
1188
continue;
1189
1190
ptr += EVT_CMD_COMPLETE_SIZE;
1191
len -= EVT_CMD_COMPLETE_SIZE;
1192
1193
r->rlen = MIN(len, r->rlen);
1194
memcpy(r->rparam, ptr, r->rlen);
1195
goto done;
1196
1197
case EVT_REMOTE_NAME_REQ_COMPLETE:
1198
if (hdr->evt != r->event)
1199
break;
1200
1201
rn = (void *) ptr;
1202
cp = r->cparam;
1203
1204
if (bacmp(&rn->bdaddr, &cp->bdaddr))
1205
continue;
1206
1207
r->rlen = MIN(len, r->rlen);
1208
memcpy(r->rparam, ptr, r->rlen);
1209
goto done;
1210
1211
case EVT_LE_META_EVENT:
1212
me = (void *) ptr;
1213
1214
if (me->subevent != r->event)
1215
continue;
1216
1217
len -= 1;
1218
r->rlen = MIN(len, r->rlen);
1219
memcpy(r->rparam, me->data, r->rlen);
1220
goto done;
1221
1222
default:
1223
if (hdr->evt != r->event)
1224
break;
1225
1226
r->rlen = MIN(len, r->rlen);
1227
memcpy(r->rparam, ptr, r->rlen);
1228
goto done;
1229
}
1230
}
1231
errno = ETIMEDOUT;
1232
1233
failed:
1234
err = errno;
1235
setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));
1236
errno = err;
1237
return -1;
1238
1239
done:
1240
setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));
1241
return 0;
1242
}
1243
1244
int hci_create_connection(int dd, const bdaddr_t *bdaddr, uint16_t ptype,
1245
uint16_t clkoffset, uint8_t rswitch,
1246
uint16_t *handle, int to)
1247
{
1248
evt_conn_complete rp;
1249
create_conn_cp cp;
1250
struct hci_request rq;
1251
1252
memset(&cp, 0, sizeof(cp));
1253
bacpy(&cp.bdaddr, bdaddr);
1254
cp.pkt_type = ptype;
1255
cp.pscan_rep_mode = 0x02;
1256
cp.clock_offset = clkoffset;
1257
cp.role_switch = rswitch;
1258
1259
memset(&rq, 0, sizeof(rq));
1260
rq.ogf = OGF_LINK_CTL;
1261
rq.ocf = OCF_CREATE_CONN;
1262
rq.event = EVT_CONN_COMPLETE;
1263
rq.cparam = &cp;
1264
rq.clen = CREATE_CONN_CP_SIZE;
1265
rq.rparam = &rp;
1266
rq.rlen = EVT_CONN_COMPLETE_SIZE;
1267
1268
if (hci_send_req(dd, &rq, to) < 0)
1269
return -1;
1270
1271
if (rp.status) {
1272
errno = EIO;
1273
return -1;
1274
}
1275
1276
*handle = rp.handle;
1277
return 0;
1278
}
1279
1280
int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to)
1281
{
1282
evt_disconn_complete rp;
1283
disconnect_cp cp;
1284
struct hci_request rq;
1285
1286
memset(&cp, 0, sizeof(cp));
1287
cp.handle = handle;
1288
cp.reason = reason;
1289
1290
memset(&rq, 0, sizeof(rq));
1291
rq.ogf = OGF_LINK_CTL;
1292
rq.ocf = OCF_DISCONNECT;
1293
rq.event = EVT_DISCONN_COMPLETE;
1294
rq.cparam = &cp;
1295
rq.clen = DISCONNECT_CP_SIZE;
1296
rq.rparam = &rp;
1297
rq.rlen = EVT_DISCONN_COMPLETE_SIZE;
1298
1299
if (hci_send_req(dd, &rq, to) < 0)
1300
return -1;
1301
1302
if (rp.status) {
1303
errno = EIO;
1304
return -1;
1305
}
1306
return 0;
1307
}
1308
1309
int hci_le_add_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to)
1310
{
1311
struct hci_request rq;
1312
le_add_device_to_white_list_cp cp;
1313
uint8_t status;
1314
1315
memset(&cp, 0, sizeof(cp));
1316
cp.bdaddr_type = type;
1317
bacpy(&cp.bdaddr, bdaddr);
1318
1319
memset(&rq, 0, sizeof(rq));
1320
rq.ogf = OGF_LE_CTL;
1321
rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
1322
rq.cparam = &cp;
1323
rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
1324
rq.rparam = &status;
1325
rq.rlen = 1;
1326
1327
if (hci_send_req(dd, &rq, to) < 0)
1328
return -1;
1329
1330
if (status) {
1331
errno = EIO;
1332
return -1;
1333
}
1334
1335
return 0;
1336
}
1337
1338
int hci_le_rm_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to)
1339
{
1340
struct hci_request rq;
1341
le_remove_device_from_white_list_cp cp;
1342
uint8_t status;
1343
1344
memset(&cp, 0, sizeof(cp));
1345
cp.bdaddr_type = type;
1346
bacpy(&cp.bdaddr, bdaddr);
1347
1348
memset(&rq, 0, sizeof(rq));
1349
rq.ogf = OGF_LE_CTL;
1350
rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
1351
rq.cparam = &cp;
1352
rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;
1353
rq.rparam = &status;
1354
rq.rlen = 1;
1355
1356
if (hci_send_req(dd, &rq, to) < 0)
1357
return -1;
1358
1359
if (status) {
1360
errno = EIO;
1361
return -1;
1362
}
1363
1364
return 0;
1365
}
1366
1367
int hci_le_read_white_list_size(int dd, uint8_t *size, int to)
1368
{
1369
struct hci_request rq;
1370
le_read_white_list_size_rp rp;
1371
1372
memset(&rp, 0, sizeof(rp));
1373
memset(&rq, 0, sizeof(rq));
1374
1375
rq.ogf = OGF_LE_CTL;
1376
rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
1377
rq.rparam = &rp;
1378
rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
1379
1380
if (hci_send_req(dd, &rq, to) < 0)
1381
return -1;
1382
1383
if (rp.status) {
1384
errno = EIO;
1385
return -1;
1386
}
1387
1388
if (size)
1389
*size = rp.size;
1390
1391
return 0;
1392
}
1393
1394
int hci_le_clear_white_list(int dd, int to)
1395
{
1396
struct hci_request rq;
1397
uint8_t status;
1398
1399
memset(&rq, 0, sizeof(rq));
1400
rq.ogf = OGF_LE_CTL;
1401
rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
1402
rq.rparam = &status;
1403
rq.rlen = 1;
1404
1405
if (hci_send_req(dd, &rq, to) < 0)
1406
return -1;
1407
1408
if (status) {
1409
errno = EIO;
1410
return -1;
1411
}
1412
1413
return 0;
1414
}
1415
1416
int hci_read_local_name(int dd, int len, char *name, int to)
1417
{
1418
read_local_name_rp rp;
1419
struct hci_request rq;
1420
1421
memset(&rq, 0, sizeof(rq));
1422
rq.ogf = OGF_HOST_CTL;
1423
rq.ocf = OCF_READ_LOCAL_NAME;
1424
rq.rparam = &rp;
1425
rq.rlen = READ_LOCAL_NAME_RP_SIZE;
1426
1427
if (hci_send_req(dd, &rq, to) < 0)
1428
return -1;
1429
1430
if (rp.status) {
1431
errno = EIO;
1432
return -1;
1433
}
1434
1435
rp.name[247] = '\0';
1436
strncpy(name, (char *) rp.name, len);
1437
return 0;
1438
}
1439
1440
int hci_write_local_name(int dd, const char *name, int to)
1441
{
1442
change_local_name_cp cp;
1443
struct hci_request rq;
1444
1445
memset(&cp, 0, sizeof(cp));
1446
strncpy((char *) cp.name, name, sizeof(cp.name));
1447
1448
memset(&rq, 0, sizeof(rq));
1449
rq.ogf = OGF_HOST_CTL;
1450
rq.ocf = OCF_CHANGE_LOCAL_NAME;
1451
rq.cparam = &cp;
1452
rq.clen = CHANGE_LOCAL_NAME_CP_SIZE;
1453
1454
if (hci_send_req(dd, &rq, to) < 0)
1455
return -1;
1456
1457
return 0;
1458
}
1459
1460
int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr,
1461
uint8_t pscan_rep_mode,
1462
uint16_t clkoffset,
1463
int len, char *name, int to)
1464
{
1465
evt_remote_name_req_complete rn;
1466
remote_name_req_cp cp;
1467
struct hci_request rq;
1468
1469
memset(&cp, 0, sizeof(cp));
1470
bacpy(&cp.bdaddr, bdaddr);
1471
cp.pscan_rep_mode = pscan_rep_mode;
1472
cp.clock_offset = clkoffset;
1473
1474
memset(&rq, 0, sizeof(rq));
1475
rq.ogf = OGF_LINK_CTL;
1476
rq.ocf = OCF_REMOTE_NAME_REQ;
1477
rq.cparam = &cp;
1478
rq.clen = REMOTE_NAME_REQ_CP_SIZE;
1479
rq.event = EVT_REMOTE_NAME_REQ_COMPLETE;
1480
rq.rparam = &rn;
1481
rq.rlen = EVT_REMOTE_NAME_REQ_COMPLETE_SIZE;
1482
1483
if (hci_send_req(dd, &rq, to) < 0)
1484
return -1;
1485
1486
if (rn.status) {
1487
errno = EIO;
1488
return -1;
1489
}
1490
1491
rn.name[247] = '\0';
1492
strncpy(name, (char *) rn.name, len);
1493
return 0;
1494
}
1495
1496
int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name,
1497
int to)
1498
{
1499
return hci_read_remote_name_with_clock_offset(dd, bdaddr, 0x02, 0x0000,
1500
len, name, to);
1501
}
1502
1503
int hci_read_remote_name_cancel(int dd, const bdaddr_t *bdaddr, int to)
1504
{
1505
remote_name_req_cancel_cp cp;
1506
struct hci_request rq;
1507
1508
memset(&cp, 0, sizeof(cp));
1509
bacpy(&cp.bdaddr, bdaddr);
1510
1511
memset(&rq, 0, sizeof(rq));
1512
rq.ogf = OGF_LINK_CTL;
1513
rq.ocf = OCF_REMOTE_NAME_REQ_CANCEL;
1514
rq.cparam = &cp;
1515
rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE;
1516
1517
if (hci_send_req(dd, &rq, to) < 0)
1518
return -1;
1519
1520
return 0;
1521
}
1522
1523
int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver,
1524
int to)
1525
{
1526
evt_read_remote_version_complete rp;
1527
read_remote_version_cp cp;
1528
struct hci_request rq;
1529
1530
memset(&cp, 0, sizeof(cp));
1531
cp.handle = handle;
1532
1533
memset(&rq, 0, sizeof(rq));
1534
rq.ogf = OGF_LINK_CTL;
1535
rq.ocf = OCF_READ_REMOTE_VERSION;
1536
rq.event = EVT_READ_REMOTE_VERSION_COMPLETE;
1537
rq.cparam = &cp;
1538
rq.clen = READ_REMOTE_VERSION_CP_SIZE;
1539
rq.rparam = &rp;
1540
rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE;
1541
1542
if (hci_send_req(dd, &rq, to) < 0)
1543
return -1;
1544
1545
if (rp.status) {
1546
errno = EIO;
1547
return -1;
1548
}
1549
1550
ver->manufacturer = btohs(rp.manufacturer);
1551
ver->lmp_ver = rp.lmp_ver;
1552
ver->lmp_subver = btohs(rp.lmp_subver);
1553
return 0;
1554
}
1555
1556
int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to)
1557
{
1558
evt_read_remote_features_complete rp;
1559
read_remote_features_cp cp;
1560
struct hci_request rq;
1561
1562
memset(&cp, 0, sizeof(cp));
1563
cp.handle = handle;
1564
1565
memset(&rq, 0, sizeof(rq));
1566
rq.ogf = OGF_LINK_CTL;
1567
rq.ocf = OCF_READ_REMOTE_FEATURES;
1568
rq.event = EVT_READ_REMOTE_FEATURES_COMPLETE;
1569
rq.cparam = &cp;
1570
rq.clen = READ_REMOTE_FEATURES_CP_SIZE;
1571
rq.rparam = &rp;
1572
rq.rlen = EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE;
1573
1574
if (hci_send_req(dd, &rq, to) < 0)
1575
return -1;
1576
1577
if (rp.status) {
1578
errno = EIO;
1579
return -1;
1580
}
1581
1582
if (features)
1583
memcpy(features, rp.features, 8);
1584
1585
return 0;
1586
}
1587
1588
int hci_read_remote_ext_features(int dd, uint16_t handle, uint8_t page,
1589
uint8_t *max_page, uint8_t *features,
1590
int to)
1591
{
1592
evt_read_remote_ext_features_complete rp;
1593
read_remote_ext_features_cp cp;
1594
struct hci_request rq;
1595
1596
memset(&cp, 0, sizeof(cp));
1597
cp.handle = handle;
1598
cp.page_num = page;
1599
1600
memset(&rq, 0, sizeof(rq));
1601
rq.ogf = OGF_LINK_CTL;
1602
rq.ocf = OCF_READ_REMOTE_EXT_FEATURES;
1603
rq.event = EVT_READ_REMOTE_EXT_FEATURES_COMPLETE;
1604
rq.cparam = &cp;
1605
rq.clen = READ_REMOTE_EXT_FEATURES_CP_SIZE;
1606
rq.rparam = &rp;
1607
rq.rlen = EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE;
1608
1609
if (hci_send_req(dd, &rq, to) < 0)
1610
return -1;
1611
1612
if (rp.status) {
1613
errno = EIO;
1614
return -1;
1615
}
1616
1617
if (max_page)
1618
*max_page = rp.max_page_num;
1619
1620
if (features)
1621
memcpy(features, rp.features, 8);
1622
1623
return 0;
1624
}
1625
1626
int hci_read_clock_offset(int dd, uint16_t handle, uint16_t *clkoffset, int to)
1627
{
1628
evt_read_clock_offset_complete rp;
1629
read_clock_offset_cp cp;
1630
struct hci_request rq;
1631
1632
memset(&cp, 0, sizeof(cp));
1633
cp.handle = handle;
1634
1635
memset(&rq, 0, sizeof(rq));
1636
rq.ogf = OGF_LINK_CTL;
1637
rq.ocf = OCF_READ_CLOCK_OFFSET;
1638
rq.event = EVT_READ_CLOCK_OFFSET_COMPLETE;
1639
rq.cparam = &cp;
1640
rq.clen = READ_CLOCK_OFFSET_CP_SIZE;
1641
rq.rparam = &rp;
1642
rq.rlen = EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE;
1643
1644
if (hci_send_req(dd, &rq, to) < 0)
1645
return -1;
1646
1647
if (rp.status) {
1648
errno = EIO;
1649
return -1;
1650
}
1651
1652
*clkoffset = rp.clock_offset;
1653
return 0;
1654
}
1655
1656
int hci_read_local_version(int dd, struct hci_version *ver, int to)
1657
{
1658
read_local_version_rp rp;
1659
struct hci_request rq;
1660
1661
memset(&rq, 0, sizeof(rq));
1662
rq.ogf = OGF_INFO_PARAM;
1663
rq.ocf = OCF_READ_LOCAL_VERSION;
1664
rq.rparam = &rp;
1665
rq.rlen = READ_LOCAL_VERSION_RP_SIZE;
1666
1667
if (hci_send_req(dd, &rq, to) < 0)
1668
return -1;
1669
1670
if (rp.status) {
1671
errno = EIO;
1672
return -1;
1673
}
1674
1675
ver->manufacturer = btohs(rp.manufacturer);
1676
ver->hci_ver = rp.hci_ver;
1677
ver->hci_rev = btohs(rp.hci_rev);
1678
ver->lmp_ver = rp.lmp_ver;
1679
ver->lmp_subver = btohs(rp.lmp_subver);
1680
return 0;
1681
}
1682
1683
int hci_read_local_commands(int dd, uint8_t *commands, int to)
1684
{
1685
read_local_commands_rp rp;
1686
struct hci_request rq;
1687
1688
memset(&rq, 0, sizeof(rq));
1689
rq.ogf = OGF_INFO_PARAM;
1690
rq.ocf = OCF_READ_LOCAL_COMMANDS;
1691
rq.rparam = &rp;
1692
rq.rlen = READ_LOCAL_COMMANDS_RP_SIZE;
1693
1694
if (hci_send_req(dd, &rq, to) < 0)
1695
return -1;
1696
1697
if (rp.status) {
1698
errno = EIO;
1699
return -1;
1700
}
1701
1702
if (commands)
1703
memcpy(commands, rp.commands, 64);
1704
1705
return 0;
1706
}
1707
1708
int hci_read_local_features(int dd, uint8_t *features, int to)
1709
{
1710
read_local_features_rp rp;
1711
struct hci_request rq;
1712
1713
memset(&rq, 0, sizeof(rq));
1714
rq.ogf = OGF_INFO_PARAM;
1715
rq.ocf = OCF_READ_LOCAL_FEATURES;
1716
rq.rparam = &rp;
1717
rq.rlen = READ_LOCAL_FEATURES_RP_SIZE;
1718
1719
if (hci_send_req(dd, &rq, to) < 0)
1720
return -1;
1721
1722
if (rp.status) {
1723
errno = EIO;
1724
return -1;
1725
}
1726
1727
if (features)
1728
memcpy(features, rp.features, 8);
1729
1730
return 0;
1731
}
1732
1733
int hci_read_local_ext_features(int dd, uint8_t page, uint8_t *max_page,
1734
uint8_t *features, int to)
1735
{
1736
read_local_ext_features_cp cp;
1737
read_local_ext_features_rp rp;
1738
struct hci_request rq;
1739
1740
cp.page_num = page;
1741
1742
memset(&rq, 0, sizeof(rq));
1743
rq.ogf = OGF_INFO_PARAM;
1744
rq.ocf = OCF_READ_LOCAL_EXT_FEATURES;
1745
rq.cparam = &cp;
1746
rq.clen = READ_LOCAL_EXT_FEATURES_CP_SIZE;
1747
rq.rparam = &rp;
1748
rq.rlen = READ_LOCAL_EXT_FEATURES_RP_SIZE;
1749
1750
if (hci_send_req(dd, &rq, to) < 0)
1751
return -1;
1752
1753
if (rp.status) {
1754
errno = EIO;
1755
return -1;
1756
}
1757
1758
if (max_page)
1759
*max_page = rp.max_page_num;
1760
1761
if (features)
1762
memcpy(features, rp.features, 8);
1763
1764
return 0;
1765
}
1766
1767
int hci_read_bd_addr(int dd, bdaddr_t *bdaddr, int to)
1768
{
1769
read_bd_addr_rp rp;
1770
struct hci_request rq;
1771
1772
memset(&rq, 0, sizeof(rq));
1773
rq.ogf = OGF_INFO_PARAM;
1774
rq.ocf = OCF_READ_BD_ADDR;
1775
rq.rparam = &rp;
1776
rq.rlen = READ_BD_ADDR_RP_SIZE;
1777
1778
if (hci_send_req(dd, &rq, to) < 0)
1779
return -1;
1780
1781
if (rp.status) {
1782
errno = EIO;
1783
return -1;
1784
}
1785
1786
if (bdaddr)
1787
bacpy(bdaddr, &rp.bdaddr);
1788
1789
return 0;
1790
}
1791
1792
int hci_read_class_of_dev(int dd, uint8_t *cls, int to)
1793
{
1794
read_class_of_dev_rp rp;
1795
struct hci_request rq;
1796
1797
memset(&rq, 0, sizeof(rq));
1798
rq.ogf = OGF_HOST_CTL;
1799
rq.ocf = OCF_READ_CLASS_OF_DEV;
1800
rq.rparam = &rp;
1801
rq.rlen = READ_CLASS_OF_DEV_RP_SIZE;
1802
1803
if (hci_send_req(dd, &rq, to) < 0)
1804
return -1;
1805
1806
if (rp.status) {
1807
errno = EIO;
1808
return -1;
1809
}
1810
1811
memcpy(cls, rp.dev_class, 3);
1812
return 0;
1813
}
1814
1815
int hci_write_class_of_dev(int dd, uint32_t cls, int to)
1816
{
1817
write_class_of_dev_cp cp;
1818
struct hci_request rq;
1819
1820
memset(&rq, 0, sizeof(rq));
1821
cp.dev_class[0] = cls & 0xff;
1822
cp.dev_class[1] = (cls >> 8) & 0xff;
1823
cp.dev_class[2] = (cls >> 16) & 0xff;
1824
rq.ogf = OGF_HOST_CTL;
1825
rq.ocf = OCF_WRITE_CLASS_OF_DEV;
1826
rq.cparam = &cp;
1827
rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE;
1828
return hci_send_req(dd, &rq, to);
1829
}
1830
1831
int hci_read_voice_setting(int dd, uint16_t *vs, int to)
1832
{
1833
read_voice_setting_rp rp;
1834
struct hci_request rq;
1835
1836
memset(&rq, 0, sizeof(rq));
1837
rq.ogf = OGF_HOST_CTL;
1838
rq.ocf = OCF_READ_VOICE_SETTING;
1839
rq.rparam = &rp;
1840
rq.rlen = READ_VOICE_SETTING_RP_SIZE;
1841
1842
if (hci_send_req(dd, &rq, to) < 0)
1843
return -1;
1844
1845
if (rp.status) {
1846
errno = EIO;
1847
return -1;
1848
}
1849
1850
*vs = rp.voice_setting;
1851
return 0;
1852
}
1853
1854
int hci_write_voice_setting(int dd, uint16_t vs, int to)
1855
{
1856
write_voice_setting_cp cp;
1857
struct hci_request rq;
1858
1859
memset(&rq, 0, sizeof(rq));
1860
cp.voice_setting = vs;
1861
rq.ogf = OGF_HOST_CTL;
1862
rq.ocf = OCF_WRITE_VOICE_SETTING;
1863
rq.cparam = &cp;
1864
rq.clen = WRITE_VOICE_SETTING_CP_SIZE;
1865
1866
return hci_send_req(dd, &rq, to);
1867
}
1868
1869
int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to)
1870
{
1871
read_current_iac_lap_rp rp;
1872
struct hci_request rq;
1873
1874
memset(&rq, 0, sizeof(rq));
1875
rq.ogf = OGF_HOST_CTL;
1876
rq.ocf = OCF_READ_CURRENT_IAC_LAP;
1877
rq.rparam = &rp;
1878
rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE;
1879
1880
if (hci_send_req(dd, &rq, to) < 0)
1881
return -1;
1882
1883
if (rp.status) {
1884
errno = EIO;
1885
return -1;
1886
}
1887
1888
*num_iac = rp.num_current_iac;
1889
memcpy(lap, rp.lap, rp.num_current_iac * 3);
1890
return 0;
1891
}
1892
1893
int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to)
1894
{
1895
write_current_iac_lap_cp cp;
1896
struct hci_request rq;
1897
1898
memset(&cp, 0, sizeof(cp));
1899
cp.num_current_iac = num_iac;
1900
memcpy(&cp.lap, lap, num_iac * 3);
1901
1902
memset(&rq, 0, sizeof(rq));
1903
rq.ogf = OGF_HOST_CTL;
1904
rq.ocf = OCF_WRITE_CURRENT_IAC_LAP;
1905
rq.cparam = &cp;
1906
rq.clen = num_iac * 3 + 1;
1907
1908
return hci_send_req(dd, &rq, to);
1909
}
1910
1911
int hci_read_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to)
1912
{
1913
read_stored_link_key_cp cp;
1914
struct hci_request rq;
1915
1916
memset(&cp, 0, sizeof(cp));
1917
bacpy(&cp.bdaddr, bdaddr);
1918
cp.read_all = all;
1919
1920
memset(&rq, 0, sizeof(rq));
1921
rq.ogf = OGF_HOST_CTL;
1922
rq.ocf = OCF_READ_STORED_LINK_KEY;
1923
rq.cparam = &cp;
1924
rq.clen = READ_STORED_LINK_KEY_CP_SIZE;
1925
1926
return hci_send_req(dd, &rq, to);
1927
}
1928
1929
int hci_write_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t *key, int to)
1930
{
1931
unsigned char cp[WRITE_STORED_LINK_KEY_CP_SIZE + 6 + 16];
1932
struct hci_request rq;
1933
1934
memset(&cp, 0, sizeof(cp));
1935
cp[0] = 1;
1936
bacpy((bdaddr_t *) (cp + 1), bdaddr);
1937
memcpy(cp + 7, key, 16);
1938
1939
memset(&rq, 0, sizeof(rq));
1940
rq.ogf = OGF_HOST_CTL;
1941
rq.ocf = OCF_WRITE_STORED_LINK_KEY;
1942
rq.cparam = &cp;
1943
rq.clen = WRITE_STORED_LINK_KEY_CP_SIZE + 6 + 16;
1944
1945
return hci_send_req(dd, &rq, to);
1946
}
1947
1948
int hci_delete_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to)
1949
{
1950
delete_stored_link_key_cp cp;
1951
struct hci_request rq;
1952
1953
memset(&cp, 0, sizeof(cp));
1954
bacpy(&cp.bdaddr, bdaddr);
1955
cp.delete_all = all;
1956
1957
memset(&rq, 0, sizeof(rq));
1958
rq.ogf = OGF_HOST_CTL;
1959
rq.ocf = OCF_DELETE_STORED_LINK_KEY;
1960
rq.cparam = &cp;
1961
rq.clen = DELETE_STORED_LINK_KEY_CP_SIZE;
1962
1963
return hci_send_req(dd, &rq, to);
1964
}
1965
1966
int hci_authenticate_link(int dd, uint16_t handle, int to)
1967
{
1968
auth_requested_cp cp;
1969
evt_auth_complete rp;
1970
struct hci_request rq;
1971
1972
cp.handle = handle;
1973
1974
rq.ogf = OGF_LINK_CTL;
1975
rq.ocf = OCF_AUTH_REQUESTED;
1976
rq.event = EVT_AUTH_COMPLETE;
1977
rq.cparam = &cp;
1978
rq.clen = AUTH_REQUESTED_CP_SIZE;
1979
rq.rparam = &rp;
1980
rq.rlen = EVT_AUTH_COMPLETE_SIZE;
1981
1982
if (hci_send_req(dd, &rq, to) < 0)
1983
return -1;
1984
1985
if (rp.status) {
1986
errno = EIO;
1987
return -1;
1988
}
1989
1990
return 0;
1991
}
1992
1993
int hci_encrypt_link(int dd, uint16_t handle, uint8_t encrypt, int to)
1994
{
1995
set_conn_encrypt_cp cp;
1996
evt_encrypt_change rp;
1997
struct hci_request rq;
1998
1999
cp.handle = handle;
2000
cp.encrypt = encrypt;
2001
2002
rq.ogf = OGF_LINK_CTL;
2003
rq.ocf = OCF_SET_CONN_ENCRYPT;
2004
rq.event = EVT_ENCRYPT_CHANGE;
2005
rq.cparam = &cp;
2006
rq.clen = SET_CONN_ENCRYPT_CP_SIZE;
2007
rq.rparam = &rp;
2008
rq.rlen = EVT_ENCRYPT_CHANGE_SIZE;
2009
2010
if (hci_send_req(dd, &rq, to) < 0)
2011
return -1;
2012
2013
if (rp.status) {
2014
errno = EIO;
2015
return -1;
2016
}
2017
2018
return 0;
2019
}
2020
2021
int hci_change_link_key(int dd, uint16_t handle, int to)
2022
{
2023
change_conn_link_key_cp cp;
2024
evt_change_conn_link_key_complete rp;
2025
struct hci_request rq;
2026
2027
cp.handle = handle;
2028
2029
rq.ogf = OGF_LINK_CTL;
2030
rq.ocf = OCF_CHANGE_CONN_LINK_KEY;
2031
rq.event = EVT_CHANGE_CONN_LINK_KEY_COMPLETE;
2032
rq.cparam = &cp;
2033
rq.clen = CHANGE_CONN_LINK_KEY_CP_SIZE;
2034
rq.rparam = &rp;
2035
rq.rlen = EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE;
2036
2037
if (hci_send_req(dd, &rq, to) < 0)
2038
return -1;
2039
2040
if (rp.status) {
2041
errno = EIO;
2042
return -1;
2043
}
2044
2045
return 0;
2046
}
2047
2048
int hci_switch_role(int dd, bdaddr_t *bdaddr, uint8_t role, int to)
2049
{
2050
switch_role_cp cp;
2051
evt_role_change rp;
2052
struct hci_request rq;
2053
2054
bacpy(&cp.bdaddr, bdaddr);
2055
cp.role = role;
2056
rq.ogf = OGF_LINK_POLICY;
2057
rq.ocf = OCF_SWITCH_ROLE;
2058
rq.cparam = &cp;
2059
rq.clen = SWITCH_ROLE_CP_SIZE;
2060
rq.rparam = &rp;
2061
rq.rlen = EVT_ROLE_CHANGE_SIZE;
2062
rq.event = EVT_ROLE_CHANGE;
2063
2064
if (hci_send_req(dd, &rq, to) < 0)
2065
return -1;
2066
2067
if (rp.status) {
2068
errno = EIO;
2069
return -1;
2070
}
2071
2072
return 0;
2073
}
2074
2075
int hci_park_mode(int dd, uint16_t handle, uint16_t max_interval,
2076
uint16_t min_interval, int to)
2077
{
2078
park_mode_cp cp;
2079
evt_mode_change rp;
2080
struct hci_request rq;
2081
2082
memset(&cp, 0, sizeof (cp));
2083
cp.handle = handle;
2084
cp.max_interval = max_interval;
2085
cp.min_interval = min_interval;
2086
2087
memset(&rq, 0, sizeof (rq));
2088
rq.ogf = OGF_LINK_POLICY;
2089
rq.ocf = OCF_PARK_MODE;
2090
rq.event = EVT_MODE_CHANGE;
2091
rq.cparam = &cp;
2092
rq.clen = PARK_MODE_CP_SIZE;
2093
rq.rparam = &rp;
2094
rq.rlen = EVT_MODE_CHANGE_SIZE;
2095
2096
if (hci_send_req(dd, &rq, to) < 0)
2097
return -1;
2098
2099
if (rp.status) {
2100
errno = EIO;
2101
return -1;
2102
}
2103
2104
return 0;
2105
}
2106
2107
int hci_exit_park_mode(int dd, uint16_t handle, int to)
2108
{
2109
exit_park_mode_cp cp;
2110
evt_mode_change rp;
2111
struct hci_request rq;
2112
2113
memset(&cp, 0, sizeof (cp));
2114
cp.handle = handle;
2115
2116
memset (&rq, 0, sizeof (rq));
2117
rq.ogf = OGF_LINK_POLICY;
2118
rq.ocf = OCF_EXIT_PARK_MODE;
2119
rq.event = EVT_MODE_CHANGE;
2120
rq.cparam = &cp;
2121
rq.clen = EXIT_PARK_MODE_CP_SIZE;
2122
rq.rparam = &rp;
2123
rq.rlen = EVT_MODE_CHANGE_SIZE;
2124
2125
if (hci_send_req(dd, &rq, to) < 0)
2126
return -1;
2127
2128
if (rp.status) {
2129
errno = EIO;
2130
return -1;
2131
}
2132
2133
return 0;
2134
}
2135
2136
int hci_read_inquiry_scan_type(int dd, uint8_t *type, int to)
2137
{
2138
read_inquiry_scan_type_rp rp;
2139
struct hci_request rq;
2140
2141
memset(&rq, 0, sizeof(rq));
2142
rq.ogf = OGF_HOST_CTL;
2143
rq.ocf = OCF_READ_INQUIRY_SCAN_TYPE;
2144
rq.rparam = &rp;
2145
rq.rlen = READ_INQUIRY_SCAN_TYPE_RP_SIZE;
2146
2147
if (hci_send_req(dd, &rq, to) < 0)
2148
return -1;
2149
2150
if (rp.status) {
2151
errno = EIO;
2152
return -1;
2153
}
2154
2155
*type = rp.type;
2156
return 0;
2157
}
2158
2159
int hci_write_inquiry_scan_type(int dd, uint8_t type, int to)
2160
{
2161
write_inquiry_scan_type_cp cp;
2162
write_inquiry_scan_type_rp rp;
2163
struct hci_request rq;
2164
2165
memset(&cp, 0, sizeof(cp));
2166
cp.type = type;
2167
2168
memset(&rq, 0, sizeof(rq));
2169
rq.ogf = OGF_HOST_CTL;
2170
rq.ocf = OCF_WRITE_INQUIRY_SCAN_TYPE;
2171
rq.cparam = &cp;
2172
rq.clen = WRITE_INQUIRY_SCAN_TYPE_CP_SIZE;
2173
rq.rparam = &rp;
2174
rq.rlen = WRITE_INQUIRY_SCAN_TYPE_RP_SIZE;
2175
2176
if (hci_send_req(dd, &rq, to) < 0)
2177
return -1;
2178
2179
if (rp.status) {
2180
errno = EIO;
2181
return -1;
2182
}
2183
2184
return 0;
2185
}
2186
2187
int hci_read_inquiry_mode(int dd, uint8_t *mode, int to)
2188
{
2189
read_inquiry_mode_rp rp;
2190
struct hci_request rq;
2191
2192
memset(&rq, 0, sizeof(rq));
2193
rq.ogf = OGF_HOST_CTL;
2194
rq.ocf = OCF_READ_INQUIRY_MODE;
2195
rq.rparam = &rp;
2196
rq.rlen = READ_INQUIRY_MODE_RP_SIZE;
2197
2198
if (hci_send_req(dd, &rq, to) < 0)
2199
return -1;
2200
2201
if (rp.status) {
2202
errno = EIO;
2203
return -1;
2204
}
2205
2206
*mode = rp.mode;
2207
return 0;
2208
}
2209
2210
int hci_write_inquiry_mode(int dd, uint8_t mode, int to)
2211
{
2212
write_inquiry_mode_cp cp;
2213
write_inquiry_mode_rp rp;
2214
struct hci_request rq;
2215
2216
memset(&cp, 0, sizeof(cp));
2217
cp.mode = mode;
2218
2219
memset(&rq, 0, sizeof(rq));
2220
rq.ogf = OGF_HOST_CTL;
2221
rq.ocf = OCF_WRITE_INQUIRY_MODE;
2222
rq.cparam = &cp;
2223
rq.clen = WRITE_INQUIRY_MODE_CP_SIZE;
2224
rq.rparam = &rp;
2225
rq.rlen = WRITE_INQUIRY_MODE_RP_SIZE;
2226
2227
if (hci_send_req(dd, &rq, to) < 0)
2228
return -1;
2229
2230
if (rp.status) {
2231
errno = EIO;
2232
return -1;
2233
}
2234
2235
return 0;
2236
}
2237
2238
int hci_read_afh_mode(int dd, uint8_t *mode, int to)
2239
{
2240
read_afh_mode_rp rp;
2241
struct hci_request rq;
2242
2243
memset(&rq, 0, sizeof(rq));
2244
rq.ogf = OGF_HOST_CTL;
2245
rq.ocf = OCF_READ_AFH_MODE;
2246
rq.rparam = &rp;
2247
rq.rlen = READ_AFH_MODE_RP_SIZE;
2248
2249
if (hci_send_req(dd, &rq, to) < 0)
2250
return -1;
2251
2252
if (rp.status) {
2253
errno = EIO;
2254
return -1;
2255
}
2256
2257
*mode = rp.mode;
2258
return 0;
2259
}
2260
2261
int hci_write_afh_mode(int dd, uint8_t mode, int to)
2262
{
2263
write_afh_mode_cp cp;
2264
write_afh_mode_rp rp;
2265
struct hci_request rq;
2266
2267
memset(&cp, 0, sizeof(cp));
2268
cp.mode = mode;
2269
2270
memset(&rq, 0, sizeof(rq));
2271
rq.ogf = OGF_HOST_CTL;
2272
rq.ocf = OCF_WRITE_AFH_MODE;
2273
rq.cparam = &cp;
2274
rq.clen = WRITE_AFH_MODE_CP_SIZE;
2275
rq.rparam = &rp;
2276
rq.rlen = WRITE_AFH_MODE_RP_SIZE;
2277
2278
if (hci_send_req(dd, &rq, to) < 0)
2279
return -1;
2280
2281
if (rp.status) {
2282
errno = EIO;
2283
return -1;
2284
}
2285
2286
return 0;
2287
}
2288
2289
int hci_read_ext_inquiry_response(int dd, uint8_t *fec, uint8_t *data, int to)
2290
{
2291
read_ext_inquiry_response_rp rp;
2292
struct hci_request rq;
2293
2294
memset(&rq, 0, sizeof(rq));
2295
rq.ogf = OGF_HOST_CTL;
2296
rq.ocf = OCF_READ_EXT_INQUIRY_RESPONSE;
2297
rq.rparam = &rp;
2298
rq.rlen = READ_EXT_INQUIRY_RESPONSE_RP_SIZE;
2299
2300
if (hci_send_req(dd, &rq, to) < 0)
2301
return -1;
2302
2303
if (rp.status) {
2304
errno = EIO;
2305
return -1;
2306
}
2307
2308
*fec = rp.fec;
2309
memcpy(data, rp.data, HCI_MAX_EIR_LENGTH);
2310
2311
return 0;
2312
}
2313
2314
int hci_write_ext_inquiry_response(int dd, uint8_t fec, uint8_t *data, int to)
2315
{
2316
write_ext_inquiry_response_cp cp;
2317
write_ext_inquiry_response_rp rp;
2318
struct hci_request rq;
2319
2320
memset(&cp, 0, sizeof(cp));
2321
cp.fec = fec;
2322
memcpy(cp.data, data, HCI_MAX_EIR_LENGTH);
2323
2324
memset(&rq, 0, sizeof(rq));
2325
rq.ogf = OGF_HOST_CTL;
2326
rq.ocf = OCF_WRITE_EXT_INQUIRY_RESPONSE;
2327
rq.cparam = &cp;
2328
rq.clen = WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE;
2329
rq.rparam = &rp;
2330
rq.rlen = WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE;
2331
2332
if (hci_send_req(dd, &rq, to) < 0)
2333
return -1;
2334
2335
if (rp.status) {
2336
errno = EIO;
2337
return -1;
2338
}
2339
2340
return 0;
2341
}
2342
2343
int hci_read_simple_pairing_mode(int dd, uint8_t *mode, int to)
2344
{
2345
read_simple_pairing_mode_rp rp;
2346
struct hci_request rq;
2347
2348
memset(&rq, 0, sizeof(rq));
2349
rq.ogf = OGF_HOST_CTL;
2350
rq.ocf = OCF_READ_SIMPLE_PAIRING_MODE;
2351
rq.rparam = &rp;
2352
rq.rlen = READ_SIMPLE_PAIRING_MODE_RP_SIZE;
2353
2354
if (hci_send_req(dd, &rq, to) < 0)
2355
return -1;
2356
2357
if (rp.status) {
2358
errno = EIO;
2359
return -1;
2360
}
2361
2362
*mode = rp.mode;
2363
return 0;
2364
}
2365
2366
int hci_write_simple_pairing_mode(int dd, uint8_t mode, int to)
2367
{
2368
write_simple_pairing_mode_cp cp;
2369
write_simple_pairing_mode_rp rp;
2370
struct hci_request rq;
2371
2372
memset(&cp, 0, sizeof(cp));
2373
cp.mode = mode;
2374
2375
memset(&rq, 0, sizeof(rq));
2376
rq.ogf = OGF_HOST_CTL;
2377
rq.ocf = OCF_WRITE_SIMPLE_PAIRING_MODE;
2378
rq.cparam = &cp;
2379
rq.clen = WRITE_SIMPLE_PAIRING_MODE_CP_SIZE;
2380
rq.rparam = &rp;
2381
rq.rlen = WRITE_SIMPLE_PAIRING_MODE_RP_SIZE;
2382
2383
if (hci_send_req(dd, &rq, to) < 0)
2384
return -1;
2385
2386
if (rp.status) {
2387
errno = EIO;
2388
return -1;
2389
}
2390
2391
return 0;
2392
}
2393
2394
int hci_read_local_oob_data(int dd, uint8_t *hash, uint8_t *randomizer, int to)
2395
{
2396
read_local_oob_data_rp rp;
2397
struct hci_request rq;
2398
2399
memset(&rq, 0, sizeof(rq));
2400
rq.ogf = OGF_HOST_CTL;
2401
rq.ocf = OCF_READ_LOCAL_OOB_DATA;
2402
rq.rparam = &rp;
2403
rq.rlen = READ_LOCAL_OOB_DATA_RP_SIZE;
2404
2405
if (hci_send_req(dd, &rq, to) < 0)
2406
return -1;
2407
2408
if (rp.status) {
2409
errno = EIO;
2410
return -1;
2411
}
2412
2413
memcpy(hash, rp.hash, 16);
2414
memcpy(randomizer, rp.randomizer, 16);
2415
return 0;
2416
}
2417
2418
int hci_read_inq_response_tx_power_level(int dd, int8_t *level, int to)
2419
{
2420
read_inq_response_tx_power_level_rp rp;
2421
struct hci_request rq;
2422
2423
memset(&rq, 0, sizeof(rq));
2424
rq.ogf = OGF_HOST_CTL;
2425
rq.ocf = OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL;
2426
rq.rparam = &rp;
2427
rq.rlen = READ_INQ_RESPONSE_TX_POWER_LEVEL_RP_SIZE;
2428
2429
if (hci_send_req(dd, &rq, to) < 0)
2430
return -1;
2431
2432
if (rp.status) {
2433
errno = EIO;
2434
return -1;
2435
}
2436
2437
*level = rp.level;
2438
return 0;
2439
}
2440
2441
int hci_read_inquiry_transmit_power_level(int dd, int8_t *level, int to)
2442
{
2443
return hci_read_inq_response_tx_power_level(dd, level, to);
2444
}
2445
2446
int hci_write_inquiry_transmit_power_level(int dd, int8_t level, int to)
2447
{
2448
write_inquiry_transmit_power_level_cp cp;
2449
write_inquiry_transmit_power_level_rp rp;
2450
struct hci_request rq;
2451
2452
memset(&cp, 0, sizeof(cp));
2453
cp.level = level;
2454
2455
memset(&rq, 0, sizeof(rq));
2456
rq.ogf = OGF_HOST_CTL;
2457
rq.ocf = OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL;
2458
rq.cparam = &cp;
2459
rq.clen = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_CP_SIZE;
2460
rq.rparam = &rp;
2461
rq.rlen = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE;
2462
2463
if (hci_send_req(dd, &rq, to) < 0)
2464
return -1;
2465
2466
if (rp.status) {
2467
errno = EIO;
2468
return -1;
2469
}
2470
2471
return 0;
2472
}
2473
2474
int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type,
2475
int8_t *level, int to)
2476
{
2477
read_transmit_power_level_cp cp;
2478
read_transmit_power_level_rp rp;
2479
struct hci_request rq;
2480
2481
memset(&cp, 0, sizeof(cp));
2482
cp.handle = handle;
2483
cp.type = type;
2484
2485
memset(&rq, 0, sizeof(rq));
2486
rq.ogf = OGF_HOST_CTL;
2487
rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL;
2488
rq.cparam = &cp;
2489
rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE;
2490
rq.rparam = &rp;
2491
rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE;
2492
2493
if (hci_send_req(dd, &rq, to) < 0)
2494
return -1;
2495
2496
if (rp.status) {
2497
errno = EIO;
2498
return -1;
2499
}
2500
2501
*level = rp.level;
2502
return 0;
2503
}
2504
2505
int hci_read_link_policy(int dd, uint16_t handle, uint16_t *policy, int to)
2506
{
2507
read_link_policy_rp rp;
2508
struct hci_request rq;
2509
2510
memset(&rq, 0, sizeof(rq));
2511
rq.ogf = OGF_LINK_POLICY;
2512
rq.ocf = OCF_READ_LINK_POLICY;
2513
rq.cparam = &handle;
2514
rq.clen = 2;
2515
rq.rparam = &rp;
2516
rq.rlen = READ_LINK_POLICY_RP_SIZE;
2517
2518
if (hci_send_req(dd, &rq, to) < 0)
2519
return -1;
2520
2521
if (rp.status) {
2522
errno = EIO;
2523
return -1;
2524
}
2525
2526
*policy = rp.policy;
2527
return 0;
2528
}
2529
2530
int hci_write_link_policy(int dd, uint16_t handle, uint16_t policy, int to)
2531
{
2532
write_link_policy_cp cp;
2533
write_link_policy_rp rp;
2534
struct hci_request rq;
2535
2536
memset(&cp, 0, sizeof(cp));
2537
cp.handle = handle;
2538
cp.policy = policy;
2539
2540
memset(&rq, 0, sizeof(rq));
2541
rq.ogf = OGF_LINK_POLICY;
2542
rq.ocf = OCF_WRITE_LINK_POLICY;
2543
rq.cparam = &cp;
2544
rq.clen = WRITE_LINK_POLICY_CP_SIZE;
2545
rq.rparam = &rp;
2546
rq.rlen = WRITE_LINK_POLICY_RP_SIZE;
2547
2548
if (hci_send_req(dd, &rq, to) < 0)
2549
return -1;
2550
2551
if (rp.status) {
2552
errno = EIO;
2553
return -1;
2554
}
2555
2556
return 0;
2557
}
2558
2559
int hci_read_link_supervision_timeout(int dd, uint16_t handle,
2560
uint16_t *timeout, int to)
2561
{
2562
read_link_supervision_timeout_rp rp;
2563
struct hci_request rq;
2564
2565
memset(&rq, 0, sizeof(rq));
2566
rq.ogf = OGF_HOST_CTL;
2567
rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT;
2568
rq.cparam = &handle;
2569
rq.clen = 2;
2570
rq.rparam = &rp;
2571
rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE;
2572
2573
if (hci_send_req(dd, &rq, to) < 0)
2574
return -1;
2575
2576
if (rp.status) {
2577
errno = EIO;
2578
return -1;
2579
}
2580
2581
*timeout = rp.timeout;
2582
return 0;
2583
}
2584
2585
int hci_write_link_supervision_timeout(int dd, uint16_t handle,
2586
uint16_t timeout, int to)
2587
{
2588
write_link_supervision_timeout_cp cp;
2589
write_link_supervision_timeout_rp rp;
2590
struct hci_request rq;
2591
2592
memset(&cp, 0, sizeof(cp));
2593
cp.handle = handle;
2594
cp.timeout = timeout;
2595
2596
memset(&rq, 0, sizeof(rq));
2597
rq.ogf = OGF_HOST_CTL;
2598
rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT;
2599
rq.cparam = &cp;
2600
rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE;
2601
rq.rparam = &rp;
2602
rq.rlen = WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE;
2603
2604
if (hci_send_req(dd, &rq, to) < 0)
2605
return -1;
2606
2607
if (rp.status) {
2608
errno = EIO;
2609
return -1;
2610
}
2611
2612
return 0;
2613
}
2614
2615
int hci_set_afh_classification(int dd, uint8_t *map, int to)
2616
{
2617
set_afh_classification_cp cp;
2618
set_afh_classification_rp rp;
2619
struct hci_request rq;
2620
2621
memset(&cp, 0, sizeof(cp));
2622
memcpy(cp.map, map, 10);
2623
2624
memset(&rq, 0, sizeof(rq));
2625
rq.ogf = OGF_HOST_CTL;
2626
rq.ocf = OCF_SET_AFH_CLASSIFICATION;
2627
rq.cparam = &cp;
2628
rq.clen = SET_AFH_CLASSIFICATION_CP_SIZE;
2629
rq.rparam = &rp;
2630
rq.rlen = SET_AFH_CLASSIFICATION_RP_SIZE;
2631
2632
if (hci_send_req(dd, &rq, to) < 0)
2633
return -1;
2634
2635
if (rp.status) {
2636
errno = EIO;
2637
return -1;
2638
}
2639
2640
return 0;
2641
}
2642
2643
int hci_read_link_quality(int dd, uint16_t handle, uint8_t *link_quality,
2644
int to)
2645
{
2646
read_link_quality_rp rp;
2647
struct hci_request rq;
2648
2649
memset(&rq, 0, sizeof(rq));
2650
rq.ogf = OGF_STATUS_PARAM;
2651
rq.ocf = OCF_READ_LINK_QUALITY;
2652
rq.cparam = &handle;
2653
rq.clen = 2;
2654
rq.rparam = &rp;
2655
rq.rlen = READ_LINK_QUALITY_RP_SIZE;
2656
2657
if (hci_send_req(dd, &rq, to) < 0)
2658
return -1;
2659
2660
if (rp.status) {
2661
errno = EIO;
2662
return -1;
2663
}
2664
2665
*link_quality = rp.link_quality;
2666
return 0;
2667
}
2668
2669
int hci_read_rssi(int dd, uint16_t handle, int8_t *rssi, int to)
2670
{
2671
read_rssi_rp rp;
2672
struct hci_request rq;
2673
2674
memset(&rq, 0, sizeof(rq));
2675
rq.ogf = OGF_STATUS_PARAM;
2676
rq.ocf = OCF_READ_RSSI;
2677
rq.cparam = &handle;
2678
rq.clen = 2;
2679
rq.rparam = &rp;
2680
rq.rlen = READ_RSSI_RP_SIZE;
2681
2682
if (hci_send_req(dd, &rq, to) < 0)
2683
return -1;
2684
2685
if (rp.status) {
2686
errno = EIO;
2687
return -1;
2688
}
2689
2690
*rssi = rp.rssi;
2691
return 0;
2692
}
2693
2694
int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map,
2695
int to)
2696
{
2697
read_afh_map_rp rp;
2698
struct hci_request rq;
2699
2700
memset(&rq, 0, sizeof(rq));
2701
rq.ogf = OGF_STATUS_PARAM;
2702
rq.ocf = OCF_READ_AFH_MAP;
2703
rq.cparam = &handle;
2704
rq.clen = 2;
2705
rq.rparam = &rp;
2706
rq.rlen = READ_AFH_MAP_RP_SIZE;
2707
2708
if (hci_send_req(dd, &rq, to) < 0)
2709
return -1;
2710
2711
if (rp.status) {
2712
errno = EIO;
2713
return -1;
2714
}
2715
2716
*mode = rp.mode;
2717
memcpy(map, rp.map, 10);
2718
return 0;
2719
}
2720
2721
int hci_read_clock(int dd, uint16_t handle, uint8_t which, uint32_t *clock,
2722
uint16_t *accuracy, int to)
2723
{
2724
read_clock_cp cp;
2725
read_clock_rp rp;
2726
struct hci_request rq;
2727
2728
memset(&cp, 0, sizeof(cp));
2729
cp.handle = handle;
2730
cp.which_clock = which;
2731
2732
memset(&rq, 0, sizeof(rq));
2733
rq.ogf = OGF_STATUS_PARAM;
2734
rq.ocf = OCF_READ_CLOCK;
2735
rq.cparam = &cp;
2736
rq.clen = READ_CLOCK_CP_SIZE;
2737
rq.rparam = &rp;
2738
rq.rlen = READ_CLOCK_RP_SIZE;
2739
2740
if (hci_send_req(dd, &rq, to) < 0)
2741
return -1;
2742
2743
if (rp.status) {
2744
errno = EIO;
2745
return -1;
2746
}
2747
2748
*clock = rp.clock;
2749
*accuracy = rp.accuracy;
2750
return 0;
2751
}
2752
2753
int hci_le_set_scan_enable(int dd, uint8_t enable, uint8_t filter_dup, int to)
2754
{
2755
struct hci_request rq;
2756
le_set_scan_enable_cp scan_cp;
2757
uint8_t status;
2758
2759
memset(&scan_cp, 0, sizeof(scan_cp));
2760
scan_cp.enable = enable;
2761
scan_cp.filter_dup = filter_dup;
2762
2763
memset(&rq, 0, sizeof(rq));
2764
rq.ogf = OGF_LE_CTL;
2765
rq.ocf = OCF_LE_SET_SCAN_ENABLE;
2766
rq.cparam = &scan_cp;
2767
rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE;
2768
rq.rparam = &status;
2769
rq.rlen = 1;
2770
2771
if (hci_send_req(dd, &rq, to) < 0)
2772
return -1;
2773
2774
if (status) {
2775
errno = EIO;
2776
return -1;
2777
}
2778
2779
return 0;
2780
}
2781
2782
int hci_le_set_scan_parameters(int dd, uint8_t type,
2783
uint16_t interval, uint16_t window,
2784
uint8_t own_type, uint8_t filter, int to)
2785
{
2786
struct hci_request rq;
2787
le_set_scan_parameters_cp param_cp;
2788
uint8_t status;
2789
2790
memset(&param_cp, 0, sizeof(param_cp));
2791
param_cp.type = type;
2792
param_cp.interval = interval;
2793
param_cp.window = window;
2794
param_cp.own_bdaddr_type = own_type;
2795
param_cp.filter = filter;
2796
2797
memset(&rq, 0, sizeof(rq));
2798
rq.ogf = OGF_LE_CTL;
2799
rq.ocf = OCF_LE_SET_SCAN_PARAMETERS;
2800
rq.cparam = &param_cp;
2801
rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE;
2802
rq.rparam = &status;
2803
rq.rlen = 1;
2804
2805
if (hci_send_req(dd, &rq, to) < 0)
2806
return -1;
2807
2808
if (status) {
2809
errno = EIO;
2810
return -1;
2811
}
2812
2813
return 0;
2814
}
2815
2816
int hci_le_set_advertise_enable(int dd, uint8_t enable, int to)
2817
{
2818
struct hci_request rq;
2819
le_set_advertise_enable_cp adv_cp;
2820
uint8_t status;
2821
2822
memset(&adv_cp, 0, sizeof(adv_cp));
2823
adv_cp.enable = enable;
2824
2825
memset(&rq, 0, sizeof(rq));
2826
rq.ogf = OGF_LE_CTL;
2827
rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
2828
rq.cparam = &adv_cp;
2829
rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
2830
rq.rparam = &status;
2831
rq.rlen = 1;
2832
2833
if (hci_send_req(dd, &rq, to) < 0)
2834
return -1;
2835
2836
if (status) {
2837
errno = EIO;
2838
return -1;
2839
}
2840
2841
return 0;
2842
}
2843
2844
int hci_le_create_conn(int dd, uint16_t interval, uint16_t window,
2845
uint8_t initiator_filter, uint8_t peer_bdaddr_type,
2846
bdaddr_t peer_bdaddr, uint8_t own_bdaddr_type,
2847
uint16_t min_interval, uint16_t max_interval,
2848
uint16_t latency, uint16_t supervision_timeout,
2849
uint16_t min_ce_length, uint16_t max_ce_length,
2850
uint16_t *handle, int to)
2851
{
2852
struct hci_request rq;
2853
le_create_connection_cp create_conn_cp;
2854
evt_le_connection_complete conn_complete_rp;
2855
2856
memset(&create_conn_cp, 0, sizeof(create_conn_cp));
2857
create_conn_cp.interval = interval;
2858
create_conn_cp.window = window;
2859
create_conn_cp.initiator_filter = initiator_filter;
2860
create_conn_cp.peer_bdaddr_type = peer_bdaddr_type;
2861
create_conn_cp.peer_bdaddr = peer_bdaddr;
2862
create_conn_cp.own_bdaddr_type = own_bdaddr_type;
2863
create_conn_cp.min_interval = min_interval;
2864
create_conn_cp.max_interval = max_interval;
2865
create_conn_cp.latency = latency;
2866
create_conn_cp.supervision_timeout = supervision_timeout;
2867
create_conn_cp.min_ce_length = min_ce_length;
2868
create_conn_cp.max_ce_length = max_ce_length;
2869
2870
memset(&rq, 0, sizeof(rq));
2871
rq.ogf = OGF_LE_CTL;
2872
rq.ocf = OCF_LE_CREATE_CONN;
2873
rq.event = EVT_LE_CONN_COMPLETE;
2874
rq.cparam = &create_conn_cp;
2875
rq.clen = LE_CREATE_CONN_CP_SIZE;
2876
rq.rparam = &conn_complete_rp;
2877
rq.rlen = EVT_CONN_COMPLETE_SIZE;
2878
2879
if (hci_send_req(dd, &rq, to) < 0)
2880
return -1;
2881
2882
if (conn_complete_rp.status) {
2883
errno = EIO;
2884
return -1;
2885
}
2886
2887
if (handle)
2888
*handle = conn_complete_rp.handle;
2889
2890
return 0;
2891
}
2892
2893
int hci_le_conn_update(int dd, uint16_t handle, uint16_t min_interval,
2894
uint16_t max_interval, uint16_t latency,
2895
uint16_t supervision_timeout, int to)
2896
{
2897
evt_le_connection_update_complete evt;
2898
le_connection_update_cp cp;
2899
struct hci_request rq;
2900
2901
memset(&cp, 0, sizeof(cp));
2902
cp.handle = handle;
2903
cp.min_interval = min_interval;
2904
cp.max_interval = max_interval;
2905
cp.latency = latency;
2906
cp.supervision_timeout = supervision_timeout;
2907
cp.min_ce_length = htobs(0x0001);
2908
cp.max_ce_length = htobs(0x0001);
2909
2910
memset(&rq, 0, sizeof(rq));
2911
rq.ogf = OGF_LE_CTL;
2912
rq.ocf = OCF_LE_CONN_UPDATE;
2913
rq.cparam = &cp;
2914
rq.clen = LE_CONN_UPDATE_CP_SIZE;
2915
rq.event = EVT_LE_CONN_UPDATE_COMPLETE;
2916
rq.rparam = &evt;
2917
rq.rlen = sizeof(evt);
2918
2919
if (hci_send_req(dd, &rq, to) < 0)
2920
return -1;
2921
2922
if (evt.status) {
2923
errno = EIO;
2924
return -1;
2925
}
2926
2927
return 0;
2928
}
2929
2930