diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2005-06-10 05:30:28 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2005-06-10 05:30:28 +0000 | 
| commit | f285dc875c194aab8b1048b53d9681b43fa1a18c (patch) | |
| tree | ab01cdb7c425aca493ff6215864a30cd8fc6ca80 | |
| parent | 9ea3fe29624242544794b25154dc1b246e5e10cf (diff) | |
Allow reading of complex PS keys
| -rw-r--r-- | tools/csr.c | 48 | ||||
| -rw-r--r-- | tools/csr.h | 1 | ||||
| -rw-r--r-- | tools/pskey.c | 73 | 
3 files changed, 99 insertions, 23 deletions
| diff --git a/tools/csr.c b/tools/csr.c index 4829a66d..6b34fc3f 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -386,6 +386,12 @@ char *csr_pskeytostr(uint16_t pskey)  		return "Minimum encryption key length";  	case CSR_PSKEY_ENC_KEY_LMAX:  		return "Maximum encryption key length"; +	case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: +		return "Local supported features block"; +	case CSR_PSKEY_HCI_LMP_LOCAL_VERSION: +		return "The HCI and LMP version reported locally"; +	case CSR_PSKEY_LMP_REMOTE_VERSION: +		return "The LMP version reported remotely";  	case CSR_PSKEY_HOSTIO_MAP_SCO_PCM:  		return "Map SCO over PCM";  	case CSR_PSKEY_UART_BAUDRATE: @@ -486,6 +492,48 @@ int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *val  	return 0;  } +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length) +{ +	unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, +				seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, +				pskey & 0xff, pskey >> 8, +				(length / 2) & 0xff, (length / 2) >> 8, +				0x00, 0x00, 0x00, 0x00 }; + +	unsigned char cp[254], rp[254]; +	struct hci_request rq; + +	memset(&cp, 0, sizeof(cp)); +	cp[0] = 0xc2; +	memcpy(cp + 1, cmd, sizeof(cmd)); + +	memset(&rq, 0, sizeof(rq)); +	rq.ogf    = OGF_VENDOR_CMD; +	rq.ocf    = 0x00; +	rq.event  = EVT_VENDOR; +	rq.cparam = cp; +	rq.clen   = sizeof(cmd) + 1; +	rq.rparam = rp; +	rq.rlen   = sizeof(rp); + +	if (hci_send_req(dd, &rq, 2000) < 0) +		return -1; + +	if (rp[0] != 0xc2) { +		errno = EIO; +		return -1; +	} + +	if ((rp[9] + (rp[10] << 8)) != 0) { +		errno = ENXIO; +		return -1; +	} + +	memcpy(value, rp + 17, length); + +	return 0; +} +  int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value)  {  	unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, diff --git a/tools/csr.h b/tools/csr.h index 347e1d54..61df145e 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -77,5 +77,6 @@ char *csr_pskeytostr(uint16_t pskey);  int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length);  int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length);  int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value);  int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); diff --git a/tools/pskey.c b/tools/pskey.c index 2b4bc210..9a4dd547 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -43,8 +43,9 @@  #include "csr.h"  #define CSR_TYPE_NULL	0 -#define CSR_TYPE_UINT8	1 -#define CSR_TYPE_UINT16	2 +#define CSR_TYPE_ARRAY	1 +#define CSR_TYPE_UINT8	2 +#define CSR_TYPE_UINT16	3  static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[])  { @@ -73,19 +74,38 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[])  static int read_pskey(int dd, uint16_t pskey, int type)  { -	uint16_t value; -	int err; +	uint8_t array[64]; +	uint16_t value = 0; +	int i, err, size = sizeof(array); -	if (type != CSR_TYPE_UINT8 && type != CSR_TYPE_UINT16) { +	memset(array, 0, sizeof(array)); + +	if (type != CSR_TYPE_ARRAY && +			type != CSR_TYPE_UINT8 && +			type != CSR_TYPE_UINT16) {  		errno = EFAULT;  		return -1;  	} -	err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); -	if (err < 0) -		return err; +	if (type != CSR_TYPE_ARRAY) { +		err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); +		if (err < 0) +			return err; + +		printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); +	} else { +		if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) +			size = 8; -	printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); +		err = csr_read_pskey_complex(dd, 0x4711, pskey, 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"); +	}  	return err;  } @@ -95,31 +115,38 @@ static struct {  	int type;  	char *str;  } storage[] = { -	{ CSR_PSKEY_ENC_KEY_LMIN,          CSR_TYPE_UINT16, "keymin"   }, -	{ CSR_PSKEY_ENC_KEY_LMAX,          CSR_TYPE_UINT16, "keymax"   }, -	{ CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version"  }, -	{ CSR_PSKEY_LMP_REMOTE_VERSION,    CSR_TYPE_UINT8,  "remver"   }, -	{ 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_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" }, +	{ 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_HCI_LMP_LOCAL_VERSION,    CSR_TYPE_UINT16, "version"  }, +	{ CSR_PSKEY_LMP_REMOTE_VERSION,       CSR_TYPE_UINT8,  "remver"   }, +	{ 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_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; +	int i, pos = 0;  	printf("pskey - Utility for changing CSR persistent storage\n\n");  	printf("Usage:\n"  		"\tpskey [-i <dev>] <key> [value]\n\n");  	printf("Keys:\n\t"); -		for (i = 0; storage[i].pskey; i++) -			printf("%s ", storage[i].str); +	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");  } | 
