3
* BlueZ - Bluetooth protocol stack for Linux
5
* Copyright (C) 2004-2008 Marcel Holtmann <marcel@holtmann.org>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32
#include <sys/socket.h>
34
#include <bluetooth/bluetooth.h>
35
#include <bluetooth/hci.h>
36
#include <bluetooth/hci_lib.h>
40
#define CSR_TRANSPORT_UNKNOWN 0
41
#define CSR_TRANSPORT_HCI 1
42
#define CSR_TRANSPORT_USB 2
43
#define CSR_TRANSPORT_BCSP 3
44
#define CSR_TRANSPORT_H4 4
45
#define CSR_TRANSPORT_3WIRE 5
47
#define CSR_STORES_PSI (0x0001)
48
#define CSR_STORES_PSF (0x0002)
49
#define CSR_STORES_PSROM (0x0004)
50
#define CSR_STORES_PSRAM (0x0008)
51
#define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF)
53
#define CSR_TYPE_NULL 0
54
#define CSR_TYPE_COMPLEX 1
55
#define CSR_TYPE_UINT8 2
56
#define CSR_TYPE_UINT16 3
57
#define CSR_TYPE_UINT32 4
59
#define CSR_TYPE_ARRAY CSR_TYPE_COMPLEX
60
#define CSR_TYPE_BDADDR CSR_TYPE_COMPLEX
62
static inline int transport_open(int transport, char *device)
65
case CSR_TRANSPORT_HCI:
66
return csr_open_hci(device);
68
case CSR_TRANSPORT_USB:
69
return csr_open_usb(device);
71
case CSR_TRANSPORT_BCSP:
72
return csr_open_bcsp(device);
73
case CSR_TRANSPORT_H4:
74
return csr_open_h4(device);
75
case CSR_TRANSPORT_3WIRE:
76
return csr_open_3wire(device);
78
fprintf(stderr, "Unsupported transport\n");
83
static inline int transport_read(int transport, uint16_t varid, uint8_t *value, uint16_t length)
86
case CSR_TRANSPORT_HCI:
87
return csr_read_hci(varid, value, length);
89
case CSR_TRANSPORT_USB:
90
return csr_read_usb(varid, value, length);
92
case CSR_TRANSPORT_BCSP:
93
return csr_read_bcsp(varid, value, length);
94
case CSR_TRANSPORT_H4:
95
return csr_read_h4(varid, value, length);
96
case CSR_TRANSPORT_3WIRE:
97
return csr_read_3wire(varid, value, length);
104
static inline int transport_write(int transport, uint16_t varid, uint8_t *value, uint16_t length)
107
case CSR_TRANSPORT_HCI:
108
return csr_write_hci(varid, value, length);
110
case CSR_TRANSPORT_USB:
111
return csr_write_usb(varid, value, length);
113
case CSR_TRANSPORT_BCSP:
114
return csr_write_bcsp(varid, value, length);
115
case CSR_TRANSPORT_H4:
116
return csr_write_h4(varid, value, length);
117
case CSR_TRANSPORT_3WIRE:
118
return csr_write_3wire(varid, value, length);
125
static inline void transport_close(int transport)
128
case CSR_TRANSPORT_HCI:
132
case CSR_TRANSPORT_USB:
136
case CSR_TRANSPORT_BCSP:
139
case CSR_TRANSPORT_H4:
142
case CSR_TRANSPORT_3WIRE:
154
{ CSR_PSKEY_BDADDR, CSR_TYPE_BDADDR, 8, "bdaddr" },
155
{ CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, 0, "country" },
156
{ CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, 0, "devclass" },
157
{ CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, 0, "keymin" },
158
{ CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, 0, "keymax" },
159
{ CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, 8, "features" },
160
{ CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, 18, "commands" },
161
{ CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, 0, "version" },
162
{ CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, 0, "remver" },
163
{ CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, 0, "hciextn" },
164
{ CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, 0, "mapsco" },
165
{ CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, 0, "baudrate" },
166
{ CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, 0, "hostintf" },
167
{ CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, 0, "anafreq" },
168
{ CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, 0, "anaftrim" },
169
{ CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, 0, "usbvid" },
170
{ CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, 0, "usbpid" },
171
{ CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, 0, "dfupid" },
172
{ CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, 0, "bootmode" },
176
static char *storestostr(uint16_t stores)
194
static char *memorytostr(uint16_t type)
198
return "Flash memory";
202
return "RAM (transient)";
204
return "ROM (or \"read-only\" flash memory)";
210
#define OPT_RANGE(min, max) \
211
if (argc < (min)) { errno = EINVAL; return -1; } \
212
if (argc > (max)) { errno = E2BIG; return -1; }
214
static struct option help_options[] = {
215
{ "help", 0, 0, 'h' },
219
static int opt_help(int argc, char *argv[], int *help)
223
while ((opt=getopt_long(argc, argv, "+h", help_options, NULL)) != EOF) {
235
#define OPT_HELP(range, help) \
236
opt_help(argc, argv, (help)); \
237
argc -= optind; argv += optind; optind = 0; \
238
OPT_RANGE((range), (range))
240
static int cmd_builddef(int transport, int argc, char *argv[])
243
uint16_t def = 0x0000, nextdef = 0x0000;
248
printf("Build definitions:\n");
251
memset(array, 0, sizeof(array));
252
array[0] = def & 0xff;
255
err = transport_read(transport, CSR_VARID_GET_NEXT_BUILDDEF, array, 8);
261
nextdef = array[2] | (array[3] << 8);
263
if (nextdef == 0x0000)
268
printf("0x%04x - %s\n", def, csr_builddeftostr(def));
274
static int cmd_keylen(int transport, int argc, char *argv[])
277
uint16_t handle, keylen;
282
handle = atoi(argv[0]);
284
memset(array, 0, sizeof(array));
285
array[0] = handle & 0xff;
286
array[1] = handle >> 8;
288
err = transport_read(transport, CSR_VARID_CRYPT_KEY_LENGTH, array, 8);
294
handle = array[0] | (array[1] << 8);
295
keylen = array[2] | (array[3] << 8);
297
printf("Crypt key length: %d bit\n", keylen * 8);
302
static int cmd_clock(int transport, int argc, char *argv[])
310
memset(array, 0, sizeof(array));
312
err = transport_read(transport, CSR_VARID_BT_CLOCK, array, 8);
318
clock = array[2] | (array[3] << 8) | (array[0] << 16) | (array[1] << 24);
320
printf("Bluetooth clock: 0x%04x (%d)\n", clock, clock);
325
static int cmd_rand(int transport, int argc, char *argv[])
333
memset(array, 0, sizeof(array));
335
err = transport_read(transport, CSR_VARID_RAND, array, 8);
341
rand = array[0] | (array[1] << 8);
343
printf("Random number: 0x%02x (%d)\n", rand, rand);
348
static int cmd_chiprev(int transport, int argc, char *argv[])
357
memset(array, 0, sizeof(array));
359
err = transport_read(transport, CSR_VARID_CHIPREV, array, 8);
365
rev = array[0] | (array[1] << 8);
375
str = "BC2-External A";
378
str = "BC2-External B";
384
str = "BC3-Multimedia";
393
str = "BC4-External";
403
printf("Chip revision: 0x%04x (%s)\n", rev, str);
408
static int cmd_buildname(int transport, int argc, char *argv[])
416
memset(array, 0, sizeof(array));
418
err = transport_read(transport, CSR_VARID_READ_BUILD_NAME, array, 128);
424
for (i = 0; i < sizeof(name); i++)
425
name[i] = array[(i * 2) + 4];
427
printf("Build name: %s\n", name);
432
static int cmd_panicarg(int transport, int argc, char *argv[])
440
memset(array, 0, sizeof(array));
442
err = transport_read(transport, CSR_VARID_PANIC_ARG, array, 8);
448
error = array[0] | (array[1] << 8);
450
printf("Panic code: 0x%02x (%s)\n", error,
451
error < 0x100 ? "valid" : "invalid");
456
static int cmd_faultarg(int transport, int argc, char *argv[])
464
memset(array, 0, sizeof(array));
466
err = transport_read(transport, CSR_VARID_FAULT_ARG, array, 8);
472
error = array[0] | (array[1] << 8);
474
printf("Fault code: 0x%02x (%s)\n", error,
475
error < 0x100 ? "valid" : "invalid");
480
static int cmd_coldreset(int transport, int argc, char *argv[])
482
return transport_write(transport, CSR_VARID_COLD_RESET, NULL, 0);
485
static int cmd_warmreset(int transport, int argc, char *argv[])
487
return transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
490
static int cmd_disabletx(int transport, int argc, char *argv[])
492
return transport_write(transport, CSR_VARID_DISABLE_TX, NULL, 0);
495
static int cmd_enabletx(int transport, int argc, char *argv[])
497
return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0);
500
static int cmd_singlechan(int transport, int argc, char *argv[])
507
channel = atoi(argv[0]);
509
if (channel > 2401 && channel < 2481)
517
memset(array, 0, sizeof(array));
518
array[0] = channel & 0xff;
519
array[1] = channel >> 8;
521
return transport_write(transport, CSR_VARID_SINGLE_CHAN, array, 8);
524
static int cmd_hoppingon(int transport, int argc, char *argv[])
526
return transport_write(transport, CSR_VARID_HOPPING_ON, NULL, 0);
529
static int cmd_rttxdata1(int transport, int argc, char *argv[])
532
uint16_t freq, level;
536
freq = atoi(argv[0]);
538
if (!strncasecmp(argv[1], "0x", 2))
539
level = strtol(argv[1], NULL, 16);
541
level = atoi(argv[1]);
543
memset(array, 0, sizeof(array));
546
array[2] = freq & 0xff;
547
array[3] = freq >> 8;
548
array[4] = level & 0xff;
549
array[5] = level >> 8;
551
return transport_write(transport, CSR_VARID_RADIOTEST, array, 8);
554
static int cmd_radiotest(int transport, int argc, char *argv[])
557
uint16_t freq, level, test;
561
freq = atoi(argv[0]);
563
if (!strncasecmp(argv[1], "0x", 2))
564
level = strtol(argv[1], NULL, 16);
566
level = atoi(argv[1]);
568
test = atoi(argv[2]);
570
memset(array, 0, sizeof(array));
571
array[0] = test & 0xff;
572
array[1] = test >> 8;
573
array[2] = freq & 0xff;
574
array[3] = freq >> 8;
575
array[4] = level & 0xff;
576
array[5] = level >> 8;
578
return transport_write(transport, CSR_VARID_RADIOTEST, array, 8);
581
static int cmd_memtypes(int transport, int argc, char *argv[])
584
uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 };
589
for (i = 0; i < 4; i++) {
590
memset(array, 0, sizeof(array));
591
array[0] = stores[i] & 0xff;
592
array[1] = stores[i] >> 8;
594
err = transport_read(transport, CSR_VARID_PS_MEMORY_TYPE, array, 8);
598
type = array[2] + (array[3] << 8);
600
printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]),
601
stores[i], memorytostr(type), type);
607
static struct option pskey_options[] = {
608
{ "stores", 1, 0, 's' },
609
{ "reset", 0, 0, 'r' },
610
{ "help", 0, 0, 'h' },
614
static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int *help)
618
while ((opt=getopt_long(argc, argv, "+s:rh", pskey_options, NULL)) != EOF) {
623
if (!strcasecmp(optarg, "default"))
625
else if (!strcasecmp(optarg, "implementation"))
627
else if (!strcasecmp(optarg, "factory"))
629
else if (!strcasecmp(optarg, "rom"))
631
else if (!strcasecmp(optarg, "ram"))
633
else if (!strcasecmp(optarg, "psi"))
635
else if (!strcasecmp(optarg, "psf"))
637
else if (!strcasecmp(optarg, "psrom"))
639
else if (!strcasecmp(optarg, "psram"))
641
else if (!strncasecmp(optarg, "0x", 2))
642
*stores = strtol(optarg, NULL, 16);
644
*stores = atoi(optarg);
662
#define OPT_PSKEY(min, max, stores, reset, help) \
663
opt_pskey(argc, argv, (stores), (reset), (help)); \
664
argc -= optind; argv += optind; optind = 0; \
665
OPT_RANGE((min), (max))
667
static int cmd_psget(int transport, int argc, char *argv[])
670
uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT;
672
int i, err, reset = 0;
674
memset(array, 0, sizeof(array));
676
OPT_PSKEY(1, 1, &stores, &reset, NULL);
678
if (strncasecmp(argv[0], "0x", 2)) {
679
pskey = atoi(argv[0]);
681
for (i = 0; storage[i].pskey; i++) {
682
if (strcasecmp(storage[i].str, argv[0]))
685
pskey = storage[i].pskey;
689
pskey = strtol(argv[0] + 2, NULL, 16);
691
memset(array, 0, sizeof(array));
692
array[0] = pskey & 0xff;
693
array[1] = pskey >> 8;
694
array[2] = stores & 0xff;
695
array[3] = stores >> 8;
697
err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
701
length = array[2] + (array[3] << 8);
702
if (length + 6 > sizeof(array) / 2)
705
memset(array, 0, sizeof(array));
706
array[0] = pskey & 0xff;
707
array[1] = pskey >> 8;
708
array[2] = length & 0xff;
709
array[3] = length >> 8;
710
array[4] = stores & 0xff;
711
array[5] = stores >> 8;
713
err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2);
719
value = array[6] | (array[7] << 8);
720
printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value);
724
val32 = array[8] | (array[9] << 8) | (array[6] << 16) | (array[7] << 24);
725
printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32);
729
printf("%s:", csr_pskeytostr(pskey));
730
for (i = 0; i < length; i++)
731
printf(" 0x%02x%02x", array[(i * 2) + 6], array[(i * 2) + 7]);
737
transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
742
static int cmd_psset(int transport, int argc, char *argv[])
745
uint16_t pskey, length, value, stores = CSR_STORES_PSRAM;
747
int i, err, reset = 0;
749
memset(array, 0, sizeof(array));
751
OPT_PSKEY(2, 81, &stores, &reset, NULL);
753
if (strncasecmp(argv[0], "0x", 2)) {
754
pskey = atoi(argv[0]);
756
for (i = 0; storage[i].pskey; i++) {
757
if (strcasecmp(storage[i].str, argv[0]))
760
pskey = storage[i].pskey;
764
pskey = strtol(argv[0] + 2, NULL, 16);
766
memset(array, 0, sizeof(array));
767
array[0] = pskey & 0xff;
768
array[1] = pskey >> 8;
769
array[2] = stores & 0xff;
770
array[3] = stores >> 8;
772
err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
776
length = array[2] + (array[3] << 8);
777
if (length + 6 > sizeof(array) / 2)
780
memset(array, 0, sizeof(array));
781
array[0] = pskey & 0xff;
782
array[1] = pskey >> 8;
783
array[2] = length & 0xff;
784
array[3] = length >> 8;
785
array[4] = stores & 0xff;
786
array[5] = stores >> 8;
798
if (!strncasecmp(argv[0], "0x", 2))
799
value = strtol(argv[0] + 2, NULL, 16);
801
value = atoi(argv[0]);
803
array[6] = value & 0xff;
804
array[7] = value >> 8;
813
if (!strncasecmp(argv[0], "0x", 2))
814
val32 = strtol(argv[0] + 2, NULL, 16);
816
val32 = atoi(argv[0]);
818
array[6] = (val32 & 0xff0000) >> 16;
819
array[7] = val32 >> 24;
820
array[8] = val32 & 0xff;
821
array[9] = (val32 & 0xff00) >> 8;
825
if (argc != length * 2) {
830
for (i = 0; i < length * 2; i++)
831
if (!strncasecmp(argv[0], "0x", 2))
832
array[i + 6] = strtol(argv[i] + 2, NULL, 16);
834
array[i + 6] = atoi(argv[i]);
838
err = transport_write(transport, CSR_VARID_PS, array, (length + 3) * 2);
843
transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
848
static int cmd_psclr(int transport, int argc, char *argv[])
851
uint16_t pskey, stores = CSR_STORES_PSRAM;
852
int i, err, reset = 0;
854
OPT_PSKEY(1, 1, &stores, &reset, NULL);
856
if (strncasecmp(argv[0], "0x", 2)) {
857
pskey = atoi(argv[0]);
859
for (i = 0; storage[i].pskey; i++) {
860
if (strcasecmp(storage[i].str, argv[0]))
863
pskey = storage[i].pskey;
867
pskey = strtol(argv[0] + 2, NULL, 16);
869
memset(array, 0, sizeof(array));
870
array[0] = pskey & 0xff;
871
array[1] = pskey >> 8;
872
array[2] = stores & 0xff;
873
array[3] = stores >> 8;
875
err = transport_write(transport, CSR_VARID_PS_CLR_STORES, array, 8);
880
transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
885
static int cmd_pslist(int transport, int argc, char *argv[])
888
uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT;
891
OPT_PSKEY(0, 0, &stores, &reset, NULL);
894
memset(array, 0, sizeof(array));
895
array[0] = pskey & 0xff;
896
array[1] = pskey >> 8;
897
array[2] = stores & 0xff;
898
array[3] = stores >> 8;
900
err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8);
904
pskey = array[4] + (array[5] << 8);
908
memset(array, 0, sizeof(array));
909
array[0] = pskey & 0xff;
910
array[1] = pskey >> 8;
911
array[2] = stores & 0xff;
912
array[3] = stores >> 8;
914
err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
918
length = array[2] + (array[3] << 8);
920
printf("0x%04x - %s (%d bytes)\n", pskey,
921
csr_pskeytostr(pskey), length * 2);
925
transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
930
static int cmd_psread(int transport, int argc, char *argv[])
933
uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT;
935
int i, err, reset = 0;
937
OPT_PSKEY(0, 0, &stores, &reset, NULL);
940
memset(array, 0, sizeof(array));
941
array[0] = pskey & 0xff;
942
array[1] = pskey >> 8;
943
array[2] = stores & 0xff;
944
array[3] = stores >> 8;
946
err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8);
950
pskey = array[4] + (array[5] << 8);
954
memset(array, 0, sizeof(array));
955
array[0] = pskey & 0xff;
956
array[1] = pskey >> 8;
957
array[2] = stores & 0xff;
958
array[3] = stores >> 8;
960
err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
964
length = array[2] + (array[3] << 8);
965
if (length + 6 > sizeof(array) / 2)
968
memset(array, 0, sizeof(array));
969
array[0] = pskey & 0xff;
970
array[1] = pskey >> 8;
971
array[2] = length & 0xff;
972
array[3] = length >> 8;
973
array[4] = stores & 0xff;
974
array[5] = stores >> 8;
976
err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2);
980
str = csr_pskeytoval(pskey);
981
if (!strcasecmp(str, "UNKNOWN")) {
982
sprintf(val, "0x%04x", pskey);
986
printf("// %s%s\n&%04x =", str ? "PSKEY_" : "",
987
str ? str : val, pskey);
988
for (i = 0; i < length; i++)
989
printf(" %02x%02x", array[(i * 2) + 7], array[(i * 2) + 6]);
994
transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
999
static int cmd_psload(int transport, int argc, char *argv[])
1002
uint16_t pskey, length, size, stores = CSR_STORES_PSRAM;
1006
OPT_PSKEY(1, 1, &stores, &reset, NULL);
1010
memset(array, 0, sizeof(array));
1011
size = sizeof(array) - 6;
1013
while (psr_get(&pskey, array + 6, &size) == 0) {
1014
str = csr_pskeytoval(pskey);
1015
if (!strcasecmp(str, "UNKNOWN")) {
1016
sprintf(val, "0x%04x", pskey);
1020
printf("Loading %s%s ... ", str ? "PSKEY_" : "",
1026
array[0] = pskey & 0xff;
1027
array[1] = pskey >> 8;
1028
array[2] = length & 0xff;
1029
array[3] = length >> 8;
1030
array[4] = stores & 0xff;
1031
array[5] = stores >> 8;
1033
err = transport_write(transport, CSR_VARID_PS, array, size + 6);
1035
printf("%s\n", err < 0 ? "failed" : "done");
1037
memset(array, 0, sizeof(array));
1038
size = sizeof(array) - 6;
1042
transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
1047
static int cmd_pscheck(int transport, int argc, char *argv[])
1050
uint16_t pskey, size;
1057
while (psr_get(&pskey, array, &size) == 0) {
1058
printf("0x%04x =", pskey);
1059
for (i = 0; i < size; i++)
1060
printf(" 0x%02x", array[i]);
1069
int (*func)(int transport, int argc, char *argv[]);
1073
{ "builddef", cmd_builddef, "", "Get build definitions" },
1074
{ "keylen", cmd_keylen, "<handle>", "Get current crypt key length" },
1075
{ "clock", cmd_clock, "", "Get local Bluetooth clock" },
1076
{ "rand", cmd_rand, "", "Get random number" },
1077
{ "chiprev", cmd_chiprev, "", "Get chip revision" },
1078
{ "buildname", cmd_buildname, "", "Get the full build name" },
1079
{ "panicarg", cmd_panicarg, "", "Get panic code argument" },
1080
{ "faultarg", cmd_faultarg, "", "Get fault code argument" },
1081
{ "coldreset", cmd_coldreset, "", "Perform cold reset" },
1082
{ "warmreset", cmd_warmreset, "", "Perform warm reset" },
1083
{ "disabletx", cmd_disabletx, "", "Disable TX on the device" },
1084
{ "enabletx", cmd_enabletx, "", "Enable TX on the device" },
1085
{ "singlechan",cmd_singlechan,"<channel>", "Lock radio on specific channel" },
1086
{ "hoppingon", cmd_hoppingon, "", "Revert to channel hopping" },
1087
{ "rttxdata1", cmd_rttxdata1, "<freq> <level>", "TXData1 radio test" },
1088
{ "radiotest", cmd_radiotest, "<freq> <level> <id>", "Run radio tests" },
1089
{ "memtypes", cmd_memtypes, NULL, "Get memory types" },
1090
{ "psget", cmd_psget, "<key>", "Get value for PS key" },
1091
{ "psset", cmd_psset, "<key> <value>", "Set value for PS key" },
1092
{ "psclr", cmd_psclr, "<key>", "Clear value for PS key" },
1093
{ "pslist", cmd_pslist, NULL, "List all PS keys" },
1094
{ "psread", cmd_psread, NULL, "Read all PS keys" },
1095
{ "psload", cmd_psload, "<file>", "Load all PS keys from PSR file" },
1096
{ "pscheck", cmd_pscheck, "<file>", "Check PSR file" },
1100
static void usage(void)
1104
printf("bccmd - Utility for the CSR BCCMD interface\n\n");
1106
"\tbccmd [options] <command>\n\n");
1109
"\t-t <transport> Select the transport\n"
1110
"\t-d <device> Select the device\n"
1111
"\t-h, --help Display help\n"
1114
printf("Transports:\n"
1115
"\tHCI USB BCSP H4 3WIRE\n\n");
1117
printf("Commands:\n");
1118
for (i = 0; commands[i].str; i++)
1119
printf("\t%-10s %-20s\t%s\n", commands[i].str,
1120
commands[i].arg ? commands[i].arg : " ",
1124
printf("Keys:\n\t");
1125
for (i = 0; storage[i].pskey; i++) {
1126
printf("%s ", storage[i].str);
1127
pos += strlen(storage[i].str) + 1;
1136
static struct option main_options[] = {
1137
{ "transport", 1, 0, 't' },
1138
{ "device", 1, 0, 'd' },
1139
{ "help", 0, 0, 'h' },
1143
int main(int argc, char *argv[])
1145
char *device = NULL;
1146
int i, err, opt, transport = CSR_TRANSPORT_HCI;
1148
while ((opt=getopt_long(argc, argv, "+t:d:i:h", main_options, NULL)) != EOF) {
1151
if (!strcasecmp(optarg, "hci"))
1152
transport = CSR_TRANSPORT_HCI;
1153
else if (!strcasecmp(optarg, "usb"))
1154
transport = CSR_TRANSPORT_USB;
1155
else if (!strcasecmp(optarg, "bcsp"))
1156
transport = CSR_TRANSPORT_BCSP;
1157
else if (!strcasecmp(optarg, "h4"))
1158
transport = CSR_TRANSPORT_H4;
1159
else if (!strcasecmp(optarg, "h5"))
1160
transport = CSR_TRANSPORT_3WIRE;
1161
else if (!strcasecmp(optarg, "3wire"))
1162
transport = CSR_TRANSPORT_3WIRE;
1163
else if (!strcasecmp(optarg, "twutl"))
1164
transport = CSR_TRANSPORT_3WIRE;
1166
transport = CSR_TRANSPORT_UNKNOWN;
1171
device = strdup(optarg);
1190
if (transport_open(transport, device) < 0)
1196
for (i = 0; commands[i].str; i++) {
1197
if (strcasecmp(commands[i].str, argv[0]))
1200
err = commands[i].func(transport, argc, argv);
1202
transport_close(transport);
1205
fprintf(stderr, "Can't execute command: %s (%d)\n",
1206
strerror(errno), errno);
1213
fprintf(stderr, "Unsupported command\n");
1215
transport_close(transport);