📄 bccmd.c
字号:
/* * * 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_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)#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_COMPLEXstatic 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); case CSR_TRANSPORT_BCSP: 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; }}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); case CSR_TRANSPORT_BCSP: 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; }}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); case CSR_TRANSPORT_BCSP: 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; }}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; case CSR_TRANSPORT_3WIRE: csr_close_3wire(); break; }}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 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 transport, int argc, char *argv[]){ uint8_t array[8]; uint16_t def = 0x0000, nextdef = 0x0000; int err = 0; OPT_HELP(0, NULL); printf("Build definitions:\n"); while (1) { memset(array, 0, sizeof(array)); array[0] = def & 0xff; array[1] = def >> 8; err = transport_read(transport, CSR_VARID_GET_NEXT_BUILDDEF, array, 8); if (err < 0) { errno = -err; break; } nextdef = array[2] | (array[3] << 8); if (nextdef == 0x0000) break; def = nextdef; printf("0x%04x - %s\n", def, csr_builddeftostr(def)); } return err;}static int cmd_keylen(int transport, int argc, char *argv[]){ uint8_t array[8]; uint16_t handle, keylen; int err; OPT_HELP(1, NULL); handle = atoi(argv[0]); memset(array, 0, sizeof(array)); array[0] = handle & 0xff; array[1] = handle >> 8; err = transport_read(transport, CSR_VARID_CRYPT_KEY_LENGTH, array, 8); if (err < 0) { errno = -err; return -1; } 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 transport, int argc, char *argv[]){ uint8_t array[8]; uint32_t clock; int err; OPT_HELP(0, NULL); 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 transport, int argc, char *argv[]){ uint8_t array[8]; uint16_t rand; int err; OPT_HELP(0, NULL); 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_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]; uint16_t error; int err; OPT_HELP(0, NULL); 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 transport, int argc, char *argv[]){ uint8_t array[8]; uint16_t error; int err; OPT_HELP(0, NULL); 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 transport, int argc, char *argv[]){ return transport_write(transport, CSR_VARID_COLD_RESET, NULL, 0);}static int cmd_warmreset(int transport, int argc, char *argv[]){ return transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0);}static int cmd_disabletx(int transport, int argc, char *argv[]){ return transport_write(transport, CSR_VARID_DISABLE_TX, NULL, 0);}static int cmd_enabletx(int transport, int argc, char *argv[]){ return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0);}static int cmd_memtypes(int transport, 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[0] = stores[i] & 0xff; array[1] = stores[i] >> 8; err = transport_read(transport, CSR_VARID_PS_MEMORY_TYPE, array, 8); if (err < 0) continue; type = array[2] + (array[3] << 8); printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]), stores[i], memorytostr(type), type); } return 0;}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 transport, int argc, char *argv[]){ uint8_t array[128]; uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT; uint32_t val32; int i, err, reset = 0; memset(array, 0, sizeof(array)); 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]))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -