3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2004-2010 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>
35 #include "lib/bluetooth.h"
37 #include "lib/hci_lib.h"
41 #define CSR_TRANSPORT_UNKNOWN 0
42 #define CSR_TRANSPORT_HCI 1
43 #define CSR_TRANSPORT_USB 2
44 #define CSR_TRANSPORT_BCSP 3
45 #define CSR_TRANSPORT_H4 4
46 #define CSR_TRANSPORT_3WIRE 5
48 #define CSR_STORES_PSI (0x0001)
49 #define CSR_STORES_PSF (0x0002)
50 #define CSR_STORES_PSROM (0x0004)
51 #define CSR_STORES_PSRAM (0x0008)
52 #define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF)
54 #define CSR_TYPE_NULL 0
55 #define CSR_TYPE_COMPLEX 1
56 #define CSR_TYPE_UINT8 2
57 #define CSR_TYPE_UINT16 3
58 #define CSR_TYPE_UINT32 4
60 #define CSR_TYPE_ARRAY CSR_TYPE_COMPLEX
61 #define CSR_TYPE_BDADDR CSR_TYPE_COMPLEX
63 static inline int transport_open(int transport, char *device, speed_t bcsp_rate)
66 case CSR_TRANSPORT_HCI:
67 return csr_open_hci(device);
68 case CSR_TRANSPORT_USB:
69 return csr_open_usb(device);
70 case CSR_TRANSPORT_BCSP:
71 return csr_open_bcsp(device, bcsp_rate);
72 case CSR_TRANSPORT_H4:
73 return csr_open_h4(device);
74 case CSR_TRANSPORT_3WIRE:
75 return csr_open_3wire(device);
77 fprintf(stderr, "Unsupported transport\n");
82 static inline int transport_read(int transport, uint16_t varid, uint8_t *value, uint16_t length)
85 case CSR_TRANSPORT_HCI:
86 return csr_read_hci(varid, value, length);
87 case CSR_TRANSPORT_USB:
88 return csr_read_usb(varid, value, length);
89 case CSR_TRANSPORT_BCSP:
90 return csr_read_bcsp(varid, value, length);
91 case CSR_TRANSPORT_H4:
92 return csr_read_h4(varid, value, length);
93 case CSR_TRANSPORT_3WIRE:
94 return csr_read_3wire(varid, value, length);
101 static inline int transport_write(int transport, uint16_t varid, uint8_t *value, uint16_t length)
104 case CSR_TRANSPORT_HCI:
105 return csr_write_hci(varid, value, length);
106 case CSR_TRANSPORT_USB:
107 return csr_write_usb(varid, value, length);
108 case CSR_TRANSPORT_BCSP:
109 return csr_write_bcsp(varid, value, length);
110 case CSR_TRANSPORT_H4:
111 return csr_write_h4(varid, value, length);
112 case CSR_TRANSPORT_3WIRE:
113 return csr_write_3wire(varid, value, length);
120 static inline void transport_close(int transport)
123 case CSR_TRANSPORT_HCI:
126 case CSR_TRANSPORT_USB:
129 case CSR_TRANSPORT_BCSP:
132 case CSR_TRANSPORT_H4:
135 case CSR_TRANSPORT_3WIRE:
147 { CSR_PSKEY_BDADDR, CSR_TYPE_BDADDR, 8, "bdaddr" },
148 { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, 0, "country" },
149 { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, 0, "devclass" },
150 { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, 0, "keymin" },
151 { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, 0, "keymax" },
152 { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, 8, "features" },
153 { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, 18, "commands" },
154 { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, 0, "version" },
155 { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, 0, "remver" },
156 { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, 0, "hciextn" },
157 { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, 0, "mapsco" },
158 { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, 0, "baudrate" },
159 { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, 0, "hostintf" },
160 { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, 0, "anafreq" },
161 { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, 0, "anaftrim" },
162 { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, 0, "usbvid" },
163 { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, 0, "usbpid" },
164 { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, 0, "dfupid" },
165 { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, 0, "bootmode" },
169 static char *storestostr(uint16_t stores)
187 static char *memorytostr(uint16_t type)
191 return "Flash memory";
195 return "RAM (transient)";
197 return "ROM (or \"read-only\" flash memory)";
203 #define OPT_RANGE(min, max) \
204 if (argc < (min)) { errno = EINVAL; return -1; } \
205 if (argc > (max)) { errno = E2BIG; return -1; }
207 static struct option help_options[] = {
208 { "help", 0, 0, 'h' },
212 static int opt_help(int argc, char *argv[], int *help)
216 while ((opt=getopt_long(argc, argv, "+h", help_options, NULL)) != EOF) {
228 #define OPT_HELP(range, help) \
229 opt_help(argc, argv, (help)); \
230 argc -= optind; argv += optind; optind = 0; \
231 OPT_RANGE((range), (range))
233 static int cmd_builddef(int transport, int argc, char *argv[])
236 uint16_t def = 0x0000, nextdef = 0x0000;
241 printf("Build definitions:\n");
244 memset(array, 0, sizeof(array));
245 array[0] = def & 0xff;
248 err = transport_read(transport, CSR_VARID_GET_NEXT_BUILDDEF, array, 8);
252 nextdef = array[2] | (array[3] << 8);
254 if (nextdef == 0x0000)
259 printf("0x%04x - %s\n", def, csr_builddeftostr(def));
265 static int cmd_keylen(int transport, int argc, char *argv[])
268 uint16_t handle, keylen;
273 handle = atoi(argv[0]);
275 memset(array, 0, sizeof(array));
276 array[0] = handle & 0xff;
277 array[1] = handle >> 8;
279 err = transport_read(transport, CSR_VARID_CRYPT_KEY_LENGTH, array, 8);
283 keylen = array[2] | (array[3] << 8);
285 printf("Crypt key length: %d bit\n", keylen * 8);
290 static int cmd_clock(int transport, int argc, char *argv[])
298 memset(array, 0, sizeof(array));
300 err = transport_read(transport, CSR_VARID_BT_CLOCK, array, 8);
304 clock = array[2] | (array[3] << 8) | (array[0] << 16) | (array[1] << 24);
306 printf("Bluetooth clock: 0x%04x (%d)\n", clock, clock);
311 static int cmd_rand(int transport, int argc, char *argv[])
319 memset(array, 0, sizeof(array));
321 err = transport_read(transport, CSR_VARID_RAND, array, 8);
325 rand = array[0] | (array[1] << 8);
327 printf("Random number: 0x%02x (%d)\n", rand, rand);
332 static int cmd_chiprev(int transport, int argc, char *argv[])
341 memset(array, 0, sizeof(array));
343 err = transport_read(transport, CSR_VARID_CHIPREV, array, 8);
347 rev = array[0] | (array[1] << 8);
357 str = "BC2-External A";
360 str = "BC2-External B";
366 str = "BC3-Multimedia";
375 str = "BC4-External";
385 printf("Chip revision: 0x%04x (%s)\n", rev, str);
390 static int cmd_buildname(int transport, int argc, char *argv[])
399 memset(array, 0, sizeof(array));
401 err = transport_read(transport, CSR_VARID_READ_BUILD_NAME, array, 128);
405 for (i = 0; i < sizeof(name); i++)
406 name[i] = array[(i * 2) + 4];
408 printf("Build name: %s\n", name);
413 static int cmd_panicarg(int transport, int argc, char *argv[])
421 memset(array, 0, sizeof(array));
423 err = transport_read(transport, CSR_VARID_PANIC_ARG, array, 8);
427 error = array[0] | (array[1] << 8);
429 printf("Panic code: 0x%02x (%s)\n", error,
430 error < 0x100 ? "valid" : "invalid");
435 static int cmd_faultarg(int transport, int argc, char *argv[])
443 memset(array, 0, sizeof(array));
445 err = transport_read(transport, CSR_VARID_FAULT_ARG, array, 8);
449 error = array[0] | (array[1] << 8);
451 printf("Fault code: 0x%02x (%s)\n", error,
452 error < 0x100 ? "valid" : "invalid");
457 static int cmd_coldreset(int transport, int argc, char *argv[])
459 return transport_write(transport, CSR_VARID_COLD_RESET, NULL, 0);
462 static int cmd_warmreset(int transport, int argc, char *argv[])
464 return transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
467 static int cmd_disabletx(int transport, int argc, char *argv[])
469 return transport_write(transport, CSR_VARID_DISABLE_TX, NULL, 0);
472 static int cmd_enabletx(int transport, int argc, char *argv[])
474 return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0);
477 static int cmd_singlechan(int transport, int argc, char *argv[])
484 channel = atoi(argv[0]);
486 if (channel > 2401 && channel < 2481)
494 memset(array, 0, sizeof(array));
495 array[0] = channel & 0xff;
496 array[1] = channel >> 8;
498 return transport_write(transport, CSR_VARID_SINGLE_CHAN, array, 8);
501 static int cmd_hoppingon(int transport, int argc, char *argv[])
503 return transport_write(transport, CSR_VARID_HOPPING_ON, NULL, 0);
506 static int cmd_rttxdata1(int transport, int argc, char *argv[])
509 uint16_t freq, level;
513 freq = atoi(argv[0]);
515 if (!strncasecmp(argv[1], "0x", 2))
516 level = strtol(argv[1], NULL, 16);
518 level = atoi(argv[1]);
520 memset(array, 0, sizeof(array));
523 array[2] = freq & 0xff;
524 array[3] = freq >> 8;
525 array[4] = level & 0xff;
526 array[5] = level >> 8;
528 return transport_write(transport, CSR_VARID_RADIOTEST, array, 8);
531 static int cmd_radiotest(int transport, int argc, char *argv[])
534 uint16_t freq, level, test;
538 freq = atoi(argv[0]);
540 if (!strncasecmp(argv[1], "0x", 2))
541 level = strtol(argv[1], NULL, 16);
543 level = atoi(argv[1]);
545 test = atoi(argv[2]);
547 memset(array, 0, sizeof(array));
548 array[0] = test & 0xff;
549 array[1] = test >> 8;
550 array[2] = freq & 0xff;
551 array[3] = freq >> 8;
552 array[4] = level & 0xff;
553 array[5] = level >> 8;
555 return transport_write(transport, CSR_VARID_RADIOTEST, array, 8);
558 static int cmd_memtypes(int transport, int argc, char *argv[])
561 uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 };
566 for (i = 0; i < 4; i++) {
567 memset(array, 0, sizeof(array));
568 array[0] = stores[i] & 0xff;
569 array[1] = stores[i] >> 8;
571 err = transport_read(transport, CSR_VARID_PS_MEMORY_TYPE, array, 8);
575 type = array[2] + (array[3] << 8);
577 printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]),
578 stores[i], memorytostr(type), type);
584 static struct option pskey_options[] = {
585 { "stores", 1, 0, 's' },
586 { "reset", 0, 0, 'r' },
587 { "help", 0, 0, 'h' },
591 static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int *help)
595 while ((opt=getopt_long(argc, argv, "+s:rh", pskey_options, NULL)) != EOF) {
600 if (!strcasecmp(optarg, "default"))
602 else if (!strcasecmp(optarg, "implementation"))
604 else if (!strcasecmp(optarg, "factory"))
606 else if (!strcasecmp(optarg, "rom"))
608 else if (!strcasecmp(optarg, "ram"))
610 else if (!strcasecmp(optarg, "psi"))
612 else if (!strcasecmp(optarg, "psf"))
614 else if (!strcasecmp(optarg, "psrom"))
616 else if (!strcasecmp(optarg, "psram"))
618 else if (!strncasecmp(optarg, "0x", 2))
619 *stores = strtol(optarg, NULL, 16);
621 *stores = atoi(optarg);
639 #define OPT_PSKEY(min, max, stores, reset, help) \
640 opt_pskey(argc, argv, (stores), (reset), (help)); \
641 argc -= optind; argv += optind; optind = 0; \
642 OPT_RANGE((min), (max))
644 static int cmd_psget(int transport, int argc, char *argv[])
647 uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT;
649 int i, err, reset = 0;
651 memset(array, 0, sizeof(array));
653 OPT_PSKEY(1, 1, &stores, &reset, NULL);
655 if (strncasecmp(argv[0], "0x", 2)) {
656 pskey = atoi(argv[0]);
658 for (i = 0; storage[i].pskey; i++) {
659 if (strcasecmp(storage[i].str, argv[0]))
662 pskey = storage[i].pskey;
666 pskey = strtol(argv[0] + 2, NULL, 16);
668 memset(array, 0, sizeof(array));
669 array[0] = pskey & 0xff;
670 array[1] = pskey >> 8;
671 array[2] = stores & 0xff;
672 array[3] = stores >> 8;
674 err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
678 length = array[2] + (array[3] << 8);
679 if (length + 6 > (int) sizeof(array) / 2)
682 memset(array, 0, sizeof(array));
683 array[0] = pskey & 0xff;
684 array[1] = pskey >> 8;
685 array[2] = length & 0xff;
686 array[3] = length >> 8;
687 array[4] = stores & 0xff;
688 array[5] = stores >> 8;
690 err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2);
696 value = array[6] | (array[7] << 8);
697 printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value);
701 val32 = array[8] | (array[9] << 8) | (array[6] << 16) | (array[7] << 24);
702 printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32);
706 printf("%s:", csr_pskeytostr(pskey));
707 for (i = 0; i < length; i++)
708 printf(" 0x%02x%02x", array[(i * 2) + 6], array[(i * 2) + 7]);
714 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
719 static int cmd_psset(int transport, int argc, char *argv[])
722 uint16_t pskey, length, value, stores = CSR_STORES_PSRAM;
724 int i, err, reset = 0;
726 memset(array, 0, sizeof(array));
728 OPT_PSKEY(2, 81, &stores, &reset, NULL);
730 if (strncasecmp(argv[0], "0x", 2)) {
731 pskey = atoi(argv[0]);
733 for (i = 0; storage[i].pskey; i++) {
734 if (strcasecmp(storage[i].str, argv[0]))
737 pskey = storage[i].pskey;
741 pskey = strtol(argv[0] + 2, NULL, 16);
743 memset(array, 0, sizeof(array));
744 array[0] = pskey & 0xff;
745 array[1] = pskey >> 8;
746 array[2] = stores & 0xff;
747 array[3] = stores >> 8;
749 err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
753 length = array[2] + (array[3] << 8);
754 if (length + 6 > (int) sizeof(array) / 2)
757 memset(array, 0, sizeof(array));
758 array[0] = pskey & 0xff;
759 array[1] = pskey >> 8;
760 array[2] = length & 0xff;
761 array[3] = length >> 8;
762 array[4] = stores & 0xff;
763 array[5] = stores >> 8;
775 if (!strncasecmp(argv[0], "0x", 2))
776 value = strtol(argv[0] + 2, NULL, 16);
778 value = atoi(argv[0]);
780 array[6] = value & 0xff;
781 array[7] = value >> 8;
790 if (!strncasecmp(argv[0], "0x", 2))
791 val32 = strtol(argv[0] + 2, NULL, 16);
793 val32 = atoi(argv[0]);
795 array[6] = (val32 & 0xff0000) >> 16;
796 array[7] = val32 >> 24;
797 array[8] = val32 & 0xff;
798 array[9] = (val32 & 0xff00) >> 8;
802 if (argc != length * 2) {
807 for (i = 0; i < length * 2; i++)
808 if (!strncasecmp(argv[0], "0x", 2))
809 array[i + 6] = strtol(argv[i] + 2, NULL, 16);
811 array[i + 6] = atoi(argv[i]);
815 err = transport_write(transport, CSR_VARID_PS, array, (length + 3) * 2);
820 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
825 static int cmd_psclr(int transport, int argc, char *argv[])
828 uint16_t pskey, stores = CSR_STORES_PSRAM;
829 int i, err, reset = 0;
831 OPT_PSKEY(1, 1, &stores, &reset, NULL);
833 if (strncasecmp(argv[0], "0x", 2)) {
834 pskey = atoi(argv[0]);
836 for (i = 0; storage[i].pskey; i++) {
837 if (strcasecmp(storage[i].str, argv[0]))
840 pskey = storage[i].pskey;
844 pskey = strtol(argv[0] + 2, NULL, 16);
846 memset(array, 0, sizeof(array));
847 array[0] = pskey & 0xff;
848 array[1] = pskey >> 8;
849 array[2] = stores & 0xff;
850 array[3] = stores >> 8;
852 err = transport_write(transport, CSR_VARID_PS_CLR_STORES, array, 8);
857 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
862 static int cmd_pslist(int transport, int argc, char *argv[])
865 uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT;
868 OPT_PSKEY(0, 0, &stores, &reset, NULL);
871 memset(array, 0, sizeof(array));
872 array[0] = pskey & 0xff;
873 array[1] = pskey >> 8;
874 array[2] = stores & 0xff;
875 array[3] = stores >> 8;
877 err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8);
881 pskey = array[4] + (array[5] << 8);
885 memset(array, 0, sizeof(array));
886 array[0] = pskey & 0xff;
887 array[1] = pskey >> 8;
888 array[2] = stores & 0xff;
889 array[3] = stores >> 8;
891 err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
895 length = array[2] + (array[3] << 8);
897 printf("0x%04x - %s (%d bytes)\n", pskey,
898 csr_pskeytostr(pskey), length * 2);
902 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
907 static int cmd_psread(int transport, int argc, char *argv[])
910 uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT;
912 int i, err, reset = 0;
914 OPT_PSKEY(0, 0, &stores, &reset, NULL);
917 memset(array, 0, sizeof(array));
918 array[0] = pskey & 0xff;
919 array[1] = pskey >> 8;
920 array[2] = stores & 0xff;
921 array[3] = stores >> 8;
923 err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8);
927 pskey = array[4] + (array[5] << 8);
931 memset(array, 0, sizeof(array));
932 array[0] = pskey & 0xff;
933 array[1] = pskey >> 8;
934 array[2] = stores & 0xff;
935 array[3] = stores >> 8;
937 err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
941 length = array[2] + (array[3] << 8);
942 if (length + 6 > (int) sizeof(array) / 2)
945 memset(array, 0, sizeof(array));
946 array[0] = pskey & 0xff;
947 array[1] = pskey >> 8;
948 array[2] = length & 0xff;
949 array[3] = length >> 8;
950 array[4] = stores & 0xff;
951 array[5] = stores >> 8;
953 err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2);
957 str = csr_pskeytoval(pskey);
958 if (!strcasecmp(str, "UNKNOWN")) {
959 sprintf(val, "0x%04x", pskey);
963 printf("// %s%s\n&%04x =", str ? "PSKEY_" : "",
964 str ? str : val, pskey);
965 for (i = 0; i < length; i++)
966 printf(" %02x%02x", array[(i * 2) + 7], array[(i * 2) + 6]);
971 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
976 static int cmd_psload(int transport, int argc, char *argv[])
979 uint16_t pskey, length, size, stores = CSR_STORES_PSRAM;
983 OPT_PSKEY(1, 1, &stores, &reset, NULL);
987 memset(array, 0, sizeof(array));
988 size = sizeof(array) - 6;
990 while (psr_get(&pskey, array + 6, &size) == 0) {
991 str = csr_pskeytoval(pskey);
992 if (!strcasecmp(str, "UNKNOWN")) {
993 sprintf(val, "0x%04x", pskey);
997 printf("Loading %s%s ... ", str ? "PSKEY_" : "",
1003 array[0] = pskey & 0xff;
1004 array[1] = pskey >> 8;
1005 array[2] = length & 0xff;
1006 array[3] = length >> 8;
1007 array[4] = stores & 0xff;
1008 array[5] = stores >> 8;
1010 err = transport_write(transport, CSR_VARID_PS, array, size + 6);
1012 printf("%s\n", err < 0 ? "failed" : "done");
1014 memset(array, 0, sizeof(array));
1015 size = sizeof(array) - 6;
1019 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
1024 static int cmd_pscheck(int transport, int argc, char *argv[])
1027 uint16_t pskey, size;
1034 while (psr_get(&pskey, array, &size) == 0) {
1035 printf("0x%04x =", pskey);
1036 for (i = 0; i < size; i++)
1037 printf(" 0x%02x", array[i]);
1044 static int cmd_adc(int transport, int argc, char *argv[])
1047 uint16_t mux, value;
1052 if (!strncasecmp(argv[0], "0x", 2))
1053 mux = strtol(argv[0], NULL, 16);
1055 mux = atoi(argv[0]);
1057 /* Request an ADC read from a particular mux'ed input */
1058 memset(array, 0, sizeof(array));
1059 array[0] = mux & 0xff;
1060 array[1] = mux >> 8;
1062 err = transport_write(transport, CSR_VARID_ADC, array, 2);
1068 /* have to wait a short while, then read result */
1070 err = transport_read(transport, CSR_VARID_ADC_RES, array, 8);
1076 mux = array[0] | (array[1] << 8);
1077 value = array[4] | (array[5] << 8);
1079 printf("ADC value from Mux 0x%02x : 0x%04x (%s)\n", mux, value,
1080 array[2] == 1 ? "valid" : "invalid");
1087 int (*func)(int transport, int argc, char *argv[]);
1091 { "builddef", cmd_builddef, "", "Get build definitions" },
1092 { "keylen", cmd_keylen, "<handle>", "Get current crypt key length" },
1093 { "clock", cmd_clock, "", "Get local Bluetooth clock" },
1094 { "rand", cmd_rand, "", "Get random number" },
1095 { "chiprev", cmd_chiprev, "", "Get chip revision" },
1096 { "buildname", cmd_buildname, "", "Get the full build name" },
1097 { "panicarg", cmd_panicarg, "", "Get panic code argument" },
1098 { "faultarg", cmd_faultarg, "", "Get fault code argument" },
1099 { "coldreset", cmd_coldreset, "", "Perform cold reset" },
1100 { "warmreset", cmd_warmreset, "", "Perform warm reset" },
1101 { "disabletx", cmd_disabletx, "", "Disable TX on the device" },
1102 { "enabletx", cmd_enabletx, "", "Enable TX on the device" },
1103 { "singlechan",cmd_singlechan,"<channel>", "Lock radio on specific channel" },
1104 { "hoppingon", cmd_hoppingon, "", "Revert to channel hopping" },
1105 { "rttxdata1", cmd_rttxdata1, "<freq> <level>", "TXData1 radio test" },
1106 { "radiotest", cmd_radiotest, "<freq> <level> <id>", "Run radio tests" },
1107 { "memtypes", cmd_memtypes, NULL, "Get memory types" },
1108 { "psget", cmd_psget, "<key>", "Get value for PS key" },
1109 { "psset", cmd_psset, "<key> <value>", "Set value for PS key" },
1110 { "psclr", cmd_psclr, "<key>", "Clear value for PS key" },
1111 { "pslist", cmd_pslist, NULL, "List all PS keys" },
1112 { "psread", cmd_psread, NULL, "Read all PS keys" },
1113 { "psload", cmd_psload, "<file>", "Load all PS keys from PSR file" },
1114 { "pscheck", cmd_pscheck, "<file>", "Check PSR file" },
1115 { "adc", cmd_adc, "<mux>", "Read ADC value of <mux> input" },
1119 static void usage(void)
1123 printf("bccmd - Utility for the CSR BCCMD interface\n\n");
1125 "\tbccmd [options] <command>\n\n");
1128 "\t-t <transport> Select the transport\n"
1129 "\t-d <device> Select the device\n"
1130 "\t-b <bcsp rate> Select the bcsp transfer rate\n"
1131 "\t-h, --help Display help\n"
1134 printf("Transports:\n"
1135 "\tHCI USB BCSP H4 3WIRE\n\n");
1137 printf("Commands:\n");
1138 for (i = 0; commands[i].str; i++)
1139 printf("\t%-10s %-20s\t%s\n", commands[i].str,
1140 commands[i].arg ? commands[i].arg : " ",
1144 printf("Keys:\n\t");
1145 for (i = 0; storage[i].pskey; i++) {
1146 printf("%s ", storage[i].str);
1147 pos += strlen(storage[i].str) + 1;
1156 static struct option main_options[] = {
1157 { "transport", 1, 0, 't' },
1158 { "device", 1, 0, 'd' },
1159 { "bcsprate", 1, 0, 'b'},
1160 { "help", 0, 0, 'h' },
1164 int main(int argc, char *argv[])
1166 char *device = NULL;
1167 int i, err, opt, transport = CSR_TRANSPORT_HCI;
1168 speed_t bcsp_rate = B38400;
1170 while ((opt=getopt_long(argc, argv, "+t:d:i:b:h", main_options, NULL)) != EOF) {
1173 if (!strcasecmp(optarg, "hci"))
1174 transport = CSR_TRANSPORT_HCI;
1175 else if (!strcasecmp(optarg, "usb"))
1176 transport = CSR_TRANSPORT_USB;
1177 else if (!strcasecmp(optarg, "bcsp"))
1178 transport = CSR_TRANSPORT_BCSP;
1179 else if (!strcasecmp(optarg, "h4"))
1180 transport = CSR_TRANSPORT_H4;
1181 else if (!strcasecmp(optarg, "h5"))
1182 transport = CSR_TRANSPORT_3WIRE;
1183 else if (!strcasecmp(optarg, "3wire"))
1184 transport = CSR_TRANSPORT_3WIRE;
1185 else if (!strcasecmp(optarg, "twutl"))
1186 transport = CSR_TRANSPORT_3WIRE;
1188 transport = CSR_TRANSPORT_UNKNOWN;
1193 device = strdup(optarg);
1196 switch (atoi(optarg)) {
1197 case 9600: bcsp_rate = B9600; break;
1198 case 19200: bcsp_rate = B19200; break;
1199 case 38400: bcsp_rate = B38400; break;
1200 case 57600: bcsp_rate = B57600; break;
1201 case 115200: bcsp_rate = B115200; break;
1202 case 230400: bcsp_rate = B230400; break;
1203 case 460800: bcsp_rate = B460800; break;
1204 case 500000: bcsp_rate = B500000; break;
1205 case 576000: bcsp_rate = B576000; break;
1206 case 921600: bcsp_rate = B921600; break;
1207 case 1000000: bcsp_rate = B1000000; break;
1208 case 1152000: bcsp_rate = B1152000; break;
1209 case 1500000: bcsp_rate = B1500000; break;
1210 case 2000000: bcsp_rate = B2000000; break;
1212 case 2500000: bcsp_rate = B2500000; break;
1215 case 3000000: bcsp_rate = B3000000; break;
1218 case 3500000: bcsp_rate = B3500000; break;
1221 case 4000000: bcsp_rate = B4000000; break;
1224 printf("Unknown BCSP baud rate specified, defaulting to 38400bps\n");
1244 if (transport_open(transport, device, bcsp_rate) < 0)
1249 for (i = 0; commands[i].str; i++) {
1250 if (strcasecmp(commands[i].str, argv[0]))
1253 err = commands[i].func(transport, argc, argv);
1255 transport_close(transport);
1258 fprintf(stderr, "Can't execute command: %s (%d)\n",
1259 strerror(errno), errno);
1266 fprintf(stderr, "Unsupported command\n");
1268 transport_close(transport);