diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2005-11-06 21:00:58 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2005-11-06 21:00:58 +0000 | 
| commit | 50a8cc8a256f3ef56a6144cabd2ae6ee5848e46d (patch) | |
| tree | e87bce02680dea3e05c51f2c727d91b6805cf726 | |
| parent | 9410c612d365b3aabf13da966e6782225068954f (diff) | |
Update to the new BCCMD interface utility
| -rw-r--r-- | acinclude.m4 | 18 | ||||
| -rw-r--r-- | tools/Makefile.am | 36 | ||||
| -rw-r--r-- | tools/bccmd.c | 749 | ||||
| -rw-r--r-- | tools/csrinit.8 | 35 | ||||
| -rw-r--r-- | tools/csrinit.c | 97 | ||||
| -rw-r--r-- | tools/pskey.c | 581 | 
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); -} | 
