Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c
105644 views
1
/*-
2
* host_controller_baseband.c
3
*
4
* SPDX-License-Identifier: BSD-2-Clause
5
*
6
* Copyright (c) 2001-2002 Maksim Yevmenkin <[email protected]>
7
* All rights reserved.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
*
18
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
* SUCH DAMAGE.
29
*
30
* $Id: host_controller_baseband.c,v 1.4 2003/08/18 19:19:53 max Exp $
31
*/
32
33
#define L2CAP_SOCKET_CHECKED
34
#include <bluetooth.h>
35
#include <errno.h>
36
#include <stdio.h>
37
#include <string.h>
38
#include "hccontrol.h"
39
40
/* Convert hex ASCII to int4 */
41
static int
42
hci_hexa2int4(const char *a)
43
{
44
if ('0' <= *a && *a <= '9')
45
return (*a - '0');
46
47
if ('A' <= *a && *a <= 'F')
48
return (*a - 'A' + 0xa);
49
50
if ('a' <= *a && *a <= 'f')
51
return (*a - 'a' + 0xa);
52
53
return (-1);
54
}
55
56
/* Convert hex ASCII to int8 */
57
static int
58
hci_hexa2int8(const char *a)
59
{
60
int hi = hci_hexa2int4(a);
61
int lo = hci_hexa2int4(a + 1);
62
63
if (hi < 0 || lo < 0)
64
return (-1);
65
66
return ((hi << 4) | lo);
67
}
68
69
/* Convert ascii hex string to the uint8_t[] */
70
static int
71
hci_hexstring2array(char const *s, uint8_t *a, int asize)
72
{
73
int i, l, b;
74
75
l = strlen(s) / 2;
76
if (l > asize)
77
l = asize;
78
79
for (i = 0; i < l; i++) {
80
b = hci_hexa2int8(s + i * 2);
81
if (b < 0)
82
return (-1);
83
84
a[i] = (b & 0xff);
85
}
86
87
return (0);
88
}
89
90
/* Send RESET to the unit */
91
static int
92
hci_reset(int s, int argc, char **argv)
93
{
94
ng_hci_status_rp rp;
95
int n;
96
97
n = sizeof(rp);
98
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
99
NG_HCI_OCF_RESET), (char *) &rp, &n) == ERROR)
100
return (ERROR);
101
102
if (rp.status != 0x00) {
103
fprintf(stdout, "Status: %s [%#02x]\n",
104
hci_status2str(rp.status), rp.status);
105
return (FAILED);
106
}
107
108
return (OK);
109
} /* hci_reset */
110
111
/* Send Read_PIN_Type command to the unit */
112
static int
113
hci_read_pin_type(int s, int argc, char **argv)
114
{
115
ng_hci_read_pin_type_rp rp;
116
int n;
117
118
n = sizeof(rp);
119
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
120
NG_HCI_OCF_READ_PIN_TYPE),
121
(char *) &rp, &n) == ERROR)
122
return (ERROR);
123
124
if (rp.status != 0x00) {
125
fprintf(stdout, "Status: %s [%#02x]\n",
126
hci_status2str(rp.status), rp.status);
127
return (FAILED);
128
}
129
130
fprintf(stdout, "PIN type: %s [%#02x]\n",
131
hci_pin2str(rp.pin_type), rp.pin_type);
132
133
return (OK);
134
} /* hci_read_pin_type */
135
136
/* Send Write_PIN_Type command to the unit */
137
static int
138
hci_write_pin_type(int s, int argc, char **argv)
139
{
140
ng_hci_write_pin_type_cp cp;
141
ng_hci_write_pin_type_rp rp;
142
int n;
143
144
/* parse command parameters */
145
switch (argc) {
146
case 1:
147
if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)
148
return (USAGE);
149
150
cp.pin_type = (uint8_t) n;
151
break;
152
153
default:
154
return (USAGE);
155
}
156
157
/* send command */
158
n = sizeof(rp);
159
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
160
NG_HCI_OCF_WRITE_PIN_TYPE),
161
(char const *) &cp, sizeof(cp),
162
(char *) &rp , &n) == ERROR)
163
return (ERROR);
164
165
if (rp.status != 0x00) {
166
fprintf(stdout, "Status: %s [%#02x]\n",
167
hci_status2str(rp.status), rp.status);
168
return (FAILED);
169
}
170
171
return (OK);
172
} /* hci_write_pin_type */
173
174
/* Send Read_Stored_Link_Key command to the unit */
175
static int
176
hci_read_stored_link_key(int s, int argc, char **argv)
177
{
178
struct {
179
ng_hci_cmd_pkt_t hdr;
180
ng_hci_read_stored_link_key_cp cp;
181
} __attribute__ ((packed)) cmd;
182
183
struct {
184
ng_hci_event_pkt_t hdr;
185
union {
186
ng_hci_command_compl_ep cc;
187
ng_hci_return_link_keys_ep key;
188
uint8_t b[NG_HCI_EVENT_PKT_SIZE];
189
} ep;
190
} __attribute__ ((packed)) event;
191
192
int n, n1;
193
194
/* Send command */
195
memset(&cmd, 0, sizeof(cmd));
196
cmd.hdr.type = NG_HCI_CMD_PKT;
197
cmd.hdr.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
198
NG_HCI_OCF_READ_STORED_LINK_KEY));
199
cmd.hdr.length = sizeof(cmd.cp);
200
201
switch (argc) {
202
case 1:
203
/* parse BD_ADDR */
204
if (!bt_aton(argv[0], &cmd.cp.bdaddr)) {
205
struct hostent *he = NULL;
206
207
if ((he = bt_gethostbyname(argv[0])) == NULL)
208
return (USAGE);
209
210
memcpy(&cmd.cp.bdaddr, he->h_addr, sizeof(cmd.cp.bdaddr));
211
}
212
break;
213
214
default:
215
cmd.cp.read_all = 1;
216
break;
217
}
218
219
if (hci_send(s, (char const *) &cmd, sizeof(cmd)) != OK)
220
return (ERROR);
221
222
/* Receive events */
223
again:
224
memset(&event, 0, sizeof(event));
225
n = sizeof(event);
226
if (hci_recv(s, (char *) &event, &n) != OK)
227
return (ERROR);
228
229
if (n <= sizeof(event.hdr)) {
230
errno = EMSGSIZE;
231
return (ERROR);
232
}
233
234
if (event.hdr.type != NG_HCI_EVENT_PKT) {
235
errno = EIO;
236
return (ERROR);
237
}
238
239
/* Parse event */
240
switch (event.hdr.event) {
241
case NG_HCI_EVENT_COMMAND_COMPL: {
242
ng_hci_read_stored_link_key_rp *rp = NULL;
243
244
if (event.ep.cc.opcode == 0x0000 ||
245
event.ep.cc.opcode != cmd.hdr.opcode)
246
goto again;
247
248
rp = (ng_hci_read_stored_link_key_rp *)(event.ep.b +
249
sizeof(event.ep.cc));
250
251
fprintf(stdout, "Complete: Status: %s [%#x]\n",
252
hci_status2str(rp->status), rp->status);
253
fprintf(stdout, "Maximum Number of keys: %d\n",
254
le16toh(rp->max_num_keys));
255
fprintf(stdout, "Number of keys read: %d\n",
256
le16toh(rp->num_keys_read));
257
} break;
258
259
case NG_HCI_EVENT_RETURN_LINK_KEYS: {
260
struct _key {
261
bdaddr_t bdaddr;
262
uint8_t key[NG_HCI_KEY_SIZE];
263
} __attribute__ ((packed)) *k = NULL;
264
265
fprintf(stdout, "Event: Number of keys: %d\n",
266
event.ep.key.num_keys);
267
268
k = (struct _key *)(event.ep.b + sizeof(event.ep.key));
269
for (n = 0; n < event.ep.key.num_keys; n++) {
270
fprintf(stdout, "\t%d: %s ",
271
n + 1, hci_bdaddr2str(&k->bdaddr));
272
273
for (n1 = 0; n1 < sizeof(k->key); n1++)
274
fprintf(stdout, "%02x", k->key[n1]);
275
fprintf(stdout, "\n");
276
277
k ++;
278
}
279
280
goto again;
281
282
} break;
283
284
default:
285
goto again;
286
}
287
288
return (OK);
289
} /* hci_read_store_link_key */
290
291
/* Send Write_Stored_Link_Key command to the unit */
292
static int
293
hci_write_stored_link_key(int s, int argc, char **argv)
294
{
295
struct {
296
ng_hci_write_stored_link_key_cp p;
297
bdaddr_t bdaddr;
298
uint8_t key[NG_HCI_KEY_SIZE];
299
} cp;
300
ng_hci_write_stored_link_key_rp rp;
301
int32_t n;
302
303
memset(&cp, 0, sizeof(cp));
304
305
switch (argc) {
306
case 2:
307
cp.p.num_keys_write = 1;
308
309
/* parse BD_ADDR */
310
if (!bt_aton(argv[0], &cp.bdaddr)) {
311
struct hostent *he = NULL;
312
313
if ((he = bt_gethostbyname(argv[0])) == NULL)
314
return (USAGE);
315
316
memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
317
}
318
319
/* parse key */
320
if (hci_hexstring2array(argv[1], cp.key, sizeof(cp.key)) < 0)
321
return (USAGE);
322
break;
323
324
default:
325
return (USAGE);
326
}
327
328
/* send command */
329
n = sizeof(rp);
330
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
331
NG_HCI_OCF_WRITE_STORED_LINK_KEY),
332
(char const *) &cp, sizeof(cp),
333
(char *) &rp, &n) == ERROR)
334
return (ERROR);
335
336
if (rp.status != 0x00) {
337
fprintf(stdout, "Status: %s [%#02x]\n",
338
hci_status2str(rp.status), rp.status);
339
return (FAILED);
340
}
341
342
fprintf(stdout, "Number of keys written: %d\n", rp.num_keys_written);
343
344
return (OK);
345
} /* hci_write_stored_link_key */
346
347
348
/* Send Delete_Stored_Link_Key command to the unit */
349
static int
350
hci_delete_stored_link_key(int s, int argc, char **argv)
351
{
352
ng_hci_delete_stored_link_key_cp cp;
353
ng_hci_delete_stored_link_key_rp rp;
354
int32_t n;
355
356
memset(&cp, 0, sizeof(cp));
357
358
switch (argc) {
359
case 1:
360
/* parse BD_ADDR */
361
if (!bt_aton(argv[0], &cp.bdaddr)) {
362
struct hostent *he = NULL;
363
364
if ((he = bt_gethostbyname(argv[0])) == NULL)
365
return (USAGE);
366
367
memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
368
}
369
break;
370
371
default:
372
cp.delete_all = 1;
373
break;
374
}
375
376
/* send command */
377
n = sizeof(cp);
378
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
379
NG_HCI_OCF_DELETE_STORED_LINK_KEY),
380
(char const *) &cp, sizeof(cp),
381
(char *) &rp, &n) == ERROR)
382
return (ERROR);
383
384
if (rp.status != 0x00) {
385
fprintf(stdout, "Status: %s [%#02x]\n",
386
hci_status2str(rp.status), rp.status);
387
return (FAILED);
388
}
389
390
fprintf(stdout, "Number of keys deleted: %d\n", rp.num_keys_deleted);
391
392
return (OK);
393
} /* hci_delete_stored_link_key */
394
395
/* Send Change_Local_Name command to the unit */
396
static int
397
hci_change_local_name(int s, int argc, char **argv)
398
{
399
ng_hci_change_local_name_cp cp;
400
ng_hci_change_local_name_rp rp;
401
int n;
402
403
/* parse command parameters */
404
switch (argc) {
405
case 1:
406
snprintf(cp.name, sizeof(cp.name), "%s", argv[0]);
407
break;
408
409
default:
410
return (USAGE);
411
}
412
413
/* send command */
414
n = sizeof(rp);
415
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
416
NG_HCI_OCF_CHANGE_LOCAL_NAME),
417
(char const *) &cp, sizeof(cp),
418
(char *) &rp, &n) == ERROR)
419
return (ERROR);
420
421
if (rp.status != 0x00) {
422
fprintf(stdout, "Status: %s [%#02x]\n",
423
hci_status2str(rp.status), rp.status);
424
return (FAILED);
425
}
426
427
return (OK);
428
} /* hci_change_local_name */
429
430
/* Send Read_Local_Name command to the unit */
431
static int
432
hci_read_local_name(int s, int argc, char **argv)
433
{
434
ng_hci_read_local_name_rp rp;
435
int n;
436
437
n = sizeof(rp);
438
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
439
NG_HCI_OCF_READ_LOCAL_NAME),
440
(char *) &rp, &n) == ERROR)
441
return (ERROR);
442
443
if (rp.status != 0x00) {
444
fprintf(stdout, "Status: %s [%#02x]\n",
445
hci_status2str(rp.status), rp.status);
446
return (FAILED);
447
}
448
449
fprintf(stdout, "Local name: %s\n", rp.name);
450
451
return (OK);
452
} /* hci_read_local_name */
453
454
/* Send Read_Connection_Accept_Timeout to the unit */
455
static int
456
hci_read_connection_accept_timeout(int s, int argc, char **argv)
457
{
458
ng_hci_read_con_accept_timo_rp rp;
459
int n;
460
461
n = sizeof(rp);
462
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
463
NG_HCI_OCF_READ_CON_ACCEPT_TIMO),
464
(char *) &rp, &n) == ERROR)
465
return (ERROR);
466
467
if (rp.status != 0x00) {
468
fprintf(stdout, "Status: %s [%#02x]\n",
469
hci_status2str(rp.status), rp.status);
470
return (FAILED);
471
}
472
473
rp.timeout = le16toh(rp.timeout);
474
fprintf(stdout, "Connection accept timeout: %.2f msec [%d slots]\n",
475
rp.timeout * 0.625, rp.timeout);
476
477
return (OK);
478
} /* hci_read_connection_accept_timeout */
479
480
/* Send Write_Connection_Accept_Timeout to the unit */
481
static int
482
hci_write_connection_accept_timeout(int s, int argc, char **argv)
483
{
484
ng_hci_write_con_accept_timo_cp cp;
485
ng_hci_write_con_accept_timo_rp rp;
486
int n;
487
488
/* parse command parameters */
489
switch (argc) {
490
case 1:
491
if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xb540)
492
return (USAGE);
493
494
cp.timeout = (uint16_t) n;
495
cp.timeout = htole16(cp.timeout);
496
break;
497
498
default:
499
return (USAGE);
500
}
501
502
/* send command */
503
n = sizeof(rp);
504
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
505
NG_HCI_OCF_WRITE_CON_ACCEPT_TIMO),
506
(char const *) &cp, sizeof(cp),
507
(char *) &rp, &n) == ERROR)
508
return (ERROR);
509
510
if (rp.status != 0x00) {
511
fprintf(stdout, "Status: %s [%#02x]\n",
512
hci_status2str(rp.status), rp.status);
513
return (FAILED);
514
}
515
516
return (OK);
517
} /* hci_write_connection_accept_timeout */
518
519
/* Send Read_Page_Timeout command to the unit */
520
static int
521
hci_read_page_timeout(int s, int argc, char **argv)
522
{
523
ng_hci_read_page_timo_rp rp;
524
int n;
525
526
n = sizeof(rp);
527
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
528
NG_HCI_OCF_READ_PAGE_TIMO),
529
(char *) &rp, &n) == ERROR)
530
return (ERROR);
531
532
if (rp.status != 0x00) {
533
fprintf(stdout, "Status: %s [%#02x]\n",
534
hci_status2str(rp.status), rp.status);
535
return (FAILED);
536
}
537
538
rp.timeout = le16toh(rp.timeout);
539
fprintf(stdout, "Page timeout: %.2f msec [%d slots]\n",
540
rp.timeout * 0.625, rp.timeout);
541
542
return (OK);
543
} /* hci_read_page_timeoout */
544
545
/* Send Write_Page_Timeout command to the unit */
546
static int
547
hci_write_page_timeout(int s, int argc, char **argv)
548
{
549
ng_hci_write_page_timo_cp cp;
550
ng_hci_write_page_timo_rp rp;
551
int n;
552
553
/* parse command parameters */
554
switch (argc) {
555
case 1:
556
if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xffff)
557
return (USAGE);
558
559
cp.timeout = (uint16_t) n;
560
cp.timeout = htole16(cp.timeout);
561
break;
562
563
default:
564
return (USAGE);
565
}
566
567
/* send command */
568
n = sizeof(rp);
569
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
570
NG_HCI_OCF_WRITE_PAGE_TIMO),
571
(char const *) &cp, sizeof(cp),
572
(char *) &rp, &n) == ERROR)
573
return (ERROR);
574
575
if (rp.status != 0x00) {
576
fprintf(stdout, "Status: %s [%#02x]\n",
577
hci_status2str(rp.status), rp.status);
578
return (FAILED);
579
}
580
581
return (OK);
582
} /* hci_write_page_timeout */
583
584
/* Send Read_Scan_Enable command to the unit */
585
static int
586
hci_read_scan_enable(int s, int argc, char **argv)
587
{
588
ng_hci_read_scan_enable_rp rp;
589
int n;
590
591
n = sizeof(rp);
592
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
593
NG_HCI_OCF_READ_SCAN_ENABLE),
594
(char *) &rp, &n) == ERROR)
595
return (ERROR);
596
597
if (rp.status != 0x00) {
598
fprintf(stdout, "Status: %s [%#02x]\n",
599
hci_status2str(rp.status), rp.status);
600
return (FAILED);
601
}
602
603
fprintf(stdout, "Scan enable: %s [%#02x]\n",
604
hci_scan2str(rp.scan_enable), rp.scan_enable);
605
606
return (OK);
607
} /* hci_read_scan_enable */
608
609
/* Send Write_Scan_Enable command to the unit */
610
static int
611
hci_write_scan_enable(int s, int argc, char **argv)
612
{
613
ng_hci_write_scan_enable_cp cp;
614
ng_hci_write_scan_enable_rp rp;
615
int n;
616
617
/* parse command parameters */
618
switch (argc) {
619
case 1:
620
if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3)
621
return (USAGE);
622
623
cp.scan_enable = (uint8_t) n;
624
break;
625
626
default:
627
return (USAGE);
628
}
629
630
n = sizeof(rp);
631
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
632
NG_HCI_OCF_WRITE_SCAN_ENABLE),
633
(char const *) &cp, sizeof(cp),
634
(char *) &rp, &n) == ERROR)
635
return (ERROR);
636
637
if (rp.status != 0x00) {
638
fprintf(stdout, "Status: %s [%#02x]\n",
639
hci_status2str(rp.status), rp.status);
640
return (FAILED);
641
}
642
643
return (OK);
644
} /* hci_write_scan_enable */
645
646
/* Send Read_Page_Scan_Activity command to the unit */
647
static int
648
hci_read_page_scan_activity(int s, int argc, char **argv)
649
{
650
ng_hci_read_page_scan_activity_rp rp;
651
int n;
652
653
n = sizeof(rp);
654
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
655
NG_HCI_OCF_READ_PAGE_SCAN_ACTIVITY),
656
(char *) &rp, &n) == ERROR)
657
return (ERROR);
658
659
if (rp.status != 0x00) {
660
fprintf(stdout, "Status: %s [%#02x]\n",
661
hci_status2str(rp.status), rp.status);
662
return (FAILED);
663
}
664
665
rp.page_scan_interval = le16toh(rp.page_scan_interval);
666
rp.page_scan_window = le16toh(rp.page_scan_window);
667
668
fprintf(stdout, "Page Scan Interval: %.2f msec [%d slots]\n",
669
rp.page_scan_interval * 0.625, rp.page_scan_interval);
670
fprintf(stdout, "Page Scan Window: %.2f msec [%d slots]\n",
671
rp.page_scan_window * 0.625, rp.page_scan_window);
672
673
return (OK);
674
} /* hci_read_page_scan_activity */
675
676
/* Send Write_Page_Scan_Activity command to the unit */
677
static int
678
hci_write_page_scan_activity(int s, int argc, char **argv)
679
{
680
ng_hci_write_page_scan_activity_cp cp;
681
ng_hci_write_page_scan_activity_rp rp;
682
int n;
683
684
/* parse command parameters */
685
switch (argc) {
686
case 2:
687
/* page scan interval */
688
if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
689
return (USAGE);
690
691
cp.page_scan_interval = (uint16_t) n;
692
693
/* page scan window */
694
if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
695
return (USAGE);
696
697
cp.page_scan_window = (uint16_t) n;
698
699
if (cp.page_scan_window > cp.page_scan_interval)
700
return (USAGE);
701
702
cp.page_scan_interval = htole16(cp.page_scan_interval);
703
cp.page_scan_window = htole16(cp.page_scan_window);
704
break;
705
706
default:
707
return (USAGE);
708
}
709
710
/* send command */
711
n = sizeof(rp);
712
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
713
NG_HCI_OCF_WRITE_PAGE_SCAN_ACTIVITY),
714
(char const *) &cp, sizeof(cp),
715
(char *) &rp, &n) == ERROR)
716
return (ERROR);
717
718
if (rp.status != 0x00) {
719
fprintf(stdout, "Status: %s [%#02x]\n",
720
hci_status2str(rp.status), rp.status);
721
return (FAILED);
722
}
723
724
return (OK);
725
} /* hci_write_page_scan_activity */
726
727
/* Send Read_Inquiry_Scan_Activity command to the unit */
728
static int
729
hci_read_inquiry_scan_activity(int s, int argc, char **argv)
730
{
731
ng_hci_read_inquiry_scan_activity_rp rp;
732
int n;
733
734
n = sizeof(rp);
735
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
736
NG_HCI_OCF_READ_INQUIRY_SCAN_ACTIVITY),
737
(char *) &rp, &n) == ERROR)
738
return (ERROR);
739
740
if (rp.status != 0x00) {
741
fprintf(stdout, "Status: %s [%#02x]\n",
742
hci_status2str(rp.status), rp.status);
743
return (FAILED);
744
}
745
746
rp.inquiry_scan_interval = le16toh(rp.inquiry_scan_interval);
747
rp.inquiry_scan_window = le16toh(rp.inquiry_scan_window);
748
749
fprintf(stdout, "Inquiry Scan Interval: %.2f msec [%d slots]\n",
750
rp.inquiry_scan_interval * 0.625, rp.inquiry_scan_interval);
751
fprintf(stdout, "Inquiry Scan Window: %.2f msec [%d slots]\n",
752
rp.inquiry_scan_window * 0.625, rp.inquiry_scan_interval);
753
754
return (OK);
755
} /* hci_read_inquiry_scan_activity */
756
757
/* Send Write_Inquiry_Scan_Activity command to the unit */
758
static int
759
hci_write_inquiry_scan_activity(int s, int argc, char **argv)
760
{
761
ng_hci_write_inquiry_scan_activity_cp cp;
762
ng_hci_write_inquiry_scan_activity_rp rp;
763
int n;
764
765
/* parse command parameters */
766
switch (argc) {
767
case 2:
768
/* inquiry scan interval */
769
if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
770
return (USAGE);
771
772
cp.inquiry_scan_interval = (uint16_t) n;
773
774
/* inquiry scan window */
775
if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
776
return (USAGE);
777
778
cp.inquiry_scan_window = (uint16_t) n;
779
780
if (cp.inquiry_scan_window > cp.inquiry_scan_interval)
781
return (USAGE);
782
783
cp.inquiry_scan_interval =
784
htole16(cp.inquiry_scan_interval);
785
cp.inquiry_scan_window = htole16(cp.inquiry_scan_window);
786
break;
787
788
default:
789
return (USAGE);
790
}
791
792
/* send command */
793
n = sizeof(rp);
794
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
795
NG_HCI_OCF_WRITE_INQUIRY_SCAN_ACTIVITY),
796
(char const *) &cp, sizeof(cp),
797
(char *) &rp, &n) == ERROR)
798
return (ERROR);
799
800
if (rp.status != 0x00) {
801
fprintf(stdout, "Status: %s [%#02x]\n",
802
hci_status2str(rp.status), rp.status);
803
return (FAILED);
804
}
805
806
return (OK);
807
} /* hci_write_inquiry_scan_activity */
808
809
/* Send Read_Authentication_Enable command to the unit */
810
static int
811
hci_read_authentication_enable(int s, int argc, char **argv)
812
{
813
ng_hci_read_auth_enable_rp rp;
814
int n;
815
816
n = sizeof(rp);
817
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
818
NG_HCI_OCF_READ_AUTH_ENABLE),
819
(char *) &rp, &n) == ERROR)
820
return (ERROR);
821
822
if (rp.status != 0x00) {
823
fprintf(stdout, "Status: %s [%#02x]\n",
824
hci_status2str(rp.status), rp.status);
825
return (FAILED);
826
}
827
828
fprintf(stdout, "Authentication Enable: %s [%d]\n",
829
rp.auth_enable? "Enabled" : "Disabled", rp.auth_enable);
830
831
return (OK);
832
} /* hci_read_authentication_enable */
833
834
/* Send Write_Authentication_Enable command to the unit */
835
static int
836
hci_write_authentication_enable(int s, int argc, char **argv)
837
{
838
ng_hci_write_auth_enable_cp cp;
839
ng_hci_write_auth_enable_rp rp;
840
int n;
841
842
/* parse command parameters */
843
switch (argc) {
844
case 1:
845
if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)
846
return (USAGE);
847
848
cp.auth_enable = (uint8_t) n;
849
break;
850
851
default:
852
return (USAGE);
853
}
854
855
/* send command */
856
n = sizeof(rp);
857
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
858
NG_HCI_OCF_WRITE_AUTH_ENABLE),
859
(char const *) &cp, sizeof(cp),
860
(char *) &rp, &n) == ERROR)
861
return (ERROR);
862
863
if (rp.status != 0x00) {
864
fprintf(stdout, "Status: %s [%#02x]\n",
865
hci_status2str(rp.status), rp.status);
866
return (FAILED);
867
}
868
869
return (OK);
870
} /* hci_write_authentication_enable */
871
872
/* Send Read_Encryption_Mode command to the unit */
873
static int
874
hci_read_encryption_mode(int s, int argc, char **argv)
875
{
876
ng_hci_read_encryption_mode_rp rp;
877
int n;
878
879
n = sizeof(rp);
880
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
881
NG_HCI_OCF_READ_ENCRYPTION_MODE),
882
(char *) &rp, &n) == ERROR)
883
return (ERROR);
884
885
if (rp.status != 0x00) {
886
fprintf(stdout, "Status: %s [%#02x]\n",
887
hci_status2str(rp.status), rp.status);
888
return (FAILED);
889
}
890
891
fprintf(stdout, "Encryption mode: %s [%#02x]\n",
892
hci_encrypt2str(rp.encryption_mode, 0), rp.encryption_mode);
893
894
return (OK);
895
} /* hci_read_encryption_mode */
896
897
/* Send Write_Encryption_Mode command to the unit */
898
static int
899
hci_write_encryption_mode(int s, int argc, char **argv)
900
{
901
ng_hci_write_encryption_mode_cp cp;
902
ng_hci_write_encryption_mode_rp rp;
903
int n;
904
905
/* parse command parameters */
906
switch (argc) {
907
case 1:
908
if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2)
909
return (USAGE);
910
911
cp.encryption_mode = (uint8_t) n;
912
break;
913
914
default:
915
return (USAGE);
916
}
917
918
/* send command */
919
n = sizeof(rp);
920
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
921
NG_HCI_OCF_WRITE_ENCRYPTION_MODE),
922
(char const *) &cp, sizeof(cp),
923
(char *) &rp, &n) == ERROR)
924
return (ERROR);
925
926
if (rp.status != 0x00) {
927
fprintf(stdout, "Status: %s [%#02x]\n",
928
hci_status2str(rp.status), rp.status);
929
return (FAILED);
930
}
931
932
return (OK);
933
} /* hci_write_encryption_mode */
934
935
/* Send Read_Class_Of_Device command to the unit */
936
static int
937
hci_read_class_of_device(int s, int argc, char **argv)
938
{
939
ng_hci_read_unit_class_rp rp;
940
int n;
941
942
n = sizeof(rp);
943
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
944
NG_HCI_OCF_READ_UNIT_CLASS),
945
(char *) &rp, &n) == ERROR)
946
return (ERROR);
947
948
if (rp.status != 0x00) {
949
fprintf(stdout, "Status: %s [%#02x]\n",
950
hci_status2str(rp.status), rp.status);
951
return (FAILED);
952
}
953
954
fprintf(stdout, "Class: %02x:%02x:%02x\n",
955
rp.uclass[2], rp.uclass[1], rp.uclass[0]);
956
957
return (0);
958
} /* hci_read_class_of_device */
959
960
/* Send Write_Class_Of_Device command to the unit */
961
static int
962
hci_write_class_of_device(int s, int argc, char **argv)
963
{
964
ng_hci_write_unit_class_cp cp;
965
ng_hci_write_unit_class_rp rp;
966
int n0, n1, n2;
967
968
/* parse command parameters */
969
switch (argc) {
970
case 1:
971
if (sscanf(argv[0], "%x:%x:%x", &n2, &n1, &n0) != 3)
972
return (USAGE);
973
974
cp.uclass[0] = (n0 & 0xff);
975
cp.uclass[1] = (n1 & 0xff);
976
cp.uclass[2] = (n2 & 0xff);
977
break;
978
979
default:
980
return (USAGE);
981
}
982
983
/* send command */
984
n0 = sizeof(rp);
985
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
986
NG_HCI_OCF_WRITE_UNIT_CLASS),
987
(char const *) &cp, sizeof(cp),
988
(char *) &rp, &n0) == ERROR)
989
return (ERROR);
990
991
if (rp.status != 0x00) {
992
fprintf(stdout, "Status: %s [%#02x]\n",
993
hci_status2str(rp.status), rp.status);
994
return (FAILED);
995
}
996
997
return (OK);
998
} /* hci_write_class_of_device */
999
1000
/* Send Read_Voice_Settings command to the unit */
1001
static int
1002
hci_read_voice_settings(int s, int argc, char **argv)
1003
{
1004
ng_hci_read_voice_settings_rp rp;
1005
int n,
1006
input_coding,
1007
input_data_format,
1008
input_sample_size;
1009
1010
n = sizeof(rp);
1011
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1012
NG_HCI_OCF_READ_VOICE_SETTINGS),
1013
(char *) &rp, &n) == ERROR)
1014
return (ERROR);
1015
1016
if (rp.status != 0x00) {
1017
fprintf(stdout, "Status: %s [%#02x]\n",
1018
hci_status2str(rp.status), rp.status);
1019
return (FAILED);
1020
}
1021
1022
rp.settings = le16toh(rp.settings);
1023
1024
input_coding = (rp.settings & 0x0300) >> 8;
1025
input_data_format = (rp.settings & 0x00c0) >> 6;
1026
input_sample_size = (rp.settings & 0x0020) >> 5;
1027
1028
fprintf(stdout, "Voice settings: %#04x\n", rp.settings);
1029
fprintf(stdout, "Input coding: %s [%d]\n",
1030
hci_coding2str(input_coding), input_coding);
1031
fprintf(stdout, "Input data format: %s [%d]\n",
1032
hci_vdata2str(input_data_format), input_data_format);
1033
1034
if (input_coding == 0x00) /* Only for Linear PCM */
1035
fprintf(stdout, "Input sample size: %d bit [%d]\n",
1036
input_sample_size? 16 : 8, input_sample_size);
1037
1038
return (OK);
1039
} /* hci_read_voice_settings */
1040
1041
/* Send Write_Voice_Settings command to the unit */
1042
static int
1043
hci_write_voice_settings(int s, int argc, char **argv)
1044
{
1045
ng_hci_write_voice_settings_cp cp;
1046
ng_hci_write_voice_settings_rp rp;
1047
int n;
1048
1049
/* parse command parameters */
1050
switch (argc) {
1051
case 1:
1052
if (sscanf(argv[0], "%x", &n) != 1)
1053
return (USAGE);
1054
1055
cp.settings = (uint16_t) n;
1056
cp.settings = htole16(cp.settings);
1057
break;
1058
1059
default:
1060
return (USAGE);
1061
}
1062
1063
/* send command */
1064
n = sizeof(rp);
1065
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1066
NG_HCI_OCF_WRITE_VOICE_SETTINGS),
1067
(char const *) &cp, sizeof(cp),
1068
(char *) &rp, &n) == ERROR)
1069
return (ERROR);
1070
1071
if (rp.status != 0x00) {
1072
fprintf(stdout, "Status: %s [%#02x]\n",
1073
hci_status2str(rp.status), rp.status);
1074
return (FAILED);
1075
}
1076
1077
return (OK);
1078
} /* hci_write_voice_settings */
1079
1080
/* Send Read_Number_Broadcast_Restransmissions */
1081
static int
1082
hci_read_number_broadcast_retransmissions(int s, int argc, char **argv)
1083
{
1084
ng_hci_read_num_broadcast_retrans_rp rp;
1085
int n;
1086
1087
n = sizeof(rp);
1088
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1089
NG_HCI_OCF_READ_NUM_BROADCAST_RETRANS),
1090
(char *) &rp, &n) == ERROR)
1091
return (ERROR);
1092
1093
if (rp.status != 0x00) {
1094
fprintf(stdout, "Status: %s [%#02x]\n",
1095
hci_status2str(rp.status), rp.status);
1096
return (FAILED);
1097
}
1098
1099
fprintf(stdout, "Number of broadcast retransmissions: %d\n",
1100
rp.counter);
1101
1102
return (OK);
1103
} /* hci_read_number_broadcast_retransmissions */
1104
1105
/* Send Write_Number_Broadcast_Restransmissions */
1106
static int
1107
hci_write_number_broadcast_retransmissions(int s, int argc, char **argv)
1108
{
1109
ng_hci_write_num_broadcast_retrans_cp cp;
1110
ng_hci_write_num_broadcast_retrans_rp rp;
1111
int n;
1112
1113
/* parse command parameters */
1114
switch (argc) {
1115
case 1:
1116
if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0xff)
1117
return (USAGE);
1118
1119
cp.counter = (uint8_t) n;
1120
break;
1121
1122
default:
1123
return (USAGE);
1124
}
1125
1126
/* send command */
1127
n = sizeof(rp);
1128
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1129
NG_HCI_OCF_WRITE_NUM_BROADCAST_RETRANS),
1130
(char const *) &cp, sizeof(cp),
1131
(char *) &rp, &n) == ERROR)
1132
return (ERROR);
1133
1134
if (rp.status != 0x00) {
1135
fprintf(stdout, "Status: %s [%#02x]\n",
1136
hci_status2str(rp.status), rp.status);
1137
return (FAILED);
1138
}
1139
1140
return (OK);
1141
} /* hci_write_number_broadcast_retransmissions */
1142
1143
/* Send Read_Hold_Mode_Activity command to the unit */
1144
static int
1145
hci_read_hold_mode_activity(int s, int argc, char **argv)
1146
{
1147
ng_hci_read_hold_mode_activity_rp rp;
1148
int n;
1149
char buffer[1024];
1150
1151
n = sizeof(rp);
1152
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1153
NG_HCI_OCF_READ_HOLD_MODE_ACTIVITY),
1154
(char *) &rp, &n) == ERROR)
1155
return (ERROR);
1156
1157
if (rp.status != 0x00) {
1158
fprintf(stdout, "Status: %s [%#02x]\n",
1159
hci_status2str(rp.status), rp.status);
1160
return (FAILED);
1161
}
1162
1163
fprintf(stdout, "Hold Mode Activities: %#02x\n", rp.hold_mode_activity);
1164
if (rp.hold_mode_activity == 0)
1165
fprintf(stdout, "Maintain current Power State");
1166
else
1167
fprintf(stdout, "%s", hci_hmode2str(rp.hold_mode_activity,
1168
buffer, sizeof(buffer)));
1169
1170
fprintf(stdout, "\n");
1171
1172
return (OK);
1173
} /* hci_read_hold_mode_activity */
1174
1175
/* Send Write_Hold_Mode_Activity command to the unit */
1176
static int
1177
hci_write_hold_mode_activity(int s, int argc, char **argv)
1178
{
1179
ng_hci_write_hold_mode_activity_cp cp;
1180
ng_hci_write_hold_mode_activity_rp rp;
1181
int n;
1182
1183
/* parse command parameters */
1184
switch (argc) {
1185
case 1:
1186
if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 4)
1187
return (USAGE);
1188
1189
cp.hold_mode_activity = (uint8_t) n;
1190
break;
1191
1192
default:
1193
return (USAGE);
1194
}
1195
1196
/* send command */
1197
n = sizeof(rp);
1198
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1199
NG_HCI_OCF_WRITE_HOLD_MODE_ACTIVITY),
1200
(char const *) &cp, sizeof(cp),
1201
(char *) &rp, &n) == ERROR)
1202
return (ERROR);
1203
1204
if (rp.status != 0x00) {
1205
fprintf(stdout, "Status: %s [%#02x]\n",
1206
hci_status2str(rp.status), rp.status);
1207
return (FAILED);
1208
}
1209
1210
return (OK);
1211
} /* hci_write_hold_mode_activity */
1212
1213
/* Send Read_SCO_Flow_Control_Enable command to the unit */
1214
static int
1215
hci_read_sco_flow_control_enable(int s, int argc, char **argv)
1216
{
1217
ng_hci_read_sco_flow_control_rp rp;
1218
int n;
1219
1220
n = sizeof(rp);
1221
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1222
NG_HCI_OCF_READ_SCO_FLOW_CONTROL),
1223
(char *) &rp, &n) == ERROR)
1224
return (ERROR);
1225
1226
if (rp.status != 0x00) {
1227
fprintf(stdout, "Status: %s [%#02x]\n",
1228
hci_status2str(rp.status), rp.status);
1229
return (FAILED);
1230
}
1231
1232
fprintf(stdout, "SCO flow control %s [%d]\n",
1233
rp.flow_control? "enabled" : "disabled", rp.flow_control);
1234
1235
return (OK);
1236
} /* hci_read_sco_flow_control_enable */
1237
1238
/* Send Write_SCO_Flow_Control_Enable command to the unit */
1239
static int
1240
hci_write_sco_flow_control_enable(int s, int argc, char **argv)
1241
{
1242
ng_hci_write_sco_flow_control_cp cp;
1243
ng_hci_write_sco_flow_control_rp rp;
1244
int n;
1245
1246
/* parse command parameters */
1247
switch (argc) {
1248
case 1:
1249
if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)
1250
return (USAGE);
1251
1252
cp.flow_control = (uint8_t) n;
1253
break;
1254
1255
default:
1256
return (USAGE);
1257
}
1258
1259
/* send command */
1260
n = sizeof(rp);
1261
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1262
NG_HCI_OCF_WRITE_SCO_FLOW_CONTROL),
1263
(char const *) &cp, sizeof(cp),
1264
(char *) &rp, &n) == ERROR)
1265
return (ERROR);
1266
1267
if (rp.status != 0x00) {
1268
fprintf(stdout, "Status: %s [%#02x]\n",
1269
hci_status2str(rp.status), rp.status);
1270
return (FAILED);
1271
}
1272
1273
return (OK);
1274
} /* hci_write_sco_flow_control_enable */
1275
1276
/* Send Read_Link_Supervision_Timeout command to the unit */
1277
static int
1278
hci_read_link_supervision_timeout(int s, int argc, char **argv)
1279
{
1280
ng_hci_read_link_supervision_timo_cp cp;
1281
ng_hci_read_link_supervision_timo_rp rp;
1282
int n;
1283
1284
switch (argc) {
1285
case 1:
1286
/* connection handle */
1287
if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
1288
return (USAGE);
1289
1290
cp.con_handle = (uint16_t) (n & 0x0fff);
1291
cp.con_handle = htole16(cp.con_handle);
1292
break;
1293
1294
default:
1295
return (USAGE);
1296
}
1297
1298
/* send command */
1299
n = sizeof(rp);
1300
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1301
NG_HCI_OCF_READ_LINK_SUPERVISION_TIMO),
1302
(char const *) &cp, sizeof(cp),
1303
(char *) &rp, &n) == ERROR)
1304
return (ERROR);
1305
1306
if (rp.status != 0x00) {
1307
fprintf(stdout, "Status: %s [%#02x]\n",
1308
hci_status2str(rp.status), rp.status);
1309
return (FAILED);
1310
}
1311
1312
rp.timeout = le16toh(rp.timeout);
1313
1314
fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
1315
fprintf(stdout, "Link supervision timeout: %.2f msec [%d slots]\n",
1316
rp.timeout * 0.625, rp.timeout);
1317
1318
return (OK);
1319
} /* hci_read_link_supervision_timeout */
1320
1321
/* Send Write_Link_Supervision_Timeout command to the unit */
1322
static int
1323
hci_write_link_supervision_timeout(int s, int argc, char **argv)
1324
{
1325
ng_hci_write_link_supervision_timo_cp cp;
1326
ng_hci_write_link_supervision_timo_rp rp;
1327
int n;
1328
1329
switch (argc) {
1330
case 2:
1331
/* connection handle */
1332
if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
1333
return (USAGE);
1334
1335
cp.con_handle = (uint16_t) (n & 0x0fff);
1336
cp.con_handle = htole16(cp.con_handle);
1337
1338
/* link supervision timeout */
1339
if (sscanf(argv[1], "%d", &n) != 1 || n < 0 || n > 0xffff)
1340
return (USAGE);
1341
1342
cp.timeout = (uint16_t) (n & 0x0fff);
1343
cp.timeout = htole16(cp.timeout);
1344
break;
1345
1346
default:
1347
return (USAGE);
1348
}
1349
1350
/* send command */
1351
n = sizeof(rp);
1352
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1353
NG_HCI_OCF_WRITE_LINK_SUPERVISION_TIMO),
1354
(char const *) &cp, sizeof(cp),
1355
(char *) &rp, &n) == ERROR)
1356
return (ERROR);
1357
1358
if (rp.status != 0x00) {
1359
fprintf(stdout, "Status: %s [%#02x]\n",
1360
hci_status2str(rp.status), rp.status);
1361
return (FAILED);
1362
}
1363
1364
return (OK);
1365
} /* hci_write_link_supervision_timeout */
1366
1367
/* Send Read_Page_Scan_Period_Mode command to the unit */
1368
static int
1369
hci_read_page_scan_period_mode(int s, int argc, char **argv)
1370
{
1371
ng_hci_read_page_scan_period_rp rp;
1372
int n;
1373
1374
n = sizeof(rp);
1375
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1376
NG_HCI_OCF_READ_PAGE_SCAN_PERIOD),
1377
(char *) &rp, &n) == ERROR)
1378
return (ERROR);
1379
1380
if (rp.status != 0x00) {
1381
fprintf(stdout, "Status: %s [%#02x]\n",
1382
hci_status2str(rp.status), rp.status);
1383
return (FAILED);
1384
}
1385
1386
fprintf(stdout, "Page scan period mode: %#02x\n",
1387
rp.page_scan_period_mode);
1388
1389
return (OK);
1390
} /* hci_read_page_scan_period_mode */
1391
1392
/* Send Write_Page_Scan_Period_Mode command to the unit */
1393
static int
1394
hci_write_page_scan_period_mode(int s, int argc, char **argv)
1395
{
1396
ng_hci_write_page_scan_period_cp cp;
1397
ng_hci_write_page_scan_period_rp rp;
1398
int n;
1399
1400
/* parse command arguments */
1401
switch (argc) {
1402
case 1:
1403
if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2)
1404
return (USAGE);
1405
1406
cp.page_scan_period_mode = (n & 0xff);
1407
break;
1408
1409
default:
1410
return (USAGE);
1411
}
1412
1413
/* send command */
1414
n = sizeof(rp);
1415
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1416
NG_HCI_OCF_WRITE_PAGE_SCAN_PERIOD),
1417
(char const *) &cp, sizeof(cp),
1418
(char *) &rp, &n) == ERROR)
1419
return (ERROR);
1420
1421
if (rp.status != 0x00) {
1422
fprintf(stdout, "Status: %s [%#02x]\n",
1423
hci_status2str(rp.status), rp.status);
1424
return (FAILED);
1425
}
1426
1427
return (OK);
1428
} /* hci_write_page_scan_period_mode */
1429
1430
/* Send Read_Page_Scan_Mode command to the unit */
1431
static int
1432
hci_read_page_scan_mode(int s, int argc, char **argv)
1433
{
1434
ng_hci_read_page_scan_rp rp;
1435
int n;
1436
1437
n = sizeof(rp);
1438
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1439
NG_HCI_OCF_READ_PAGE_SCAN),
1440
(char *) &rp, &n) == ERROR)
1441
return (ERROR);
1442
1443
if (rp.status != 0x00) {
1444
fprintf(stdout, "Status: %s [%#02x]\n",
1445
hci_status2str(rp.status), rp.status);
1446
return (FAILED);
1447
}
1448
1449
fprintf(stdout, "Page scan mode: %#02x\n", rp.page_scan_mode);
1450
1451
return (OK);
1452
} /* hci_read_page_scan_mode */
1453
1454
/* Send Write_Page_Scan_Mode command to the unit */
1455
static int
1456
hci_write_page_scan_mode(int s, int argc, char **argv)
1457
{
1458
ng_hci_write_page_scan_cp cp;
1459
ng_hci_write_page_scan_rp rp;
1460
int n;
1461
1462
/* parse command arguments */
1463
switch (argc) {
1464
case 1:
1465
if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3)
1466
return (USAGE);
1467
1468
cp.page_scan_mode = (n & 0xff);
1469
break;
1470
1471
default:
1472
return (USAGE);
1473
}
1474
1475
/* send command */
1476
n = sizeof(rp);
1477
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1478
NG_HCI_OCF_WRITE_PAGE_SCAN),
1479
(char const *) &cp, sizeof(cp),
1480
(char *) &rp, &n) == ERROR)
1481
return (ERROR);
1482
1483
if (rp.status != 0x00) {
1484
fprintf(stdout, "Status: %s [%#02x]\n",
1485
hci_status2str(rp.status), rp.status);
1486
return (FAILED);
1487
}
1488
1489
return (OK);
1490
} /* hci_write_page_scan_mode */
1491
1492
static int
1493
hci_read_le_host_support(int s, int argc, char **argv)
1494
{
1495
ng_hci_read_le_host_supported_rp rp;
1496
int n;
1497
n = sizeof(rp);
1498
if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1499
NG_HCI_OCF_READ_LE_HOST_SUPPORTED),
1500
(char *) &rp, &n) == ERROR)
1501
return (ERROR);
1502
1503
if (rp.status != 0x00) {
1504
fprintf(stdout, "Status: %s [%#02x]\n",
1505
hci_status2str(rp.status), rp.status);
1506
return (FAILED);
1507
}
1508
1509
fprintf(stdout, "LE Host support: %#02x\n", rp.le_supported_host);
1510
fprintf(stdout, "Simultaneous LE Host : %#02x\n", rp.simultaneous_le_host);
1511
1512
return (OK);
1513
1514
}
1515
static int
1516
hci_write_le_host_support(int s, int argc, char **argv)
1517
{
1518
ng_hci_write_le_host_supported_cp cp;
1519
ng_hci_write_le_host_supported_rp rp;
1520
1521
int n;
1522
1523
cp.le_supported_host = 0;
1524
cp.simultaneous_le_host = 0;
1525
switch (argc) {
1526
case 2:
1527
if (sscanf(argv[1], "%d", &n) != 1 || (n != 0 && n != 1)){
1528
printf("-ARGC2: %d\n", n);
1529
return (USAGE);
1530
}
1531
cp.simultaneous_le_host = (n &1);
1532
1533
case 1:
1534
if (sscanf(argv[0], "%d", &n) != 1 || (n != 0 && n != 1)){
1535
printf("+ARGC1: %d\n", n);
1536
return (USAGE);
1537
}
1538
1539
cp.le_supported_host = (n &1);
1540
break;
1541
1542
default:
1543
return (USAGE);
1544
}
1545
1546
1547
/* send command */
1548
n = sizeof(rp);
1549
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1550
NG_HCI_OCF_WRITE_LE_HOST_SUPPORTED),
1551
(char const *) &cp, sizeof(cp),
1552
(char *) &rp, &n) == ERROR)
1553
return (ERROR);
1554
1555
if (rp.status != 0x00) {
1556
fprintf(stdout, "Status: %s [%#02x]\n",
1557
hci_status2str(rp.status), rp.status);
1558
return (FAILED);
1559
}
1560
1561
return (OK);
1562
}
1563
1564
struct hci_command host_controller_baseband_commands[] = {
1565
{
1566
"reset",
1567
"\nThe Reset command will reset the Host Controller and the Link Manager.\n" \
1568
"After the reset is completed, the current operational state will be lost,\n" \
1569
"the Bluetooth unit will enter standby mode and the Host Controller will\n" \
1570
"automatically revert to the default values for the parameters for which\n" \
1571
"default values are defined in the specification.",
1572
&hci_reset
1573
},
1574
{
1575
"read_pin_type",
1576
"\nThe Read_PIN_Type command is used for the Host to read whether the Link\n" \
1577
"Manager assumes that the Host supports variable PIN codes only a fixed PIN\n" \
1578
"code.",
1579
&hci_read_pin_type
1580
},
1581
{
1582
"write_pin_type <pin_type>",
1583
"\nThe Write_PIN_Type command is used for the Host to write to the Host\n" \
1584
"Controller whether the Host supports variable PIN codes or only a fixed PIN\n"\
1585
"code.\n\n" \
1586
"\t<pin_type> - dd; 0 - Variable; 1 - Fixed",
1587
&hci_write_pin_type
1588
},
1589
{
1590
"read_stored_link_key [<BD_ADDR>]",
1591
"\nThe Read_Stored_Link_Key command provides the ability to read one or\n" \
1592
"more link keys stored in the Bluetooth Host Controller. The Bluetooth Host\n" \
1593
"Controller can store a limited number of link keys for other Bluetooth\n" \
1594
"devices.\n\n" \
1595
"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name",
1596
&hci_read_stored_link_key
1597
},
1598
{
1599
"write_stored_link_key <BD_ADDR> <key>",
1600
"\nThe Write_Stored_Link_Key command provides the ability to write one\n" \
1601
"or more link keys to be stored in the Bluetooth Host Controller. The\n" \
1602
"Bluetooth Host Controller can store a limited number of link keys for other\n"\
1603
"Bluetooth devices. If no additional space is available in the Bluetooth\n"\
1604
"Host Controller then no additional link keys will be stored.\n\n" \
1605
"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name\n" \
1606
"\t<key> - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx up to 16 bytes link key",
1607
&hci_write_stored_link_key
1608
},
1609
{
1610
"delete_stored_link_key [<BD_ADDR>]",
1611
"\nThe Delete_Stored_Link_Key command provides the ability to remove one\n" \
1612
"or more of the link keys stored in the Bluetooth Host Controller. The\n" \
1613
"Bluetooth Host Controller can store a limited number of link keys for other\n"\
1614
"Bluetooth devices.\n\n" \
1615
"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name",
1616
&hci_delete_stored_link_key
1617
},
1618
{
1619
"change_local_name <name>",
1620
"\nThe Change_Local_Name command provides the ability to modify the user\n" \
1621
"friendly name for the Bluetooth unit.\n\n" \
1622
"\t<name> - string",
1623
&hci_change_local_name
1624
},
1625
{
1626
"read_local_name",
1627
"\nThe Read_Local_Name command provides the ability to read the\n" \
1628
"stored user-friendly name for the Bluetooth unit.",
1629
&hci_read_local_name
1630
},
1631
{
1632
"read_connection_accept_timeout",
1633
"\nThis command will read the value for the Connection_Accept_Timeout\n" \
1634
"configuration parameter. The Connection_Accept_Timeout configuration\n" \
1635
"parameter allows the Bluetooth hardware to automatically deny a\n" \
1636
"connection request after a specified time period has occurred and\n" \
1637
"the new connection is not accepted. Connection Accept Timeout\n" \
1638
"measured in Number of Baseband slots.",
1639
&hci_read_connection_accept_timeout
1640
},
1641
{
1642
"write_connection_accept_timeout <timeout>",
1643
"\nThis command will write the value for the Connection_Accept_Timeout\n" \
1644
"configuration parameter.\n\n" \
1645
"\t<timeout> - dddd; measured in number of baseband slots.",
1646
&hci_write_connection_accept_timeout
1647
},
1648
{
1649
"read_page_timeout",
1650
"\nThis command will read the value for the Page_Timeout configuration\n" \
1651
"parameter. The Page_Timeout configuration parameter defines the\n" \
1652
"maximum time the local Link Manager will wait for a baseband page\n" \
1653
"response from the remote unit at a locally initiated connection\n" \
1654
"attempt. Page Timeout measured in Number of Baseband slots.",
1655
&hci_read_page_timeout
1656
},
1657
{
1658
"write_page_timeout <timeout>",
1659
"\nThis command will write the value for the Page_Timeout configuration\n" \
1660
"parameter.\n\n" \
1661
"\t<timeout> - dddd; measured in number of baseband slots.",
1662
&hci_write_page_timeout
1663
},
1664
{
1665
"read_scan_enable",
1666
"\nThis command will read the value for the Scan_Enable parameter. The\n" \
1667
"Scan_Enable parameter controls whether or not the Bluetooth uint\n" \
1668
"will periodically scan for page attempts and/or inquiry requests\n" \
1669
"from other Bluetooth unit.\n\n" \
1670
"\t0x00 - No Scans enabled.\n" \
1671
"\t0x01 - Inquiry Scan enabled. Page Scan disabled.\n" \
1672
"\t0x02 - Inquiry Scan disabled. Page Scan enabled.\n" \
1673
"\t0x03 - Inquiry Scan enabled. Page Scan enabled.",
1674
&hci_read_scan_enable
1675
},
1676
{
1677
"write_scan_enable <scan_enable>",
1678
"\nThis command will write the value for the Scan_Enable parameter.\n" \
1679
"The Scan_Enable parameter controls whether or not the Bluetooth\n" \
1680
"unit will periodically scan for page attempts and/or inquiry\n" \
1681
"requests from other Bluetooth unit.\n\n" \
1682
"\t<scan_enable> - dd;\n" \
1683
"\t0 - No Scans enabled.\n" \
1684
"\t1 - Inquiry Scan enabled. Page Scan disabled.\n" \
1685
"\t2 - Inquiry Scan disabled. Page Scan enabled.\n" \
1686
"\t3 - Inquiry Scan enabled. Page Scan enabled.",
1687
&hci_write_scan_enable
1688
},
1689
{
1690
"read_page_scan_activity",
1691
"\nThis command will read the value for Page_Scan_Activity configuration\n" \
1692
"parameters. The Page_Scan_Interval configuration parameter defines the\n" \
1693
"amount of time between consecutive page scans. This time interval is \n" \
1694
"defined from when the Host Controller started its last page scan until\n" \
1695
"it begins the next page scan. The Page_Scan_Window configuration parameter\n" \
1696
"defines the amount of time for the duration of the page scan. The\n" \
1697
"Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.",
1698
&hci_read_page_scan_activity
1699
},
1700
{
1701
"write_page_scan_activity interval(dddd) window(dddd)",
1702
"\nThis command will write the value for Page_Scan_Activity configuration\n" \
1703
"parameter. The Page_Scan_Interval configuration parameter defines the\n" \
1704
"amount of time between consecutive page scans. This is defined as the time\n" \
1705
"interval from when the Host Controller started its last page scan until it\n" \
1706
"begins the next page scan. The Page_Scan_Window configuration parameter\n" \
1707
"defines the amount of time for the duration of the page scan. \n" \
1708
"The Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.\n\n" \
1709
"\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \
1710
"\t<window> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec",
1711
&hci_write_page_scan_activity
1712
},
1713
{
1714
"read_inquiry_scan_activity",
1715
"\nThis command will read the value for Inquiry_Scan_Activity configuration\n" \
1716
"parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \
1717
"amount of time between consecutive inquiry scans. This is defined as the\n" \
1718
"time interval from when the Host Controller started its last inquiry scan\n" \
1719
"until it begins the next inquiry scan.",
1720
&hci_read_inquiry_scan_activity
1721
},
1722
{
1723
"write_inquiry_scan_activity interval(dddd) window(dddd)",
1724
"\nThis command will write the value for Inquiry_Scan_Activity configuration\n"\
1725
"parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \
1726
"amount of time between consecutive inquiry scans. This is defined as the\n" \
1727
"time interval from when the Host Controller started its last inquiry scan\n" \
1728
"until it begins the next inquiry scan. The Inquiry_Scan_Window configuration\n" \
1729
"parameter defines the amount of time for the duration of the inquiry scan.\n" \
1730
"The Inquiry_Scan_Window can only be less than or equal to the Inquiry_Scan_Interval.\n\n" \
1731
"\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \
1732
"\t<window> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec",
1733
&hci_write_inquiry_scan_activity
1734
},
1735
{
1736
"read_authentication_enable",
1737
"\nThis command will read the value for the Authentication_Enable parameter.\n"\
1738
"The Authentication_Enable parameter controls if the local unit requires\n"\
1739
"to authenticate the remote unit at connection setup (between the\n" \
1740
"Create_Connection command or acceptance of an incoming ACL connection\n"\
1741
"and the corresponding Connection Complete event). At connection setup, only\n"\
1742
"the unit(s) with the Authentication_Enable parameter enabled will try to\n"\
1743
"authenticate the other unit.",
1744
&hci_read_authentication_enable
1745
},
1746
{
1747
"write_authentication_enable enable(0|1)",
1748
"\nThis command will write the value for the Authentication_Enable parameter.\n"\
1749
"The Authentication_Enable parameter controls if the local unit requires to\n"\
1750
"authenticate the remote unit at connection setup (between the\n" \
1751
"Create_Connection command or acceptance of an incoming ACL connection\n" \
1752
"and the corresponding Connection Complete event). At connection setup, only\n"\
1753
"the unit(s) with the Authentication_Enable parameter enabled will try to\n"\
1754
"authenticate the other unit.",
1755
&hci_write_authentication_enable
1756
},
1757
{
1758
"read_encryption_mode",
1759
"\nThis command will read the value for the Encryption_Mode parameter. The\n" \
1760
"Encryption_Mode parameter controls if the local unit requires encryption\n" \
1761
"to the remote unit at connection setup (between the Create_Connection\n" \
1762
"command or acceptance of an incoming ACL connection and the corresponding\n" \
1763
"Connection Complete event). At connection setup, only the unit(s) with\n" \
1764
"the Authentication_Enable parameter enabled and Encryption_Mode parameter\n" \
1765
"enabled will try to encrypt the connection to the other unit.\n\n" \
1766
"\t<encryption_mode>:\n" \
1767
"\t0x00 - Encryption disabled.\n" \
1768
"\t0x01 - Encryption only for point-to-point packets.\n" \
1769
"\t0x02 - Encryption for both point-to-point and broadcast packets.",
1770
&hci_read_encryption_mode
1771
},
1772
{
1773
"write_encryption_mode mode(0|1|2)",
1774
"\tThis command will write the value for the Encryption_Mode parameter.\n" \
1775
"The Encryption_Mode parameter controls if the local unit requires\n" \
1776
"encryption to the remote unit at connection setup (between the\n" \
1777
"Create_Connection command or acceptance of an incoming ACL connection\n" \
1778
"and the corresponding Connection Complete event). At connection setup,\n" \
1779
"only the unit(s) with the Authentication_Enable parameter enabled and\n" \
1780
"Encryption_Mode parameter enabled will try to encrypt the connection to\n" \
1781
"the other unit.\n\n" \
1782
"\t<encryption_mode> (dd)\n" \
1783
"\t0 - Encryption disabled.\n" \
1784
"\t1 - Encryption only for point-to-point packets.\n" \
1785
"\t2 - Encryption for both point-to-point and broadcast packets.",
1786
&hci_write_encryption_mode
1787
},
1788
{
1789
"read_class_of_device",
1790
"\nThis command will read the value for the Class_of_Device parameter.\n" \
1791
"The Class_of_Device parameter is used to indicate the capabilities of\n" \
1792
"the local unit to other units.",
1793
&hci_read_class_of_device
1794
},
1795
{
1796
"write_class_of_device class(xx:xx:xx)",
1797
"\nThis command will write the value for the Class_of_Device parameter.\n" \
1798
"The Class_of_Device parameter is used to indicate the capabilities of \n" \
1799
"the local unit to other units.\n\n" \
1800
"\t<class> (xx:xx:xx) - class of device",
1801
&hci_write_class_of_device
1802
},
1803
{
1804
"read_voice_settings",
1805
"\nThis command will read the values for the Voice_Setting parameter.\n" \
1806
"The Voice_Setting parameter controls all the various settings for voice\n" \
1807
"connections. These settings apply to all voice connections, and cannot be\n" \
1808
"set for individual voice connections. The Voice_Setting parameter controls\n" \
1809
"the configuration for voice connections: Input Coding, Air coding format,\n" \
1810
"input data format, Input sample size, and linear PCM parameter.",
1811
&hci_read_voice_settings
1812
},
1813
{
1814
"write_voice_settings settings(xxxx)",
1815
"\nThis command will write the values for the Voice_Setting parameter.\n" \
1816
"The Voice_Setting parameter controls all the various settings for voice\n" \
1817
"connections. These settings apply to all voice connections, and cannot be\n" \
1818
"set for individual voice connections. The Voice_Setting parameter controls\n" \
1819
"the configuration for voice connections: Input Coding, Air coding format,\n" \
1820
"input data format, Input sample size, and linear PCM parameter.\n\n" \
1821
"\t<voice_settings> (xxxx) - voice settings",
1822
&hci_write_voice_settings
1823
},
1824
{
1825
"read_number_broadcast_retransmissions",
1826
"\nThis command will read the unit's parameter value for the Number of\n" \
1827
"Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \
1828
"unreliable.",
1829
&hci_read_number_broadcast_retransmissions
1830
},
1831
{
1832
"write_number_broadcast_retransmissions count(dd)",
1833
"\nThis command will write the unit's parameter value for the Number of\n" \
1834
"Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \
1835
"unreliable.\n\n" \
1836
"\t<count> (dd) - number of broadcast retransimissions",
1837
&hci_write_number_broadcast_retransmissions
1838
},
1839
{
1840
"read_hold_mode_activity",
1841
"\nThis command will read the value for the Hold_Mode_Activity parameter.\n" \
1842
"The Hold_Mode_Activity value is used to determine what activities should\n" \
1843
"be suspended when the unit is in hold mode.",
1844
&hci_read_hold_mode_activity
1845
},
1846
{
1847
"write_hold_mode_activity settings(0|1|2|4)",
1848
"\nThis command will write the value for the Hold_Mode_Activity parameter.\n" \
1849
"The Hold_Mode_Activity value is used to determine what activities should\n" \
1850
"be suspended when the unit is in hold mode.\n\n" \
1851
"\t<settings> (dd) - bit mask:\n" \
1852
"\t0 - Maintain current Power State. Default\n" \
1853
"\t1 - Suspend Page Scan.\n" \
1854
"\t2 - Suspend Inquiry Scan.\n" \
1855
"\t4 - Suspend Periodic Inquiries.",
1856
&hci_write_hold_mode_activity
1857
},
1858
{
1859
"read_sco_flow_control_enable",
1860
"\nThe Read_SCO_Flow_Control_Enable command provides the ability to read\n" \
1861
"the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \
1862
"decide if the Host Controller will send Number Of Completed Packets events\n" \
1863
"for SCO Connection Handles. This setting allows the Host to enable and\n" \
1864
"disable SCO flow control.",
1865
&hci_read_sco_flow_control_enable
1866
},
1867
{
1868
"write_sco_flow_control_enable enable(0|1)",
1869
"\nThe Write_SCO_Flow_Control_Enable command provides the ability to write\n" \
1870
"the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \
1871
"decide if the Host Controller will send Number Of Completed Packets events\n" \
1872
"for SCO Connection Handles. This setting allows the Host to enable and\n" \
1873
"disable SCO flow control. The SCO_Flow_Control_Enable setting can only be\n" \
1874
"changed if no connections exist.",
1875
&hci_write_sco_flow_control_enable
1876
},
1877
{
1878
"read_link_supervision_timeout <connection_handle>",
1879
"\nThis command will read the value for the Link_Supervision_Timeout\n" \
1880
"parameter for the device. The Link_Supervision_Timeout parameter is used\n" \
1881
"by the master or slave Bluetooth device to monitor link loss. If, for any\n" \
1882
"reason, no Baseband packets are received from that Connection Handle for a\n" \
1883
"duration longer than the Link_Supervision_Timeout, the connection is\n"
1884
"disconnected.\n\n" \
1885
"\t<connection_handle> - dddd; connection handle\n",
1886
&hci_read_link_supervision_timeout
1887
},
1888
{
1889
"write_link_supervision_timeout <connection_handle> <timeout>",
1890
"\nThis command will write the value for the Link_Supervision_Timeout\n" \
1891
"parameter for the device. The Link_Supervision_Timeout parameter is used\n" \
1892
"by the master or slave Bluetooth device to monitor link loss. If, for any\n" \
1893
"reason, no Baseband packets are received from that connection handle for a\n" \
1894
"duration longer than the Link_Supervision_Timeout, the connection is\n" \
1895
"disconnected.\n\n" \
1896
"\t<connection_handle> - dddd; connection handle\n" \
1897
"\t<timeout> - dddd; timeout measured in number of baseband slots\n",
1898
&hci_write_link_supervision_timeout
1899
},
1900
{
1901
"read_page_scan_period_mode",
1902
"\nThis command is used to read the mandatory Page_Scan_Period_Mode of the\n" \
1903
"local Bluetooth device. Every time an inquiry response message is sent, the\n"\
1904
"Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\
1905
"is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \
1906
"expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \
1907
"following page scans.",
1908
&hci_read_page_scan_period_mode
1909
},
1910
{
1911
"write_page_scan_period_mode <page_scan_period_mode>",
1912
"\nThis command is used to write the mandatory Page_Scan_Period_Mode of the\n" \
1913
"local Bluetooth device. Every time an inquiry response message is sent, the\n"\
1914
"Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\
1915
"is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \
1916
"expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \
1917
"following page scans.\n\n" \
1918
"\t<page_scan_period_mode> - dd; page scan period mode:\n" \
1919
"\t0x00 - P0 (Default)\n" \
1920
"\t0x01 - P1\n" \
1921
"\t0x02 - P2",
1922
&hci_write_page_scan_period_mode
1923
},
1924
{
1925
"read_page_scan_mode",
1926
"\nThis command is used to read the default page scan mode of the local\n" \
1927
"Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\
1928
"that is used for the default page scan. Currently one mandatory page scan\n"\
1929
"mode and three optional page scan modes are defined. Following an inquiry\n" \
1930
"response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \
1931
"mandatory page scan mode must be applied.",
1932
&hci_read_page_scan_mode
1933
},
1934
{
1935
"write_page_scan_mode <page_scan_mode>",
1936
"\nThis command is used to write the default page scan mode of the local\n" \
1937
"Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\
1938
"that is used for the default page scan. Currently, one mandatory page scan\n"\
1939
"mode and three optional page scan modes are defined. Following an inquiry\n"\
1940
"response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \
1941
"mandatory page scan mode must be applied.\n\n" \
1942
"\t<page_scan_mode> - dd; page scan mode:\n" \
1943
"\t0x00 - Mandatory Page Scan Mode (Default)\n" \
1944
"\t0x01 - Optional Page Scan Mode I\n" \
1945
"\t0x02 - Optional Page Scan Mode II\n" \
1946
"\t0x03 - Optional Page Scan Mode III",
1947
&hci_write_page_scan_mode
1948
},
1949
{
1950
"read_le_host_support", \
1951
"Read if this host is in LE supported mode and simultaneous LE supported mode",
1952
&hci_read_le_host_support,
1953
},
1954
{
1955
"write_le_host_support", \
1956
"write_le_host_support le_host[0|1] simultaneous_le[0|1]",
1957
&hci_write_le_host_support,
1958
},
1959
1960
{ NULL, }
1961
};
1962
1963
1964