/* * host_controller_baseband.c * * Copyright (c) 2001-2002 Maksim Yevmenkin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: host_controller_baseband.c,v 1.1 2002/11/24 20:22:38 max Exp $ * $FreeBSD$ */ #include #include #include #include #include #include #include "hccontrol.h" /* Convert hex ASCII to int4 */ static int hci_hexa2int4(const char *a) { if ('0' <= *a && *a <= '9') return (*a - '0'); if ('A' <= *a && *a <= 'F') return (*a - 'A' + 0xa); if ('a' <= *a && *a <= 'f') return (*a - 'a' + 0xa); return (-1); } /* Convert hex ASCII to int8 */ static int hci_hexa2int8(const char *a) { int hi = hci_hexa2int4(a); int lo = hci_hexa2int4(a + 1); if (hi < 0 || lo < 0) return (-1); return ((hi << 4) | lo); } /* Convert ascii hex string to the u_int8_t[] */ static int hci_hexstring2array(char const *s, u_int8_t *a, int asize) { int i, l, b; l = strlen(s) / 2; if (l > asize) l = asize; for (i = 0; i < l; i++) { b = hci_hexa2int8(s + i * 2); if (b < 0) return (-1); a[i] = (b & 0xff); } return (0); } /* Send RESET to the unit */ static int hci_reset(int s, int argc, char **argv) { ng_hci_status_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_RESET), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_reset */ /* Send Read_PIN_Type command to the unit */ static int hci_read_pin_type(int s, int argc, char **argv) { ng_hci_read_pin_type_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_PIN_TYPE), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "PIN type: %s [%#02x]\n", hci_pin2str(rp.pin_type), rp.pin_type); return (OK); } /* hci_read_pin_type */ /* Send Write_PIN_Type command to the unit */ static int hci_write_pin_type(int s, int argc, char **argv) { ng_hci_write_pin_type_cp cp; ng_hci_write_pin_type_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1) return (USAGE); cp.pin_type = (u_int8_t) n; break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_PIN_TYPE), (char const *) &cp, sizeof(cp), (char *) &rp , &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_pin_type */ /* Send Read_Stored_Link_Key command to the unit */ static int hci_read_stored_link_key(int s, int argc, char **argv) { struct { ng_hci_cmd_pkt_t hdr; ng_hci_read_stored_link_key_cp cp; } __attribute__ ((packed)) cmd; struct { ng_hci_event_pkt_t hdr; union { ng_hci_command_compl_ep cc; ng_hci_return_link_keys_ep key; u_int8_t b[NG_HCI_EVENT_PKT_SIZE]; } ep; } __attribute__ ((packed)) event; int n,a0,a1,a2,a3,a4,a5; /* Send command */ memset(&cmd, 0, sizeof(cmd)); cmd.hdr.type = NG_HCI_CMD_PKT; cmd.hdr.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_STORED_LINK_KEY)); cmd.hdr.length = sizeof(cmd.cp); switch (argc) { case 1: /* parse BD_ADDR */ if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &a5, &a4, &a3, &a2, &a1, &a0) != 6) return (USAGE); cmd.cp.bdaddr.b[0] = (a0 & 0xff); cmd.cp.bdaddr.b[1] = (a1 & 0xff); cmd.cp.bdaddr.b[2] = (a2 & 0xff); cmd.cp.bdaddr.b[3] = (a3 & 0xff); cmd.cp.bdaddr.b[4] = (a4 & 0xff); cmd.cp.bdaddr.b[5] = (a5 & 0xff); break; default: cmd.cp.read_all = 1; break; } if (hci_send(s, (char const *) &cmd, sizeof(cmd)) != OK) return (ERROR); /* Receive events */ again: memset(&event, 0, sizeof(event)); n = sizeof(event); if (hci_recv(s, (char *) &event, &n) != OK) return (ERROR); if (n <= sizeof(event.hdr)) { errno = EMSGSIZE; return (ERROR); } if (event.hdr.type != NG_HCI_EVENT_PKT) { errno = EIO; return (ERROR); } /* Parse event */ switch (event.hdr.event) { case NG_HCI_EVENT_COMMAND_COMPL: { ng_hci_read_stored_link_key_rp *rp = NULL; if (event.ep.cc.opcode == 0x0000 || event.ep.cc.opcode != cmd.hdr.opcode) goto again; rp = (ng_hci_read_stored_link_key_rp *)(event.ep.b + sizeof(event.ep.cc)); fprintf(stdout, "Complete: Status: %s [%#x]\n", hci_status2str(rp->status), rp->status); fprintf(stdout, "Maximum Number of keys: %d\n", le16toh(rp->max_num_keys)); fprintf(stdout, "Number of keys read: %d\n", le16toh(rp->num_keys_read)); } break; case NG_HCI_EVENT_RETURN_LINK_KEYS: { struct _key { bdaddr_t bdaddr; u_int8_t key[NG_HCI_KEY_SIZE]; } __attribute__ ((packed)) *k = NULL; fprintf(stdout, "Event: Number of keys: %d\n", event.ep.key.num_keys); k = (struct _key *)(event.ep.b + sizeof(event.ep.key)); for (n = 0; n < event.ep.key.num_keys; n++) { fprintf(stdout, "\t%d: %02x:%02x:%02x:%02x:%02x:%02x ", n + 1, k->bdaddr.b[5], k->bdaddr.b[4], k->bdaddr.b[3], k->bdaddr.b[2], k->bdaddr.b[1], k->bdaddr.b[0]); for (a0 = 0; a0 < sizeof(k->key); a0++) fprintf(stdout, "%02x", k->key[a0]); fprintf(stdout, "\n"); k ++; } goto again; } break; default: goto again; } return (OK); } /* hci_read_store_link_key */ /* Send Write_Stored_Link_Key command to the unit */ static int hci_write_stored_link_key(int s, int argc, char **argv) { struct { ng_hci_write_stored_link_key_cp p; bdaddr_t bdaddr; u_int8_t key[NG_HCI_KEY_SIZE]; } cp; ng_hci_write_stored_link_key_rp rp; int32_t n, a0, a1, a2, a3, a4, a5; memset(&cp, 0, sizeof(cp)); switch (argc) { case 2: cp.p.num_keys_write = 1; /* parse BD_ADDR */ if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &a5, &a4, &a3, &a2, &a1, &a0) != 6) return (USAGE); cp.bdaddr.b[0] = (a0 & 0xff); cp.bdaddr.b[1] = (a1 & 0xff); cp.bdaddr.b[2] = (a2 & 0xff); cp.bdaddr.b[3] = (a3 & 0xff); cp.bdaddr.b[4] = (a4 & 0xff); cp.bdaddr.b[5] = (a5 & 0xff); /* parse key */ if (hci_hexstring2array(argv[1], cp.key, sizeof(cp.key)) < 0) return (USAGE); break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_STORED_LINK_KEY), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "Number of keys written: %d\n", rp.num_keys_written); return (OK); } /* hci_write_stored_link_key */ /* Send Delete_Stored_Link_Key command to the unit */ static int hci_delete_stored_link_key(int s, int argc, char **argv) { ng_hci_delete_stored_link_key_cp cp; ng_hci_delete_stored_link_key_rp rp; int32_t n, a0, a1, a2, a3, a4, a5; memset(&cp, 0, sizeof(cp)); switch (argc) { case 1: /* parse BD_ADDR */ if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &a5, &a4, &a3, &a2, &a1, &a0) != 6) return (USAGE); cp.bdaddr.b[0] = (a0 & 0xff); cp.bdaddr.b[1] = (a1 & 0xff); cp.bdaddr.b[2] = (a2 & 0xff); cp.bdaddr.b[3] = (a3 & 0xff); cp.bdaddr.b[4] = (a4 & 0xff); cp.bdaddr.b[5] = (a5 & 0xff); break; default: cp.delete_all = 1; break; } /* send command */ n = sizeof(cp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_DELETE_STORED_LINK_KEY), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "Number of keys deleted: %d\n", rp.num_keys_deleted); return (OK); } /* hci_delete_stored_link_key */ /* Send Change_Local_Name command to the unit */ static int hci_change_local_name(int s, int argc, char **argv) { ng_hci_change_local_name_cp cp; ng_hci_change_local_name_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: snprintf(cp.name, sizeof(cp.name), "%s", argv[0]); break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_CHANGE_LOCAL_NAME), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_change_local_name */ /* Send Read_Local_Name command to the unit */ static int hci_read_local_name(int s, int argc, char **argv) { ng_hci_read_local_name_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_LOCAL_NAME), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "Local name: %s\n", rp.name); return (OK); } /* hci_read_local_name */ /* Send Read_Connection_Accept_Timeout to the unit */ static int hci_read_connection_accept_timeout(int s, int argc, char **argv) { ng_hci_read_con_accept_timo_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_CON_ACCEPT_TIMO), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } rp.timeout = le16toh(rp.timeout); fprintf(stdout, "Connection accept timeout: %.2f msec [%d slots]\n", rp.timeout * 0.625, rp.timeout); return (OK); } /* hci_read_connection_accept_timeout */ /* Send Write_Connection_Accept_Timeout to the unit */ static int hci_write_connection_accept_timeout(int s, int argc, char **argv) { ng_hci_write_con_accept_timo_cp cp; ng_hci_write_con_accept_timo_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xb540) return (USAGE); cp.timeout = (u_int16_t) n; cp.timeout = htole16(cp.timeout); break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_CON_ACCEPT_TIMO), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_connection_accept_timeout */ /* Send Read_Page_Timeout command to the unit */ static int hci_read_page_timeout(int s, int argc, char **argv) { ng_hci_read_page_timo_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_PAGE_TIMO), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } rp.timeout = le16toh(rp.timeout); fprintf(stdout, "Page timeout: %.2f msec [%d slots]\n", rp.timeout * 0.625, rp.timeout); return (OK); } /* hci_read_page_timeoout */ /* Send Write_Page_Timeout command to the unit */ static int hci_write_page_timeout(int s, int argc, char **argv) { ng_hci_write_page_timo_cp cp; ng_hci_write_page_timo_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xffff) return (USAGE); cp.timeout = (u_int16_t) n; cp.timeout = htole16(cp.timeout); break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_PAGE_TIMO), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_page_timeout */ /* Send Read_Scan_Enable command to the unit */ static int hci_read_scan_enable(int s, int argc, char **argv) { ng_hci_read_scan_enable_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_SCAN_ENABLE), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "Scan enable: %s [%#02x]\n", hci_scan2str(rp.scan_enable), rp.scan_enable); return (OK); } /* hci_read_scan_enable */ /* Send Write_Scan_Enable command to the unit */ static int hci_write_scan_enable(int s, int argc, char **argv) { ng_hci_write_scan_enable_cp cp; ng_hci_write_scan_enable_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3) return (USAGE); cp.scan_enable = (u_int8_t) n; break; default: return (USAGE); } n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_SCAN_ENABLE), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_scan_enable */ /* Send Read_Page_Scan_Activity command to the unit */ static int hci_read_page_scan_activity(int s, int argc, char **argv) { ng_hci_read_page_scan_activity_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_PAGE_SCAN_ACTIVITY), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } rp.page_scan_interval = le16toh(rp.page_scan_interval); rp.page_scan_window = le16toh(rp.page_scan_window); fprintf(stdout, "Page Scan Interval: %.2f msec [%d slots]\n", rp.page_scan_interval * 0.625, rp.page_scan_interval); fprintf(stdout, "Page Scan Window: %.2f msec [%d slots]\n", rp.page_scan_window * 0.625, rp.page_scan_window); return (OK); } /* hci_read_page_scan_activity */ /* Send Write_Page_Scan_Activity command to the unit */ static int hci_write_page_scan_activity(int s, int argc, char **argv) { ng_hci_write_page_scan_activity_cp cp; ng_hci_write_page_scan_activity_rp rp; int n; /* parse command parameters */ switch (argc) { case 2: /* page scan interval */ if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000) return (USAGE); cp.page_scan_interval = (u_int16_t) n; /* page scan window */ if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000) return (USAGE); cp.page_scan_window = (u_int16_t) n; if (cp.page_scan_window > cp.page_scan_interval) return (USAGE); cp.page_scan_interval = htole16(cp.page_scan_interval); cp.page_scan_window = htole16(cp.page_scan_window); break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_PAGE_SCAN_ACTIVITY), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_page_scan_activity */ /* Send Read_Inquiry_Scan_Activity command to the unit */ static int hci_read_inquiry_scan_activity(int s, int argc, char **argv) { ng_hci_read_inquiry_scan_activity_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_INQUIRY_SCAN_ACTIVITY), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } rp.inquiry_scan_interval = le16toh(rp.inquiry_scan_interval); rp.inquiry_scan_window = le16toh(rp.inquiry_scan_window); fprintf(stdout, "Inquiry Scan Interval: %.2f msec [%d slots]\n", rp.inquiry_scan_interval * 0.625, rp.inquiry_scan_interval); fprintf(stdout, "Inquiry Scan Window: %.2f msec [%d slots]\n", rp.inquiry_scan_window * 0.625, rp.inquiry_scan_interval); return (OK); } /* hci_read_inquiry_scan_activity */ /* Send Write_Inquiry_Scan_Activity command to the unit */ static int hci_write_inquiry_scan_activity(int s, int argc, char **argv) { ng_hci_write_inquiry_scan_activity_cp cp; ng_hci_write_inquiry_scan_activity_rp rp; int n; /* parse command parameters */ switch (argc) { case 2: /* inquiry scan interval */ if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000) return (USAGE); cp.inquiry_scan_interval = (u_int16_t) n; /* inquiry scan window */ if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000) return (USAGE); cp.inquiry_scan_window = (u_int16_t) n; if (cp.inquiry_scan_window > cp.inquiry_scan_interval) return (USAGE); cp.inquiry_scan_interval = htole16(cp.inquiry_scan_interval); cp.inquiry_scan_window = htole16(cp.inquiry_scan_window); break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_INQUIRY_SCAN_ACTIVITY), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_inquiry_scan_activity */ /* Send Read_Authentication_Enable command to the unit */ static int hci_read_authentication_enable(int s, int argc, char **argv) { ng_hci_read_auth_enable_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_AUTH_ENABLE), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "Authentication Enable: %s [%d]\n", rp.auth_enable? "Enabled" : "Disabled", rp.auth_enable); return (OK); } /* hci_read_authentication_enable */ /* Send Write_Authentication_Enable command to the unit */ static int hci_write_authentication_enable(int s, int argc, char **argv) { ng_hci_write_auth_enable_cp cp; ng_hci_write_auth_enable_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1) return (USAGE); cp.auth_enable = (u_int8_t) n; break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_AUTH_ENABLE), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_authentication_enable */ /* Send Read_Encryption_Mode command to the unit */ static int hci_read_encryption_mode(int s, int argc, char **argv) { ng_hci_read_encryption_mode_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_ENCRYPTION_MODE), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "Encryption mode: %s [%#02x]\n", hci_encrypt2str(rp.encryption_mode, 0), rp.encryption_mode); return (OK); } /* hci_read_encryption_mode */ /* Send Write_Encryption_Mode command to the unit */ static int hci_write_encryption_mode(int s, int argc, char **argv) { ng_hci_write_encryption_mode_cp cp; ng_hci_write_encryption_mode_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2) return (USAGE); cp.encryption_mode = (u_int8_t) n; break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_ENCRYPTION_MODE), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_encryption_mode */ /* Send Read_Class_Of_Device command to the unit */ static int hci_read_class_of_device(int s, int argc, char **argv) { ng_hci_read_unit_class_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_UNIT_CLASS), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "Class: %02x:%02x:%02x\n", rp.uclass[2], rp.uclass[1], rp.uclass[0]); return (0); } /* hci_read_class_of_device */ /* Send Write_Class_Of_Device command to the unit */ static int hci_write_class_of_device(int s, int argc, char **argv) { ng_hci_write_unit_class_cp cp; ng_hci_write_unit_class_rp rp; int n0, n1, n2; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%x:%x:%x", &n2, &n1, &n0) != 3) return (USAGE); cp.uclass[0] = (n0 & 0xff); cp.uclass[1] = (n1 & 0xff); cp.uclass[2] = (n2 & 0xff); break; default: return (USAGE); } /* send command */ n0 = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_UNIT_CLASS), (char const *) &cp, sizeof(cp), (char *) &rp, &n0) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_class_of_device */ /* Send Read_Voice_Settings command to the unit */ static int hci_read_voice_settings(int s, int argc, char **argv) { ng_hci_read_voice_settings_rp rp; int n, input_coding, input_data_format, input_sample_size; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_VOICE_SETTINGS), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } rp.settings = le16toh(rp.settings); input_coding = (rp.settings & 0x0300) >> 8; input_data_format = (rp.settings & 0x00c0) >> 6; input_sample_size = (rp.settings & 0x0020) >> 5; fprintf(stdout, "Voice settings: %#04x\n", rp.settings); fprintf(stdout, "Input coding: %s [%d]\n", hci_coding2str(input_coding), input_coding); fprintf(stdout, "Input data format: %s [%d]\n", hci_vdata2str(input_data_format), input_data_format); if (input_coding == 0x00) /* Only for Linear PCM */ fprintf(stdout, "Input sample size: %d bit [%d]\n", input_sample_size? 16 : 8, input_sample_size); return (OK); } /* hci_read_voice_settings */ /* Send Write_Voice_Settings command to the unit */ static int hci_write_voice_settings(int s, int argc, char **argv) { ng_hci_write_voice_settings_cp cp; ng_hci_write_voice_settings_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%x", &n) != 1) return (USAGE); cp.settings = (u_int16_t) n; cp.settings = htole16(cp.settings); break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_VOICE_SETTINGS), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_voice_settings */ /* Send Read_Number_Broadcast_Restransmissions */ static int hci_read_number_broadcast_retransmissions(int s, int argc, char **argv) { ng_hci_read_num_broadcast_retrans_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_NUM_BROADCAST_RETRANS), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "Number of broadcast retransmissions: %d\n", rp.counter); return (OK); } /* hci_read_number_broadcast_retransmissions */ /* Send Write_Number_Broadcast_Restransmissions */ static int hci_write_number_broadcast_retransmissions(int s, int argc, char **argv) { ng_hci_write_num_broadcast_retrans_cp cp; ng_hci_write_num_broadcast_retrans_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0xff) return (USAGE); cp.counter = (u_int8_t) n; break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_NUM_BROADCAST_RETRANS), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_number_broadcast_retransmissions */ /* Send Read_Hold_Mode_Activity command to the unit */ static int hci_read_hold_mode_activity(int s, int argc, char **argv) { ng_hci_read_hold_mode_activity_rp rp; int n; char buffer[1024]; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_HOLD_MODE_ACTIVITY), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "Hold Mode Activities: %#02x\n", rp.hold_mode_activity); if (rp.hold_mode_activity == 0) fprintf(stdout, "Maintain current Power State"); else fprintf(stdout, "%s", hci_hmode2str(rp.hold_mode_activity, buffer, sizeof(buffer))); fprintf(stdout, "\n"); return (OK); } /* hci_read_hold_mode_activity */ /* Send Write_Hold_Mode_Activity command to the unit */ static int hci_write_hold_mode_activity(int s, int argc, char **argv) { ng_hci_write_hold_mode_activity_cp cp; ng_hci_write_hold_mode_activity_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 4) return (USAGE); cp.hold_mode_activity = (u_int8_t) n; break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_HOLD_MODE_ACTIVITY), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_hold_mode_activity */ /* Send Read_SCO_Flow_Control_Enable command to the unit */ static int hci_read_sco_flow_control_enable(int s, int argc, char **argv) { ng_hci_read_sco_flow_control_rp rp; int n; n = sizeof(rp); if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_SCO_FLOW_CONTROL), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } fprintf(stdout, "SCO flow control %s [%d]\n", rp.flow_control? "enabled" : "disabled", rp.flow_control); return (OK); } /* hci_read_sco_flow_control_enable */ /* Send Write_SCO_Flow_Control_Enable command to the unit */ static int hci_write_sco_flow_control_enable(int s, int argc, char **argv) { ng_hci_write_sco_flow_control_cp cp; ng_hci_write_sco_flow_control_rp rp; int n; /* parse command parameters */ switch (argc) { case 1: if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1) return (USAGE); cp.flow_control = (u_int8_t) n; break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_SCO_FLOW_CONTROL), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_sco_flow_control_enable */ /* Send Read_Link_Supervision_Timeout command to the unit */ static int hci_read_link_supervision_timeout(int s, int argc, char **argv) { ng_hci_read_link_supervision_timo_cp cp; ng_hci_read_link_supervision_timo_rp rp; int n; switch (argc) { case 1: /* connection handle */ if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff) return (USAGE); cp.con_handle = (u_int16_t) (n & 0x0fff); cp.con_handle = htole16(cp.con_handle); break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_READ_LINK_SUPERVISION_TIMO), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } rp.timeout = le16toh(rp.timeout); fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle)); fprintf(stdout, "Link supervision timeout: %.2f msec [%d slots]\n", rp.timeout * 0.625, rp.timeout); return (OK); } /* hci_read_link_supervision_timeout */ /* Send Write_Link_Supervision_Timeout command to the unit */ static int hci_write_link_supervision_timeout(int s, int argc, char **argv) { ng_hci_write_link_supervision_timo_cp cp; ng_hci_write_link_supervision_timo_rp rp; int n; switch (argc) { case 2: /* connection handle */ if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff) return (USAGE); cp.con_handle = (u_int16_t) (n & 0x0fff); cp.con_handle = htole16(cp.con_handle); /* link supervision timeout */ if (sscanf(argv[1], "%d", &n) != 1 || n < 0 || n > 0xeff) return (USAGE); cp.timeout = (u_int16_t) (n & 0x0fff); cp.timeout = htole16(cp.timeout); break; default: return (USAGE); } /* send command */ n = sizeof(rp); if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_LINK_SUPERVISION_TIMO), (char const *) &cp, sizeof(cp), (char *) &rp, &n) == ERROR) return (ERROR); if (rp.status != 0x00) { fprintf(stdout, "Status: %s [%#02x]\n", hci_status2str(rp.status), rp.status); return (FAILED); } return (OK); } /* hci_write_link_supervision_timeout */ struct hci_command host_controller_baseband_commands[] = { { "reset", "\nThe Reset command will reset the Host Controller and the Link Manager.\n" \ "After the reset is completed, the current operational state will be lost,\n" \ "the Bluetooth unit will enter standby mode and the Host Controller will\n" \ "automatically revert to the default values for the parameters for which\n" \ "default values are defined in the specification.", &hci_reset }, { "read_pin_type", "\nThe Read_PIN_Type command is used for the Host to read whether the Link\n" \ "Manager assumes that the Host supports variable PIN codes only a fixed PIN\n" \ "code.", &hci_read_pin_type }, { "write_pin_type ", "\nThe Write_PIN_Type command is used for the Host to write to the Host\n" \ "Controller whether the Host supports variable PIN codes or only a fixed PIN\n"\ "code.\n\n" \ "\t - dd; 0 - Variable; 1 - Fixed", &hci_write_pin_type }, { "read_stored_link_key []", "\nThe Read_Stored_Link_Key command provides the ability to read one or\n" \ "more link keys stored in the Bluetooth Host Controller. The Bluetooth Host\n" \ "Controller can store a limited number of link keys for other Bluetooth\n" \ "devices.\n\n" \ "\t - xx:xx:xx:xx:xx:xx BD_ADDR", &hci_read_stored_link_key }, { "write_stored_link_key ", "\nThe Write_Stored_Link_Key command provides the ability to write one\n" \ "or more link keys to be stored in the Bluetooth Host Controller. The\n" \ "Bluetooth Host Controller can store a limited number of link keys for other\n"\ "Bluetooth devices. If no additional space is available in the Bluetooth\n"\ "Host Controller then no additional link keys will be stored.\n\n" \ "\t - xx:xx:xx:xx:xx:xx BD_ADDR\n" \ "\t - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx up to 16 bytes link key", &hci_write_stored_link_key }, { "delete_stored_link_key []", "\nThe Delete_Stored_Link_Key command provides the ability to remove one\n" \ "or more of the link keys stored in the Bluetooth Host Controller. The\n" \ "Bluetooth Host Controller can store a limited number of link keys for other\n"\ "Bluetooth devices.\n\n" \ "\t - xx:xx:xx:xx:xx:xx BD_ADDR", &hci_delete_stored_link_key }, { "change_local_name ", "\nThe Change_Local_Name command provides the ability to modify the user\n" \ "friendly name for the Bluetooth unit.\n\n" \ "\t - string", &hci_change_local_name }, { "read_local_name", "\nThe Read_Local_Name command provides the ability to read the\n" \ "stored user-friendly name for the Bluetooth unit.", &hci_read_local_name }, { "read_connection_accept_timeout", "\nThis command will read the value for the Connection_Accept_Timeout\n" \ "configuration parameter. The Connection_Accept_Timeout configuration\n" \ "parameter allows the Bluetooth hardware to automatically deny a\n" \ "connection request after a specified time period has occurred and\n" \ "the new connection is not accepted. Connection Accept Timeout\n" \ "measured in Number of Baseband slots.", &hci_read_connection_accept_timeout }, { "write_connection_accept_timeout ", "\nThis command will write the value for the Connection_Accept_Timeout\n" \ "configuration parameter.\n\n" \ "\t - dddd; measured in number of baseband slots.", &hci_write_connection_accept_timeout }, { "read_page_timeout", "\nThis command will read the value for the Page_Timeout configuration\n" \ "parameter. The Page_Timeout configuration parameter defines the\n" \ "maximum time the local Link Manager will wait for a baseband page\n" \ "response from the remote unit at a locally initiated connection\n" \ "attempt. Page Timeout measured in Number of Baseband slots.", &hci_read_page_timeout }, { "write_page_timeout ", "\nThis command will write the value for the Page_Timeout configuration\n" \ "parameter.\n\n" \ "\t - dddd; measured in number of baseband slots.", &hci_write_page_timeout }, { "read_scan_enable", "\nThis command will read the value for the Scan_Enable parameter. The\n" \ "Scan_Enable parameter controls whether or not the Bluetooth uint\n" \ "will periodically scan for page attempts and/or inquiry requests\n" \ "from other Bluetooth unit.\n\n" \ "\t0x00 - No Scans enabled.\n" \ "\t0x01 - Inquiry Scan enabled. Page Scan disabled.\n" \ "\t0x02 - Inquiry Scan disabled. Page Scan enabled.\n" \ "\t0x03 - Inquiry Scan enabled. Page Scan enabled.", &hci_read_scan_enable }, { "write_scan_enable ", "\nThis command will write the value for the Scan_Enable parameter.\n" \ "The Scan_Enable parameter controls whether or not the Bluetooth\n" \ "unit will periodically scan for page attempts and/or inquiry\n" \ "requests from other Bluetooth unit.\n\n" \ "\t - dd;\n" \ "\t0 - No Scans enabled.\n" \ "\t1 - Inquiry Scan enabled. Page Scan disabled.\n" \ "\t2 - Inquiry Scan disabled. Page Scan enabled.\n" \ "\t3 - Inquiry Scan enabled. Page Scan enabled.", &hci_write_scan_enable }, { "read_page_scan_activity", "\nThis command will read the value for Page_Scan_Activity configuration\n" \ "parameters. The Page_Scan_Interval configuration parameter defines the\n" \ "amount of time between consecutive page scans. This time interval is \n" \ "defined from when the Host Controller started its last page scan until\n" \ "it begins the next page scan. The Page_Scan_Window configuration parameter\n" \ "defines the amount of time for the duration of the page scan. The\n" \ "Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.", &hci_read_page_scan_activity }, { "write_page_scan_activity interval(dddd) window(dddd)", "\nThis command will write the value for Page_Scan_Activity configuration\n" \ "parameter. The Page_Scan_Interval configuration parameter defines the\n" \ "amount of time between consecutive page scans. This is defined as the time\n" \ "interval from when the Host Controller started its last page scan until it\n" \ "begins the next page scan. The Page_Scan_Window configuration parameter\n" \ "defines the amount of time for the duration of the page scan. \n" \ "The Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.\n\n" \ "\t - Range: 0x0012 -– 0x100, Time = N * 0.625 msec\n" \ "\t - Range: 0x0012 -– 0x100, Time = N * 0.625 msen", &hci_write_page_scan_activity }, { "read_inquiry_scan_activity", "\nThis command will read the value for Inquiry_Scan_Activity configuration\n" \ "parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \ "amount of time between consecutive inquiry scans. This is defined as the\n" \ "time interval from when the Host Controller started its last inquiry scan\n" \ "until it begins the next inquiry scan.", &hci_read_inquiry_scan_activity }, { "write_inquiry_scan_activity interval(dddd) window(dddd)", "\nThis command will write the value for Inquiry_Scan_Activity configuration\n"\ "parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \ "amount of time between consecutive inquiry scans. This is defined as the\n" \ "time interval from when the Host Controller started its last inquiry scan\n" \ "until it begins the next inquiry scan. The Inquiry_Scan_Window configuration\n" \ "parameter defines the amount of time for the duration of the inquiry scan.\n" \ "The Inquiry_Scan_Window can only be less than or equal to the Inquiry_Scan_Interval.\n\n" \ "\t - Range: 0x0012 -– 0x100, Time = N * 0.625 msec\n" \ "\t - Range: 0x0012 -– 0x100, Time = N * 0.625 msen", &hci_write_inquiry_scan_activity }, { "read_authentication_enable", "\nThis command will read the value for the Authentication_Enable parameter.\n"\ "The Authentication_Enable parameter controls if the local unit requires\n"\ "to authenticate the remote unit at connection setup (between the\n" \ "Create_Connection command or acceptance of an incoming ACL connection\n"\ "and the corresponding Connection Complete event). At connection setup, only\n"\ "the unit(s) with the Authentication_Enable parameter enabled will try to\n"\ "authenticate the other unit.", &hci_read_authentication_enable }, { "write_authentication_enable enable(0|1)", "\nThis command will write the value for the Authentication_Enable parameter.\n"\ "The Authentication_Enable parameter controls if the local unit requires to\n"\ "authenticate the remote unit at connection setup (between the\n" \ "Create_Connection command or acceptance of an incoming ACL connection\n" \ "and the corresponding Connection Complete event). At connection setup, only\n"\ "the unit(s) with the Authentication_Enable parameter enabled will try to\n"\ "authenticate the other unit.", &hci_write_authentication_enable }, { "read_encryption_mode", "\nThis command will read the value for the Encryption_Mode parameter. The\n" \ "Encryption_Mode parameter controls if the local unit requires encryption\n" \ "to the remote unit at connection setup (between the Create_Connection\n" \ "command or acceptance of an incoming ACL connection and the corresponding\n" \ "Connection Complete event). At connection setup, only the unit(s) with\n" \ "the Authentication_Enable parameter enabled and Encryption_Mode parameter\n" \ "enabled will try to encrypt the connection to the other unit.\n\n" \ "\t:\n" \ "\t0x00 - Encryption disabled.\n" \ "\t0x01 - Encryption only for point-to-point packets.\n" \ "\t0x02 - Encryption for both point-to-point and broadcast packets.", &hci_read_encryption_mode }, { "write_encryption_mode mode(0|1|2)", "\tThis command will write the value for the Encryption_Mode parameter.\n" \ "The Encryption_Mode parameter controls if the local unit requires\n" \ "encryption to the remote unit at connection setup (between the\n" \ "Create_Connection command or acceptance of an incoming ACL connection\n" \ "and the corresponding Connection Complete event). At connection setup,\n" \ "only the unit(s) with the Authentication_Enable parameter enabled and\n" \ "Encryption_Mode parameter enabled will try to encrypt the connection to\n" \ "the other unit.\n\n" \ "\t (dd)\n" \ "\t0 - Encryption disabled.\n" \ "\t1 - Encryption only for point-to-point packets.\n" \ "\t2 - Encryption for both point-to-point and broadcast packets.", &hci_write_encryption_mode }, { "read_class_of_device", "\nThis command will read the value for the Class_of_Device parameter.\n" \ "The Class_of_Device parameter is used to indicate the capabilities of\n" \ "the local unit to other units.", &hci_read_class_of_device }, { "write_class_of_device class(xx:xx:xx)", "\nThis command will write the value for the Class_of_Device parameter.\n" \ "The Class_of_Device parameter is used to indicate the capabilities of \n" \ "the local unit to other units.\n\n" \ "\t (xx:xx:xx) - class of device", &hci_write_class_of_device }, { "read_voice_settings", "\nThis command will read the values for the Voice_Setting parameter.\n" \ "The Voice_Setting parameter controls all the various settings for voice\n" \ "connections. These settings apply to all voice connections, and cannot be\n" \ "set for individual voice connections. The Voice_Setting parameter controls\n" \ "the configuration for voice connections: Input Coding, Air coding format,\n" \ "input data format, Input sample size, and linear PCM parameter.", &hci_read_voice_settings }, { "write_voice_settings settings(xxxx)", "\nThis command will write the values for the Voice_Setting parameter.\n" \ "The Voice_Setting parameter controls all the various settings for voice\n" \ "connections. These settings apply to all voice connections, and cannot be\n" \ "set for individual voice connections. The Voice_Setting parameter controls\n" \ "the configuration for voice connections: Input Coding, Air coding format,\n" \ "input data format, Input sample size, and linear PCM parameter.\n\n" \ "\t (xxxx) - voice settings", &hci_write_voice_settings }, { "read_number_broadcast_retransmissions", "\nThis command will read the unit's parameter value for the Number of\n" \ "Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \ "unreliable.", &hci_read_number_broadcast_retransmissions }, { "write_number_broadcast_retransmissions count(dd)", "\nThis command will write the unit's parameter value for the Number of\n" \ "Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \ "unreliable.\n\n" \ "\t (dd) - number of broadcast retransimissions", &hci_write_number_broadcast_retransmissions }, { "read_hold_mode_activity", "\nThis command will read the value for the Hold_Mode_Activity parameter.\n" \ "The Hold_Mode_Activity value is used to determine what activities should\n" \ "be suspended when the unit is in hold mode.", &hci_read_hold_mode_activity }, { "write_hold_mode_activity settings(0|1|2|4)", "\nThis command will write the value for the Hold_Mode_Activity parameter.\n" \ "The Hold_Mode_Activity value is used to determine what activities should\n" \ "be suspended when the unit is in hold mode.\n\n" \ "\t (dd) - bit mask:\n" \ "\t0 - Maintain current Power State. Default\n" \ "\t1 - Suspend Page Scan.\n" \ "\t2 - Suspend Inquiry Scan.\n" \ "\t4 - Suspend Periodic Inquiries.", &hci_write_hold_mode_activity }, { "read_sco_flow_control_enable", "\nThe Read_SCO_Flow_Control_Enable command provides the ability to read\n" \ "the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \ "decide if the Host Controller will send Number Of Completed Packets events\n" \ "for SCO Connection Handles. This setting allows the Host to enable and\n" \ "disable SCO flow control.", &hci_read_sco_flow_control_enable }, { "write_sco_flow_control_enable enable(0|1)", "\nThe Write_SCO_Flow_Control_Enable command provides the ability to write\n" \ "the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \ "decide if the Host Controller will send Number Of Completed Packets events\n" \ "for SCO Connection Handles. This setting allows the Host to enable and\n" \ "disable SCO flow control. The SCO_Flow_Control_Enable setting can only be\n" \ "changed if no connections exist.", &hci_write_sco_flow_control_enable }, { "read_link_supervision_timeout ", "\nThis command will read the value for the Link_Supervision_Timeout\n" \ "parameter for the device. The Link_Supervision_Timeout parameter is used\n" \ "by the master or slave Bluetooth device to monitor link loss. If, for any\n" \ "reason, no Baseband packets are received from that Connection Handle for a\n" \ "duration longer than the Link_Supervision_Timeout, the connection is\n" "disconnected.\n\n" \ "\t - dddd; connection handle\n", &hci_read_link_supervision_timeout }, { "write_link_supervision_timeout ", "\nThis command will write the value for the Link_Supervision_Timeout\n" \ "parameter for the device. The Link_Supervision_Timeout parameter is used\n" \ "by the master or slave Bluetooth device to monitor link loss. If, for any\n" \ "reason, no Baseband packets are received from that connection handle for a\n" \ "duration longer than the Link_Supervision_Timeout, the connection is\n" \ "disconnected.\n\n" \ "\t - dddd; connection handle\n" \ "\t - dddd; timeout measured in number of baseband slots\n", &hci_write_link_supervision_timeout }, { NULL, } };