Coverage Report

Created: 2023-09-25 06:17

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