📄 btctl.c
字号:
argv2str(buf, &argv[argind]); str2mask(pkt_type_map, buf, &value); } } err = hci_set_pkttype(fd, value); if (err) { fprintf(stderr, "%s\n", hci_error(err)); exit(1); } hci_close(fd); return 0;}int cmd_control(struct btctl_command *cmd){ int err = 0, fd; fd = hci_open(btdev); if (fd < 0) { printf("Unable to open device %s: %s\n", btdev, strerror(errno)); return -1; } switch (cmd->cmd) { case 0: /* page_to */ { __u16 timeo; if (argv[argind] == NULL) { // read name err = HCI_ReadPageTimeout(fd, &timeo); } else { sscanf(argv[argind], "%hu", &timeo); printf("Timeo: %u\n", timeo); err = HCI_WritePageTimeout(fd, timeo); } if (!err && argv[argind] == NULL) { // read name printf("Timeo: %u\n", timeo); } } break; case 1: /* hdisc */ { struct sockaddr_affix sa;; if (argv[argind] == NULL) { printf("Bluetooth address missed\n"); return -1; } if (strstr(argv[argind], "0x")) { err = sscanf(argv[argind++], "%hx", &sa.port); if (err <= 0) { printf("format error\n"); return 1; } } else { err = get_bda(&sa.bda, argv[argind++]); if (err) { printf("Incorrect address given\n"); return 1; } } printf("Disconnecting %s ...\n", bda2str(&sa.bda)); err = hci_disconnect(&sa); } break; case 2: /* hconnect */ { int err, sock; struct sockaddr_affix sa; if (argv[argind] == NULL) { printf("Bluetooth address missed\n"); return -1; } err = get_bda(&sa.bda, argv[argind++]); if (err) { printf("Incorrect address given\n"); return -1; } sock = socket(PF_AFFIX, SOCK_SEQPACKET, BTPROTO_HCIACL); if (sock < 0) { printf("unable to create affix socket\n"); return -1; } sa.family = PF_AFFIX; sa.devnum = HCIDEV_ANY; err = connect(sock, (struct sockaddr*)&sa, sizeof(sa)); if (err) { printf("unable to create connection\n"); return -1; } return 0; /* INQUIRY_ITEM dev; err = get_bda(&dev.bda, argv[argind++]); if (err) { printf("Incorrect address given\n"); return 1; } dev.PS_Repetition_Mode = 0x00; dev.PS_Mode = 0x00; dev.Clock_Offset = 0x00; err = __HCI_CreateConnection(fd, &dev, HCI_PT_DM1|HCI_PT_DH1|HCI_PT_DM3|HCI_PT_DH3|HCI_PT_DM5|HCI_PT_DH5, 0); */ } break; case 3: /* hpkt_type */ { int handle, type; BD_ADDR bda; if (strstr(argv[argind], "0x")) { err = sscanf(argv[argind++], "%x", &handle); if (err <= 0) { printf("format error\n"); return 1; } } else { err = get_bda(&bda, argv[argind++]); if (err) { printf("Incorrect address given\n"); return 1; } handle = hci_get_conn(fd, &bda); if (handle < 0) { printf("Connection not found\n"); return 1; } } if (argv[argind]) { err = sscanf(argv[argind++], "%x", &type); if (err <= 0) type = HCI_PT_DM1|HCI_PT_DH1|HCI_PT_DM3|HCI_PT_DH3|HCI_PT_DM5|HCI_PT_DH5; } else type = HCI_PT_DM1|HCI_PT_DH1|HCI_PT_DM3|HCI_PT_DH3|HCI_PT_DM5|HCI_PT_DH5; printf("Changing pkt_type, handle %#hx ...\n", handle); err = HCI_ChangeConnectionPacketType(fd, handle, type); } case 4: /* read broadcast retransmissions */ { __u8 Num; err = HCI_Read_Num_Broadcast_Retransmissions(fd,&Num); printf("\nRetransmissions : %d\n", Num); } break; case 5: /* write broadcast retransmissions */ { int num = 0; if (strstr(argv[argind], "0x")) { err = sscanf(argv[argind++], "%x", &num); if (err <= 0) { printf("format error\n"); return 1; } } err = HCI_Write_Num_Broadcast_Retransmissions(fd,num); } break; default: break; } if (err) { fprintf(stderr, "%s\n", hci_error(err)); exit(1); } hci_close(fd); return 0;}int cmd_pair(struct btctl_command *cmd){ int err, fd, sock; struct sockaddr_affix sa; int handle; err = get_bda(&sa.bda, argv[argind++]); if (err) { printf("Incorrect address given\n"); return 1; } fd = hci_open(btdev); if (fd < 0) { printf("Unable to open device %s: %s\n", btdev, strerror(errno)); return -1; } sock = socket(PF_AFFIX, SOCK_SEQPACKET, BTPROTO_HCIACL); if (sock < 0) { printf("unable to create affix socket\n"); return -1; } sa.family = PF_AFFIX; sa.devnum = HCIDEV_ANY; err = connect(sock, (struct sockaddr*)&sa, sizeof(sa)); if (err) { printf("unable to create connection\n"); return -1; } handle = hci_get_conn(fd, &sa.bda); if (handle < 0) { printf("Connection not found\n"); return 1; } hci_remove_key(&sa.bda); err = HCI_AuthenticationRequested(fd, handle); if (err) { fprintf(stderr, "%s\n", hci_error(err)); exit(1); } printf("Pairing completed: %s\n", err?"error":"successful"); close(sock); hci_close(fd); return 0;}int cmd_reset(struct btctl_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 btctl_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[argind]) { param = argv[argind]; 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; } argind++; } 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 (!verbose) { 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", (manf_name<NUM_LMPCOMPID)?lmp_compid[manf_name]:"Unknown", manf_name); printf("\tFeatures: %s compliant\n", lmp_version?"1.1":"1.0"); // 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 btctl_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 btctl_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" }, {"list", cmd_inquiry, 2, "", "shows know/found devices\n" }, {"flush", cmd_inquiry, 3, "", "removes all know devices from the cache\n" }, {"prompt", cmd_prompt, 0, "", "enter interactive mode\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"}, {"unbond", cmd_key, 0, "[<address>]", "remove link key from the driver\n", }, {"pair", cmd_pair, 0, "<address>", "start paring with remote device\n"}, /* HCI */ {0, 0, 0, 0, "---->>>> HCI commands <<<<----\n"}, {"inquiry", cmd_inquiry, 1, "[length]", "search for the device\n" }, {"discovery", cmd_discovery, 1, "[length]", "search for the devices and resolve their names\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"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -