📄 btctl.c
字号:
int cmd_reset(struct command *cmd){ int fd, err; fd = hci_open(btdev); if (fd < 0) { printf("Unable to open device %s: %s\n", btdev, strerror(errno)); return -1; } err = HCI_Reset(fd); if (err) { fprintf(stderr, "%s\n", hci_error(err)); exit(1); } hci_close(fd); return 0;}int cmd_debug(struct command *cmd){ int err, flag, i, addmod; __u32 dbmask; char *param; err = hci_get_dbmask(&dbmask); if (err) { fprintf(stderr, "%s\n", hci_error(err)); exit(1); } addmod = dbmask; while (__argv[optind]) { param = __argv[optind]; if (param[0] == '+') flag = 1, param++; else if (param[0] == '-') flag = 0, param++; else flag = 1; for (i = 0; debug_flags_map[i].match; i++) { if (strcasecmp(param, debug_flags_map[i].match) == 0) break; } if (!debug_flags_map[i].match) { fprintf(stderr, "invalid argument: %s\n", param); return 1; } flag?(dbmask|=debug_flags_map[i].value):(dbmask&=~debug_flags_map[i].value); if (!addmod && flag == 1 && (dbmask & DBALLMOD)) { dbmask |= DBALLDETAIL; addmod = 1; } optind++; } err = hci_set_dbmask(dbmask); if (err) { fprintf(stderr, "%s\n", hci_error(err)); exit(1); } return 0;}int print_devinfo(char *dev){ int err = 0, fd; char name[248], buf[80]; __u32 cod; __u8 val; __u8 hci_version, lmp_version; __u16 hci_revision, manf_name, lmp_subversion; __u64 lmp_features; __u16 acl_len, acl_num, sco_num; __u8 sco_len; struct hci_dev_attr da; err = hci_get_attr(dev, &da); if (err < 0) { printf("Unable to get attr: %s\n", dev); return err; } printf("%s\t%s\n", da.name, bda2str(&da.bda)); if (!verboseflag) { printf("\tFlags: %s %s %s\n", (da.flags & HCI_FLAGS_UP)?"UP":"DOWN", (da.flags & HCI_FLAGS_SCAN_INQUIRY)?"DISC":"\b", (da.flags & HCI_FLAGS_SCAN_PAGE)?"CONN":"\b"); printf("\tRX: acl:%lu sco:%lu event:%lu bytes:%lu errors:%lu dropped:%lu\n", da.stats.rx_acl, da.stats.rx_sco, da.stats.rx_event, da.stats.rx_bytes, da.stats.rx_errors, da.stats.rx_dropped); printf("\tTX: acl:%lu sco:%lu cmd:%lu bytes:%lu errors:%lu dropped:%lu\n", da.stats.tx_acl, da.stats.tx_sco, da.stats.tx_cmd, da.stats.tx_bytes, da.stats.tx_errors, da.stats.tx_dropped); mask2str(sec_mode_map, buf, da.flags & ~(HCI_SECURITY_AUTH|HCI_SECURITY_ENCRYPT)); printf("\tSecurity: %s [%cauth, %cencrypt]\n", buf, (da.flags & HCI_SECURITY_AUTH)?'+':'-', (da.flags & HCI_SECURITY_ENCRYPT)?'+':'-'); mask2str(pkt_type_map, buf, da.pkt_type); printf("\tPackets: %s\n", buf); printf("\tRole: %s, ", (da.flags & HCI_ROLE_DENY_SWITCH)?"deny switch":"allow switch"); printf("%s\n", (da.flags & HCI_ROLE_BECOME_MASTER)?"become master":"remain slave"); printf("\n"); return 0; } if (!(da.flags & HCI_FLAGS_UP)) { printf("\tDevice is down\n\n"); return 0; } fd = hci_open(dev); if (fd < 0) { printf("Unable to open: %s\n\n", dev); return 0; } err = HCI_ReadLocalName(fd, name); if (err) goto exit; printf("\tName: \"%s\"\n", name); err = HCI_ReadClassOfDevice(fd, &cod); if (err) goto exit; parse_cod(buf, cod); printf("\tClass: 0x%06X, %s\n", cod, buf); err = HCI_ReadScanEnable(fd, &val); if (err) goto exit; printf("\tScan Mode: %s, %s\n", (val&0x01)?"discoverable":"non-discoverable", (val&0x02)?"connectable":"non-connectable"); mask2str(sec_mode_map, buf, da.flags & ~(HCI_SECURITY_AUTH|HCI_SECURITY_ENCRYPT)); printf("\tSecurity: %s [%cauth, %cencrypt]\n", buf, (da.flags & HCI_SECURITY_AUTH)?'+':'-', (da.flags & HCI_SECURITY_ENCRYPT)?'+':'-'); mask2str(pkt_type_map, buf, da.pkt_type); printf("\tPackets: %s\n", buf); printf("\tRole: %s, ", (da.flags & HCI_ROLE_DENY_SWITCH)?"deny switch":"allow switch"); printf("%s\n", (da.flags & HCI_ROLE_BECOME_MASTER)?"become master":"remain slave"); err = HCI_ReadLocalVersionInformation(fd, &hci_version, &hci_revision, &lmp_version, &manf_name, &lmp_subversion); if (err) goto exit; printf("\tBaseband:\n\t\tManufacture: %s, id: %d\n" "\t\tHCI Version: %d, HCI Revision: %d\n" "\t\tLMP Version: %d, LMP Subversion: %d\n" "\t\tFeatures: 1.%d compliant\n", (manf_name<NUM_LMPCOMPID)?lmp_compid[manf_name]:"Unknown", manf_name, hci_version, hci_revision, lmp_version, lmp_subversion, lmp_version); // Read buffer information err = HCI_ReadBufferSize(fd, &acl_len, &sco_len, &acl_num, &sco_num); if (err) goto exit; printf("\tBuffers:\n"); printf("\t\tACL: %d x %d bytes\n", acl_num, acl_len); printf("\t\tSCO: %d x %d bytes\n", sco_num, sco_len); // Read Supported Features err = HCI_ReadLocalSupportedFeatures(fd, &lmp_features); if (err) goto exit; printf("\tSuported features:"); mask2str_comma(packets_features_map, buf, lmp_features); printf("\n\t\tPacket types: %s", (lmp_features&HCI_LF_PACKETS)?buf:"none"); mask2str_comma(radio_features_map, buf, lmp_features); printf("\n\t\tRadio features: %s", (lmp_features&HCI_LF_RADIO)?buf:"none"); mask2str_comma(policy_features_map, buf, lmp_features); printf("\n\t\tPolicy: %s", (lmp_features&HCI_LF_POLICY)?buf:"not supported"); printf("\n\t\tEncryption: %s", (lmp_features&HCI_LF_ENCRYPTION)?"supported":"not supported"); mask2str_comma(timing_features_map, buf, lmp_features); printf("\n\t\tClock modes: %s", (lmp_features&HCI_LF_TIMING)?buf:"none"); mask2str_comma(audio_features_map, buf, lmp_features); printf("\n\t\tAudio: %s", (lmp_features&HCI_LF_AUDIO)?buf:"not supported"); printf("\n\t\tPower Control: %s", (lmp_features&HCI_LF_POWER_CONTROL)?"supported":"not supported");exit: printf("\n\n"); close(fd); if (err){ fprintf(stderr, "%s\n", hci_error(err)); return 1; } return 0;}int devinfo(void){ int err = 0; int i, num; struct hci_dev_attr da; int devs[HCI_MAX_DEVS]; if (nameset) return print_devinfo(btdev); num = hci_get_devs(devs); if (num < 0) { fprintf(stderr, "%s\n", hci_error(num)); exit(1); return num; } if (num == 0) { printf("No Bluetooth Adapters found\n"); return 0; } for (i = 0; i < num; i++) { err = hci_get_attr_id(devs[i], &da); if (err < 0) { printf("Unable to get attr: %d\n", devs[i]); continue; } err = print_devinfo(da.name); if (err) return err; } return 0;}int cmd_test(struct command *cmd){#if 0 { struct Write_Current_IAC_LAP cmd; struct Inquiry event; INQUIRY_ITEM Item; printf("sizeof(lap) = %d, sizeof(cmd) = %d, sizeof(event) = %d, sizeof(Item) = %d\n", sizeof(cmd.IAC_LAP[0]), sizeof(cmd), sizeof(event), sizeof(Item)); printf("bda: %p, cod: %p\n", &Item.bda, &Item.bda+1); return 0; }#endif return 0;}int cmd_disabled(int cmd){ printf("\n-->> Command disabled at compilation time. Enable certain configuration options. <<--\n\n"); return 0;}struct command cmds[] = { {0, 0, 0, 0, "---->>>> General commands <<<<----\n"}, {"help", cmd_help, 0, "<command name>"}, {"debug", cmd_debug, 0, "[+|-][<module>|<detail>|all]", "\tmodule:\thcicore|afhci|hcisched|hcimgr|hcilib|hci|\n" "\t\tpl2cap|afl2cap|l2cap|\n" "\t\tprfcomm|afrfcomm|bty|rfcomm|\n" "\t\tpan|\n" "\t\tdrv|\n" "\t\tallmod\n" "\tdetail: ctrl|dump|chardump|parse|fname|func|alldetail\n" }, {"initdev", cmd_initdev, CMD_INITDEV, "<type> [params...]", }, {"up", cmd_initdev, CMD_UPDEV, "", "brings interface up\n"}, {"down", cmd_initdev, CMD_DOWNDEV, "", "brings interface down\n"}, {"capture", cmd_capture, 0, "<file> | -", "capture traffic on a HCI interface\n" "examples: btctl capture mylog.log\n" " btctl capture - | ethereal -i - -k\n" }, /* security */ {0, 0, 0, 0, "---->>>> Security commands <<<<----\n"}, {"security", cmd_security, 0, "<mode>", "mode: <open|link|service> [auth] [encrypt]\n", }, {"addpin", cmd_pincode, 1, "[<address>|default] <pin>", "add pin code to the driver (used when no btsrv or AFE run)\n"}, {"rmpin", cmd_pincode, 0, "[<address>|default]", "remove pin code from the driver\n"}, {"unpair", cmd_rmkey, 0, "[<address>]", "remove pairing with remote device (remove link key)\n", }, {"pair", cmd_pair, 0, "<address>", "start paring with remote device\n"}, /* HCI */ {0, 0, 0, 0, "---->>>> HCI commands <<<<----\n"}, {"bdaddr", cmd_bdaddr, 1, "", "read device address\n" }, {"name", cmd_name, 1, "[<name>]", "get or set device name\n" }, {"scan", cmd_scan, 1, "[+|-][disc|conn]" }, {"remotename", cmd_remotename, 1, "<bda>", "resolve remote device name\n" }, {"role", cmd_role, 1, "<allow|deny> <master|slave>" }, {"class", cmd_class, 1, "[<class> | <major> <minor> <service1> ... <servicen>]", "\tmajor:\tcomputer|phone|audio\n" "\tminor:\tdesktop|laptop|hand|server|lap\n" "\tservice:\tnetworking,information,rendring,capturing,audio,transfer,telephony\n" }, {"auth", cmd_auth, 0, "<address>", "authenticate remote device\n" }, {"pkt_type", cmd_pkttype, 0, "[<0xXXX> | <mnemonic>]", "\tmnemonic: DM1 DH1 DM3 DH3 DM5 DH5 HV1 HV2 HV3>]\n" }, {"page_to", cmd_control, 0, "[to]", "get/set page timeout\n" }, {"hdisc", cmd_control, 1, "<handle | address>", "disconnect ACL/SCO link\n" }, {"hconnect", cmd_control, 2, "<address>", "create ACL connection\n" }, {"hpkt", cmd_control, 3, "<address> [pkt_type]", "change pkt_type\n" }, {"readbroad", cmd_control, 4, "", "Read Broadcast Retransmissions\n" }, {"writebroad", cmd_control, 5, "", "Write Broadcast Retransmissions\n" }, {"reset", cmd_reset, 0, "", "reset device\n" }, {"ping", cmd_ping, 0, "<bda> <size>", "Send ping packet to remote device\n" }, {"lq", cmd_link_info, 0, "<bda>", "Show link quality\n" }, {"rssi", cmd_link_info, 1, "<bda>", "Show Received Signal Strength Indication (RSSI)\n" }, {"cpl", cmd_link_info, 2, "<bda>", "Show Current Transmit Power Level (CTPL)\n" }, {"linkinfo", cmd_link_info, 3, "<bda> [<interval>]", "Show HCI debug dump\n" }, {"pinq_start", cmd_periodic_inquiry, 0, "<length> [<max_period_len> <min_period_len> <len>]", "Start periodic inquiry mode\n" }, {"pinq_stop", cmd_periodic_inquiry, 1, "<length>", "Stop periodic inquiry mode start\n" }, {"speed", cmd_ping, 1, }, /* UART */#if defined(CONFIG_AFFIX_UART) {0, 0, 0, 0, "---->>>> UART commands <<<<----\n"}, {"init_uart", cmd_uart, CMD_INIT_UART, "<name> <vendor> [speed] [flags]", "open UART interface\n" "\tvendor: any|csr|ericsson|...]\n" }, {"open_uart", cmd_uart, CMD_OPEN_UART, "<name> <vendor> [speed] [flags]", "open UART interface\n" "\tvendor: any|csr|ericsson|...]\n" }, {"close_uart", cmd_uart, CMD_CLOSE_UART, "<name>" },#else#endif /* AUDIO */#if defined(CONFIG_AFFIX_AUDIO) {0, 0, 0, 0, "---->>>> AUDIO commands <<<<----\n"}, {"path", cmd_audio, 0, "0x00 | 0x01", "set Ericsson SCO data path" }, {"audio", cmd_audio, 1, "on|off [sync | async] [setting <SCO setting>]", "enable/disable audio (SCO) support\n" }, {"scoflow", cmd_audio, 2, }, {"addsco", cmd_addsco, 0, }, {"play", cmd_play, 0, "<bda> [<file> | -]", "send an audio stream from a file or stdin to remote device\n" }, {"record", cmd_record, 0, "<bda> [<file> | -]", "store an audio stream in a file or stdout received from remote device\n" },#endif {0, 0, 0, 0, "---->>>> Testing commands <<<<----\n"}, {"test", cmd_test, 0, }, {"switch", cmd_switch, 0, }, {"policy", cmd_switch, 1, }, /* BLUETOOTH 1.2 */#if defined(CONFIG_AFFIX_BT_1_2) {0, 0, 0, 0, "---->>>> Bluetooth 1.2 commands <<<<----\n"}, {"concancel", cmd_create_connection_cancel, 0, "<address>", "Cancels a create connection request\n"}, {"remotenamecancel", cmd_remote_name_cancel, 0, "<address>", " Cancel a Remote Name request\n" }, {"lmphandle",cmd_lmp_handle, 0, "<bda>", "Gets the LMP Handle from a current connection\n"}, {"ref", cmd_remote_extended_features, 0,"<bda> [page number]"," Read the remote extended features from a current connection\n"}, {"read_dlps",cmd_link_policy_settings,0,"", "Gives the default link policy settings of the device.\n"}, {"write_dlps",cmd_link_policy_settings,1,"<link_policy_settings>", "Sets the default link policy settings of the device.\n"}, {"flow",cmd_flow_specification,0,"<bda> <Flow direction> <Service Type> <Token Rate> <Token Bucket Size> <Peak Bandwidth> <Access Latency>","Sets the flow control parameters for the connection with <bda>\n"}, {"setafh",cmd_afh_host_channel,0,"<channels 0-31> <channels 32-63> <channels 64-79>","Sets the AFH host channels classification.\n"}, {"read_ist",cmd_inquiry_scan_type,0,"", "Gives the current inquiry scan type of the device.(0x00 Mandatory: Standard Scan, 0x01 Optional:Interlaced Scan)\n"}, {"write_ist",cmd_inquiry_scan_type,1,"0x00|0x01", "Sets the current inquiry scan type of the device. (0x00 Mandatory: Standard Scan, 0x01 Optional:Interlaced Scan)\n"}, {"read_inquiry_mode",cmd_inquiry_mode,0,"", "Returns the current inquiry mode of the device.(0x00:Standard Inquiry Result Event, 0x01:Inquiry Result format with RSSI)\n"}, {"write_inquiry_mode",cmd_inquiry_mode,1,"0x00|0x01", "Sets the current inquiry scan type of the device. (0x00 Mandatory: Standard Scan, 0x01 Optional:Interlaced Scan)\n"}, {"read_pst",cmd_page_scan_type,0,"", "Returns the current page scan type of the device.(0x00 Mandatory: Standard Scan, 0x01 Optional:Interlaced Scan)\n"}, {"write_pst",cmd_page_scan_type,1,"0x00|0x01", "Sets the current page scan type of the device.(0x00 Mandatory: Standard Scan, 0x01 Optional:Interlaced Scan)\n"}, {"read_afh_cam",cmd_afh_cam,0,"", "Returns AFH Channel Assessment Mode value of the device.(0x00 Disable, 0x01 Enable)\n"}, {"write_afh_cam",cmd_afh_cam,1,"0x00|0x01", "Sets AFH Channel Assessment Mode of the device.(0x00 Disable, 0x01 Enable)\n"}, {"lef",cmd_local_extended_features,0,"<page number>", "Reads the extended features from the local device.\n"}, {"clock",cmd_read_clock,0,"[<bda> <which clock>]","Reads the estimate value of the Bluetooth clock.\n"}, {"afhchannelmap",cmd_afh_channel_map,0,"<bda>","Returns the values for AFH_Mode (0:Disable,1:Enable) and AFH_Channel_Map (if AFH_Mode=1).\n"},#endif {0, 0, 0, NULL}};int cmd_help(struct command *cmd){ if (!__argv[optind]) { print_usage(cmd); exit(0); } return print_command_usage(cmds, __argv[optind]);}void usage(void){ printf("Usage: btctl [-i <name>] [-a] <command> [parameters..]>\n"); print_all_usage(cmds); printf("\n" "Notes:\n" "\t1. *address* argument can be replaced by cache entry number (btclt list)\n" "\n" );}int main(int argc, char **argv){ int c, lind, i, err = 0; struct option opts[] = { {"help", 0, 0, 'h'}, {"tcp", 0, 0, 't'}, {"speed", 1, 0, 'r'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; if (affix_init(argc, argv, LOG_USER)) { fprintf(stderr, "Affix initialization failed\n"); return 1; } for (;;) { c = getopt_long(argc, __argv, "+htrvsVam:i:r:", opts, &lind); if (c == -1) break; switch (c) { case 'h': usage(); return 0; break; case 'v': verboseflag = 1; break; case 'i': strncpy(btdev, optarg, IFNAMSIZ); break; case 't': linkmode = PF_INET; break; case 'a': showall = 1; break; case 'r': uart_rate = atoi(optarg); break; case 'm': uart_map = optarg; break; case 'V': printf("Affix version: %s\n", affix_version); return 0; break; case ':': printf("Missing parameters for option: %c\n", optopt); return 1; break; case '?': printf("Unknown option: %c\n", optopt); return 1; break; } } if (__argv[optind] && sscanf(__argv[optind], "bt%d", &i) > 0) { /* interface name */ sprintf(btdev, "bt%d", i); optind++; nameset = 1; } if (__argv[optind] == NULL) { err = devinfo(); goto exit; } err = call_command(cmds, __argv[optind++]);exit: return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -