From 50a8cc8a256f3ef56a6144cabd2ae6ee5848e46d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Nov 2005 21:00:58 +0000 Subject: Update to the new BCCMD interface utility --- acinclude.m4 | 18 +- tools/Makefile.am | 36 +-- tools/bccmd.c | 749 ++++++++++++++++++++++++++++++++++++++++++++++++++---- tools/csrinit.8 | 35 --- tools/csrinit.c | 97 ------- tools/pskey.c | 581 ------------------------------------------ 6 files changed, 727 insertions(+), 789 deletions(-) delete mode 100644 tools/csrinit.8 delete mode 100644 tools/csrinit.c delete mode 100644 tools/pskey.c diff --git a/acinclude.m4 b/acinclude.m4 index 8b8b4f06..65ae27b3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -297,9 +297,9 @@ AC_DEFUN([AC_ARG_BLUEZ], [ cups_enable=no pcmcia_enable=no initscripts_enable=no - avctrl_enable=${usb_found} + bccmd_enable=no + avctrl_enable=no hid2hci_enable=${usb_found} - csrinit_enable=no dfutool_enable=no bcm203x_enable=no bluepin_enable=yes @@ -325,9 +325,9 @@ AC_DEFUN([AC_ARG_BLUEZ], [ cups_enable=${enableval} pcmcia_enable=${enableval} initscripts_enable=${enableval} + bccmd_enable=${enableval} avctrl_enable=${enableval} hid2hci_enable=${enableval} - csrinit_enable=${enableval} dfutool_enable=${enableval} bcm203x_enable=${enableval} bluepin_enable=${enableval} @@ -365,6 +365,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ initscripts_enable=${enableval} ]) + AC_ARG_ENABLE(bccmd, AC_HELP_STRING([--enable-bccmd], [install BCCMD interface utility]), [ + bccmd_enable=${enableval} + ]) + AC_ARG_ENABLE(avctrl, AC_HELP_STRING([--enable-avctrl], [install Audio/Video control utility]), [ avctrl_enable=${enableval} ]) @@ -373,10 +377,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [ hid2hci_enable=${enableval} ]) - AC_ARG_ENABLE(csrinit, AC_HELP_STRING([--enable-csrinit], [install CSR ROM chip setup utility]), [ - csrinit_enable=${enableval} - ]) - AC_ARG_ENABLE(dfutool, AC_HELP_STRING([--enable-dfutool], [install DFU firmware upgrade utility]), [ dfutool_enable=${enableval} ]) @@ -385,7 +385,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ bcm203x_enable=${enableval} ]) - AC_ARG_ENABLE(bluepin, AC_HELP_STRING([--enable-bluepin], [install Python based PIN helper utility]), [ + AC_ARG_ENABLE(bluepin, AC_HELP_STRING([--enable-bluepin], [install Python based PIN helper]), [ bluepin_enable=${enableval} ]) @@ -410,9 +410,9 @@ AC_DEFUN([AC_ARG_BLUEZ], [ AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") AM_CONDITIONAL(PCMCIA, test "${pcmcia_enable}" = "yes") AM_CONDITIONAL(INITSCRIPTS, test "${initscripts_enable}" = "yes") + AM_CONDITIONAL(BCCMD, test "${bccmd_enable}" = "yes") AM_CONDITIONAL(AVCTRL, test "${avctrl_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes") - AM_CONDITIONAL(CSRINIT, test "${csrinit_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(DFUTOOL, test "${dfutool_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(BCM203X, test "${bcm203x_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(BLUEPIN, test "${bluepin_enable}" = "yes") diff --git a/tools/Makefile.am b/tools/Makefile.am index 479011ec..238a2df1 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,4 +1,12 @@ +if BCCMD +bccmd_programs = bccmd +bccmd_manfiles = bccmd.8 +else +bccmd_programs = +bccmd_manfiles = +endif + if AVCTRL avctrl_programs = avctrl avctrl_manfiles = avctrl.8 @@ -15,14 +23,6 @@ hid2hci_programs = hid2hci_manfiles = endif -if CSRINIT -csrinit_programs = csrinit -csrinit_manfiles = csrinit.8 -else -csrinit_programs = -csrinit_manfiles = -endif - if DFUTOOL dfutool_programs = dfutool dfutool_manfiles = dfutool.1 @@ -31,11 +31,11 @@ dfutool_programs = dfutool_manfiles = endif -sbin_PROGRAMS = hciattach hciconfig $(avctrl_programs) $(hid2hci_programs) $(csrinit_programs) +sbin_PROGRAMS = hciattach hciconfig $(bccmd_programs) $(avctrl_programs) $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) -noinst_PROGRAMS = hcisecfilter ppporc pskey bccmd +noinst_PROGRAMS = hcisecfilter ppporc hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a @@ -51,11 +51,10 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ -pskey_SOURCES = pskey.c csr.h csr.c -pskey_LDADD = @BLUEZ_LIBS@ - +if BCCMD bccmd_SOURCES = bccmd.c csr.h csr.c bccmd_LDADD = @BLUEZ_LIBS@ +endif if AVCTRL avctrl_LDADD = @USB_LIBS@ @@ -65,11 +64,6 @@ if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif -if CSRINIT -csrinit_SOURCES = csrinit.c csr.h -csrinit_LDADD = @USB_LIBS@ -endif - if DFUTOOL dfutool_SOURCES = dfutool.c dfu.h dfu.c dfutool_LDADD = @USB_LIBS@ @@ -80,10 +74,8 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ - $(avctrl_manfiles) $(hid2hci_manfiles) $(csrinit_manfiles) $(dfutool_manfiles) - -noinst_MANS = bccmd.8 + $(bccmd_manfiles) $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 csrinit.8 dfutool.1 bccmd.8 example.psr +EXTRA_DIST = $(man_MANS) bccmd.8 avctrl.8 hid2hci.8 dfutool.1 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/bccmd.c b/tools/bccmd.c index 46cc2be1..e41f08f5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -37,12 +37,144 @@ #include "csr.h" +#define CSR_TRANSPORT_UNKNOWN 0 +#define CSR_TRANSPORT_HCI 1 +#define CSR_TRANSPORT_USB 2 +#define CSR_TRANSPORT_BCSP 3 +#define CSR_TRANSPORT_H4 4 +#define CSR_TRANSPORT_3WIRE 5 + +#define CSR_STORES_PSI (0x0001) +#define CSR_STORES_PSF (0x0002) +#define CSR_STORES_PSROM (0x0004) +#define CSR_STORES_PSRAM (0x0008) +#define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF | CSR_STORES_PSRAM) + +#define CSR_TYPE_NULL 0 +#define CSR_TYPE_COMPLEX 1 +#define CSR_TYPE_UINT8 2 +#define CSR_TYPE_UINT16 3 +#define CSR_TYPE_UINT32 4 + +#define CSR_TYPE_ARRAY CSR_TYPE_COMPLEX +#define CSR_TYPE_BDADDR CSR_TYPE_COMPLEX + +static uint16_t seqnum = 0x0000; + +static struct { + uint16_t pskey; + int type; + int size; + char *str; +} storage[] = { + { CSR_PSKEY_BDADDR, CSR_TYPE_BDADDR, 8, "bdaddr" }, + { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, 0, "country" }, + { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, 0, "devclass" }, + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, 0, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, 0, "keymax" }, + { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, 8, "features" }, + { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, 18, "commands" }, + { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, 0, "version" }, + { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, 0, "remver" }, + { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, 0, "hciextn" }, + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, 0, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, 0, "baudrate" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, 0, "hostintf" }, + { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, 0, "anafreq" }, + { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, 0, "anaftrim" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, 0, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, 0, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, 0, "dfupid" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, 0, "bootmode" }, + { 0x0000 }, +}; + +static int pskey_size(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_BDADDR: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return 18; + default: + return 64; + } +} + +static char *storestostr(uint16_t stores) +{ + switch (stores) { + case 0x0000: + return "Default"; + case 0x0001: + return "psi"; + case 0x0002: + return "psf"; + case 0x0004: + return "psrom"; + case 0x0008: + return "psram"; + default: + return "Unknown"; + } +} + +static char *memorytostr(uint16_t type) +{ + switch (type) { + case 0x0000: + return "Flash memory"; + case 0x0001: + return "EEPROM"; + case 0x0002: + return "RAM (transient)"; + case 0x0003: + return "ROM (or \"read-only\" flash memory)"; + default: + return "Unknown"; + } +} + +#define OPT_RANGE(range) \ + if (argc < (range)) { errno = EINVAL; return -1; } \ + if (argc > (range)) { errno = E2BIG; return -1; } + +static struct option help_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static int opt_help(int argc, char *argv[], int *help) +{ + int opt; + + while ((opt=getopt_long(argc, argv, "+h", help_options, NULL)) != EOF) { + switch (opt) { + case 'h': + if (help) + *help = 1; + break; + } + } + + return optind; +} + +#define OPT_HELP(range, help) \ + opt_help(argc, argv, (help)); \ + argc -= optind; argv += optind; optind = 0; \ + OPT_RANGE((range)) + static int cmd_builddef(int dd, int argc, char *argv[]) { uint8_t buf[8]; - uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; + uint16_t def = 0x0000, nextdef = 0x0000; int err = 0; + OPT_HELP(0, NULL); + printf("Build definitions:\n"); while (1) { @@ -76,15 +208,7 @@ static int cmd_keylen(int dd, int argc, char *argv[]) uint16_t handle, keylen; int err; - if (argc < 1) { - errno = EINVAL; - return -1; - } - - if (argc > 1) { - errno = E2BIG; - return -1; - } + OPT_HELP(1, NULL); handle = atoi(argv[0]); @@ -92,7 +216,7 @@ static int cmd_keylen(int dd, int argc, char *argv[]) buf[0] = handle & 0xff; buf[1] = handle >> 8; - err = csr_read_varid_complex(dd, 0x4711, + err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); if (err < 0) { errno = -err; @@ -112,7 +236,9 @@ static int cmd_clock(int dd, int argc, char *argv[]) uint32_t clock = 0; int err; - err = csr_read_varid_uint32(dd, 0x4711, CSR_VARID_BT_CLOCK, &clock); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint32(dd, seqnum++, CSR_VARID_BT_CLOCK, &clock); if (err < 0) { errno = -err; return -1; @@ -128,7 +254,9 @@ static int cmd_rand(int dd, int argc, char *argv[]) uint16_t rand = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_RAND, &rand); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_RAND, &rand); if (err < 0) { errno = -err; return -1; @@ -144,7 +272,9 @@ static int cmd_panicarg(int dd, int argc, char *argv[]) uint16_t error = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_PANIC_ARG, &error); if (err < 0) { errno = -err; return -1; @@ -161,7 +291,9 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) uint16_t error = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_FAULT_ARG, &error); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_FAULT_ARG, &error); if (err < 0) { errno = -err; return -1; @@ -175,60 +307,555 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) static int cmd_coldreset(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_COLD_RESET); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_COLD_RESET); } static int cmd_warmreset(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_WARM_RESET); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); } static int cmd_disabletx(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_DISABLE_TX); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_DISABLE_TX); } static int cmd_enabletx(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_ENABLE_TX); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_ENABLE_TX); +} + +static int cmd_memtypes(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 }; + int i, err; + + OPT_HELP(0, NULL); + + for (i = 0; i < 4; i++) { + memset(array, 0, sizeof(array)); + array[2] = stores[i] & 0xff; + array[3] = stores[i] >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); + if (err < 0) + break; + + type = array[4] + (array[5] << 8); + + printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]), + stores[i], memorytostr(type), type); + } + + return err; +} + +static struct option pskey_options[] = { + { "stores", 1, 0, 's' }, + { "reset", 0, 0, 'r' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int *help) +{ + int opt; + + while ((opt=getopt_long(argc, argv, "+s:rh", pskey_options, NULL)) != EOF) { + switch (opt) { + case 's': + if (!stores) + break; + if (!strcasecmp(optarg, "default")) + *stores = 0x0000; + else if (!strcasecmp(optarg, "implementation")) + *stores = 0x0001; + else if (!strcasecmp(optarg, "factory")) + *stores = 0x0002; + else if (!strcasecmp(optarg, "rom")) + *stores = 0x0004; + else if (!strcasecmp(optarg, "ram")) + *stores = 0x0008; + else if (!strcasecmp(optarg, "psi")) + *stores = 0x0001; + else if (!strcasecmp(optarg, "psf")) + *stores = 0x0002; + else if (!strcasecmp(optarg, "psrom")) + *stores = 0x0004; + else if (!strcasecmp(optarg, "psram")) + *stores = 0x0008; + else if (!strncasecmp(optarg, "0x", 2)) + *stores = strtol(optarg, NULL, 16); + else + *stores = atoi(optarg); + break; + + case 'r': + if (reset) + *reset = 1; + break; + + case 'h': + if (help) + *help = 1; + break; + } + } + + return optind; +} + +#define OPT_PSKEY(range, stores, reset, help) \ + opt_pskey(argc, argv, (stores), (reset), (help)); \ + argc -= optind; argv += optind; optind = 0; \ + OPT_RANGE((range)) + +static int cmd_psget(int dd, int argc, char *argv[]) +{ + uint8_t array[64]; + uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT; + uint32_t val32; + int i, err, size, reset = 0, type = CSR_TYPE_NULL; + + memset(array, 0, sizeof(array)); + + OPT_PSKEY(1, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + type = storage[i].type; + size = storage[i].type; + break; + } + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } else { + pskey = strtol(argv[0] + 2, NULL, 16); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } + + switch (type) { + case CSR_TYPE_COMPLEX: + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + return err; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + return -EIO; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, stores, + array, length * 2); + if (err < 0) + return err; + + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < length; i++) + printf(" 0x%02x%02x", array[i * 2], array[(i * 2) + 1]); + printf("\n"); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: + err = csr_read_pskey_uint16(dd, seqnum++, pskey, stores, &value); + if (err < 0) + return err; + + printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); + break; + + case CSR_TYPE_UINT32: + err = csr_read_pskey_uint32(dd, seqnum++, pskey, stores, &val32); + if (err < 0) + return err; + + printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; + } + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_psset(int dd, int argc, char *argv[]) +{ + uint8_t array[64]; + uint16_t pskey, value, stores = CSR_STORES_PSRAM; + uint32_t val32; + int i, err, size, reset = 0, type = CSR_TYPE_NULL; + + memset(array, 0, sizeof(array)); + + OPT_PSKEY(2, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + type = storage[i].type; + size = storage[i].type; + break; + } + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } else { + pskey = strtol(argv[0] + 2, NULL, 16); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } + + argc--; + argv++; + + switch (type) { + case CSR_TYPE_COMPLEX: + size = pskey_size(pskey); + + if (argc != size) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < size; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i] = strtol(argv[i] + 2, NULL, 16); + else + array[i] = atoi(argv[i]); + + err = csr_write_pskey_complex(dd, seqnum++, pskey, + stores, array, size); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: + if (argc != 1) { + errno = E2BIG; + return -1; + } + + if (!strncasecmp(argv[0], "0x", 2)) + value = strtol(argv[0] + 2, NULL, 16); + else + value = atoi(argv[0]); + + err = csr_write_pskey_uint16(dd, seqnum++, pskey, stores, value); + break; + + case CSR_TYPE_UINT32: + if (argc != 1) { + errno = E2BIG; + return -1; + } + + if (!strncasecmp(argv[0], "0x", 2)) + val32 = strtol(argv[0] + 2, NULL, 16); + else + val32 = atoi(argv[0]); + + err = csr_write_pskey_uint32(dd, seqnum++, pskey, stores, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; + } + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_psclr(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t pskey, stores = CSR_STORES_PSRAM; + int i, err, reset = 0; + + OPT_PSKEY(1, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + break; + } + pskey = atoi(argv[0]); + } else + pskey = strtol(argv[0] + 2, NULL, 16); + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_write_varid_complex(dd, seqnum++, + CSR_VARID_PS_CLR_STORES, array, sizeof(array)); + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_pslist(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; + int err, reset = 0; + + OPT_PSKEY(0, &stores, &reset, NULL); + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, sizeof(array)); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, sizeof(array)); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + + printf("0x%04x - %s (%d bytes)\n", pskey, + csr_pskeytostr(pskey), length * 2); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_psread(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; + char *str, val[7]; + int i, err, reset = 0; + + OPT_PSKEY(0, &stores, &reset, NULL); + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, 8); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + continue; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, + stores, array, length * 2); + if (err < 0) + continue; + + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", + str ? str : val, pskey); + for (i = 0; i < length; i++) + printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf("\n"); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_psload(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey, size, stores = CSR_STORES_PSRAM; + char *str, val[7]; + int err, reset = 0; + + OPT_PSKEY(1, &stores, &reset, NULL); + + psr_read(argv[0]); + + while (psr_get(&pskey, array, &size) == 0) { + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("Loading %s%s ... ", str ? "PSKEY_" : "", + str ? str : val); + fflush(stdout); + + err = csr_write_pskey_complex(dd, seqnum++, pskey, + stores, array, size); + + printf("%s\n", err < 0 ? "failed" : "done"); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_pscheck(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey, size; + int i; + + OPT_HELP(1, NULL); + + psr_read(argv[0]); + + while (psr_get(&pskey, array, &size) == 0) { + printf("0x%04x =", pskey); + for (i = 0; i < size; i++) + printf(" 0x%02x", array[i]); + printf("\n"); + } + + return 0; } static struct { char *str; - int (*func)(int dd, int argc, char **argv); + int (*func)(int dd, int argc, char *argv[]); char *arg; char *doc; } commands[] = { - { "builddef", cmd_builddef, "", "Get build definitions" }, - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, - { "rand", cmd_rand, "", "Get random number" }, - { "panicarg", cmd_panicarg, "", "Get panic code argument" }, - { "faultarg", cmd_faultarg, "", "Get fault code argument" }, - { "coldreset", cmd_coldreset, "", "Perform cold reset" }, - { "warmreset", cmd_warmreset, "", "Perform warm reset" }, - { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, - { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, - { NULL }, + { "builddef", cmd_builddef, "", "Get build definitions" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "rand", cmd_rand, "", "Get random number" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "coldreset", cmd_coldreset, "", "Perform cold reset" }, + { "warmreset", cmd_warmreset, "", "Perform warm reset" }, + { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, + { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, + { "memtypes", cmd_memtypes, NULL, "Get memory types" }, + { "psget", cmd_psget, "", "Get value for PS key" }, + { "psset", cmd_psset, " ", "Set value for PS key" }, + { "psclr", cmd_psclr, "", "Clear value for PS key" }, + { "pslist", cmd_pslist, NULL, "List all PS keys" }, + { "psread", cmd_psread, NULL, "Read all PS keys" }, + { "psload", cmd_psload, "", "Load all PS keys from PSR file" }, + { "pscheck", cmd_pscheck, "", "Check PSR file" }, + { NULL } }; static void usage(void) { - int i; + int i, pos = 0; printf("bccmd - Utility for the CSR BCCMD interface\n\n"); printf("Usage:\n" - "\tbccmd [-i ] \n\n"); + "\tbccmd [options] \n\n"); + + printf("Options:\n" + "\t-t Select the transport\n" + "\t-d Select the device\n" + "\t-h, --help Display help\n" + "\n"); printf("Commands:\n"); - for (i = 0; commands[i].str; i++) - printf("\t%-10s%-8s\t%s\n", commands[i].str, - commands[i].arg, commands[i].doc); + for (i = 0; commands[i].str; i++) + printf("\t%-10s %-14s\t%s\n", commands[i].str, + commands[i].arg ? commands[i].arg : " ", + commands[i].doc); + printf("\n"); + + printf("Keys:\n\t"); + for (i = 0; storage[i].pskey; i++) { + printf("%s ", storage[i].str); + pos += strlen(storage[i].str) + 1; + if (pos > 60) { + printf("\n\t"); + pos = 0; + } + } + printf("\n"); } static struct option main_options[] = { + { "transport", 1, 0, 't' }, + { "device", 1, 0, 'd' }, { "help", 0, 0, 'h' }, - { "device", 1, 0, 'i' }, { 0, 0, 0, 0 } }; @@ -236,16 +863,33 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0; + char *device = NULL; + int i, err, opt, dd, dev, transport = CSR_TRANSPORT_HCI; - while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+t:d:i:h", main_options, NULL)) != EOF) { switch (opt) { + case 't': + if (!strcasecmp(optarg, "hci")) + transport = CSR_TRANSPORT_HCI; + else if (!strcasecmp(optarg, "usb")) + transport = CSR_TRANSPORT_USB; + else if (!strcasecmp(optarg, "bcsp")) + transport = CSR_TRANSPORT_BCSP; + else if (!strcasecmp(optarg, "h4")) + transport = CSR_TRANSPORT_H4; + else if (!strcasecmp(optarg, "h5")) + transport = CSR_TRANSPORT_3WIRE; + else if (!strcasecmp(optarg, "3wire")) + transport = CSR_TRANSPORT_3WIRE; + else if (!strcasecmp(optarg, "twutl")) + transport = CSR_TRANSPORT_3WIRE; + else + transport = CSR_TRANSPORT_UNKNOWN; + break; + + case 'd': case 'i': - dev = hci_devid(optarg); - if (dev < 0) { - perror("Invalid device"); - exit(1); - } + device = strdup(optarg); break; case 'h': @@ -264,6 +908,21 @@ int main(int argc, char *argv[]) exit(1); } + if (transport != CSR_TRANSPORT_HCI) { + fprintf(stderr, "Unsupported transport\n"); + exit(1); + } + + if (device) { + dev = hci_devid(device); + if (dev < 0) { + fprintf(stderr, "Device not available\n"); + exit(1); + } + free(device); + } else + dev = 0; + dd = hci_open_dev(dev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", @@ -295,7 +954,7 @@ int main(int argc, char *argv[]) if (strcasecmp(commands[i].str, argv[0])) continue; - err = commands[i].func(dd, argc - 1, argv + 1); + err = commands[i].func(dd, argc, argv); hci_close_dev(dd); diff --git a/tools/csrinit.8 b/tools/csrinit.8 deleted file mode 100644 index 35a033d9..00000000 --- a/tools/csrinit.8 +++ /dev/null @@ -1,35 +0,0 @@ -.\" -.\" This program is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2 of the License, or -.\" (at your option) any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program; if not, write to the Free Software -.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -.\" -.\" -.TH CSRINIT 8 "SEPTEMBER 8, 2005" "" "" - -.SH NAME -csrinit \- Utility for the setting up CSR ROM chips -.SH SYNOPSIS -.BR "csrinit -[ -.I options -] -.SH DESCRIPTION -.B csrinit -is used to setup the ROM chips from CSR. -.SH OPTIONS -.TP -.BI -h -Gives a list of possible options. -.SH AUTHOR -Written by Marcel Holtmann . -.br diff --git a/tools/csrinit.c b/tools/csrinit.c deleted file mode 100644 index a56dbde9..00000000 --- a/tools/csrinit.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2005 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include - -#include "csr.h" - -#ifdef NEED_USB_GET_BUSSES -static inline struct usb_bus *usb_get_busses(void) -{ - return usb_busses; -} -#endif - -#ifndef USB_DIR_OUT -#define USB_DIR_OUT 0x00 -#endif - -#ifndef USB_DIR_IN -#define USB_DIR_IN 0x80 -#endif - -static void usage(void) -{ - printf("csrinit - Utility for the setting up CSR ROM chips\n\n"); - - printf("Usage:\n" - "\tcsrinit [options]\n" - "\n"); - - printf("Options:\n" - "\t-h, --help Display help\n" - "\n"); -} - -static struct option main_options[] = { - { "help", 0, 0, 'h' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char *argv[]) -{ - int opt; - - while ((opt = getopt_long(argc, argv, "+h", main_options, NULL)) != -1) { - switch (opt) { - case 'h': - usage(); - exit(0); - - default: - exit(0); - } - } - - argc -= optind; - argv += optind; - optind = 0; - - if (argc < 1) { - usage(); - exit(1); - } - - usb_init(); - - return 0; -} diff --git a/tools/pskey.c b/tools/pskey.c deleted file mode 100644 index c185cf58..00000000 --- a/tools/pskey.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2005 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "csr.h" - -#define CSR_TYPE_NULL 0 -#define CSR_TYPE_ARRAY 1 -#define CSR_TYPE_UINT8 2 -#define CSR_TYPE_UINT16 3 -#define CSR_TYPE_UINT32 4 - -enum { - NONE = 0, - MEMORY, - LIST, - READ, -}; - -static char *storestostr(uint16_t stores) -{ - switch (stores) { - case 0x0000: - return "Default"; - case 0x0001: - return "psi"; - case 0x0002: - return "psf"; - case 0x0004: - return "psrom"; - case 0x0008: - return "psram"; - default: - return "Unknown"; - } -} - -static char *memorytostr(uint16_t type) -{ - switch (type) { - case 0x0000: - return "Flash memory"; - case 0x0001: - return "EEPROM"; - case 0x0002: - return "RAM (transient)"; - case 0x0003: - return "ROM (or \"read-only\" flash memory)"; - default: - return "Unknown"; - } -} - -static int cmd_memory(int dd, uint16_t stores, int argc, char *argv[]) -{ - uint8_t array[8]; - uint16_t type; - int err; - - memset(array, 0, sizeof(array)); - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, 0x4711, - CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); - if (err < 0) - return err; - - type = array[4] + (array[5] << 8); - - printf("%s (0x%04x) = %s (%d)\n", storestostr(stores), stores, - memorytostr(type), type); - - return 0; -} - -static int cmd_list(int dd, uint16_t stores, int argc, char *argv[]) -{ - uint8_t array[8]; - uint16_t length, seqnum = 0x0000, pskey = 0x0000; - int err; - - while (1) { - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, sizeof(array)); - if (err < 0) - break; - - pskey = array[4] + (array[5] << 8); - if (pskey == 0x0000) - break; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, sizeof(array)); - if (err < 0) - continue; - - length = array[2] + (array[3] << 8); - - printf("0x%04x - %s (%d bytes)\n", pskey, - csr_pskeytostr(pskey), length * 2); - } - - return 0; -} - -static int cmd_read(int dd, uint16_t stores, int argc, char *argv[]) -{ - uint8_t array[256]; - uint16_t length, seqnum = 0x0000, pskey = 0x0000; - char *str, val[7]; - int i, err; - - while (1) { - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, 8); - if (err < 0) - break; - - pskey = array[4] + (array[5] << 8); - if (pskey == 0x0000) - break; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); - if (err < 0) - continue; - - length = array[2] + (array[3] << 8); - if (length > sizeof(array) / 2) - continue; - - err = csr_read_pskey_complex(dd, seqnum++, pskey, - stores, array, length * 2); - if (err < 0) - continue; - - str = csr_pskeytoval(pskey); - if (!strcasecmp(str, "UNKNOWN")) { - sprintf(val, "0x%04x", pskey); - str = NULL; - } - - printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", - str ? str : val, pskey); - for (i = 0; i < length; i++) - printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); - printf("\n"); - } - - return 0; -} - -static int pskey_size(uint16_t pskey) -{ - switch (pskey) { - case CSR_PSKEY_BDADDR: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: - return 18; - default: - return 64; - } -} - -static int write_pskey(int dd, uint16_t pskey, uint16_t stores, int type, int argc, char *argv[]) -{ - uint8_t array[64]; - uint16_t value; - uint32_t val32; - int i, err, size = sizeof(array); - - memset(array, 0, sizeof(array)); - - switch (type) { - case CSR_TYPE_ARRAY: - size = pskey_size(pskey); - - if (argc != size) { - errno = EINVAL; - return -1; - } - - for (i = 0; i < size; i++) - if (!strncasecmp(argv[0], "0x", 2)) - array[i] = strtol(argv[i] + 2, NULL, 16); - else - array[i] = atoi(argv[i]); - - err = csr_write_pskey_complex(dd, 0x4711, pskey, - stores, array, size); - break; - - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: - if (argc != 1) { - errno = E2BIG; - return -1; - } - - if (!strncasecmp(argv[0], "0x", 2)) - value = strtol(argv[0] + 2, NULL, 16); - else - value = atoi(argv[0]); - - err = csr_write_pskey_uint16(dd, 0x4711, pskey, stores, value); - break; - - case CSR_TYPE_UINT32: - if (argc != 1) { - errno = E2BIG; - return -1; - } - - if (!strncasecmp(argv[0], "0x", 2)) - val32 = strtol(argv[0] + 2, NULL, 16); - else - val32 = atoi(argv[0]); - - err = csr_write_pskey_uint32(dd, 0x4711, pskey, stores, val32); - break; - - default: - errno = EFAULT; - err = -1; - break; - } - - return err; -} - -static int read_pskey(int dd, uint16_t pskey, uint16_t stores, int type) -{ - uint8_t array[64]; - uint16_t value = 0; - uint32_t val32 = 0; - int i, err, size = sizeof(array); - - memset(array, 0, sizeof(array)); - - switch (type) { - case CSR_TYPE_ARRAY: - size = pskey_size(pskey); - - err = csr_read_pskey_complex(dd, 0x4711, pskey, stores, array, size); - if (err < 0) - return err; - - printf("%s:", csr_pskeytostr(pskey)); - for (i = 0; i < size; i++) - printf(" 0x%02x", array[i]); - printf("\n"); - break; - - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: - err = csr_read_pskey_uint16(dd, 0x4711, pskey, stores, &value); - if (err < 0) - return err; - - printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); - break; - - case CSR_TYPE_UINT32: - err = csr_read_pskey_uint32(dd, 0x4711, pskey, stores, &val32); - if (err < 0) - return err; - - printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); - break; - - default: - errno = EFAULT; - err = -1; - break; - } - - return err; -} - -static int delete_pskey(int dd, uint16_t pskey, uint16_t stores) -{ - uint8_t array[8]; - int err; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_write_varid_complex(dd, 0x4711, - CSR_VARID_PS_CLR_STORES, array, sizeof(array)); - - return err; -} - -static struct { - uint16_t pskey; - int type; - char *str; -} storage[] = { - { CSR_PSKEY_BDADDR, CSR_TYPE_ARRAY, "bdaddr" }, - { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, "country" }, - { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, "devclass" }, - { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, - { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, - { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, - { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, "commands" }, - { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, - { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, - { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, "hciextn" }, - { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, - { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, - { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, - { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, "anafreq" }, - { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, "anaftrim" }, - { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, - { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, - { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, - { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, - { 0x0000, CSR_TYPE_NULL, NULL }, -}; - -static void usage(void) -{ - int i, pos = 0; - - printf("pskey - Utility for changing CSR persistent storage\n\n"); - printf("Usage:\n" - "\tpskey [-i ] [-r] [-s stores] [value]\n" - "\tpskey [-i ] [-r] [-s stores] --clear \n" - "\tpskey [-i ] [-s stores] --memory\n" - "\tpskey [-i ] [-s stores] --list\n" - "\tpskey [-i ] [-s stores] --read\n\n"); - - printf("Keys:\n\t"); - for (i = 0; storage[i].pskey; i++) { - printf("%s ", storage[i].str); - pos += strlen(storage[i].str) + 1; - if (pos > 60) { - printf("\n\t"); - pos = 0; - } - } - printf("\n"); -} - -static struct option main_options[] = { - { "device", 1, 0, 'i' }, - { "reset", 0, 0, 'r' }, - { "stores", 1, 0, 's' }, - { "clear", 0, 0, 'c' }, - { "memory", 0, 0, 'M' }, - { "list", 0, 0, 'L' }, - { "read", 0, 0, 'R' }, - { "help", 0, 0, 'h' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char *argv[]) -{ - struct hci_dev_info di; - struct hci_version ver; - uint16_t stores = 0x0001 | 0x0002 | 0x0008; - int i, err, dd, opt, dev = 0, reset = 0, clear = 0, mode = NONE; - - while ((opt=getopt_long(argc, argv, "+i:rs:cMLRh", main_options, NULL)) != -1) { - switch (opt) { - case 'i': - dev = hci_devid(optarg); - if (dev < 0) { - perror("Invalid device"); - exit(1); - } - break; - - case 'r': - reset = 1; - break; - - case 's': - if (!strcasecmp(optarg, "default")) - stores = 0x0000; - else if (!strcasecmp(optarg, "implementation")) - stores = 0x0001; - else if (!strcasecmp(optarg, "factory")) - stores = 0x0002; - else if (!strcasecmp(optarg, "rom")) - stores = 0x0004; - else if (!strcasecmp(optarg, "ram")) - stores = 0x0008; - else if (!strcasecmp(optarg, "psi")) - stores = 0x0001; - else if (!strcasecmp(optarg, "psf")) - stores = 0x0002; - else if (!strcasecmp(optarg, "psrom")) - stores = 0x0004; - else if (!strcasecmp(optarg, "psram")) - stores = 0x0008; - else if (!strncasecmp(optarg, "0x", 2)) - stores = strtol(optarg, NULL, 16); - else - stores = atoi(optarg); - break; - - case 'c': - clear = 1; - break; - - case 'M': - mode = MEMORY; - break; - - case 'L': - mode = LIST; - break; - - case 'R': - mode = READ; - break; - - case 'h': - default: - usage(); - exit(0); - } - } - - argc -= optind; - argv += optind; - optind = 0; - - if (mode == NONE && argc < 1) { - usage(); - exit(1); - } - - dd = hci_open_dev(dev); - if (dd < 0) { - fprintf(stderr, "Can't open device hci%d: %s (%d)\n", - dev, strerror(errno), errno); - exit(1); - } - - if (hci_devinfo(dev, &di) < 0) { - fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (hci_read_local_version(dd, &ver, 1000) < 0) { - fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (ver.manufacturer != 10) { - fprintf(stderr, "Unsupported manufacturer\n"); - hci_close_dev(dd); - exit(1); - } - - if (mode > 0) { - switch (mode) { - case MEMORY: - err = cmd_memory(dd, stores, argc, argv); - break; - case LIST: - err = cmd_list(dd, stores, argc, argv); - break; - case READ: - err = cmd_read(dd, stores, argc, argv); - break; - default: - usage(); - err = -1; - break; - } - - hci_close_dev(dd); - exit(err < 0 ? 1 : 0); - } - - for (i = 0; storage[i].pskey; i++) { - if (strcasecmp(storage[i].str, argv[0])) - continue; - - if (argc > 1) { - err = write_pskey(dd, storage[i].pskey, stores, - storage[i].type, argc - 1, argv + 1); - - if (!err && reset) - csr_write_varid_valueless(dd, 0x0000, - CSR_VARID_WARM_RESET); - } else { - if (clear) - err = delete_pskey(dd, storage[i].pskey, stores); - else - err = read_pskey(dd, storage[i].pskey, - stores, storage[i].type); - } - - hci_close_dev(dd); - - if (err < 0) { - fprintf(stderr, "Can't %s persistent storage: %s (%d)\n", - argc > 1 ? "write" : "read", strerror(errno), errno); - exit(1); - } - - exit(0); - } - - fprintf(stderr, "Unsupported persistent storage\n"); - - hci_close_dev(dd); - - exit(1); -} -- cgit