Path: blob/main/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c
105644 views
/*-1* host_controller_baseband.c2*3* SPDX-License-Identifier: BSD-2-Clause4*5* Copyright (c) 2001-2002 Maksim Yevmenkin <[email protected]>6* All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*29* $Id: host_controller_baseband.c,v 1.4 2003/08/18 19:19:53 max Exp $30*/3132#define L2CAP_SOCKET_CHECKED33#include <bluetooth.h>34#include <errno.h>35#include <stdio.h>36#include <string.h>37#include "hccontrol.h"3839/* Convert hex ASCII to int4 */40static int41hci_hexa2int4(const char *a)42{43if ('0' <= *a && *a <= '9')44return (*a - '0');4546if ('A' <= *a && *a <= 'F')47return (*a - 'A' + 0xa);4849if ('a' <= *a && *a <= 'f')50return (*a - 'a' + 0xa);5152return (-1);53}5455/* Convert hex ASCII to int8 */56static int57hci_hexa2int8(const char *a)58{59int hi = hci_hexa2int4(a);60int lo = hci_hexa2int4(a + 1);6162if (hi < 0 || lo < 0)63return (-1);6465return ((hi << 4) | lo);66}6768/* Convert ascii hex string to the uint8_t[] */69static int70hci_hexstring2array(char const *s, uint8_t *a, int asize)71{72int i, l, b;7374l = strlen(s) / 2;75if (l > asize)76l = asize;7778for (i = 0; i < l; i++) {79b = hci_hexa2int8(s + i * 2);80if (b < 0)81return (-1);8283a[i] = (b & 0xff);84}8586return (0);87}8889/* Send RESET to the unit */90static int91hci_reset(int s, int argc, char **argv)92{93ng_hci_status_rp rp;94int n;9596n = sizeof(rp);97if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,98NG_HCI_OCF_RESET), (char *) &rp, &n) == ERROR)99return (ERROR);100101if (rp.status != 0x00) {102fprintf(stdout, "Status: %s [%#02x]\n",103hci_status2str(rp.status), rp.status);104return (FAILED);105}106107return (OK);108} /* hci_reset */109110/* Send Read_PIN_Type command to the unit */111static int112hci_read_pin_type(int s, int argc, char **argv)113{114ng_hci_read_pin_type_rp rp;115int n;116117n = sizeof(rp);118if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,119NG_HCI_OCF_READ_PIN_TYPE),120(char *) &rp, &n) == ERROR)121return (ERROR);122123if (rp.status != 0x00) {124fprintf(stdout, "Status: %s [%#02x]\n",125hci_status2str(rp.status), rp.status);126return (FAILED);127}128129fprintf(stdout, "PIN type: %s [%#02x]\n",130hci_pin2str(rp.pin_type), rp.pin_type);131132return (OK);133} /* hci_read_pin_type */134135/* Send Write_PIN_Type command to the unit */136static int137hci_write_pin_type(int s, int argc, char **argv)138{139ng_hci_write_pin_type_cp cp;140ng_hci_write_pin_type_rp rp;141int n;142143/* parse command parameters */144switch (argc) {145case 1:146if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)147return (USAGE);148149cp.pin_type = (uint8_t) n;150break;151152default:153return (USAGE);154}155156/* send command */157n = sizeof(rp);158if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,159NG_HCI_OCF_WRITE_PIN_TYPE),160(char const *) &cp, sizeof(cp),161(char *) &rp , &n) == ERROR)162return (ERROR);163164if (rp.status != 0x00) {165fprintf(stdout, "Status: %s [%#02x]\n",166hci_status2str(rp.status), rp.status);167return (FAILED);168}169170return (OK);171} /* hci_write_pin_type */172173/* Send Read_Stored_Link_Key command to the unit */174static int175hci_read_stored_link_key(int s, int argc, char **argv)176{177struct {178ng_hci_cmd_pkt_t hdr;179ng_hci_read_stored_link_key_cp cp;180} __attribute__ ((packed)) cmd;181182struct {183ng_hci_event_pkt_t hdr;184union {185ng_hci_command_compl_ep cc;186ng_hci_return_link_keys_ep key;187uint8_t b[NG_HCI_EVENT_PKT_SIZE];188} ep;189} __attribute__ ((packed)) event;190191int n, n1;192193/* Send command */194memset(&cmd, 0, sizeof(cmd));195cmd.hdr.type = NG_HCI_CMD_PKT;196cmd.hdr.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,197NG_HCI_OCF_READ_STORED_LINK_KEY));198cmd.hdr.length = sizeof(cmd.cp);199200switch (argc) {201case 1:202/* parse BD_ADDR */203if (!bt_aton(argv[0], &cmd.cp.bdaddr)) {204struct hostent *he = NULL;205206if ((he = bt_gethostbyname(argv[0])) == NULL)207return (USAGE);208209memcpy(&cmd.cp.bdaddr, he->h_addr, sizeof(cmd.cp.bdaddr));210}211break;212213default:214cmd.cp.read_all = 1;215break;216}217218if (hci_send(s, (char const *) &cmd, sizeof(cmd)) != OK)219return (ERROR);220221/* Receive events */222again:223memset(&event, 0, sizeof(event));224n = sizeof(event);225if (hci_recv(s, (char *) &event, &n) != OK)226return (ERROR);227228if (n <= sizeof(event.hdr)) {229errno = EMSGSIZE;230return (ERROR);231}232233if (event.hdr.type != NG_HCI_EVENT_PKT) {234errno = EIO;235return (ERROR);236}237238/* Parse event */239switch (event.hdr.event) {240case NG_HCI_EVENT_COMMAND_COMPL: {241ng_hci_read_stored_link_key_rp *rp = NULL;242243if (event.ep.cc.opcode == 0x0000 ||244event.ep.cc.opcode != cmd.hdr.opcode)245goto again;246247rp = (ng_hci_read_stored_link_key_rp *)(event.ep.b +248sizeof(event.ep.cc));249250fprintf(stdout, "Complete: Status: %s [%#x]\n",251hci_status2str(rp->status), rp->status);252fprintf(stdout, "Maximum Number of keys: %d\n",253le16toh(rp->max_num_keys));254fprintf(stdout, "Number of keys read: %d\n",255le16toh(rp->num_keys_read));256} break;257258case NG_HCI_EVENT_RETURN_LINK_KEYS: {259struct _key {260bdaddr_t bdaddr;261uint8_t key[NG_HCI_KEY_SIZE];262} __attribute__ ((packed)) *k = NULL;263264fprintf(stdout, "Event: Number of keys: %d\n",265event.ep.key.num_keys);266267k = (struct _key *)(event.ep.b + sizeof(event.ep.key));268for (n = 0; n < event.ep.key.num_keys; n++) {269fprintf(stdout, "\t%d: %s ",270n + 1, hci_bdaddr2str(&k->bdaddr));271272for (n1 = 0; n1 < sizeof(k->key); n1++)273fprintf(stdout, "%02x", k->key[n1]);274fprintf(stdout, "\n");275276k ++;277}278279goto again;280281} break;282283default:284goto again;285}286287return (OK);288} /* hci_read_store_link_key */289290/* Send Write_Stored_Link_Key command to the unit */291static int292hci_write_stored_link_key(int s, int argc, char **argv)293{294struct {295ng_hci_write_stored_link_key_cp p;296bdaddr_t bdaddr;297uint8_t key[NG_HCI_KEY_SIZE];298} cp;299ng_hci_write_stored_link_key_rp rp;300int32_t n;301302memset(&cp, 0, sizeof(cp));303304switch (argc) {305case 2:306cp.p.num_keys_write = 1;307308/* parse BD_ADDR */309if (!bt_aton(argv[0], &cp.bdaddr)) {310struct hostent *he = NULL;311312if ((he = bt_gethostbyname(argv[0])) == NULL)313return (USAGE);314315memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));316}317318/* parse key */319if (hci_hexstring2array(argv[1], cp.key, sizeof(cp.key)) < 0)320return (USAGE);321break;322323default:324return (USAGE);325}326327/* send command */328n = sizeof(rp);329if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,330NG_HCI_OCF_WRITE_STORED_LINK_KEY),331(char const *) &cp, sizeof(cp),332(char *) &rp, &n) == ERROR)333return (ERROR);334335if (rp.status != 0x00) {336fprintf(stdout, "Status: %s [%#02x]\n",337hci_status2str(rp.status), rp.status);338return (FAILED);339}340341fprintf(stdout, "Number of keys written: %d\n", rp.num_keys_written);342343return (OK);344} /* hci_write_stored_link_key */345346347/* Send Delete_Stored_Link_Key command to the unit */348static int349hci_delete_stored_link_key(int s, int argc, char **argv)350{351ng_hci_delete_stored_link_key_cp cp;352ng_hci_delete_stored_link_key_rp rp;353int32_t n;354355memset(&cp, 0, sizeof(cp));356357switch (argc) {358case 1:359/* parse BD_ADDR */360if (!bt_aton(argv[0], &cp.bdaddr)) {361struct hostent *he = NULL;362363if ((he = bt_gethostbyname(argv[0])) == NULL)364return (USAGE);365366memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));367}368break;369370default:371cp.delete_all = 1;372break;373}374375/* send command */376n = sizeof(cp);377if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,378NG_HCI_OCF_DELETE_STORED_LINK_KEY),379(char const *) &cp, sizeof(cp),380(char *) &rp, &n) == ERROR)381return (ERROR);382383if (rp.status != 0x00) {384fprintf(stdout, "Status: %s [%#02x]\n",385hci_status2str(rp.status), rp.status);386return (FAILED);387}388389fprintf(stdout, "Number of keys deleted: %d\n", rp.num_keys_deleted);390391return (OK);392} /* hci_delete_stored_link_key */393394/* Send Change_Local_Name command to the unit */395static int396hci_change_local_name(int s, int argc, char **argv)397{398ng_hci_change_local_name_cp cp;399ng_hci_change_local_name_rp rp;400int n;401402/* parse command parameters */403switch (argc) {404case 1:405snprintf(cp.name, sizeof(cp.name), "%s", argv[0]);406break;407408default:409return (USAGE);410}411412/* send command */413n = sizeof(rp);414if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,415NG_HCI_OCF_CHANGE_LOCAL_NAME),416(char const *) &cp, sizeof(cp),417(char *) &rp, &n) == ERROR)418return (ERROR);419420if (rp.status != 0x00) {421fprintf(stdout, "Status: %s [%#02x]\n",422hci_status2str(rp.status), rp.status);423return (FAILED);424}425426return (OK);427} /* hci_change_local_name */428429/* Send Read_Local_Name command to the unit */430static int431hci_read_local_name(int s, int argc, char **argv)432{433ng_hci_read_local_name_rp rp;434int n;435436n = sizeof(rp);437if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,438NG_HCI_OCF_READ_LOCAL_NAME),439(char *) &rp, &n) == ERROR)440return (ERROR);441442if (rp.status != 0x00) {443fprintf(stdout, "Status: %s [%#02x]\n",444hci_status2str(rp.status), rp.status);445return (FAILED);446}447448fprintf(stdout, "Local name: %s\n", rp.name);449450return (OK);451} /* hci_read_local_name */452453/* Send Read_Connection_Accept_Timeout to the unit */454static int455hci_read_connection_accept_timeout(int s, int argc, char **argv)456{457ng_hci_read_con_accept_timo_rp rp;458int n;459460n = sizeof(rp);461if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,462NG_HCI_OCF_READ_CON_ACCEPT_TIMO),463(char *) &rp, &n) == ERROR)464return (ERROR);465466if (rp.status != 0x00) {467fprintf(stdout, "Status: %s [%#02x]\n",468hci_status2str(rp.status), rp.status);469return (FAILED);470}471472rp.timeout = le16toh(rp.timeout);473fprintf(stdout, "Connection accept timeout: %.2f msec [%d slots]\n",474rp.timeout * 0.625, rp.timeout);475476return (OK);477} /* hci_read_connection_accept_timeout */478479/* Send Write_Connection_Accept_Timeout to the unit */480static int481hci_write_connection_accept_timeout(int s, int argc, char **argv)482{483ng_hci_write_con_accept_timo_cp cp;484ng_hci_write_con_accept_timo_rp rp;485int n;486487/* parse command parameters */488switch (argc) {489case 1:490if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xb540)491return (USAGE);492493cp.timeout = (uint16_t) n;494cp.timeout = htole16(cp.timeout);495break;496497default:498return (USAGE);499}500501/* send command */502n = sizeof(rp);503if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,504NG_HCI_OCF_WRITE_CON_ACCEPT_TIMO),505(char const *) &cp, sizeof(cp),506(char *) &rp, &n) == ERROR)507return (ERROR);508509if (rp.status != 0x00) {510fprintf(stdout, "Status: %s [%#02x]\n",511hci_status2str(rp.status), rp.status);512return (FAILED);513}514515return (OK);516} /* hci_write_connection_accept_timeout */517518/* Send Read_Page_Timeout command to the unit */519static int520hci_read_page_timeout(int s, int argc, char **argv)521{522ng_hci_read_page_timo_rp rp;523int n;524525n = sizeof(rp);526if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,527NG_HCI_OCF_READ_PAGE_TIMO),528(char *) &rp, &n) == ERROR)529return (ERROR);530531if (rp.status != 0x00) {532fprintf(stdout, "Status: %s [%#02x]\n",533hci_status2str(rp.status), rp.status);534return (FAILED);535}536537rp.timeout = le16toh(rp.timeout);538fprintf(stdout, "Page timeout: %.2f msec [%d slots]\n",539rp.timeout * 0.625, rp.timeout);540541return (OK);542} /* hci_read_page_timeoout */543544/* Send Write_Page_Timeout command to the unit */545static int546hci_write_page_timeout(int s, int argc, char **argv)547{548ng_hci_write_page_timo_cp cp;549ng_hci_write_page_timo_rp rp;550int n;551552/* parse command parameters */553switch (argc) {554case 1:555if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xffff)556return (USAGE);557558cp.timeout = (uint16_t) n;559cp.timeout = htole16(cp.timeout);560break;561562default:563return (USAGE);564}565566/* send command */567n = sizeof(rp);568if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,569NG_HCI_OCF_WRITE_PAGE_TIMO),570(char const *) &cp, sizeof(cp),571(char *) &rp, &n) == ERROR)572return (ERROR);573574if (rp.status != 0x00) {575fprintf(stdout, "Status: %s [%#02x]\n",576hci_status2str(rp.status), rp.status);577return (FAILED);578}579580return (OK);581} /* hci_write_page_timeout */582583/* Send Read_Scan_Enable command to the unit */584static int585hci_read_scan_enable(int s, int argc, char **argv)586{587ng_hci_read_scan_enable_rp rp;588int n;589590n = sizeof(rp);591if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,592NG_HCI_OCF_READ_SCAN_ENABLE),593(char *) &rp, &n) == ERROR)594return (ERROR);595596if (rp.status != 0x00) {597fprintf(stdout, "Status: %s [%#02x]\n",598hci_status2str(rp.status), rp.status);599return (FAILED);600}601602fprintf(stdout, "Scan enable: %s [%#02x]\n",603hci_scan2str(rp.scan_enable), rp.scan_enable);604605return (OK);606} /* hci_read_scan_enable */607608/* Send Write_Scan_Enable command to the unit */609static int610hci_write_scan_enable(int s, int argc, char **argv)611{612ng_hci_write_scan_enable_cp cp;613ng_hci_write_scan_enable_rp rp;614int n;615616/* parse command parameters */617switch (argc) {618case 1:619if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3)620return (USAGE);621622cp.scan_enable = (uint8_t) n;623break;624625default:626return (USAGE);627}628629n = sizeof(rp);630if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,631NG_HCI_OCF_WRITE_SCAN_ENABLE),632(char const *) &cp, sizeof(cp),633(char *) &rp, &n) == ERROR)634return (ERROR);635636if (rp.status != 0x00) {637fprintf(stdout, "Status: %s [%#02x]\n",638hci_status2str(rp.status), rp.status);639return (FAILED);640}641642return (OK);643} /* hci_write_scan_enable */644645/* Send Read_Page_Scan_Activity command to the unit */646static int647hci_read_page_scan_activity(int s, int argc, char **argv)648{649ng_hci_read_page_scan_activity_rp rp;650int n;651652n = sizeof(rp);653if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,654NG_HCI_OCF_READ_PAGE_SCAN_ACTIVITY),655(char *) &rp, &n) == ERROR)656return (ERROR);657658if (rp.status != 0x00) {659fprintf(stdout, "Status: %s [%#02x]\n",660hci_status2str(rp.status), rp.status);661return (FAILED);662}663664rp.page_scan_interval = le16toh(rp.page_scan_interval);665rp.page_scan_window = le16toh(rp.page_scan_window);666667fprintf(stdout, "Page Scan Interval: %.2f msec [%d slots]\n",668rp.page_scan_interval * 0.625, rp.page_scan_interval);669fprintf(stdout, "Page Scan Window: %.2f msec [%d slots]\n",670rp.page_scan_window * 0.625, rp.page_scan_window);671672return (OK);673} /* hci_read_page_scan_activity */674675/* Send Write_Page_Scan_Activity command to the unit */676static int677hci_write_page_scan_activity(int s, int argc, char **argv)678{679ng_hci_write_page_scan_activity_cp cp;680ng_hci_write_page_scan_activity_rp rp;681int n;682683/* parse command parameters */684switch (argc) {685case 2:686/* page scan interval */687if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000)688return (USAGE);689690cp.page_scan_interval = (uint16_t) n;691692/* page scan window */693if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000)694return (USAGE);695696cp.page_scan_window = (uint16_t) n;697698if (cp.page_scan_window > cp.page_scan_interval)699return (USAGE);700701cp.page_scan_interval = htole16(cp.page_scan_interval);702cp.page_scan_window = htole16(cp.page_scan_window);703break;704705default:706return (USAGE);707}708709/* send command */710n = sizeof(rp);711if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,712NG_HCI_OCF_WRITE_PAGE_SCAN_ACTIVITY),713(char const *) &cp, sizeof(cp),714(char *) &rp, &n) == ERROR)715return (ERROR);716717if (rp.status != 0x00) {718fprintf(stdout, "Status: %s [%#02x]\n",719hci_status2str(rp.status), rp.status);720return (FAILED);721}722723return (OK);724} /* hci_write_page_scan_activity */725726/* Send Read_Inquiry_Scan_Activity command to the unit */727static int728hci_read_inquiry_scan_activity(int s, int argc, char **argv)729{730ng_hci_read_inquiry_scan_activity_rp rp;731int n;732733n = sizeof(rp);734if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,735NG_HCI_OCF_READ_INQUIRY_SCAN_ACTIVITY),736(char *) &rp, &n) == ERROR)737return (ERROR);738739if (rp.status != 0x00) {740fprintf(stdout, "Status: %s [%#02x]\n",741hci_status2str(rp.status), rp.status);742return (FAILED);743}744745rp.inquiry_scan_interval = le16toh(rp.inquiry_scan_interval);746rp.inquiry_scan_window = le16toh(rp.inquiry_scan_window);747748fprintf(stdout, "Inquiry Scan Interval: %.2f msec [%d slots]\n",749rp.inquiry_scan_interval * 0.625, rp.inquiry_scan_interval);750fprintf(stdout, "Inquiry Scan Window: %.2f msec [%d slots]\n",751rp.inquiry_scan_window * 0.625, rp.inquiry_scan_interval);752753return (OK);754} /* hci_read_inquiry_scan_activity */755756/* Send Write_Inquiry_Scan_Activity command to the unit */757static int758hci_write_inquiry_scan_activity(int s, int argc, char **argv)759{760ng_hci_write_inquiry_scan_activity_cp cp;761ng_hci_write_inquiry_scan_activity_rp rp;762int n;763764/* parse command parameters */765switch (argc) {766case 2:767/* inquiry scan interval */768if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000)769return (USAGE);770771cp.inquiry_scan_interval = (uint16_t) n;772773/* inquiry scan window */774if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000)775return (USAGE);776777cp.inquiry_scan_window = (uint16_t) n;778779if (cp.inquiry_scan_window > cp.inquiry_scan_interval)780return (USAGE);781782cp.inquiry_scan_interval =783htole16(cp.inquiry_scan_interval);784cp.inquiry_scan_window = htole16(cp.inquiry_scan_window);785break;786787default:788return (USAGE);789}790791/* send command */792n = sizeof(rp);793if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,794NG_HCI_OCF_WRITE_INQUIRY_SCAN_ACTIVITY),795(char const *) &cp, sizeof(cp),796(char *) &rp, &n) == ERROR)797return (ERROR);798799if (rp.status != 0x00) {800fprintf(stdout, "Status: %s [%#02x]\n",801hci_status2str(rp.status), rp.status);802return (FAILED);803}804805return (OK);806} /* hci_write_inquiry_scan_activity */807808/* Send Read_Authentication_Enable command to the unit */809static int810hci_read_authentication_enable(int s, int argc, char **argv)811{812ng_hci_read_auth_enable_rp rp;813int n;814815n = sizeof(rp);816if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,817NG_HCI_OCF_READ_AUTH_ENABLE),818(char *) &rp, &n) == ERROR)819return (ERROR);820821if (rp.status != 0x00) {822fprintf(stdout, "Status: %s [%#02x]\n",823hci_status2str(rp.status), rp.status);824return (FAILED);825}826827fprintf(stdout, "Authentication Enable: %s [%d]\n",828rp.auth_enable? "Enabled" : "Disabled", rp.auth_enable);829830return (OK);831} /* hci_read_authentication_enable */832833/* Send Write_Authentication_Enable command to the unit */834static int835hci_write_authentication_enable(int s, int argc, char **argv)836{837ng_hci_write_auth_enable_cp cp;838ng_hci_write_auth_enable_rp rp;839int n;840841/* parse command parameters */842switch (argc) {843case 1:844if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)845return (USAGE);846847cp.auth_enable = (uint8_t) n;848break;849850default:851return (USAGE);852}853854/* send command */855n = sizeof(rp);856if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,857NG_HCI_OCF_WRITE_AUTH_ENABLE),858(char const *) &cp, sizeof(cp),859(char *) &rp, &n) == ERROR)860return (ERROR);861862if (rp.status != 0x00) {863fprintf(stdout, "Status: %s [%#02x]\n",864hci_status2str(rp.status), rp.status);865return (FAILED);866}867868return (OK);869} /* hci_write_authentication_enable */870871/* Send Read_Encryption_Mode command to the unit */872static int873hci_read_encryption_mode(int s, int argc, char **argv)874{875ng_hci_read_encryption_mode_rp rp;876int n;877878n = sizeof(rp);879if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,880NG_HCI_OCF_READ_ENCRYPTION_MODE),881(char *) &rp, &n) == ERROR)882return (ERROR);883884if (rp.status != 0x00) {885fprintf(stdout, "Status: %s [%#02x]\n",886hci_status2str(rp.status), rp.status);887return (FAILED);888}889890fprintf(stdout, "Encryption mode: %s [%#02x]\n",891hci_encrypt2str(rp.encryption_mode, 0), rp.encryption_mode);892893return (OK);894} /* hci_read_encryption_mode */895896/* Send Write_Encryption_Mode command to the unit */897static int898hci_write_encryption_mode(int s, int argc, char **argv)899{900ng_hci_write_encryption_mode_cp cp;901ng_hci_write_encryption_mode_rp rp;902int n;903904/* parse command parameters */905switch (argc) {906case 1:907if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2)908return (USAGE);909910cp.encryption_mode = (uint8_t) n;911break;912913default:914return (USAGE);915}916917/* send command */918n = sizeof(rp);919if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,920NG_HCI_OCF_WRITE_ENCRYPTION_MODE),921(char const *) &cp, sizeof(cp),922(char *) &rp, &n) == ERROR)923return (ERROR);924925if (rp.status != 0x00) {926fprintf(stdout, "Status: %s [%#02x]\n",927hci_status2str(rp.status), rp.status);928return (FAILED);929}930931return (OK);932} /* hci_write_encryption_mode */933934/* Send Read_Class_Of_Device command to the unit */935static int936hci_read_class_of_device(int s, int argc, char **argv)937{938ng_hci_read_unit_class_rp rp;939int n;940941n = sizeof(rp);942if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,943NG_HCI_OCF_READ_UNIT_CLASS),944(char *) &rp, &n) == ERROR)945return (ERROR);946947if (rp.status != 0x00) {948fprintf(stdout, "Status: %s [%#02x]\n",949hci_status2str(rp.status), rp.status);950return (FAILED);951}952953fprintf(stdout, "Class: %02x:%02x:%02x\n",954rp.uclass[2], rp.uclass[1], rp.uclass[0]);955956return (0);957} /* hci_read_class_of_device */958959/* Send Write_Class_Of_Device command to the unit */960static int961hci_write_class_of_device(int s, int argc, char **argv)962{963ng_hci_write_unit_class_cp cp;964ng_hci_write_unit_class_rp rp;965int n0, n1, n2;966967/* parse command parameters */968switch (argc) {969case 1:970if (sscanf(argv[0], "%x:%x:%x", &n2, &n1, &n0) != 3)971return (USAGE);972973cp.uclass[0] = (n0 & 0xff);974cp.uclass[1] = (n1 & 0xff);975cp.uclass[2] = (n2 & 0xff);976break;977978default:979return (USAGE);980}981982/* send command */983n0 = sizeof(rp);984if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,985NG_HCI_OCF_WRITE_UNIT_CLASS),986(char const *) &cp, sizeof(cp),987(char *) &rp, &n0) == ERROR)988return (ERROR);989990if (rp.status != 0x00) {991fprintf(stdout, "Status: %s [%#02x]\n",992hci_status2str(rp.status), rp.status);993return (FAILED);994}995996return (OK);997} /* hci_write_class_of_device */998999/* Send Read_Voice_Settings command to the unit */1000static int1001hci_read_voice_settings(int s, int argc, char **argv)1002{1003ng_hci_read_voice_settings_rp rp;1004int n,1005input_coding,1006input_data_format,1007input_sample_size;10081009n = sizeof(rp);1010if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1011NG_HCI_OCF_READ_VOICE_SETTINGS),1012(char *) &rp, &n) == ERROR)1013return (ERROR);10141015if (rp.status != 0x00) {1016fprintf(stdout, "Status: %s [%#02x]\n",1017hci_status2str(rp.status), rp.status);1018return (FAILED);1019}10201021rp.settings = le16toh(rp.settings);10221023input_coding = (rp.settings & 0x0300) >> 8;1024input_data_format = (rp.settings & 0x00c0) >> 6;1025input_sample_size = (rp.settings & 0x0020) >> 5;10261027fprintf(stdout, "Voice settings: %#04x\n", rp.settings);1028fprintf(stdout, "Input coding: %s [%d]\n",1029hci_coding2str(input_coding), input_coding);1030fprintf(stdout, "Input data format: %s [%d]\n",1031hci_vdata2str(input_data_format), input_data_format);10321033if (input_coding == 0x00) /* Only for Linear PCM */1034fprintf(stdout, "Input sample size: %d bit [%d]\n",1035input_sample_size? 16 : 8, input_sample_size);10361037return (OK);1038} /* hci_read_voice_settings */10391040/* Send Write_Voice_Settings command to the unit */1041static int1042hci_write_voice_settings(int s, int argc, char **argv)1043{1044ng_hci_write_voice_settings_cp cp;1045ng_hci_write_voice_settings_rp rp;1046int n;10471048/* parse command parameters */1049switch (argc) {1050case 1:1051if (sscanf(argv[0], "%x", &n) != 1)1052return (USAGE);10531054cp.settings = (uint16_t) n;1055cp.settings = htole16(cp.settings);1056break;10571058default:1059return (USAGE);1060}10611062/* send command */1063n = sizeof(rp);1064if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1065NG_HCI_OCF_WRITE_VOICE_SETTINGS),1066(char const *) &cp, sizeof(cp),1067(char *) &rp, &n) == ERROR)1068return (ERROR);10691070if (rp.status != 0x00) {1071fprintf(stdout, "Status: %s [%#02x]\n",1072hci_status2str(rp.status), rp.status);1073return (FAILED);1074}10751076return (OK);1077} /* hci_write_voice_settings */10781079/* Send Read_Number_Broadcast_Restransmissions */1080static int1081hci_read_number_broadcast_retransmissions(int s, int argc, char **argv)1082{1083ng_hci_read_num_broadcast_retrans_rp rp;1084int n;10851086n = sizeof(rp);1087if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1088NG_HCI_OCF_READ_NUM_BROADCAST_RETRANS),1089(char *) &rp, &n) == ERROR)1090return (ERROR);10911092if (rp.status != 0x00) {1093fprintf(stdout, "Status: %s [%#02x]\n",1094hci_status2str(rp.status), rp.status);1095return (FAILED);1096}10971098fprintf(stdout, "Number of broadcast retransmissions: %d\n",1099rp.counter);11001101return (OK);1102} /* hci_read_number_broadcast_retransmissions */11031104/* Send Write_Number_Broadcast_Restransmissions */1105static int1106hci_write_number_broadcast_retransmissions(int s, int argc, char **argv)1107{1108ng_hci_write_num_broadcast_retrans_cp cp;1109ng_hci_write_num_broadcast_retrans_rp rp;1110int n;11111112/* parse command parameters */1113switch (argc) {1114case 1:1115if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0xff)1116return (USAGE);11171118cp.counter = (uint8_t) n;1119break;11201121default:1122return (USAGE);1123}11241125/* send command */1126n = sizeof(rp);1127if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1128NG_HCI_OCF_WRITE_NUM_BROADCAST_RETRANS),1129(char const *) &cp, sizeof(cp),1130(char *) &rp, &n) == ERROR)1131return (ERROR);11321133if (rp.status != 0x00) {1134fprintf(stdout, "Status: %s [%#02x]\n",1135hci_status2str(rp.status), rp.status);1136return (FAILED);1137}11381139return (OK);1140} /* hci_write_number_broadcast_retransmissions */11411142/* Send Read_Hold_Mode_Activity command to the unit */1143static int1144hci_read_hold_mode_activity(int s, int argc, char **argv)1145{1146ng_hci_read_hold_mode_activity_rp rp;1147int n;1148char buffer[1024];11491150n = sizeof(rp);1151if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1152NG_HCI_OCF_READ_HOLD_MODE_ACTIVITY),1153(char *) &rp, &n) == ERROR)1154return (ERROR);11551156if (rp.status != 0x00) {1157fprintf(stdout, "Status: %s [%#02x]\n",1158hci_status2str(rp.status), rp.status);1159return (FAILED);1160}11611162fprintf(stdout, "Hold Mode Activities: %#02x\n", rp.hold_mode_activity);1163if (rp.hold_mode_activity == 0)1164fprintf(stdout, "Maintain current Power State");1165else1166fprintf(stdout, "%s", hci_hmode2str(rp.hold_mode_activity,1167buffer, sizeof(buffer)));11681169fprintf(stdout, "\n");11701171return (OK);1172} /* hci_read_hold_mode_activity */11731174/* Send Write_Hold_Mode_Activity command to the unit */1175static int1176hci_write_hold_mode_activity(int s, int argc, char **argv)1177{1178ng_hci_write_hold_mode_activity_cp cp;1179ng_hci_write_hold_mode_activity_rp rp;1180int n;11811182/* parse command parameters */1183switch (argc) {1184case 1:1185if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 4)1186return (USAGE);11871188cp.hold_mode_activity = (uint8_t) n;1189break;11901191default:1192return (USAGE);1193}11941195/* send command */1196n = sizeof(rp);1197if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1198NG_HCI_OCF_WRITE_HOLD_MODE_ACTIVITY),1199(char const *) &cp, sizeof(cp),1200(char *) &rp, &n) == ERROR)1201return (ERROR);12021203if (rp.status != 0x00) {1204fprintf(stdout, "Status: %s [%#02x]\n",1205hci_status2str(rp.status), rp.status);1206return (FAILED);1207}12081209return (OK);1210} /* hci_write_hold_mode_activity */12111212/* Send Read_SCO_Flow_Control_Enable command to the unit */1213static int1214hci_read_sco_flow_control_enable(int s, int argc, char **argv)1215{1216ng_hci_read_sco_flow_control_rp rp;1217int n;12181219n = sizeof(rp);1220if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1221NG_HCI_OCF_READ_SCO_FLOW_CONTROL),1222(char *) &rp, &n) == ERROR)1223return (ERROR);12241225if (rp.status != 0x00) {1226fprintf(stdout, "Status: %s [%#02x]\n",1227hci_status2str(rp.status), rp.status);1228return (FAILED);1229}12301231fprintf(stdout, "SCO flow control %s [%d]\n",1232rp.flow_control? "enabled" : "disabled", rp.flow_control);12331234return (OK);1235} /* hci_read_sco_flow_control_enable */12361237/* Send Write_SCO_Flow_Control_Enable command to the unit */1238static int1239hci_write_sco_flow_control_enable(int s, int argc, char **argv)1240{1241ng_hci_write_sco_flow_control_cp cp;1242ng_hci_write_sco_flow_control_rp rp;1243int n;12441245/* parse command parameters */1246switch (argc) {1247case 1:1248if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)1249return (USAGE);12501251cp.flow_control = (uint8_t) n;1252break;12531254default:1255return (USAGE);1256}12571258/* send command */1259n = sizeof(rp);1260if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1261NG_HCI_OCF_WRITE_SCO_FLOW_CONTROL),1262(char const *) &cp, sizeof(cp),1263(char *) &rp, &n) == ERROR)1264return (ERROR);12651266if (rp.status != 0x00) {1267fprintf(stdout, "Status: %s [%#02x]\n",1268hci_status2str(rp.status), rp.status);1269return (FAILED);1270}12711272return (OK);1273} /* hci_write_sco_flow_control_enable */12741275/* Send Read_Link_Supervision_Timeout command to the unit */1276static int1277hci_read_link_supervision_timeout(int s, int argc, char **argv)1278{1279ng_hci_read_link_supervision_timo_cp cp;1280ng_hci_read_link_supervision_timo_rp rp;1281int n;12821283switch (argc) {1284case 1:1285/* connection handle */1286if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)1287return (USAGE);12881289cp.con_handle = (uint16_t) (n & 0x0fff);1290cp.con_handle = htole16(cp.con_handle);1291break;12921293default:1294return (USAGE);1295}12961297/* send command */1298n = sizeof(rp);1299if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1300NG_HCI_OCF_READ_LINK_SUPERVISION_TIMO),1301(char const *) &cp, sizeof(cp),1302(char *) &rp, &n) == ERROR)1303return (ERROR);13041305if (rp.status != 0x00) {1306fprintf(stdout, "Status: %s [%#02x]\n",1307hci_status2str(rp.status), rp.status);1308return (FAILED);1309}13101311rp.timeout = le16toh(rp.timeout);13121313fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));1314fprintf(stdout, "Link supervision timeout: %.2f msec [%d slots]\n",1315rp.timeout * 0.625, rp.timeout);13161317return (OK);1318} /* hci_read_link_supervision_timeout */13191320/* Send Write_Link_Supervision_Timeout command to the unit */1321static int1322hci_write_link_supervision_timeout(int s, int argc, char **argv)1323{1324ng_hci_write_link_supervision_timo_cp cp;1325ng_hci_write_link_supervision_timo_rp rp;1326int n;13271328switch (argc) {1329case 2:1330/* connection handle */1331if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)1332return (USAGE);13331334cp.con_handle = (uint16_t) (n & 0x0fff);1335cp.con_handle = htole16(cp.con_handle);13361337/* link supervision timeout */1338if (sscanf(argv[1], "%d", &n) != 1 || n < 0 || n > 0xffff)1339return (USAGE);13401341cp.timeout = (uint16_t) (n & 0x0fff);1342cp.timeout = htole16(cp.timeout);1343break;13441345default:1346return (USAGE);1347}13481349/* send command */1350n = sizeof(rp);1351if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1352NG_HCI_OCF_WRITE_LINK_SUPERVISION_TIMO),1353(char const *) &cp, sizeof(cp),1354(char *) &rp, &n) == ERROR)1355return (ERROR);13561357if (rp.status != 0x00) {1358fprintf(stdout, "Status: %s [%#02x]\n",1359hci_status2str(rp.status), rp.status);1360return (FAILED);1361}13621363return (OK);1364} /* hci_write_link_supervision_timeout */13651366/* Send Read_Page_Scan_Period_Mode command to the unit */1367static int1368hci_read_page_scan_period_mode(int s, int argc, char **argv)1369{1370ng_hci_read_page_scan_period_rp rp;1371int n;13721373n = sizeof(rp);1374if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1375NG_HCI_OCF_READ_PAGE_SCAN_PERIOD),1376(char *) &rp, &n) == ERROR)1377return (ERROR);13781379if (rp.status != 0x00) {1380fprintf(stdout, "Status: %s [%#02x]\n",1381hci_status2str(rp.status), rp.status);1382return (FAILED);1383}13841385fprintf(stdout, "Page scan period mode: %#02x\n",1386rp.page_scan_period_mode);13871388return (OK);1389} /* hci_read_page_scan_period_mode */13901391/* Send Write_Page_Scan_Period_Mode command to the unit */1392static int1393hci_write_page_scan_period_mode(int s, int argc, char **argv)1394{1395ng_hci_write_page_scan_period_cp cp;1396ng_hci_write_page_scan_period_rp rp;1397int n;13981399/* parse command arguments */1400switch (argc) {1401case 1:1402if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2)1403return (USAGE);14041405cp.page_scan_period_mode = (n & 0xff);1406break;14071408default:1409return (USAGE);1410}14111412/* send command */1413n = sizeof(rp);1414if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1415NG_HCI_OCF_WRITE_PAGE_SCAN_PERIOD),1416(char const *) &cp, sizeof(cp),1417(char *) &rp, &n) == ERROR)1418return (ERROR);14191420if (rp.status != 0x00) {1421fprintf(stdout, "Status: %s [%#02x]\n",1422hci_status2str(rp.status), rp.status);1423return (FAILED);1424}14251426return (OK);1427} /* hci_write_page_scan_period_mode */14281429/* Send Read_Page_Scan_Mode command to the unit */1430static int1431hci_read_page_scan_mode(int s, int argc, char **argv)1432{1433ng_hci_read_page_scan_rp rp;1434int n;14351436n = sizeof(rp);1437if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1438NG_HCI_OCF_READ_PAGE_SCAN),1439(char *) &rp, &n) == ERROR)1440return (ERROR);14411442if (rp.status != 0x00) {1443fprintf(stdout, "Status: %s [%#02x]\n",1444hci_status2str(rp.status), rp.status);1445return (FAILED);1446}14471448fprintf(stdout, "Page scan mode: %#02x\n", rp.page_scan_mode);14491450return (OK);1451} /* hci_read_page_scan_mode */14521453/* Send Write_Page_Scan_Mode command to the unit */1454static int1455hci_write_page_scan_mode(int s, int argc, char **argv)1456{1457ng_hci_write_page_scan_cp cp;1458ng_hci_write_page_scan_rp rp;1459int n;14601461/* parse command arguments */1462switch (argc) {1463case 1:1464if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3)1465return (USAGE);14661467cp.page_scan_mode = (n & 0xff);1468break;14691470default:1471return (USAGE);1472}14731474/* send command */1475n = sizeof(rp);1476if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1477NG_HCI_OCF_WRITE_PAGE_SCAN),1478(char const *) &cp, sizeof(cp),1479(char *) &rp, &n) == ERROR)1480return (ERROR);14811482if (rp.status != 0x00) {1483fprintf(stdout, "Status: %s [%#02x]\n",1484hci_status2str(rp.status), rp.status);1485return (FAILED);1486}14871488return (OK);1489} /* hci_write_page_scan_mode */14901491static int1492hci_read_le_host_support(int s, int argc, char **argv)1493{1494ng_hci_read_le_host_supported_rp rp;1495int n;1496n = sizeof(rp);1497if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1498NG_HCI_OCF_READ_LE_HOST_SUPPORTED),1499(char *) &rp, &n) == ERROR)1500return (ERROR);15011502if (rp.status != 0x00) {1503fprintf(stdout, "Status: %s [%#02x]\n",1504hci_status2str(rp.status), rp.status);1505return (FAILED);1506}15071508fprintf(stdout, "LE Host support: %#02x\n", rp.le_supported_host);1509fprintf(stdout, "Simultaneous LE Host : %#02x\n", rp.simultaneous_le_host);15101511return (OK);15121513}1514static int1515hci_write_le_host_support(int s, int argc, char **argv)1516{1517ng_hci_write_le_host_supported_cp cp;1518ng_hci_write_le_host_supported_rp rp;15191520int n;15211522cp.le_supported_host = 0;1523cp.simultaneous_le_host = 0;1524switch (argc) {1525case 2:1526if (sscanf(argv[1], "%d", &n) != 1 || (n != 0 && n != 1)){1527printf("-ARGC2: %d\n", n);1528return (USAGE);1529}1530cp.simultaneous_le_host = (n &1);15311532case 1:1533if (sscanf(argv[0], "%d", &n) != 1 || (n != 0 && n != 1)){1534printf("+ARGC1: %d\n", n);1535return (USAGE);1536}15371538cp.le_supported_host = (n &1);1539break;15401541default:1542return (USAGE);1543}154415451546/* send command */1547n = sizeof(rp);1548if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,1549NG_HCI_OCF_WRITE_LE_HOST_SUPPORTED),1550(char const *) &cp, sizeof(cp),1551(char *) &rp, &n) == ERROR)1552return (ERROR);15531554if (rp.status != 0x00) {1555fprintf(stdout, "Status: %s [%#02x]\n",1556hci_status2str(rp.status), rp.status);1557return (FAILED);1558}15591560return (OK);1561}15621563struct hci_command host_controller_baseband_commands[] = {1564{1565"reset",1566"\nThe Reset command will reset the Host Controller and the Link Manager.\n" \1567"After the reset is completed, the current operational state will be lost,\n" \1568"the Bluetooth unit will enter standby mode and the Host Controller will\n" \1569"automatically revert to the default values for the parameters for which\n" \1570"default values are defined in the specification.",1571&hci_reset1572},1573{1574"read_pin_type",1575"\nThe Read_PIN_Type command is used for the Host to read whether the Link\n" \1576"Manager assumes that the Host supports variable PIN codes only a fixed PIN\n" \1577"code.",1578&hci_read_pin_type1579},1580{1581"write_pin_type <pin_type>",1582"\nThe Write_PIN_Type command is used for the Host to write to the Host\n" \1583"Controller whether the Host supports variable PIN codes or only a fixed PIN\n"\1584"code.\n\n" \1585"\t<pin_type> - dd; 0 - Variable; 1 - Fixed",1586&hci_write_pin_type1587},1588{1589"read_stored_link_key [<BD_ADDR>]",1590"\nThe Read_Stored_Link_Key command provides the ability to read one or\n" \1591"more link keys stored in the Bluetooth Host Controller. The Bluetooth Host\n" \1592"Controller can store a limited number of link keys for other Bluetooth\n" \1593"devices.\n\n" \1594"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name",1595&hci_read_stored_link_key1596},1597{1598"write_stored_link_key <BD_ADDR> <key>",1599"\nThe Write_Stored_Link_Key command provides the ability to write one\n" \1600"or more link keys to be stored in the Bluetooth Host Controller. The\n" \1601"Bluetooth Host Controller can store a limited number of link keys for other\n"\1602"Bluetooth devices. If no additional space is available in the Bluetooth\n"\1603"Host Controller then no additional link keys will be stored.\n\n" \1604"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name\n" \1605"\t<key> - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx up to 16 bytes link key",1606&hci_write_stored_link_key1607},1608{1609"delete_stored_link_key [<BD_ADDR>]",1610"\nThe Delete_Stored_Link_Key command provides the ability to remove one\n" \1611"or more of the link keys stored in the Bluetooth Host Controller. The\n" \1612"Bluetooth Host Controller can store a limited number of link keys for other\n"\1613"Bluetooth devices.\n\n" \1614"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name",1615&hci_delete_stored_link_key1616},1617{1618"change_local_name <name>",1619"\nThe Change_Local_Name command provides the ability to modify the user\n" \1620"friendly name for the Bluetooth unit.\n\n" \1621"\t<name> - string",1622&hci_change_local_name1623},1624{1625"read_local_name",1626"\nThe Read_Local_Name command provides the ability to read the\n" \1627"stored user-friendly name for the Bluetooth unit.",1628&hci_read_local_name1629},1630{1631"read_connection_accept_timeout",1632"\nThis command will read the value for the Connection_Accept_Timeout\n" \1633"configuration parameter. The Connection_Accept_Timeout configuration\n" \1634"parameter allows the Bluetooth hardware to automatically deny a\n" \1635"connection request after a specified time period has occurred and\n" \1636"the new connection is not accepted. Connection Accept Timeout\n" \1637"measured in Number of Baseband slots.",1638&hci_read_connection_accept_timeout1639},1640{1641"write_connection_accept_timeout <timeout>",1642"\nThis command will write the value for the Connection_Accept_Timeout\n" \1643"configuration parameter.\n\n" \1644"\t<timeout> - dddd; measured in number of baseband slots.",1645&hci_write_connection_accept_timeout1646},1647{1648"read_page_timeout",1649"\nThis command will read the value for the Page_Timeout configuration\n" \1650"parameter. The Page_Timeout configuration parameter defines the\n" \1651"maximum time the local Link Manager will wait for a baseband page\n" \1652"response from the remote unit at a locally initiated connection\n" \1653"attempt. Page Timeout measured in Number of Baseband slots.",1654&hci_read_page_timeout1655},1656{1657"write_page_timeout <timeout>",1658"\nThis command will write the value for the Page_Timeout configuration\n" \1659"parameter.\n\n" \1660"\t<timeout> - dddd; measured in number of baseband slots.",1661&hci_write_page_timeout1662},1663{1664"read_scan_enable",1665"\nThis command will read the value for the Scan_Enable parameter. The\n" \1666"Scan_Enable parameter controls whether or not the Bluetooth uint\n" \1667"will periodically scan for page attempts and/or inquiry requests\n" \1668"from other Bluetooth unit.\n\n" \1669"\t0x00 - No Scans enabled.\n" \1670"\t0x01 - Inquiry Scan enabled. Page Scan disabled.\n" \1671"\t0x02 - Inquiry Scan disabled. Page Scan enabled.\n" \1672"\t0x03 - Inquiry Scan enabled. Page Scan enabled.",1673&hci_read_scan_enable1674},1675{1676"write_scan_enable <scan_enable>",1677"\nThis command will write the value for the Scan_Enable parameter.\n" \1678"The Scan_Enable parameter controls whether or not the Bluetooth\n" \1679"unit will periodically scan for page attempts and/or inquiry\n" \1680"requests from other Bluetooth unit.\n\n" \1681"\t<scan_enable> - dd;\n" \1682"\t0 - No Scans enabled.\n" \1683"\t1 - Inquiry Scan enabled. Page Scan disabled.\n" \1684"\t2 - Inquiry Scan disabled. Page Scan enabled.\n" \1685"\t3 - Inquiry Scan enabled. Page Scan enabled.",1686&hci_write_scan_enable1687},1688{1689"read_page_scan_activity",1690"\nThis command will read the value for Page_Scan_Activity configuration\n" \1691"parameters. The Page_Scan_Interval configuration parameter defines the\n" \1692"amount of time between consecutive page scans. This time interval is \n" \1693"defined from when the Host Controller started its last page scan until\n" \1694"it begins the next page scan. The Page_Scan_Window configuration parameter\n" \1695"defines the amount of time for the duration of the page scan. The\n" \1696"Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.",1697&hci_read_page_scan_activity1698},1699{1700"write_page_scan_activity interval(dddd) window(dddd)",1701"\nThis command will write the value for Page_Scan_Activity configuration\n" \1702"parameter. The Page_Scan_Interval configuration parameter defines the\n" \1703"amount of time between consecutive page scans. This is defined as the time\n" \1704"interval from when the Host Controller started its last page scan until it\n" \1705"begins the next page scan. The Page_Scan_Window configuration parameter\n" \1706"defines the amount of time for the duration of the page scan. \n" \1707"The Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.\n\n" \1708"\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \1709"\t<window> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec",1710&hci_write_page_scan_activity1711},1712{1713"read_inquiry_scan_activity",1714"\nThis command will read the value for Inquiry_Scan_Activity configuration\n" \1715"parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \1716"amount of time between consecutive inquiry scans. This is defined as the\n" \1717"time interval from when the Host Controller started its last inquiry scan\n" \1718"until it begins the next inquiry scan.",1719&hci_read_inquiry_scan_activity1720},1721{1722"write_inquiry_scan_activity interval(dddd) window(dddd)",1723"\nThis command will write the value for Inquiry_Scan_Activity configuration\n"\1724"parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \1725"amount of time between consecutive inquiry scans. This is defined as the\n" \1726"time interval from when the Host Controller started its last inquiry scan\n" \1727"until it begins the next inquiry scan. The Inquiry_Scan_Window configuration\n" \1728"parameter defines the amount of time for the duration of the inquiry scan.\n" \1729"The Inquiry_Scan_Window can only be less than or equal to the Inquiry_Scan_Interval.\n\n" \1730"\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \1731"\t<window> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec",1732&hci_write_inquiry_scan_activity1733},1734{1735"read_authentication_enable",1736"\nThis command will read the value for the Authentication_Enable parameter.\n"\1737"The Authentication_Enable parameter controls if the local unit requires\n"\1738"to authenticate the remote unit at connection setup (between the\n" \1739"Create_Connection command or acceptance of an incoming ACL connection\n"\1740"and the corresponding Connection Complete event). At connection setup, only\n"\1741"the unit(s) with the Authentication_Enable parameter enabled will try to\n"\1742"authenticate the other unit.",1743&hci_read_authentication_enable1744},1745{1746"write_authentication_enable enable(0|1)",1747"\nThis command will write the value for the Authentication_Enable parameter.\n"\1748"The Authentication_Enable parameter controls if the local unit requires to\n"\1749"authenticate the remote unit at connection setup (between the\n" \1750"Create_Connection command or acceptance of an incoming ACL connection\n" \1751"and the corresponding Connection Complete event). At connection setup, only\n"\1752"the unit(s) with the Authentication_Enable parameter enabled will try to\n"\1753"authenticate the other unit.",1754&hci_write_authentication_enable1755},1756{1757"read_encryption_mode",1758"\nThis command will read the value for the Encryption_Mode parameter. The\n" \1759"Encryption_Mode parameter controls if the local unit requires encryption\n" \1760"to the remote unit at connection setup (between the Create_Connection\n" \1761"command or acceptance of an incoming ACL connection and the corresponding\n" \1762"Connection Complete event). At connection setup, only the unit(s) with\n" \1763"the Authentication_Enable parameter enabled and Encryption_Mode parameter\n" \1764"enabled will try to encrypt the connection to the other unit.\n\n" \1765"\t<encryption_mode>:\n" \1766"\t0x00 - Encryption disabled.\n" \1767"\t0x01 - Encryption only for point-to-point packets.\n" \1768"\t0x02 - Encryption for both point-to-point and broadcast packets.",1769&hci_read_encryption_mode1770},1771{1772"write_encryption_mode mode(0|1|2)",1773"\tThis command will write the value for the Encryption_Mode parameter.\n" \1774"The Encryption_Mode parameter controls if the local unit requires\n" \1775"encryption to the remote unit at connection setup (between the\n" \1776"Create_Connection command or acceptance of an incoming ACL connection\n" \1777"and the corresponding Connection Complete event). At connection setup,\n" \1778"only the unit(s) with the Authentication_Enable parameter enabled and\n" \1779"Encryption_Mode parameter enabled will try to encrypt the connection to\n" \1780"the other unit.\n\n" \1781"\t<encryption_mode> (dd)\n" \1782"\t0 - Encryption disabled.\n" \1783"\t1 - Encryption only for point-to-point packets.\n" \1784"\t2 - Encryption for both point-to-point and broadcast packets.",1785&hci_write_encryption_mode1786},1787{1788"read_class_of_device",1789"\nThis command will read the value for the Class_of_Device parameter.\n" \1790"The Class_of_Device parameter is used to indicate the capabilities of\n" \1791"the local unit to other units.",1792&hci_read_class_of_device1793},1794{1795"write_class_of_device class(xx:xx:xx)",1796"\nThis command will write the value for the Class_of_Device parameter.\n" \1797"The Class_of_Device parameter is used to indicate the capabilities of \n" \1798"the local unit to other units.\n\n" \1799"\t<class> (xx:xx:xx) - class of device",1800&hci_write_class_of_device1801},1802{1803"read_voice_settings",1804"\nThis command will read the values for the Voice_Setting parameter.\n" \1805"The Voice_Setting parameter controls all the various settings for voice\n" \1806"connections. These settings apply to all voice connections, and cannot be\n" \1807"set for individual voice connections. The Voice_Setting parameter controls\n" \1808"the configuration for voice connections: Input Coding, Air coding format,\n" \1809"input data format, Input sample size, and linear PCM parameter.",1810&hci_read_voice_settings1811},1812{1813"write_voice_settings settings(xxxx)",1814"\nThis command will write the values for the Voice_Setting parameter.\n" \1815"The Voice_Setting parameter controls all the various settings for voice\n" \1816"connections. These settings apply to all voice connections, and cannot be\n" \1817"set for individual voice connections. The Voice_Setting parameter controls\n" \1818"the configuration for voice connections: Input Coding, Air coding format,\n" \1819"input data format, Input sample size, and linear PCM parameter.\n\n" \1820"\t<voice_settings> (xxxx) - voice settings",1821&hci_write_voice_settings1822},1823{1824"read_number_broadcast_retransmissions",1825"\nThis command will read the unit's parameter value for the Number of\n" \1826"Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \1827"unreliable.",1828&hci_read_number_broadcast_retransmissions1829},1830{1831"write_number_broadcast_retransmissions count(dd)",1832"\nThis command will write the unit's parameter value for the Number of\n" \1833"Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \1834"unreliable.\n\n" \1835"\t<count> (dd) - number of broadcast retransimissions",1836&hci_write_number_broadcast_retransmissions1837},1838{1839"read_hold_mode_activity",1840"\nThis command will read the value for the Hold_Mode_Activity parameter.\n" \1841"The Hold_Mode_Activity value is used to determine what activities should\n" \1842"be suspended when the unit is in hold mode.",1843&hci_read_hold_mode_activity1844},1845{1846"write_hold_mode_activity settings(0|1|2|4)",1847"\nThis command will write the value for the Hold_Mode_Activity parameter.\n" \1848"The Hold_Mode_Activity value is used to determine what activities should\n" \1849"be suspended when the unit is in hold mode.\n\n" \1850"\t<settings> (dd) - bit mask:\n" \1851"\t0 - Maintain current Power State. Default\n" \1852"\t1 - Suspend Page Scan.\n" \1853"\t2 - Suspend Inquiry Scan.\n" \1854"\t4 - Suspend Periodic Inquiries.",1855&hci_write_hold_mode_activity1856},1857{1858"read_sco_flow_control_enable",1859"\nThe Read_SCO_Flow_Control_Enable command provides the ability to read\n" \1860"the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \1861"decide if the Host Controller will send Number Of Completed Packets events\n" \1862"for SCO Connection Handles. This setting allows the Host to enable and\n" \1863"disable SCO flow control.",1864&hci_read_sco_flow_control_enable1865},1866{1867"write_sco_flow_control_enable enable(0|1)",1868"\nThe Write_SCO_Flow_Control_Enable command provides the ability to write\n" \1869"the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \1870"decide if the Host Controller will send Number Of Completed Packets events\n" \1871"for SCO Connection Handles. This setting allows the Host to enable and\n" \1872"disable SCO flow control. The SCO_Flow_Control_Enable setting can only be\n" \1873"changed if no connections exist.",1874&hci_write_sco_flow_control_enable1875},1876{1877"read_link_supervision_timeout <connection_handle>",1878"\nThis command will read the value for the Link_Supervision_Timeout\n" \1879"parameter for the device. The Link_Supervision_Timeout parameter is used\n" \1880"by the master or slave Bluetooth device to monitor link loss. If, for any\n" \1881"reason, no Baseband packets are received from that Connection Handle for a\n" \1882"duration longer than the Link_Supervision_Timeout, the connection is\n"1883"disconnected.\n\n" \1884"\t<connection_handle> - dddd; connection handle\n",1885&hci_read_link_supervision_timeout1886},1887{1888"write_link_supervision_timeout <connection_handle> <timeout>",1889"\nThis command will write the value for the Link_Supervision_Timeout\n" \1890"parameter for the device. The Link_Supervision_Timeout parameter is used\n" \1891"by the master or slave Bluetooth device to monitor link loss. If, for any\n" \1892"reason, no Baseband packets are received from that connection handle for a\n" \1893"duration longer than the Link_Supervision_Timeout, the connection is\n" \1894"disconnected.\n\n" \1895"\t<connection_handle> - dddd; connection handle\n" \1896"\t<timeout> - dddd; timeout measured in number of baseband slots\n",1897&hci_write_link_supervision_timeout1898},1899{1900"read_page_scan_period_mode",1901"\nThis command is used to read the mandatory Page_Scan_Period_Mode of the\n" \1902"local Bluetooth device. Every time an inquiry response message is sent, the\n"\1903"Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\1904"is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \1905"expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \1906"following page scans.",1907&hci_read_page_scan_period_mode1908},1909{1910"write_page_scan_period_mode <page_scan_period_mode>",1911"\nThis command is used to write the mandatory Page_Scan_Period_Mode of the\n" \1912"local Bluetooth device. Every time an inquiry response message is sent, the\n"\1913"Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\1914"is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \1915"expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \1916"following page scans.\n\n" \1917"\t<page_scan_period_mode> - dd; page scan period mode:\n" \1918"\t0x00 - P0 (Default)\n" \1919"\t0x01 - P1\n" \1920"\t0x02 - P2",1921&hci_write_page_scan_period_mode1922},1923{1924"read_page_scan_mode",1925"\nThis command is used to read the default page scan mode of the local\n" \1926"Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\1927"that is used for the default page scan. Currently one mandatory page scan\n"\1928"mode and three optional page scan modes are defined. Following an inquiry\n" \1929"response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \1930"mandatory page scan mode must be applied.",1931&hci_read_page_scan_mode1932},1933{1934"write_page_scan_mode <page_scan_mode>",1935"\nThis command is used to write the default page scan mode of the local\n" \1936"Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\1937"that is used for the default page scan. Currently, one mandatory page scan\n"\1938"mode and three optional page scan modes are defined. Following an inquiry\n"\1939"response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \1940"mandatory page scan mode must be applied.\n\n" \1941"\t<page_scan_mode> - dd; page scan mode:\n" \1942"\t0x00 - Mandatory Page Scan Mode (Default)\n" \1943"\t0x01 - Optional Page Scan Mode I\n" \1944"\t0x02 - Optional Page Scan Mode II\n" \1945"\t0x03 - Optional Page Scan Mode III",1946&hci_write_page_scan_mode1947},1948{1949"read_le_host_support", \1950"Read if this host is in LE supported mode and simultaneous LE supported mode",1951&hci_read_le_host_support,1952},1953{1954"write_le_host_support", \1955"write_le_host_support le_host[0|1] simultaneous_le[0|1]",1956&hci_write_le_host_support,1957},19581959{ NULL, }1960};1961196219631964