From fd1420fe08910f599bbb3bc84840318d1b99f748 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:51:27 +0000 Subject: Add tool for the CSR BCCMD interface --- tools/bccmd.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 tools/bccmd.c (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c new file mode 100644 index 00000000..4b4a1fb4 --- /dev/null +++ b/tools/bccmd.c @@ -0,0 +1,193 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "csr.h" + +static int cmd_keylen(int dd, int argc, char *argv[]) +{ + uint8_t buf[8]; + uint16_t handle, keylen; + int err; + + if (argc < 1) { + errno = EINVAL; + return -1; + } + + if (argc > 1) { + errno = E2BIG; + return -1; + } + + handle = atoi(argv[0]); + + memset(buf, 0, sizeof(buf)); + buf[0] = handle & 0xff; + buf[1] = handle >> 8; + + err = csr_read_varid_complex(dd, 0x4711, + CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); + if (err < 0) { + errno = -err; + return -1; + } + + handle = buf[0] | (buf[1] << 8); + keylen = buf[2] | (buf[3] << 8); + + printf("Crypt key length: %d bit\n", keylen * 8); + + return 0; +} + +static struct { + char *str; + int (*func)(int dd, int argc, char **argv); + char *arg; + char *doc; +} commands[] = { + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { NULL }, +}; + +static void usage(void) +{ + int i; + + printf("bccmd - Utility for the CSR BCCMD interface\n\n"); + printf("Usage:\n" + "\tbccmd [-i ] \n\n"); + + printf("Commands:\n"); + for (i = 0; commands[i].str; i++) + printf("\t%s\t%s\t%s\n", commands[i].str, + commands[i].arg, commands[i].doc); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct hci_dev_info di; + struct hci_version ver; + int i, err, dd, opt, dev = 0; + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (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); + } + + for (i = 0; commands[i].str; i++) { + if (strcasecmp(commands[i].str, argv[0])) + continue; + + err = commands[i].func(dd, argc - 1, argv + 1); + + hci_close_dev(dd); + + if (err < 0) { + fprintf(stderr, "Can't execute command: %s (%d)\n", + strerror(errno), errno); + exit(1); + } + + exit(0); + } + + fprintf(stderr, "Unsupported command\n"); + + hci_close_dev(dd); + + exit(1); +} -- cgit From ab788511066ea30c788d907fd44c8427f97b6e54 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:10:34 +0000 Subject: Add support for getting the local Bluetooth clock --- tools/bccmd.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 4b4a1fb4..5e358b01 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -79,6 +79,22 @@ static int cmd_keylen(int dd, int argc, char *argv[]) return 0; } +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); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Bluetooth clock: 0x%04x (%d)\n", clock, clock); + + return 0; +} + static struct { char *str; int (*func)(int dd, int argc, char **argv); @@ -86,6 +102,7 @@ static struct { char *doc; } commands[] = { { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { NULL }, }; @@ -99,7 +116,7 @@ static void usage(void) printf("Commands:\n"); for (i = 0; commands[i].str; i++) - printf("\t%s\t%s\t%s\n", commands[i].str, + printf("\t%s\t%-8s\t%s\n", commands[i].str, commands[i].arg, commands[i].doc); } -- cgit From 4f32352b05190a3f70828c38f4a4f25655bb696e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 13:13:17 +0000 Subject: Move CSR panic and fault code reading to the bccmd tool --- tools/bccmd.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 5e358b01..df39a3df 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -95,14 +95,50 @@ static int cmd_clock(int dd, int argc, char *argv[]) return 0; } +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); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Panic code: 0x%02x (%s)\n", error, + error < 0x100 ? "valid" : "invalid"); + + return 0; +} + +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); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Fault code: 0x%02x (%s)\n", error, + error < 0x100 ? "valid" : "invalid"); + + return 0; +} + static struct { char *str; int (*func)(int dd, int argc, char **argv); char *arg; char *doc; } commands[] = { - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, { NULL }, }; @@ -116,7 +152,7 @@ static void usage(void) printf("Commands:\n"); for (i = 0; commands[i].str; i++) - printf("\t%s\t%-8s\t%s\n", commands[i].str, + printf("\t%-10s%-8s\t%s\n", commands[i].str, commands[i].arg, commands[i].doc); } -- cgit From 87af78afc0d5753583825f061c36f7705762c576 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 22 Aug 2005 20:38:18 +0000 Subject: Add support for reset and transmitter modification --- tools/bccmd.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index df39a3df..e476165e 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -95,6 +95,22 @@ static int cmd_clock(int dd, int argc, char *argv[]) return 0; } +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); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Random number: 0x%02x (%d)\n", rand, rand); + + return 0; +} + static int cmd_panicarg(int dd, int argc, char *argv[]) { uint16_t error = 0; @@ -129,16 +145,41 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) return 0; } +static int cmd_coldreset(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, 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); +} + +static int cmd_disabletx(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, 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); +} + static struct { char *str; int (*func)(int dd, int argc, char **argv); char *arg; char *doc; } commands[] = { - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, - { "panicarg", cmd_panicarg, "", "Get panic code argument" }, - { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "rand", cmd_rand, "", "Get random number" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "coldreset", cmd_coldreset, "", "Perform cold reset" }, + { "warmreset", cmd_warmreset, "", "Perform warm reset" }, + { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, + { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, { NULL }, }; -- cgit From 7dbda16a2352e6c935c47b49ecca3336bdc2a5da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 01:55:51 +0000 Subject: Add support for reading the build definitions --- tools/bccmd.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index e476165e..4d32c089 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -42,6 +42,41 @@ #include "csr.h" +static int cmd_builddef(int dd, int argc, char *argv[]) +{ + uint8_t buf[8]; + uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; + int err = 0; + + printf("Build definitions:"); + + while (1) { + memset(buf, 0, sizeof(buf)); + buf[0] = def & 0xff; + buf[1] = def >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_GET_NEXT_BUILDDEF, buf, sizeof(buf)); + if (err < 0) { + errno = -err; + break; + } + + nextdef = buf[2] | (buf[3] << 8); + + if (nextdef == 0x0000) + break; + + def = nextdef; + + printf(" %s (0x%02x)", csr_builddeftostr(def), def); + } + + printf("\n"); + + return err; +} + static int cmd_keylen(int dd, int argc, char *argv[]) { uint8_t buf[8]; @@ -171,6 +206,7 @@ static struct { char *arg; char *doc; } commands[] = { + { "builddef", cmd_builddef, "", "Get build definitions" }, { "keylen", cmd_keylen, "", "Get current crypt key length" }, { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { "rand", cmd_rand, "", "Get random number" }, -- cgit From ed31ef0927bc60f9ecb24c1733aabb8540adc72b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 01:59:11 +0000 Subject: Display one build definition per line --- tools/bccmd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 4d32c089..18d38766 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -48,7 +48,7 @@ static int cmd_builddef(int dd, int argc, char *argv[]) uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; int err = 0; - printf("Build definitions:"); + printf("Build definitions:\n"); while (1) { memset(buf, 0, sizeof(buf)); @@ -69,11 +69,9 @@ static int cmd_builddef(int dd, int argc, char *argv[]) def = nextdef; - printf(" %s (0x%02x)", csr_builddeftostr(def), def); + printf("0x%04x - %s\n", def, csr_builddeftostr(def)); } - printf("\n"); - return err; } -- cgit From 632a9432774ff3a0c6e556e8f32a565b38890767 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 22:36:31 +0000 Subject: Big cleanup of CVS relics --- tools/bccmd.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 18d38766..46cc2be1 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 * - * - * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From 50a8cc8a256f3ef56a6144cabd2ae6ee5848e46d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Nov 2005 21:00:58 +0000 Subject: Update to the new BCCMD interface utility --- tools/bccmd.c | 749 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 704 insertions(+), 45 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 46cc2be1..e41f08f5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -37,12 +37,144 @@ #include "csr.h" +#define CSR_TRANSPORT_UNKNOWN 0 +#define CSR_TRANSPORT_HCI 1 +#define CSR_TRANSPORT_USB 2 +#define CSR_TRANSPORT_BCSP 3 +#define CSR_TRANSPORT_H4 4 +#define CSR_TRANSPORT_3WIRE 5 + +#define CSR_STORES_PSI (0x0001) +#define CSR_STORES_PSF (0x0002) +#define CSR_STORES_PSROM (0x0004) +#define CSR_STORES_PSRAM (0x0008) +#define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF | CSR_STORES_PSRAM) + +#define CSR_TYPE_NULL 0 +#define CSR_TYPE_COMPLEX 1 +#define CSR_TYPE_UINT8 2 +#define CSR_TYPE_UINT16 3 +#define CSR_TYPE_UINT32 4 + +#define CSR_TYPE_ARRAY CSR_TYPE_COMPLEX +#define CSR_TYPE_BDADDR CSR_TYPE_COMPLEX + +static uint16_t seqnum = 0x0000; + +static struct { + uint16_t pskey; + int type; + int size; + char *str; +} storage[] = { + { CSR_PSKEY_BDADDR, CSR_TYPE_BDADDR, 8, "bdaddr" }, + { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, 0, "country" }, + { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, 0, "devclass" }, + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, 0, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, 0, "keymax" }, + { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, 8, "features" }, + { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, 18, "commands" }, + { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, 0, "version" }, + { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, 0, "remver" }, + { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, 0, "hciextn" }, + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, 0, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, 0, "baudrate" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, 0, "hostintf" }, + { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, 0, "anafreq" }, + { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, 0, "anaftrim" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, 0, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, 0, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, 0, "dfupid" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, 0, "bootmode" }, + { 0x0000 }, +}; + +static int pskey_size(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_BDADDR: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return 18; + default: + return 64; + } +} + +static char *storestostr(uint16_t stores) +{ + switch (stores) { + case 0x0000: + return "Default"; + case 0x0001: + return "psi"; + case 0x0002: + return "psf"; + case 0x0004: + return "psrom"; + case 0x0008: + return "psram"; + default: + return "Unknown"; + } +} + +static char *memorytostr(uint16_t type) +{ + switch (type) { + case 0x0000: + return "Flash memory"; + case 0x0001: + return "EEPROM"; + case 0x0002: + return "RAM (transient)"; + case 0x0003: + return "ROM (or \"read-only\" flash memory)"; + default: + return "Unknown"; + } +} + +#define OPT_RANGE(range) \ + if (argc < (range)) { errno = EINVAL; return -1; } \ + if (argc > (range)) { errno = E2BIG; return -1; } + +static struct option help_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static int opt_help(int argc, char *argv[], int *help) +{ + int opt; + + while ((opt=getopt_long(argc, argv, "+h", help_options, NULL)) != EOF) { + switch (opt) { + case 'h': + if (help) + *help = 1; + break; + } + } + + return optind; +} + +#define OPT_HELP(range, help) \ + opt_help(argc, argv, (help)); \ + argc -= optind; argv += optind; optind = 0; \ + OPT_RANGE((range)) + static int cmd_builddef(int dd, int argc, char *argv[]) { uint8_t buf[8]; - uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; + uint16_t def = 0x0000, nextdef = 0x0000; int err = 0; + OPT_HELP(0, NULL); + printf("Build definitions:\n"); while (1) { @@ -76,15 +208,7 @@ static int cmd_keylen(int dd, int argc, char *argv[]) uint16_t handle, keylen; int err; - if (argc < 1) { - errno = EINVAL; - return -1; - } - - if (argc > 1) { - errno = E2BIG; - return -1; - } + OPT_HELP(1, NULL); handle = atoi(argv[0]); @@ -92,7 +216,7 @@ static int cmd_keylen(int dd, int argc, char *argv[]) buf[0] = handle & 0xff; buf[1] = handle >> 8; - err = csr_read_varid_complex(dd, 0x4711, + err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); if (err < 0) { errno = -err; @@ -112,7 +236,9 @@ static int cmd_clock(int dd, int argc, char *argv[]) uint32_t clock = 0; int err; - err = csr_read_varid_uint32(dd, 0x4711, CSR_VARID_BT_CLOCK, &clock); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint32(dd, seqnum++, CSR_VARID_BT_CLOCK, &clock); if (err < 0) { errno = -err; return -1; @@ -128,7 +254,9 @@ static int cmd_rand(int dd, int argc, char *argv[]) uint16_t rand = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_RAND, &rand); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_RAND, &rand); if (err < 0) { errno = -err; return -1; @@ -144,7 +272,9 @@ static int cmd_panicarg(int dd, int argc, char *argv[]) uint16_t error = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_PANIC_ARG, &error); if (err < 0) { errno = -err; return -1; @@ -161,7 +291,9 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) uint16_t error = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_FAULT_ARG, &error); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_FAULT_ARG, &error); if (err < 0) { errno = -err; return -1; @@ -175,60 +307,555 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) static int cmd_coldreset(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_COLD_RESET); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_COLD_RESET); } static int cmd_warmreset(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_WARM_RESET); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); } static int cmd_disabletx(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_DISABLE_TX); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_DISABLE_TX); } static int cmd_enabletx(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_ENABLE_TX); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_ENABLE_TX); +} + +static int cmd_memtypes(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 }; + int i, err; + + OPT_HELP(0, NULL); + + for (i = 0; i < 4; i++) { + memset(array, 0, sizeof(array)); + array[2] = stores[i] & 0xff; + array[3] = stores[i] >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); + if (err < 0) + break; + + type = array[4] + (array[5] << 8); + + printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]), + stores[i], memorytostr(type), type); + } + + return err; +} + +static struct option pskey_options[] = { + { "stores", 1, 0, 's' }, + { "reset", 0, 0, 'r' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int *help) +{ + int opt; + + while ((opt=getopt_long(argc, argv, "+s:rh", pskey_options, NULL)) != EOF) { + switch (opt) { + case 's': + if (!stores) + break; + if (!strcasecmp(optarg, "default")) + *stores = 0x0000; + else if (!strcasecmp(optarg, "implementation")) + *stores = 0x0001; + else if (!strcasecmp(optarg, "factory")) + *stores = 0x0002; + else if (!strcasecmp(optarg, "rom")) + *stores = 0x0004; + else if (!strcasecmp(optarg, "ram")) + *stores = 0x0008; + else if (!strcasecmp(optarg, "psi")) + *stores = 0x0001; + else if (!strcasecmp(optarg, "psf")) + *stores = 0x0002; + else if (!strcasecmp(optarg, "psrom")) + *stores = 0x0004; + else if (!strcasecmp(optarg, "psram")) + *stores = 0x0008; + else if (!strncasecmp(optarg, "0x", 2)) + *stores = strtol(optarg, NULL, 16); + else + *stores = atoi(optarg); + break; + + case 'r': + if (reset) + *reset = 1; + break; + + case 'h': + if (help) + *help = 1; + break; + } + } + + return optind; +} + +#define OPT_PSKEY(range, stores, reset, help) \ + opt_pskey(argc, argv, (stores), (reset), (help)); \ + argc -= optind; argv += optind; optind = 0; \ + OPT_RANGE((range)) + +static int cmd_psget(int dd, int argc, char *argv[]) +{ + uint8_t array[64]; + uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT; + uint32_t val32; + int i, err, size, reset = 0, type = CSR_TYPE_NULL; + + memset(array, 0, sizeof(array)); + + OPT_PSKEY(1, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + type = storage[i].type; + size = storage[i].type; + break; + } + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } else { + pskey = strtol(argv[0] + 2, NULL, 16); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } + + switch (type) { + case CSR_TYPE_COMPLEX: + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + return err; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + return -EIO; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, stores, + array, length * 2); + if (err < 0) + return err; + + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < length; i++) + printf(" 0x%02x%02x", array[i * 2], array[(i * 2) + 1]); + printf("\n"); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: + err = csr_read_pskey_uint16(dd, seqnum++, pskey, stores, &value); + if (err < 0) + return err; + + printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); + break; + + case CSR_TYPE_UINT32: + err = csr_read_pskey_uint32(dd, seqnum++, pskey, stores, &val32); + if (err < 0) + return err; + + printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; + } + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_psset(int dd, int argc, char *argv[]) +{ + uint8_t array[64]; + uint16_t pskey, value, stores = CSR_STORES_PSRAM; + uint32_t val32; + int i, err, size, reset = 0, type = CSR_TYPE_NULL; + + memset(array, 0, sizeof(array)); + + OPT_PSKEY(2, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + type = storage[i].type; + size = storage[i].type; + break; + } + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } else { + pskey = strtol(argv[0] + 2, NULL, 16); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } + + argc--; + argv++; + + switch (type) { + case CSR_TYPE_COMPLEX: + size = pskey_size(pskey); + + if (argc != size) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < size; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i] = strtol(argv[i] + 2, NULL, 16); + else + array[i] = atoi(argv[i]); + + err = csr_write_pskey_complex(dd, seqnum++, pskey, + stores, array, size); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: + if (argc != 1) { + errno = E2BIG; + return -1; + } + + if (!strncasecmp(argv[0], "0x", 2)) + value = strtol(argv[0] + 2, NULL, 16); + else + value = atoi(argv[0]); + + err = csr_write_pskey_uint16(dd, seqnum++, pskey, stores, value); + break; + + case CSR_TYPE_UINT32: + if (argc != 1) { + errno = E2BIG; + return -1; + } + + if (!strncasecmp(argv[0], "0x", 2)) + val32 = strtol(argv[0] + 2, NULL, 16); + else + val32 = atoi(argv[0]); + + err = csr_write_pskey_uint32(dd, seqnum++, pskey, stores, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; + } + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_psclr(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t pskey, stores = CSR_STORES_PSRAM; + int i, err, reset = 0; + + OPT_PSKEY(1, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + break; + } + pskey = atoi(argv[0]); + } else + pskey = strtol(argv[0] + 2, NULL, 16); + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_write_varid_complex(dd, seqnum++, + CSR_VARID_PS_CLR_STORES, array, sizeof(array)); + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_pslist(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; + int err, reset = 0; + + OPT_PSKEY(0, &stores, &reset, NULL); + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, sizeof(array)); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, sizeof(array)); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + + printf("0x%04x - %s (%d bytes)\n", pskey, + csr_pskeytostr(pskey), length * 2); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_psread(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; + char *str, val[7]; + int i, err, reset = 0; + + OPT_PSKEY(0, &stores, &reset, NULL); + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, 8); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + continue; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, + stores, array, length * 2); + if (err < 0) + continue; + + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", + str ? str : val, pskey); + for (i = 0; i < length; i++) + printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf("\n"); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_psload(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey, size, stores = CSR_STORES_PSRAM; + char *str, val[7]; + int err, reset = 0; + + OPT_PSKEY(1, &stores, &reset, NULL); + + psr_read(argv[0]); + + while (psr_get(&pskey, array, &size) == 0) { + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("Loading %s%s ... ", str ? "PSKEY_" : "", + str ? str : val); + fflush(stdout); + + err = csr_write_pskey_complex(dd, seqnum++, pskey, + stores, array, size); + + printf("%s\n", err < 0 ? "failed" : "done"); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_pscheck(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey, size; + int i; + + OPT_HELP(1, NULL); + + psr_read(argv[0]); + + while (psr_get(&pskey, array, &size) == 0) { + printf("0x%04x =", pskey); + for (i = 0; i < size; i++) + printf(" 0x%02x", array[i]); + printf("\n"); + } + + return 0; } static struct { char *str; - int (*func)(int dd, int argc, char **argv); + int (*func)(int dd, int argc, char *argv[]); char *arg; char *doc; } commands[] = { - { "builddef", cmd_builddef, "", "Get build definitions" }, - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, - { "rand", cmd_rand, "", "Get random number" }, - { "panicarg", cmd_panicarg, "", "Get panic code argument" }, - { "faultarg", cmd_faultarg, "", "Get fault code argument" }, - { "coldreset", cmd_coldreset, "", "Perform cold reset" }, - { "warmreset", cmd_warmreset, "", "Perform warm reset" }, - { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, - { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, - { NULL }, + { "builddef", cmd_builddef, "", "Get build definitions" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "rand", cmd_rand, "", "Get random number" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "coldreset", cmd_coldreset, "", "Perform cold reset" }, + { "warmreset", cmd_warmreset, "", "Perform warm reset" }, + { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, + { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, + { "memtypes", cmd_memtypes, NULL, "Get memory types" }, + { "psget", cmd_psget, "", "Get value for PS key" }, + { "psset", cmd_psset, " ", "Set value for PS key" }, + { "psclr", cmd_psclr, "", "Clear value for PS key" }, + { "pslist", cmd_pslist, NULL, "List all PS keys" }, + { "psread", cmd_psread, NULL, "Read all PS keys" }, + { "psload", cmd_psload, "", "Load all PS keys from PSR file" }, + { "pscheck", cmd_pscheck, "", "Check PSR file" }, + { NULL } }; static void usage(void) { - int i; + int i, pos = 0; printf("bccmd - Utility for the CSR BCCMD interface\n\n"); printf("Usage:\n" - "\tbccmd [-i ] \n\n"); + "\tbccmd [options] \n\n"); + + printf("Options:\n" + "\t-t Select the transport\n" + "\t-d Select the device\n" + "\t-h, --help Display help\n" + "\n"); printf("Commands:\n"); - for (i = 0; commands[i].str; i++) - printf("\t%-10s%-8s\t%s\n", commands[i].str, - commands[i].arg, commands[i].doc); + for (i = 0; commands[i].str; i++) + printf("\t%-10s %-14s\t%s\n", commands[i].str, + commands[i].arg ? commands[i].arg : " ", + commands[i].doc); + printf("\n"); + + printf("Keys:\n\t"); + for (i = 0; storage[i].pskey; i++) { + printf("%s ", storage[i].str); + pos += strlen(storage[i].str) + 1; + if (pos > 60) { + printf("\n\t"); + pos = 0; + } + } + printf("\n"); } static struct option main_options[] = { + { "transport", 1, 0, 't' }, + { "device", 1, 0, 'd' }, { "help", 0, 0, 'h' }, - { "device", 1, 0, 'i' }, { 0, 0, 0, 0 } }; @@ -236,16 +863,33 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0; + char *device = NULL; + int i, err, opt, dd, dev, transport = CSR_TRANSPORT_HCI; - while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+t:d:i:h", main_options, NULL)) != EOF) { switch (opt) { + case 't': + if (!strcasecmp(optarg, "hci")) + transport = CSR_TRANSPORT_HCI; + else if (!strcasecmp(optarg, "usb")) + transport = CSR_TRANSPORT_USB; + else if (!strcasecmp(optarg, "bcsp")) + transport = CSR_TRANSPORT_BCSP; + else if (!strcasecmp(optarg, "h4")) + transport = CSR_TRANSPORT_H4; + else if (!strcasecmp(optarg, "h5")) + transport = CSR_TRANSPORT_3WIRE; + else if (!strcasecmp(optarg, "3wire")) + transport = CSR_TRANSPORT_3WIRE; + else if (!strcasecmp(optarg, "twutl")) + transport = CSR_TRANSPORT_3WIRE; + else + transport = CSR_TRANSPORT_UNKNOWN; + break; + + case 'd': case 'i': - dev = hci_devid(optarg); - if (dev < 0) { - perror("Invalid device"); - exit(1); - } + device = strdup(optarg); break; case 'h': @@ -264,6 +908,21 @@ int main(int argc, char *argv[]) exit(1); } + if (transport != CSR_TRANSPORT_HCI) { + fprintf(stderr, "Unsupported transport\n"); + exit(1); + } + + if (device) { + dev = hci_devid(device); + if (dev < 0) { + fprintf(stderr, "Device not available\n"); + exit(1); + } + free(device); + } else + dev = 0; + dd = hci_open_dev(dev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", @@ -295,7 +954,7 @@ int main(int argc, char *argv[]) if (strcasecmp(commands[i].str, argv[0])) continue; - err = commands[i].func(dd, argc - 1, argv + 1); + err = commands[i].func(dd, argc, argv); hci_close_dev(dd); -- cgit From 226949879e3ed5578d678c817a955bd38597eddb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Nov 2005 09:31:00 +0000 Subject: Fix the memory types command --- tools/bccmd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index e41f08f5..902555e5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -335,21 +335,21 @@ static int cmd_memtypes(int dd, int argc, char *argv[]) for (i = 0; i < 4; i++) { memset(array, 0, sizeof(array)); - array[2] = stores[i] & 0xff; - array[3] = stores[i] >> 8; + array[0] = stores[i] & 0xff; + array[1] = stores[i] >> 8; err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); if (err < 0) - break; + continue; - type = array[4] + (array[5] << 8); + type = array[2] + (array[3] << 8); printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]), stores[i], memorytostr(type), type); } - return err; + return 0; } static struct option pskey_options[] = { -- cgit From ff1e0556d0a88335924aea13cfbce67de82d9c19 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Nov 2005 09:41:28 +0000 Subject: Fix parsing of the PS key identifier --- tools/bccmd.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 902555e5..50de4f17 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -424,6 +424,10 @@ static int cmd_psget(int dd, int argc, char *argv[]) OPT_PSKEY(1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; @@ -433,9 +437,6 @@ static int cmd_psget(int dd, int argc, char *argv[]) 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; @@ -511,6 +512,10 @@ static int cmd_psset(int dd, int argc, char *argv[]) OPT_PSKEY(2, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; @@ -520,9 +525,6 @@ static int cmd_psset(int dd, int argc, char *argv[]) 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; @@ -601,6 +603,8 @@ static int cmd_psclr(int dd, int argc, char *argv[]) OPT_PSKEY(1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { + pskey = atoi(argv[0]); + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; @@ -608,7 +612,6 @@ static int cmd_psclr(int dd, int argc, char *argv[]) pskey = storage[i].pskey; break; } - pskey = atoi(argv[0]); } else pskey = strtol(argv[0] + 2, NULL, 16); -- cgit From 254b7892bcfdbbc4ba6c8118f3d0aafc424d1f58 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Nov 2005 14:32:29 +0000 Subject: Only use psi and psf stores as default --- tools/bccmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 50de4f17..357620f5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -48,7 +48,7 @@ #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_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF) #define CSR_TYPE_NULL 0 #define CSR_TYPE_COMPLEX 1 -- cgit From 2ba0839002159cd293bb1a3d85645f04010cf33b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 20:23:47 +0000 Subject: Add USB transport to the bccmd utility --- tools/bccmd.c | 465 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 248 insertions(+), 217 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 357620f5..f39686eb 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -59,7 +59,56 @@ #define CSR_TYPE_ARRAY CSR_TYPE_COMPLEX #define CSR_TYPE_BDADDR CSR_TYPE_COMPLEX -static uint16_t seqnum = 0x0000; +static inline int transport_open(int transport, char *device) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + return csr_open_hci(device); + case CSR_TRANSPORT_USB: + return csr_open_usb(device); + default: + fprintf(stderr, "Unsupported transport\n"); + return -1; + } +} + +static inline void transport_close(int transport) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + csr_close_hci(); + break; + case CSR_TRANSPORT_USB: + csr_close_usb(); + break; + } +} + +static inline int transport_read(int transport, uint16_t varid, uint8_t *value, uint16_t length) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + return csr_read_hci(varid, value, length); + case CSR_TRANSPORT_USB: + return csr_read_usb(varid, value, length); + default: + errno = EOPNOTSUPP; + return -1; + } +} + +static inline int transport_write(int transport, uint16_t varid, uint8_t *value, uint16_t length) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + return csr_write_hci(varid, value, length); + case CSR_TRANSPORT_USB: + return csr_write_usb(varid, value, length); + default: + errno = EOPNOTSUPP; + return -1; + } +} static struct { uint16_t pskey; @@ -89,20 +138,6 @@ static struct { { 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) { @@ -167,9 +202,9 @@ static int opt_help(int argc, char *argv[], int *help) argc -= optind; argv += optind; optind = 0; \ OPT_RANGE((range)) -static int cmd_builddef(int dd, int argc, char *argv[]) +static int cmd_builddef(int transport, int argc, char *argv[]) { - uint8_t buf[8]; + uint8_t array[8]; uint16_t def = 0x0000, nextdef = 0x0000; int err = 0; @@ -178,18 +213,17 @@ static int cmd_builddef(int dd, int argc, char *argv[]) printf("Build definitions:\n"); while (1) { - memset(buf, 0, sizeof(buf)); - buf[0] = def & 0xff; - buf[1] = def >> 8; + memset(array, 0, sizeof(array)); + array[0] = def & 0xff; + array[1] = def >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_GET_NEXT_BUILDDEF, buf, sizeof(buf)); + err = transport_read(transport, CSR_VARID_GET_NEXT_BUILDDEF, array, 8); if (err < 0) { errno = -err; break; } - nextdef = buf[2] | (buf[3] << 8); + nextdef = array[2] | (array[3] << 8); if (nextdef == 0x0000) break; @@ -202,9 +236,9 @@ static int cmd_builddef(int dd, int argc, char *argv[]) return err; } -static int cmd_keylen(int dd, int argc, char *argv[]) +static int cmd_keylen(int transport, int argc, char *argv[]) { - uint8_t buf[8]; + uint8_t array[8]; uint16_t handle, keylen; int err; @@ -212,120 +246,139 @@ static int cmd_keylen(int dd, int argc, char *argv[]) handle = atoi(argv[0]); - memset(buf, 0, sizeof(buf)); - buf[0] = handle & 0xff; - buf[1] = handle >> 8; + memset(array, 0, sizeof(array)); + array[0] = handle & 0xff; + array[1] = handle >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); + err = transport_read(transport, CSR_VARID_CRYPT_KEY_LENGTH, array, 8); if (err < 0) { errno = -err; return -1; } - handle = buf[0] | (buf[1] << 8); - keylen = buf[2] | (buf[3] << 8); + handle = array[0] | (array[1] << 8); + keylen = array[2] | (array[3] << 8); printf("Crypt key length: %d bit\n", keylen * 8); return 0; } -static int cmd_clock(int dd, int argc, char *argv[]) +static int cmd_clock(int transport, int argc, char *argv[]) { - uint32_t clock = 0; + uint8_t array[8]; + uint32_t clock; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint32(dd, seqnum++, CSR_VARID_BT_CLOCK, &clock); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_BT_CLOCK, array, 8); if (err < 0) { errno = -err; return -1; } + clock = array[2] | (array[3] << 8) | (array[0] << 16) | (array[1] << 24); + printf("Bluetooth clock: 0x%04x (%d)\n", clock, clock); return 0; } -static int cmd_rand(int dd, int argc, char *argv[]) +static int cmd_rand(int transport, int argc, char *argv[]) { - uint16_t rand = 0; + uint8_t array[8]; + uint16_t rand; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_RAND, &rand); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_RAND, array, 8); if (err < 0) { errno = -err; return -1; } + rand = array[0] | (array[1] << 8); + printf("Random number: 0x%02x (%d)\n", rand, rand); return 0; } -static int cmd_panicarg(int dd, int argc, char *argv[]) +static int cmd_panicarg(int transport, int argc, char *argv[]) { - uint16_t error = 0; + uint8_t array[8]; + uint16_t error; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_PANIC_ARG, &error); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_PANIC_ARG, array, 8); if (err < 0) { errno = -err; return -1; } + error = array[0] | (array[1] << 8); + printf("Panic code: 0x%02x (%s)\n", error, error < 0x100 ? "valid" : "invalid"); return 0; } -static int cmd_faultarg(int dd, int argc, char *argv[]) +static int cmd_faultarg(int transport, int argc, char *argv[]) { - uint16_t error = 0; + uint8_t array[8]; + uint16_t error; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_FAULT_ARG, &error); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_FAULT_ARG, array, 8); if (err < 0) { errno = -err; return -1; } + error = array[0] | (array[1] << 8); + printf("Fault code: 0x%02x (%s)\n", error, error < 0x100 ? "valid" : "invalid"); return 0; } -static int cmd_coldreset(int dd, int argc, char *argv[]) +static int cmd_coldreset(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_COLD_RESET); + return transport_write(transport, CSR_VARID_COLD_RESET, NULL, 0); } -static int cmd_warmreset(int dd, int argc, char *argv[]) +static int cmd_warmreset(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + return transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); } -static int cmd_disabletx(int dd, int argc, char *argv[]) +static int cmd_disabletx(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_DISABLE_TX); + return transport_write(transport, CSR_VARID_DISABLE_TX, NULL, 0); } -static int cmd_enabletx(int dd, int argc, char *argv[]) +static int cmd_enabletx(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_ENABLE_TX); + return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0); } -static int cmd_memtypes(int dd, int argc, char *argv[]) +static int cmd_memtypes(int transport, int argc, char *argv[]) { uint8_t array[8]; uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 }; @@ -338,8 +391,7 @@ static int cmd_memtypes(int dd, int argc, char *argv[]) array[0] = stores[i] & 0xff; array[1] = stores[i] >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); + err = transport_read(transport, CSR_VARID_PS_MEMORY_TYPE, array, 8); if (err < 0) continue; @@ -412,12 +464,12 @@ static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int * argc -= optind; argv += optind; optind = 0; \ OPT_RANGE((range)) -static int cmd_psget(int dd, int argc, char *argv[]) +static int cmd_psget(int transport, int argc, char *argv[]) { - uint8_t array[64]; + uint8_t array[128]; uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT; uint32_t val32; - int i, err, size, reset = 0, type = CSR_TYPE_NULL; + int i, err, reset = 0; memset(array, 0, sizeof(array)); @@ -425,87 +477,74 @@ static int cmd_psget(int dd, int argc, char *argv[]) if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); 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; } - } else { + } 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; + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; - err = csr_read_pskey_complex(dd, seqnum++, pskey, stores, - array, length * 2); - if (err < 0) - return err; + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); + 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; + length = array[2] + (array[3] << 8); + if (length + 6 > sizeof(array) / 2) + return -EIO; + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; + + err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2); + if (err < 0) + return err; + + switch (length) { + case 1: + value = array[6] | (array[7] << 8); 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; - + case 2: + val32 = array[8] | (array[9] << 8) | (array[6] << 16) | (array[7] << 24); printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); break; default: - errno = EFAULT; - err = -1; + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < length; i++) + printf(" 0x%02x%02x", array[(i * 2) + 6], array[(i * 2) + 7]); + printf("\n"); break; } - if (!err && reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + if (reset) + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return err; } -static int cmd_psset(int dd, int argc, char *argv[]) +static int cmd_psset(int transport, int argc, char *argv[]) { - uint8_t array[64]; - uint16_t pskey, value, stores = CSR_STORES_PSRAM; + uint8_t array[128]; + uint16_t pskey, length, value, stores = CSR_STORES_PSRAM; uint32_t val32; - int i, err, size, reset = 0, type = CSR_TYPE_NULL; + int i, err, reset = 0; memset(array, 0, sizeof(array)); @@ -513,48 +552,44 @@ static int cmd_psset(int dd, int argc, char *argv[]) if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); 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; } - } else { + } else pskey = strtol(argv[0] + 2, NULL, 16); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); - } - argc--; - argv++; + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; - switch (type) { - case CSR_TYPE_COMPLEX: - size = pskey_size(pskey); + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + return err; - if (argc != size) { - errno = EINVAL; - return -1; - } + length = array[2] + (array[3] << 8); + if (length + 6 > sizeof(array) / 2) + return -EIO; - 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]); + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; - err = csr_write_pskey_complex(dd, seqnum++, pskey, - stores, array, size); - break; + argc--; + argv++; - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: + switch (length) { + case 1: if (argc != 1) { errno = E2BIG; return -1; @@ -565,10 +600,11 @@ static int cmd_psset(int dd, int argc, char *argv[]) else value = atoi(argv[0]); - err = csr_write_pskey_uint16(dd, seqnum++, pskey, stores, value); + array[6] = value & 0xff; + array[7] = value >> 8; break; - case CSR_TYPE_UINT32: + case 2: if (argc != 1) { errno = E2BIG; return -1; @@ -579,22 +615,37 @@ static int cmd_psset(int dd, int argc, char *argv[]) else val32 = atoi(argv[0]); - err = csr_write_pskey_uint32(dd, seqnum++, pskey, stores, val32); + array[6] = (val32 & 0xff0000) >> 16; + array[7] = val32 >> 24; + array[8] = val32 & 0xff; + array[9] = (val32 & 0xff00) >> 8; break; default: - errno = EFAULT; - err = -1; + if (argc != length * 2) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < length * 2; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i + 6] = strtol(argv[i] + 2, NULL, 16); + else + array[i + 6] = atoi(argv[i]); break; } - if (!err && reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + err = transport_write(transport, CSR_VARID_PS, array, (length + 3) * 2); + if (err < 0) + return err; + + if (reset) + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return err; } -static int cmd_psclr(int dd, int argc, char *argv[]) +static int cmd_psclr(int transport, int argc, char *argv[]) { uint8_t array[8]; uint16_t pskey, stores = CSR_STORES_PSRAM; @@ -621,16 +672,17 @@ static int cmd_psclr(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_write_varid_complex(dd, seqnum++, - CSR_VARID_PS_CLR_STORES, array, sizeof(array)); + err = transport_write(transport, CSR_VARID_PS_CLR_STORES, array, 8); + if (err < 0) + return err; - if (!err && reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + if (reset) + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return err; } -static int cmd_pslist(int dd, int argc, char *argv[]) +static int cmd_pslist(int transport, int argc, char *argv[]) { uint8_t array[8]; uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; @@ -645,8 +697,7 @@ static int cmd_pslist(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, sizeof(array)); + err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8); if (err < 0) break; @@ -660,8 +711,7 @@ static int cmd_pslist(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, sizeof(array)); + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); if (err < 0) continue; @@ -672,12 +722,12 @@ static int cmd_pslist(int dd, int argc, char *argv[]) } if (reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return 0; } -static int cmd_psread(int dd, int argc, char *argv[]) +static int cmd_psread(int transport, int argc, char *argv[]) { uint8_t array[256]; uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; @@ -693,8 +743,7 @@ static int cmd_psread(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, 8); + err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8); if (err < 0) break; @@ -708,17 +757,23 @@ static int cmd_psread(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); if (err < 0) continue; length = array[2] + (array[3] << 8); - if (length > sizeof(array) / 2) + if (length + 6 > sizeof(array) / 2) continue; - err = csr_read_pskey_complex(dd, seqnum++, pskey, - stores, array, length * 2); + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; + + err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2); if (err < 0) continue; @@ -731,20 +786,20 @@ static int cmd_psread(int dd, int argc, char *argv[]) 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(" %02x%02x", array[(i * 2) + 7], array[(i * 2) + 6]); printf("\n"); } if (reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return 0; } -static int cmd_psload(int dd, int argc, char *argv[]) +static int cmd_psload(int transport, int argc, char *argv[]) { uint8_t array[256]; - uint16_t pskey, size, stores = CSR_STORES_PSRAM; + uint16_t pskey, length, size, stores = CSR_STORES_PSRAM; char *str, val[7]; int err, reset = 0; @@ -752,7 +807,10 @@ static int cmd_psload(int dd, int argc, char *argv[]) psr_read(argv[0]); - while (psr_get(&pskey, array, &size) == 0) { + memset(array, 0, sizeof(array)); + size = sizeof(array) - 6; + + while (psr_get(&pskey, array + 6, &size) == 0) { str = csr_pskeytoval(pskey); if (!strcasecmp(str, "UNKNOWN")) { sprintf(val, "0x%04x", pskey); @@ -763,19 +821,30 @@ static int cmd_psload(int dd, int argc, char *argv[]) str ? str : val); fflush(stdout); - err = csr_write_pskey_complex(dd, seqnum++, pskey, - stores, array, size); + length = size / 2; + + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; + + err = transport_write(transport, CSR_VARID_PS, array, size + 6); printf("%s\n", err < 0 ? "failed" : "done"); + + memset(array, 0, sizeof(array)); + size = sizeof(array) - 6; } if (reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return 0; } -static int cmd_pscheck(int dd, int argc, char *argv[]) +static int cmd_pscheck(int transport, int argc, char *argv[]) { uint8_t array[256]; uint16_t pskey, size; @@ -797,7 +866,7 @@ static int cmd_pscheck(int dd, int argc, char *argv[]) static struct { char *str; - int (*func)(int dd, int argc, char *argv[]); + int (*func)(int transport, int argc, char *argv[]); char *arg; char *doc; } commands[] = { @@ -864,10 +933,8 @@ static struct option main_options[] = { int main(int argc, char *argv[]) { - struct hci_dev_info di; - struct hci_version ver; char *device = NULL; - int i, err, opt, dd, dev, transport = CSR_TRANSPORT_HCI; + int i, err, opt, transport = CSR_TRANSPORT_HCI; while ((opt=getopt_long(argc, argv, "+t:d:i:h", main_options, NULL)) != EOF) { switch (opt) { @@ -911,55 +978,19 @@ int main(int argc, char *argv[]) exit(1); } - if (transport != CSR_TRANSPORT_HCI) { - fprintf(stderr, "Unsupported transport\n"); + if (transport_open(transport, device) < 0) exit(1); - } - if (device) { - dev = hci_devid(device); - if (dev < 0) { - fprintf(stderr, "Device not available\n"); - exit(1); - } + if (device) free(device); - } else - dev = 0; - - 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); - } for (i = 0; commands[i].str; i++) { if (strcasecmp(commands[i].str, argv[0])) continue; - err = commands[i].func(dd, argc, argv); + err = commands[i].func(transport, argc, argv); - hci_close_dev(dd); + transport_close(transport); if (err < 0) { fprintf(stderr, "Can't execute command: %s (%d)\n", @@ -972,7 +1003,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Unsupported command\n"); - hci_close_dev(dd); + transport_close(transport); exit(1); } -- cgit From 016c7033f4b73e35ebd66ada66093f3c5fe9fbff Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 21:05:14 +0000 Subject: Add skeletons for BCSP and H4 transports --- tools/bccmd.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index f39686eb..3bdf702a 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -66,24 +66,16 @@ static inline int transport_open(int transport, char *device) return csr_open_hci(device); case CSR_TRANSPORT_USB: return csr_open_usb(device); + case CSR_TRANSPORT_BCSP: + return csr_open_bcsp(device); + case CSR_TRANSPORT_H4: + return csr_open_h4(device); default: fprintf(stderr, "Unsupported transport\n"); return -1; } } -static inline void transport_close(int transport) -{ - switch (transport) { - case CSR_TRANSPORT_HCI: - csr_close_hci(); - break; - case CSR_TRANSPORT_USB: - csr_close_usb(); - break; - } -} - static inline int transport_read(int transport, uint16_t varid, uint8_t *value, uint16_t length) { switch (transport) { @@ -91,6 +83,10 @@ static inline int transport_read(int transport, uint16_t varid, uint8_t *value, return csr_read_hci(varid, value, length); case CSR_TRANSPORT_USB: return csr_read_usb(varid, value, length); + case CSR_TRANSPORT_BCSP: + return csr_read_bcsp(varid, value, length); + case CSR_TRANSPORT_H4: + return csr_read_h4(varid, value, length); default: errno = EOPNOTSUPP; return -1; @@ -104,12 +100,34 @@ static inline int transport_write(int transport, uint16_t varid, uint8_t *value, return csr_write_hci(varid, value, length); case CSR_TRANSPORT_USB: return csr_write_usb(varid, value, length); + case CSR_TRANSPORT_BCSP: + return csr_write_bcsp(varid, value, length); + case CSR_TRANSPORT_H4: + return csr_write_h4(varid, value, length); default: errno = EOPNOTSUPP; return -1; } } +static inline void transport_close(int transport) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + csr_close_hci(); + break; + case CSR_TRANSPORT_USB: + csr_close_usb(); + break; + case CSR_TRANSPORT_BCSP: + csr_close_bcsp(); + break; + case CSR_TRANSPORT_H4: + csr_close_h4(); + break; + } +} + static struct { uint16_t pskey; int type; -- cgit From 979392c3e5cd32a4d570f7d37f22baebd04699ba Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 20:59:28 +0000 Subject: Add skeleton for 3-Wire UART transport --- tools/bccmd.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 3bdf702a..7c1260cf 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -70,6 +70,8 @@ static inline int transport_open(int transport, char *device) return csr_open_bcsp(device); case CSR_TRANSPORT_H4: return csr_open_h4(device); + case CSR_TRANSPORT_3WIRE: + return csr_open_3wire(device); default: fprintf(stderr, "Unsupported transport\n"); return -1; @@ -87,6 +89,8 @@ static inline int transport_read(int transport, uint16_t varid, uint8_t *value, return csr_read_bcsp(varid, value, length); case CSR_TRANSPORT_H4: return csr_read_h4(varid, value, length); + case CSR_TRANSPORT_3WIRE: + return csr_read_3wire(varid, value, length); default: errno = EOPNOTSUPP; return -1; @@ -104,6 +108,8 @@ static inline int transport_write(int transport, uint16_t varid, uint8_t *value, return csr_write_bcsp(varid, value, length); case CSR_TRANSPORT_H4: return csr_write_h4(varid, value, length); + case CSR_TRANSPORT_3WIRE: + return csr_write_3wire(varid, value, length); default: errno = EOPNOTSUPP; return -1; @@ -125,6 +131,9 @@ static inline void transport_close(int transport) case CSR_TRANSPORT_H4: csr_close_h4(); break; + case CSR_TRANSPORT_3WIRE: + csr_close_3wire(); + break; } } -- cgit From 7c115e06a562978ff2df7b32d7cb1aed72000a16 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 05:11:19 +0000 Subject: Add support for reading the full build name --- tools/bccmd.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 7c1260cf..291ed6a3 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -337,6 +337,30 @@ static int cmd_rand(int transport, int argc, char *argv[]) return 0; } +static int cmd_buildname(int transport, int argc, char *argv[]) +{ + uint8_t array[130]; + char name[64]; + int i, err; + + OPT_HELP(0, NULL); + + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_READ_BUILD_NAME, array, 128); + if (err < 0) { + errno = -err; + return -1; + } + + for (i = 0; i < sizeof(name); i++) + name[i] = array[(i * 2) + 4]; + + printf("Build name: %s\n", name); + + return 0; +} + static int cmd_panicarg(int transport, int argc, char *argv[]) { uint8_t array[8]; @@ -901,6 +925,7 @@ static struct { { "keylen", cmd_keylen, "", "Get current crypt key length" }, { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { "rand", cmd_rand, "", "Get random number" }, + { "buildname", cmd_buildname, "", "Get the full build name" }, { "panicarg", cmd_panicarg, "", "Get panic code argument" }, { "faultarg", cmd_faultarg, "", "Get fault code argument" }, { "coldreset", cmd_coldreset, "", "Perform cold reset" }, -- cgit From dc443fe8e6f81ae76f034e6acdc8ab5adca228fc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 05:36:33 +0000 Subject: List available transports --- tools/bccmd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 291ed6a3..78018d48 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -957,6 +957,9 @@ static void usage(void) "\t-h, --help Display help\n" "\n"); + printf("Transports:\n" + "\tHCI USB BCSP H4 3WIRE\n\n"); + printf("Commands:\n"); for (i = 0; commands[i].str; i++) printf("\t%-10s %-14s\t%s\n", commands[i].str, -- cgit From f2e48c44a7e4c9ee31b8ce2e302186f6047cfeab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 13:28:56 +0000 Subject: Update copyright information --- tools/bccmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 78018d48..62ffd0ce 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 97e0baa36f2177c90f58c3d3670feed5149f354a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 30 Jan 2006 23:22:51 +0000 Subject: Add support for TXData1 radio test command --- tools/bccmd.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 62ffd0ce..b48eb525 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -429,6 +429,31 @@ static int cmd_enabletx(int transport, int argc, char *argv[]) return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0); } +static int cmd_rttxdata1(int transport, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t freq, level; + + OPT_HELP(2, NULL); + + freq = atoi(argv[0]); + + if (!strncasecmp(argv[1], "0x", 2)) + level = strtol(argv[1], NULL, 16); + else + level = atoi(argv[1]); + + memset(array, 0, sizeof(array)); + array[0] = 0x04; + array[1] = 0x00; + array[2] = freq & 0xff; + array[3] = freq >> 8; + array[4] = level & 0xff; + array[5] = level >> 8; + + return transport_write(transport, CSR_VARID_RADIOTEST, array, 8); +} + static int cmd_memtypes(int transport, int argc, char *argv[]) { uint8_t array[8]; @@ -932,6 +957,7 @@ static struct { { "warmreset", cmd_warmreset, "", "Perform warm reset" }, { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, + { "rttxdata1", cmd_rttxdata1, " ","TXData1 radio test" }, { "memtypes", cmd_memtypes, NULL, "Get memory types" }, { "psget", cmd_psget, "", "Get value for PS key" }, { "psset", cmd_psset, " ", "Set value for PS key" }, -- cgit From f0b5cb444eba02a9b34e11b88d6a0458516450ce Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Feb 2006 11:55:35 +0000 Subject: Add support for channel selection and reverting to normal hopping --- tools/bccmd.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index b48eb525..f86b93ea 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -429,6 +429,35 @@ static int cmd_enabletx(int transport, int argc, char *argv[]) return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0); } +static int cmd_singlechan(int transport, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t channel; + + OPT_HELP(1, NULL); + + channel = atoi(argv[0]); + + if (channel > 2401 && channel < 2481) + channel -= 2402; + + if (channel > 78) { + errno = EINVAL; + return -1; + } + + memset(array, 0, sizeof(array)); + array[0] = channel & 0xff; + array[1] = channel >> 8; + + return transport_write(transport, CSR_VARID_SINGLE_CHAN, array, 8); +} + +static int cmd_hoppingon(int transport, int argc, char *argv[]) +{ + return transport_write(transport, CSR_VARID_HOPPING_ON, NULL, 0); +} + static int cmd_rttxdata1(int transport, int argc, char *argv[]) { uint8_t array[8]; @@ -957,6 +986,8 @@ static struct { { "warmreset", cmd_warmreset, "", "Perform warm reset" }, { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, + { "singlechan",cmd_singlechan,"", "Lock radio on specific channel" }, + { "hoppingon", cmd_hoppingon, "", "Revert to channel hopping" }, { "rttxdata1", cmd_rttxdata1, " ","TXData1 radio test" }, { "memtypes", cmd_memtypes, NULL, "Get memory types" }, { "psget", cmd_psget, "", "Get value for PS key" }, -- cgit From 8f1b0911978d19b9e20f152db3fc427fc3b4ee07 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 Jun 2006 09:45:55 +0000 Subject: Accept list of bytes as input for key values --- tools/bccmd.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index f86b93ea..2e426e79 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -199,9 +199,9 @@ static char *memorytostr(uint16_t type) } } -#define OPT_RANGE(range) \ - if (argc < (range)) { errno = EINVAL; return -1; } \ - if (argc > (range)) { errno = E2BIG; return -1; } +#define OPT_RANGE(min, max) \ + if (argc < (min)) { errno = EINVAL; return -1; } \ + if (argc > (max)) { errno = E2BIG; return -1; } static struct option help_options[] = { { "help", 0, 0, 'h' }, @@ -227,7 +227,7 @@ static int opt_help(int argc, char *argv[], int *help) #define OPT_HELP(range, help) \ opt_help(argc, argv, (help)); \ argc -= optind; argv += optind; optind = 0; \ - OPT_RANGE((range)) + OPT_RANGE((range), (range)) static int cmd_builddef(int transport, int argc, char *argv[]) { @@ -564,10 +564,10 @@ static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int * return optind; } -#define OPT_PSKEY(range, stores, reset, help) \ +#define OPT_PSKEY(min, max, stores, reset, help) \ opt_pskey(argc, argv, (stores), (reset), (help)); \ argc -= optind; argv += optind; optind = 0; \ - OPT_RANGE((range)) + OPT_RANGE((min), (max)) static int cmd_psget(int transport, int argc, char *argv[]) { @@ -578,7 +578,7 @@ static int cmd_psget(int transport, int argc, char *argv[]) memset(array, 0, sizeof(array)); - OPT_PSKEY(1, &stores, &reset, NULL); + OPT_PSKEY(1, 1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); @@ -653,7 +653,7 @@ static int cmd_psset(int transport, int argc, char *argv[]) memset(array, 0, sizeof(array)); - OPT_PSKEY(2, &stores, &reset, NULL); + OPT_PSKEY(2, 81, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); @@ -756,7 +756,7 @@ static int cmd_psclr(int transport, int argc, char *argv[]) uint16_t pskey, stores = CSR_STORES_PSRAM; int i, err, reset = 0; - OPT_PSKEY(1, &stores, &reset, NULL); + OPT_PSKEY(1, 1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); @@ -793,7 +793,7 @@ static int cmd_pslist(int transport, int argc, char *argv[]) uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; int err, reset = 0; - OPT_PSKEY(0, &stores, &reset, NULL); + OPT_PSKEY(0, 0, &stores, &reset, NULL); while (1) { memset(array, 0, sizeof(array)); @@ -839,7 +839,7 @@ static int cmd_psread(int transport, int argc, char *argv[]) char *str, val[7]; int i, err, reset = 0; - OPT_PSKEY(0, &stores, &reset, NULL); + OPT_PSKEY(0, 0, &stores, &reset, NULL); while (1) { memset(array, 0, sizeof(array)); @@ -908,7 +908,7 @@ static int cmd_psload(int transport, int argc, char *argv[]) char *str, val[7]; int err, reset = 0; - OPT_PSKEY(1, &stores, &reset, NULL); + OPT_PSKEY(1, 1, &stores, &reset, NULL); psr_read(argv[0]); -- cgit From 607695ed109340f4b7a5628420e0a8e8aee34f4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 17:48:12 +0000 Subject: Update copyright information --- tools/bccmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 2e426e79..4ce06675 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 1bc5e02b94a1524de2ccb7e2f0704a895ad77de6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 23 Jan 2007 07:29:27 +0000 Subject: Make it possible to disable USB support --- tools/bccmd.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 4ce06675..7f5deb5b 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -64,8 +64,10 @@ static inline int transport_open(int transport, char *device) switch (transport) { case CSR_TRANSPORT_HCI: return csr_open_hci(device); +#ifdef HAVE_LIBUSB case CSR_TRANSPORT_USB: return csr_open_usb(device); +#endif case CSR_TRANSPORT_BCSP: return csr_open_bcsp(device); case CSR_TRANSPORT_H4: @@ -83,8 +85,10 @@ static inline int transport_read(int transport, uint16_t varid, uint8_t *value, switch (transport) { case CSR_TRANSPORT_HCI: return csr_read_hci(varid, value, length); +#ifdef HAVE_LIBUSB case CSR_TRANSPORT_USB: return csr_read_usb(varid, value, length); +#endif case CSR_TRANSPORT_BCSP: return csr_read_bcsp(varid, value, length); case CSR_TRANSPORT_H4: @@ -102,8 +106,10 @@ static inline int transport_write(int transport, uint16_t varid, uint8_t *value, switch (transport) { case CSR_TRANSPORT_HCI: return csr_write_hci(varid, value, length); +#ifdef HAVE_LIBUSB case CSR_TRANSPORT_USB: return csr_write_usb(varid, value, length); +#endif case CSR_TRANSPORT_BCSP: return csr_write_bcsp(varid, value, length); case CSR_TRANSPORT_H4: @@ -122,9 +128,11 @@ static inline void transport_close(int transport) case CSR_TRANSPORT_HCI: csr_close_hci(); break; +#ifdef HAVE_LIBUSB case CSR_TRANSPORT_USB: csr_close_usb(); break; +#endif case CSR_TRANSPORT_BCSP: csr_close_bcsp(); break; -- cgit From 83a5ae0fca73331da1c1cfba6d525bac30326992 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 13 Jul 2007 03:05:30 +0000 Subject: Add command for reading the chip revision --- tools/bccmd.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 7f5deb5b..8d65a454 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -345,6 +345,66 @@ static int cmd_rand(int transport, int argc, char *argv[]) return 0; } +static int cmd_chiprev(int transport, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t rev; + char *str; + int err; + + OPT_HELP(0, NULL); + + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_CHIPREV, array, 8); + if (err < 0) { + errno = -err; + return -1; + } + + rev = array[0] | (array[1] << 8); + + switch (rev) { + case 0x64: + str = "BC1 ES"; + break; + case 0x65: + str = "BC1"; + break; + case 0x89: + str = "BC2-External A"; + break; + case 0x8a: + str = "BC2-External B"; + break; + case 0x28: + str = "BC2-ROM"; + break; + case 0x43: + str = "BC3-Multimedia"; + break; + case 0x15: + str = "BC3-ROM"; + break; + case 0xe2: + str = "BC3-Flash"; + break; + case 0x26: + str = "BC4-External"; + break; + case 0x30: + str = "BC4-ROM"; + break; + default: + str = "NA"; + break; + } + + printf("Chip revision: 0x%04x (%s)\n", rev, str); + + return 0; +} + static int cmd_buildname(int transport, int argc, char *argv[]) { uint8_t array[130]; @@ -987,6 +1047,7 @@ static struct { { "keylen", cmd_keylen, "", "Get current crypt key length" }, { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { "rand", cmd_rand, "", "Get random number" }, + { "chiprev", cmd_chiprev, "", "Get chip revision" }, { "buildname", cmd_buildname, "", "Get the full build name" }, { "panicarg", cmd_panicarg, "", "Get panic code argument" }, { "faultarg", cmd_faultarg, "", "Get fault code argument" }, -- cgit From 95b9fe0e10effdae8f1721cb42c7f67862913ecb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 14 Jul 2007 13:24:26 +0000 Subject: Add generic radio test support --- tools/bccmd.c | 76 ++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 24 deletions(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index 8d65a454..efce49d8 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -551,6 +551,33 @@ static int cmd_rttxdata1(int transport, int argc, char *argv[]) return transport_write(transport, CSR_VARID_RADIOTEST, array, 8); } +static int cmd_radiotest(int transport, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t freq, level, test; + + OPT_HELP(3, NULL); + + freq = atoi(argv[0]); + + if (!strncasecmp(argv[1], "0x", 2)) + level = strtol(argv[1], NULL, 16); + else + level = atoi(argv[1]); + + test = atoi(argv[2]); + + memset(array, 0, sizeof(array)); + array[0] = test & 0xff; + array[1] = test >> 8; + array[2] = freq & 0xff; + array[3] = freq >> 8; + array[4] = level & 0xff; + array[5] = level >> 8; + + return transport_write(transport, CSR_VARID_RADIOTEST, array, 8); +} + static int cmd_memtypes(int transport, int argc, char *argv[]) { uint8_t array[8]; @@ -1043,29 +1070,30 @@ static struct { char *arg; char *doc; } commands[] = { - { "builddef", cmd_builddef, "", "Get build definitions" }, - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, - { "rand", cmd_rand, "", "Get random number" }, - { "chiprev", cmd_chiprev, "", "Get chip revision" }, - { "buildname", cmd_buildname, "", "Get the full build name" }, - { "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" }, - { "singlechan",cmd_singlechan,"", "Lock radio on specific channel" }, - { "hoppingon", cmd_hoppingon, "", "Revert to channel hopping" }, - { "rttxdata1", cmd_rttxdata1, " ","TXData1 radio test" }, - { "memtypes", cmd_memtypes, NULL, "Get memory types" }, - { "psget", cmd_psget, "", "Get value for PS key" }, - { "psset", cmd_psset, " ", "Set value for PS key" }, - { "psclr", cmd_psclr, "", "Clear value for PS key" }, - { "pslist", cmd_pslist, NULL, "List all PS keys" }, - { "psread", cmd_psread, NULL, "Read all PS keys" }, - { "psload", cmd_psload, "", "Load all PS keys from PSR file" }, - { "pscheck", cmd_pscheck, "", "Check PSR file" }, + { "builddef", cmd_builddef, "", "Get build definitions" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "rand", cmd_rand, "", "Get random number" }, + { "chiprev", cmd_chiprev, "", "Get chip revision" }, + { "buildname", cmd_buildname, "", "Get the full build name" }, + { "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" }, + { "singlechan",cmd_singlechan,"", "Lock radio on specific channel" }, + { "hoppingon", cmd_hoppingon, "", "Revert to channel hopping" }, + { "rttxdata1", cmd_rttxdata1, " ", "TXData1 radio test" }, + { "radiotest", cmd_radiotest, " ", "Run radio tests" }, + { "memtypes", cmd_memtypes, NULL, "Get memory types" }, + { "psget", cmd_psget, "", "Get value for PS key" }, + { "psset", cmd_psset, " ", "Set value for PS key" }, + { "psclr", cmd_psclr, "", "Clear value for PS key" }, + { "pslist", cmd_pslist, NULL, "List all PS keys" }, + { "psread", cmd_psread, NULL, "Read all PS keys" }, + { "psload", cmd_psload, "", "Load all PS keys from PSR file" }, + { "pscheck", cmd_pscheck, "", "Check PSR file" }, { NULL } }; @@ -1088,7 +1116,7 @@ static void usage(void) printf("Commands:\n"); for (i = 0; commands[i].str; i++) - printf("\t%-10s %-14s\t%s\n", commands[i].str, + printf("\t%-10s %-20s\t%s\n", commands[i].str, commands[i].arg ? commands[i].arg : " ", commands[i].doc); printf("\n"); -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- tools/bccmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/bccmd.c') diff --git a/tools/bccmd.c b/tools/bccmd.c index efce49d8..95cb37bb 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit