diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/hcitool.c | 116 |
1 files changed, 114 insertions, 2 deletions
diff --git a/tools/hcitool.c b/tools/hcitool.c index 730605db..ec6f007a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -886,6 +886,7 @@ 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; int opt, dd, ptype; @@ -936,10 +937,13 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; + 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"); @@ -950,6 +954,113 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } +/* Get/Set Link Supervision Timeout */ + +static struct option link_supervision_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *link_supervision_help = + "Usage:\n" + "\tlst <bdaddr> [new value in slots]\n"; + +static void cmd_link_sup_to(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_link_supervision_timeout_rp rp; + write_link_supervision_timeout_cp cp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, link_supervision_options, NULL) { + switch(opt) { + default: + printf(link_supervision_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(link_supervision_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) + return; + + 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) { + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read_link_supervision_timeout request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_link_supervision_timeout failed (0x%2.2X)\n", + rp.status); + exit(1); + } + if (rp.link_sup_to) + printf("Link supervision timeout: %u slots (%.2f msec)\n", + rp.link_sup_to, (float)rp.link_sup_to * 0.625); + else + printf("Link supervision timeout never expires\n"); + } + else { + cp.handle = cr->conn_info->handle; + cp.link_sup_to = strtol(argv[1], NULL, 10); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cp; + rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI write_link_supervision_timeout request failed"); + exit(1); + } + } + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -967,6 +1078,7 @@ struct { { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_link_quality, "Display link quality" }, + { "lst", cmd_link_sup_to, "Set/display link supervision timeout" }, { NULL, NULL, 0} }; |