summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-11-06 21:00:58 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-11-06 21:00:58 +0000
commit50a8cc8a256f3ef56a6144cabd2ae6ee5848e46d (patch)
treee87bce02680dea3e05c51f2c727d91b6805cf726
parent9410c612d365b3aabf13da966e6782225068954f (diff)
Update to the new BCCMD interface utility
-rw-r--r--acinclude.m418
-rw-r--r--tools/Makefile.am36
-rw-r--r--tools/bccmd.c749
-rw-r--r--tools/csrinit.835
-rw-r--r--tools/csrinit.c97
-rw-r--r--tools/pskey.c581
6 files changed, 727 insertions, 789 deletions
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, "<handle>", "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, "<handle>", "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, "<key>", "Get value for PS key" },
+ { "psset", cmd_psset, "<key> <value>", "Set value for PS key" },
+ { "psclr", cmd_psclr, "<key>", "Clear value for PS key" },
+ { "pslist", cmd_pslist, NULL, "List all PS keys" },
+ { "psread", cmd_psread, NULL, "Read all PS keys" },
+ { "psload", cmd_psload, "<file>", "Load all PS keys from PSR file" },
+ { "pscheck", cmd_pscheck, "<file>", "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 <dev>] <command>\n\n");
+ "\tbccmd [options] <command>\n\n");
+
+ printf("Options:\n"
+ "\t-t <transport> Select the transport\n"
+ "\t-d <device> 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 <marcel@holtmann.org>.
-.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 <marcel@holtmann.org>
- *
- *
- * 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 <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdint.h>
-#include <getopt.h>
-
-#include <usb.h>
-
-#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 <marcel@holtmann.org>
- *
- *
- * 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 <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <sys/socket.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-
-#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 <dev>] [-r] [-s stores] <key> [value]\n"
- "\tpskey [-i <dev>] [-r] [-s stores] --clear <key>\n"
- "\tpskey [-i <dev>] [-s stores] --memory\n"
- "\tpskey [-i <dev>] [-s stores] --list\n"
- "\tpskey [-i <dev>] [-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);
-}