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>
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, speed_t bcsp_rate)
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, bcsp_rate);
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);
259 nextdef = array[2] | (array[3] << 8);
261 if (nextdef == 0x0000)
266 printf("0x%04x - %s\n", def, csr_builddeftostr(def));
272 static int cmd_keylen(int transport, int argc, char *argv[])
275 uint16_t handle, keylen;
280 handle = atoi(argv[0]);
282 memset(array, 0, sizeof(array));
283 array[0] = handle & 0xff;
284 array[1] = handle >> 8;
286 err = transport_read(transport, CSR_VARID_CRYPT_KEY_LENGTH, array, 8);
290 handle = array[0] | (array[1] << 8);
291 keylen = array[2] | (array[3] << 8);
293 printf("Crypt key length: %d bit\n", keylen * 8);
298 static int cmd_clock(int transport, int argc, char *argv[])
306 memset(array, 0, sizeof(array));
308 err = transport_read(transport, CSR_VARID_BT_CLOCK, array, 8);
312 clock = array[2] | (array[3] << 8) | (array[0] << 16) | (array[1] << 24);
314 printf("Bluetooth clock: 0x%04x (%d)\n", clock, clock);
319 static int cmd_rand(int transport, int argc, char *argv[])
327 memset(array, 0, sizeof(array));
329 err = transport_read(transport, CSR_VARID_RAND, array, 8);
333 rand = array[0] | (array[1] << 8);
335 printf("Random number: 0x%02x (%d)\n", rand, rand);
340 static int cmd_chiprev(int transport, int argc, char *argv[])
349 memset(array, 0, sizeof(array));
351 err = transport_read(transport, CSR_VARID_CHIPREV, array, 8);
355 rev = array[0] | (array[1] << 8);
365 str = "BC2-External A";
368 str = "BC2-External B";
374 str = "BC3-Multimedia";
383 str = "BC4-External";
393 printf("Chip revision: 0x%04x (%s)\n", rev, str);
398 static int cmd_buildname(int transport, int argc, char *argv[])
407 memset(array, 0, sizeof(array));
409 err = transport_read(transport, CSR_VARID_READ_BUILD_NAME, array, 128);
413 for (i = 0; i < sizeof(name); i++)
414 name[i] = array[(i * 2) + 4];
416 printf("Build name: %s\n", name);
421 static int cmd_panicarg(int transport, int argc, char *argv[])
429 memset(array, 0, sizeof(array));
431 err = transport_read(transport, CSR_VARID_PANIC_ARG, array, 8);
435 error = array[0] | (array[1] << 8);
437 printf("Panic code: 0x%02x (%s)\n", error,
438 error < 0x100 ? "valid" : "invalid");
443 static int cmd_faultarg(int transport, int argc, char *argv[])
451 memset(array, 0, sizeof(array));
453 err = transport_read(transport, CSR_VARID_FAULT_ARG, array, 8);
457 error = array[0] | (array[1] << 8);
459 printf("Fault code: 0x%02x (%s)\n", error,
460 error < 0x100 ? "valid" : "invalid");
465 static int cmd_coldreset(int transport, int argc, char *argv[])
467 return transport_write(transport, CSR_VARID_COLD_RESET, NULL, 0);
470 static int cmd_warmreset(int transport, int argc, char *argv[])
472 return transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
475 static int cmd_disabletx(int transport, int argc, char *argv[])
477 return transport_write(transport, CSR_VARID_DISABLE_TX, NULL, 0);
480 static int cmd_enabletx(int transport, int argc, char *argv[])
482 return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0);
485 static int cmd_singlechan(int transport, int argc, char *argv[])
492 channel = atoi(argv[0]);
494 if (channel > 2401 && channel < 2481)
502 memset(array, 0, sizeof(array));
503 array[0] = channel & 0xff;
504 array[1] = channel >> 8;
506 return transport_write(transport, CSR_VARID_SINGLE_CHAN, array, 8);
509 static int cmd_hoppingon(int transport, int argc, char *argv[])
511 return transport_write(transport, CSR_VARID_HOPPING_ON, NULL, 0);
514 static int cmd_rttxdata1(int transport, int argc, char *argv[])
517 uint16_t freq, level;
521 freq = atoi(argv[0]);
523 if (!strncasecmp(argv[1], "0x", 2))
524 level = strtol(argv[1], NULL, 16);
526 level = atoi(argv[1]);
528 memset(array, 0, sizeof(array));
531 array[2] = freq & 0xff;
532 array[3] = freq >> 8;
533 array[4] = level & 0xff;
534 array[5] = level >> 8;
536 return transport_write(transport, CSR_VARID_RADIOTEST, array, 8);
539 static int cmd_radiotest(int transport, int argc, char *argv[])
542 uint16_t freq, level, test;
546 freq = atoi(argv[0]);
548 if (!strncasecmp(argv[1], "0x", 2))
549 level = strtol(argv[1], NULL, 16);
551 level = atoi(argv[1]);
553 test = atoi(argv[2]);
555 memset(array, 0, sizeof(array));
556 array[0] = test & 0xff;
557 array[1] = test >> 8;
558 array[2] = freq & 0xff;
559 array[3] = freq >> 8;
560 array[4] = level & 0xff;
561 array[5] = level >> 8;
563 return transport_write(transport, CSR_VARID_RADIOTEST, array, 8);
566 static int cmd_memtypes(int transport, int argc, char *argv[])
569 uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 };
574 for (i = 0; i < 4; i++) {
575 memset(array, 0, sizeof(array));
576 array[0] = stores[i] & 0xff;
577 array[1] = stores[i] >> 8;
579 err = transport_read(transport, CSR_VARID_PS_MEMORY_TYPE, array, 8);
583 type = array[2] + (array[3] << 8);
585 printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]),
586 stores[i], memorytostr(type), type);
592 static struct option pskey_options[] = {
593 { "stores", 1, 0, 's' },
594 { "reset", 0, 0, 'r' },
595 { "help", 0, 0, 'h' },
599 static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int *help)
603 while ((opt=getopt_long(argc, argv, "+s:rh", pskey_options, NULL)) != EOF) {
608 if (!strcasecmp(optarg, "default"))
610 else if (!strcasecmp(optarg, "implementation"))
612 else if (!strcasecmp(optarg, "factory"))
614 else if (!strcasecmp(optarg, "rom"))
616 else if (!strcasecmp(optarg, "ram"))
618 else if (!strcasecmp(optarg, "psi"))
620 else if (!strcasecmp(optarg, "psf"))
622 else if (!strcasecmp(optarg, "psrom"))
624 else if (!strcasecmp(optarg, "psram"))
626 else if (!strncasecmp(optarg, "0x", 2))
627 *stores = strtol(optarg, NULL, 16);
629 *stores = atoi(optarg);
647 #define OPT_PSKEY(min, max, stores, reset, help) \
648 opt_pskey(argc, argv, (stores), (reset), (help)); \
649 argc -= optind; argv += optind; optind = 0; \
650 OPT_RANGE((min), (max))
652 static int cmd_psget(int transport, int argc, char *argv[])
655 uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT;
657 int i, err, reset = 0;
659 memset(array, 0, sizeof(array));
661 OPT_PSKEY(1, 1, &stores, &reset, NULL);
663 if (strncasecmp(argv[0], "0x", 2)) {
664 pskey = atoi(argv[0]);
666 for (i = 0; storage[i].pskey; i++) {
667 if (strcasecmp(storage[i].str, argv[0]))
670 pskey = storage[i].pskey;
674 pskey = strtol(argv[0] + 2, NULL, 16);
676 memset(array, 0, sizeof(array));
677 array[0] = pskey & 0xff;
678 array[1] = pskey >> 8;
679 array[2] = stores & 0xff;
680 array[3] = stores >> 8;
682 err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
686 length = array[2] + (array[3] << 8);
687 if (length + 6 > (int) sizeof(array) / 2)
690 memset(array, 0, sizeof(array));
691 array[0] = pskey & 0xff;
692 array[1] = pskey >> 8;
693 array[2] = length & 0xff;
694 array[3] = length >> 8;
695 array[4] = stores & 0xff;
696 array[5] = stores >> 8;
698 err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2);
704 value = array[6] | (array[7] << 8);
705 printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value);
709 val32 = array[8] | (array[9] << 8) | (array[6] << 16) | (array[7] << 24);
710 printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32);
714 printf("%s:", csr_pskeytostr(pskey));
715 for (i = 0; i < length; i++)
716 printf(" 0x%02x%02x", array[(i * 2) + 6], array[(i * 2) + 7]);
722 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
727 static int cmd_psset(int transport, int argc, char *argv[])
730 uint16_t pskey, length, value, stores = CSR_STORES_PSRAM;
732 int i, err, reset = 0;
734 memset(array, 0, sizeof(array));
736 OPT_PSKEY(2, 81, &stores, &reset, NULL);
738 if (strncasecmp(argv[0], "0x", 2)) {
739 pskey = atoi(argv[0]);
741 for (i = 0; storage[i].pskey; i++) {
742 if (strcasecmp(storage[i].str, argv[0]))
745 pskey = storage[i].pskey;
749 pskey = strtol(argv[0] + 2, NULL, 16);
751 memset(array, 0, sizeof(array));
752 array[0] = pskey & 0xff;
753 array[1] = pskey >> 8;
754 array[2] = stores & 0xff;
755 array[3] = stores >> 8;
757 err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
761 length = array[2] + (array[3] << 8);
762 if (length + 6 > (int) sizeof(array) / 2)
765 memset(array, 0, sizeof(array));
766 array[0] = pskey & 0xff;
767 array[1] = pskey >> 8;
768 array[2] = length & 0xff;
769 array[3] = length >> 8;
770 array[4] = stores & 0xff;
771 array[5] = stores >> 8;
783 if (!strncasecmp(argv[0], "0x", 2))
784 value = strtol(argv[0] + 2, NULL, 16);
786 value = atoi(argv[0]);
788 array[6] = value & 0xff;
789 array[7] = value >> 8;
798 if (!strncasecmp(argv[0], "0x", 2))
799 val32 = strtol(argv[0] + 2, NULL, 16);
801 val32 = atoi(argv[0]);
803 array[6] = (val32 & 0xff0000) >> 16;
804 array[7] = val32 >> 24;
805 array[8] = val32 & 0xff;
806 array[9] = (val32 & 0xff00) >> 8;
810 if (argc != length * 2) {
815 for (i = 0; i < length * 2; i++)
816 if (!strncasecmp(argv[0], "0x", 2))
817 array[i + 6] = strtol(argv[i] + 2, NULL, 16);
819 array[i + 6] = atoi(argv[i]);
823 err = transport_write(transport, CSR_VARID_PS, array, (length + 3) * 2);
828 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
833 static int cmd_psclr(int transport, int argc, char *argv[])
836 uint16_t pskey, stores = CSR_STORES_PSRAM;
837 int i, err, reset = 0;
839 OPT_PSKEY(1, 1, &stores, &reset, NULL);
841 if (strncasecmp(argv[0], "0x", 2)) {
842 pskey = atoi(argv[0]);
844 for (i = 0; storage[i].pskey; i++) {
845 if (strcasecmp(storage[i].str, argv[0]))
848 pskey = storage[i].pskey;
852 pskey = strtol(argv[0] + 2, NULL, 16);
854 memset(array, 0, sizeof(array));
855 array[0] = pskey & 0xff;
856 array[1] = pskey >> 8;
857 array[2] = stores & 0xff;
858 array[3] = stores >> 8;
860 err = transport_write(transport, CSR_VARID_PS_CLR_STORES, array, 8);
865 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
870 static int cmd_pslist(int transport, int argc, char *argv[])
873 uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT;
876 OPT_PSKEY(0, 0, &stores, &reset, NULL);
879 memset(array, 0, sizeof(array));
880 array[0] = pskey & 0xff;
881 array[1] = pskey >> 8;
882 array[2] = stores & 0xff;
883 array[3] = stores >> 8;
885 err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8);
889 pskey = array[4] + (array[5] << 8);
893 memset(array, 0, sizeof(array));
894 array[0] = pskey & 0xff;
895 array[1] = pskey >> 8;
896 array[2] = stores & 0xff;
897 array[3] = stores >> 8;
899 err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
903 length = array[2] + (array[3] << 8);
905 printf("0x%04x - %s (%d bytes)\n", pskey,
906 csr_pskeytostr(pskey), length * 2);
910 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
915 static int cmd_psread(int transport, int argc, char *argv[])
918 uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT;
920 int i, err, reset = 0;
922 OPT_PSKEY(0, 0, &stores, &reset, NULL);
925 memset(array, 0, sizeof(array));
926 array[0] = pskey & 0xff;
927 array[1] = pskey >> 8;
928 array[2] = stores & 0xff;
929 array[3] = stores >> 8;
931 err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8);
935 pskey = array[4] + (array[5] << 8);
939 memset(array, 0, sizeof(array));
940 array[0] = pskey & 0xff;
941 array[1] = pskey >> 8;
942 array[2] = stores & 0xff;
943 array[3] = stores >> 8;
945 err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8);
949 length = array[2] + (array[3] << 8);
950 if (length + 6 > (int) sizeof(array) / 2)
953 memset(array, 0, sizeof(array));
954 array[0] = pskey & 0xff;
955 array[1] = pskey >> 8;
956 array[2] = length & 0xff;
957 array[3] = length >> 8;
958 array[4] = stores & 0xff;
959 array[5] = stores >> 8;
961 err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2);
965 str = csr_pskeytoval(pskey);
966 if (!strcasecmp(str, "UNKNOWN")) {
967 sprintf(val, "0x%04x", pskey);
971 printf("// %s%s\n&%04x =", str ? "PSKEY_" : "",
972 str ? str : val, pskey);
973 for (i = 0; i < length; i++)
974 printf(" %02x%02x", array[(i * 2) + 7], array[(i * 2) + 6]);
979 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
984 static int cmd_psload(int transport, int argc, char *argv[])
987 uint16_t pskey, length, size, stores = CSR_STORES_PSRAM;
991 OPT_PSKEY(1, 1, &stores, &reset, NULL);
995 memset(array, 0, sizeof(array));
996 size = sizeof(array) - 6;
998 while (psr_get(&pskey, array + 6, &size) == 0) {
999 str = csr_pskeytoval(pskey);
1000 if (!strcasecmp(str, "UNKNOWN")) {
1001 sprintf(val, "0x%04x", pskey);
1005 printf("Loading %s%s ... ", str ? "PSKEY_" : "",
1011 array[0] = pskey & 0xff;
1012 array[1] = pskey >> 8;
1013 array[2] = length & 0xff;
1014 array[3] = length >> 8;
1015 array[4] = stores & 0xff;
1016 array[5] = stores >> 8;
1018 err = transport_write(transport, CSR_VARID_PS, array, size + 6);
1020 printf("%s\n", err < 0 ? "failed" : "done");
1022 memset(array, 0, sizeof(array));
1023 size = sizeof(array) - 6;
1027 transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);
1032 static int cmd_pscheck(int transport, int argc, char *argv[])
1035 uint16_t pskey, size;
1042 while (psr_get(&pskey, array, &size) == 0) {
1043 printf("0x%04x =", pskey);
1044 for (i = 0; i < size; i++)
1045 printf(" 0x%02x", array[i]);
1054 int (*func)(int transport, int argc, char *argv[]);
1058 { "builddef", cmd_builddef, "", "Get build definitions" },
1059 { "keylen", cmd_keylen, "<handle>", "Get current crypt key length" },
1060 { "clock", cmd_clock, "", "Get local Bluetooth clock" },
1061 { "rand", cmd_rand, "", "Get random number" },
1062 { "chiprev", cmd_chiprev, "", "Get chip revision" },
1063 { "buildname", cmd_buildname, "", "Get the full build name" },
1064 { "panicarg", cmd_panicarg, "", "Get panic code argument" },
1065 { "faultarg", cmd_faultarg, "", "Get fault code argument" },
1066 { "coldreset", cmd_coldreset, "", "Perform cold reset" },
1067 { "warmreset", cmd_warmreset, "", "Perform warm reset" },
1068 { "disabletx", cmd_disabletx, "", "Disable TX on the device" },
1069 { "enabletx", cmd_enabletx, "", "Enable TX on the device" },
1070 { "singlechan",cmd_singlechan,"<channel>", "Lock radio on specific channel" },
1071 { "hoppingon", cmd_hoppingon, "", "Revert to channel hopping" },
1072 { "rttxdata1", cmd_rttxdata1, "<freq> <level>", "TXData1 radio test" },
1073 { "radiotest", cmd_radiotest, "<freq> <level> <id>", "Run radio tests" },
1074 { "memtypes", cmd_memtypes, NULL, "Get memory types" },
1075 { "psget", cmd_psget, "<key>", "Get value for PS key" },
1076 { "psset", cmd_psset, "<key> <value>", "Set value for PS key" },
1077 { "psclr", cmd_psclr, "<key>", "Clear value for PS key" },
1078 { "pslist", cmd_pslist, NULL, "List all PS keys" },
1079 { "psread", cmd_psread, NULL, "Read all PS keys" },
1080 { "psload", cmd_psload, "<file>", "Load all PS keys from PSR file" },
1081 { "pscheck", cmd_pscheck, "<file>", "Check PSR file" },
1085 static void usage(void)
1089 printf("bccmd - Utility for the CSR BCCMD interface\n\n");
1091 "\tbccmd [options] <command>\n\n");
1094 "\t-t <transport> Select the transport\n"
1095 "\t-d <device> Select the device\n"
1096 "\t-b <bcsp rate> Select the bcsp transfer rate\n"
1097 "\t-h, --help Display help\n"
1100 printf("Transports:\n"
1101 "\tHCI USB BCSP H4 3WIRE\n\n");
1103 printf("Commands:\n");
1104 for (i = 0; commands[i].str; i++)
1105 printf("\t%-10s %-20s\t%s\n", commands[i].str,
1106 commands[i].arg ? commands[i].arg : " ",
1110 printf("Keys:\n\t");
1111 for (i = 0; storage[i].pskey; i++) {
1112 printf("%s ", storage[i].str);
1113 pos += strlen(storage[i].str) + 1;
1122 static struct option main_options[] = {
1123 { "transport", 1, 0, 't' },
1124 { "device", 1, 0, 'd' },
1125 { "bcsprate", 1, 0, 'b'},
1126 { "help", 0, 0, 'h' },
1130 int main(int argc, char *argv[])
1132 char *device = NULL;
1133 int i, err, opt, transport = CSR_TRANSPORT_HCI;
1134 speed_t bcsp_rate = B38400;
1136 while ((opt=getopt_long(argc, argv, "+t:d:i:b:h", main_options, NULL)) != EOF) {
1139 if (!strcasecmp(optarg, "hci"))
1140 transport = CSR_TRANSPORT_HCI;
1141 else if (!strcasecmp(optarg, "usb"))
1142 transport = CSR_TRANSPORT_USB;
1143 else if (!strcasecmp(optarg, "bcsp"))
1144 transport = CSR_TRANSPORT_BCSP;
1145 else if (!strcasecmp(optarg, "h4"))
1146 transport = CSR_TRANSPORT_H4;
1147 else if (!strcasecmp(optarg, "h5"))
1148 transport = CSR_TRANSPORT_3WIRE;
1149 else if (!strcasecmp(optarg, "3wire"))
1150 transport = CSR_TRANSPORT_3WIRE;
1151 else if (!strcasecmp(optarg, "twutl"))
1152 transport = CSR_TRANSPORT_3WIRE;
1154 transport = CSR_TRANSPORT_UNKNOWN;
1159 device = strdup(optarg);
1162 switch (atoi(optarg)) {
1163 case 9600: bcsp_rate = B9600; break;
1164 case 19200: bcsp_rate = B19200; break;
1165 case 38400: bcsp_rate = B38400; break;
1166 case 57600: bcsp_rate = B57600; break;
1167 case 115200: bcsp_rate = B115200; break;
1168 case 230400: bcsp_rate = B230400; break;
1169 case 460800: bcsp_rate = B460800; break;
1170 case 500000: bcsp_rate = B500000; break;
1171 case 576000: bcsp_rate = B576000; break;
1172 case 921600: bcsp_rate = B921600; break;
1173 case 1000000: bcsp_rate = B1000000; break;
1174 case 1152000: bcsp_rate = B1152000; break;
1175 case 1500000: bcsp_rate = B1500000; break;
1176 case 2000000: bcsp_rate = B2000000; break;
1178 case 2500000: bcsp_rate = B2500000; break;
1181 case 3000000: bcsp_rate = B3000000; break;
1184 case 3500000: bcsp_rate = B3500000; break;
1187 case 4000000: bcsp_rate = B4000000; break;
1190 printf("Unknown BCSP baud rate specified, defaulting to 38400bps\n");
1210 if (transport_open(transport, device, bcsp_rate) < 0)
1215 for (i = 0; commands[i].str; i++) {
1216 if (strcasecmp(commands[i].str, argv[0]))
1219 err = commands[i].func(transport, argc, argv);
1221 transport_close(transport);
1224 fprintf(stderr, "Can't execute command: %s (%d)\n",
1225 strerror(errno), errno);
1232 fprintf(stderr, "Unsupported command\n");
1234 transport_close(transport);