📄 hcitool.c
字号:
} } argc -= optind; argv += optind; if (argc < 1) { printf(afh_help); return; } str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); } } dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); exit(1); } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("Can't allocate memory"); exit(1); } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); exit(1); } handle = htobs(cr->conn_info->handle); if (hci_read_afh_map(dd, handle, &mode, map, 1000) < 0) { perror("HCI read AFH map request failed"); exit(1); } if (mode == 0x01) { int i; printf("AFH map: 0x"); for (i = 0; i < 10; i++) printf("%02x", map[i]); printf("\n"); } else printf("AFH disabled\n"); close(dd); free(cr);}/* Set connection packet type */static struct option cpt_options[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 }};static char *cpt_help = "Usage:\n" "\tcpt <bdaddr> <packet_types>\n";static void cmd_cpt(int dev_id, int argc, char **argv){ struct hci_conn_info_req *cr; struct hci_request rq; set_conn_ptype_cp cp; evt_conn_ptype_changed rp; bdaddr_t bdaddr; unsigned int ptype; int dd, opt; for_each_opt(opt, cpt_options, NULL) { switch (opt) { default: printf(cpt_help); return; } } argc -= optind; argv += optind; if (argc < 2) { printf(cpt_help); return; } str2ba(argv[0], &bdaddr); hci_strtoptype(argv[1], &ptype); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); } } dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); exit(1); } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("Can't allocate memory"); exit(1); } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); exit(1); } cp.handle = htobs(cr->conn_info->handle); cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; rq.clen = SET_CONN_PTYPE_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_CONN_PTYPE_CHANGED_SIZE; rq.event = EVT_CONN_PTYPE_CHANGED; if (hci_send_req(dd, &rq, 100) < 0) { perror("Packet type change failed"); exit(1); } close(dd); free(cr);}/* Get/Set link supervision timeout */static struct option lst_options[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 }};static char *lst_help = "Usage:\n" "\tlst <bdaddr> [new value in slots]\n";static void cmd_lst(int dev_id, int argc, char **argv){ struct hci_conn_info_req *cr; bdaddr_t bdaddr; uint16_t timeout; int opt, dd; for_each_opt(opt, lst_options, NULL) { switch (opt) { default: printf(lst_help); return; } } argc -= optind; argv += optind; if (argc < 1) { printf(lst_help); return; } str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); } } dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); exit(1); } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("Can't allocate memory"); exit(1); } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); exit(1); } if (argc == 1) { if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle), &timeout, 1000) < 0) { perror("HCI read_link_supervision_timeout request failed"); exit(1); } timeout = btohs(timeout); if (timeout) printf("Link supervision timeout: %u slots (%.2f msec)\n", timeout, (float) timeout * 0.625); else printf("Link supervision timeout never expires\n"); } else { timeout = btohs(strtol(argv[1], NULL, 10)); if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle), timeout, 1000) < 0) { perror("HCI write_link_supervision_timeout request failed"); exit(1); } } close(dd); free(cr);}/* Request authentication */static struct option auth_options[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 }};static char *auth_help = "Usage:\n" "\tauth <bdaddr>\n";static void cmd_auth(int dev_id, int argc, char **argv){ struct hci_conn_info_req *cr; bdaddr_t bdaddr; int opt, dd; for_each_opt(opt, auth_options, NULL) { switch (opt) { default: printf(auth_help); return; } } argc -= optind; argv += optind; if (argc < 1) { printf(auth_help); return; } str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); } } dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); exit(1); } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("Can't allocate memory"); exit(1); } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); exit(1); } if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000) < 0) { perror("HCI authentication request failed"); exit(1); } close(dd); free(cr);}/* Activate encryption */static struct option enc_options[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 }};static char *enc_help = "Usage:\n" "\tenc <bdaddr> [encrypt enable]\n";static void cmd_enc(int dev_id, int argc, char **argv){ struct hci_conn_info_req *cr; bdaddr_t bdaddr; uint8_t encrypt; int opt, dd; for_each_opt(opt, enc_options, NULL) { switch (opt) { default: printf(enc_help); return; } } argc -= optind; argv += optind; if (argc < 1) { printf(enc_help); return; } str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); } } dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); exit(1); } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("Can't allocate memory"); exit(1); } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); exit(1); } encrypt = (argc > 1) ? atoi(argv[1]) : 1; if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), encrypt, 25000) < 0) { perror("HCI set encryption request failed"); exit(1); } close(dd); free(cr);}/* Change connection link key */static struct option key_options[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 }};static char *key_help = "Usage:\n" "\tkey <bdaddr>\n";static void cmd_key(int dev_id, int argc, char **argv){ struct hci_conn_info_req *cr; bdaddr_t bdaddr; int opt, dd; for_each_opt(opt, key_options, NULL) { switch (opt) { default: printf(key_help); return; } } argc -= optind; argv += optind; if (argc < 1) { printf(key_help); return; } str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); } } dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); exit(1); } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("Can't allocate memory"); exit(1); } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); exit(1); } if (hci_change_link_key(dd, htobs(cr->conn_info->handle), 25000) < 0) { perror("Changing link key failed"); exit(1); } close(dd); free(cr);}/* Read clock offset */static struct option clkoff_options[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 }};static char *clkoff_help = "Usage:\n" "\tclkoff <bdaddr>\n";static void cmd_clkoff(int dev_id, int argc, char **argv){ struct hci_conn_info_req *cr; bdaddr_t bdaddr; uint16_t offset; int opt, dd; for_each_opt(opt, clkoff_options, NULL) { switch (opt) { default: printf(clkoff_help); return; } } argc -= optind; argv += optind; if (argc < 1) { printf(clkoff_help); return; } str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); } } dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); exit(1); } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("Can't allocate memory"); exit(1); } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); exit(1); } if (hci_read_clock_offset(dd, htobs(cr->conn_info->handle), &offset, 1000) < 0) { perror("Reading clock offset failed"); exit(1); } printf("Clock offset: 0x%4.4x\n", btohs(offset)); close(dd); free(cr);}/* Read clock */static struct option clock_options[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 }};static char *clock_help = "Usage:\n" "\tclock [bdaddr] [which clock]\n";static void cmd_clock(int dev_id, int argc, char **argv){ struct hci_conn_info_req *cr; bdaddr_t bdaddr; uint8_t which; uint32_t handle, clock; uint16_t accuracy; int opt, dd; for_each_opt(opt, clock_options, NULL) { switch (opt) { default: printf(clock_help); return; } } argc -= optind; argv += optind; if (argc > 0) str2ba(argv[0], &bdaddr); else bacpy(&bdaddr, BDADDR_ANY); if (!bacmp(&bdaddr, BDADDR_ANY)) dev_id = hci_get_route(NULL); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); } } dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); exit(1); } if (bacmp(&bdaddr, BDADDR_ANY)) { cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("Can't allocate memory"); exit(1); } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); free(cr); exit(1); } handle = htobs(cr->conn_info->handle); which = (argc > 1) ? atoi(argv[1]) : 0x01; free(cr); } else { handle = 0x00; which = 0x00; } if (hci_read_clock(dd, handle, which, &clock, &accuracy, 1000) < 0) { perror("Reading clock failed"); exit(1); } accuracy = btohs(accuracy); printf("Clock: 0x%4.4x\n", btohl(clock)); printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); close(dd);}static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); char *doc;} command[] = { { "dev", cmd_dev, "Display local devices" }, { "inq", cmd_inq, "Inquire remote devices" }, { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, { "sr", cmd_sr, "Switch master/slave role" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_lq, "Display link quality" }, { "tpl", cmd_tpl, "Display transmit power level" }, { "afh", cmd_afh, "Display AFH channel map" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, { "enc", cmd_enc, "Set connection encryption" }, { "key", cmd_key, "Change connection link key" }, { "clkoff", cmd_clkoff, "Read clock offset" }, { "clock", cmd_clock, "Read local or remote clock" }, { NULL, NULL, 0 }};static void usage(void){ int i; printf("hcitool - HCI Tool ver %s\n", VERSION); printf("Usage:\n" "\thcitool [options] <command> [command parameters]\n"); printf("Options:\n" "\t--help\tDisplay help\n" "\t-i dev\tHCI device\n"); printf("Commands:\n"); for (i = 0; command[i].cmd; i++) printf("\t%-4s\t%s\n", command[i].cmd, command[i].doc); printf("\n" "For more information on the usage of each command use:\n" "\thcitool <command> --help\n" );}static struct option main_options[] = { { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, { 0, 0, 0, 0 }};int main(int argc, char **argv){ int opt, i, dev_id = -1; bdaddr_t ba; while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch (opt) { case 'i': dev_id = hci_devid(optarg); if (dev_id < 0) { perror("Invalid device"); exit(1); } break; case 'h': default: usage(); exit(0); } } argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); exit(0); } if (dev_id != -1 && hci_devba(dev_id, &ba) < 0) { perror("Device is not available"); exit(1); } for (i = 0; command[i].cmd; i++) { if (strncmp(command[i].cmd, argv[0], 3)) continue; command[i].func(dev_id, argc, argv); break; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -