Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/next/external/cache/sources/hcitools/lib/hci.c
Views: 3959
/*1*2* BlueZ - Bluetooth protocol stack for Linux3*4* Copyright (C) 2000-2001 Qualcomm Incorporated5* Copyright (C) 2002-2003 Maxim Krasnyansky <[email protected]>6* Copyright (C) 2002-2010 Marcel Holtmann <[email protected]>7*8*9* This program is free software; you can redistribute it and/or modify10* it under the terms of the GNU General Public License as published by11* the Free Software Foundation; either version 2 of the License, or12* (at your option) any later version.13*14* This program is distributed in the hope that it will be useful,15* but WITHOUT ANY WARRANTY; without even the implied warranty of16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the17* GNU General Public License for more details.18*19* You should have received a copy of the GNU General Public License20* along with this program; if not, write to the Free Software21* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA22*23*/2425#ifdef HAVE_CONFIG_H26#include <config.h>27#endif2829#include <stdio.h>30#include <errno.h>31#include <fcntl.h>32#include <unistd.h>33#include <stdlib.h>34#include <string.h>3536#include <sys/param.h>37#include <sys/uio.h>38#include <sys/poll.h>39#include <sys/types.h>40#include <sys/ioctl.h>41#include <sys/socket.h>4243#include "bluetooth.h"44#include "hci.h"45#include "hci_lib.h"4647#ifndef MIN48#define MIN(x, y) ((x) < (y) ? (x) : (y))49#endif5051typedef struct {52char *str;53unsigned int val;54} hci_map;5556static char *hci_bit2str(hci_map *m, unsigned int val)57{58char *str = malloc(120);59char *ptr = str;6061if (!str)62return NULL;6364*ptr = 0;65while (m->str) {66if ((unsigned int) m->val & val)67ptr += sprintf(ptr, "%s ", m->str);68m++;69}70return str;71}7273static int hci_str2bit(hci_map *map, char *str, unsigned int *val)74{75char *t, *ptr;76hci_map *m;77int set;7879if (!str || !(str = ptr = strdup(str)))80return 0;8182*val = set = 0;8384while ((t = strsep(&ptr, ","))) {85for (m = map; m->str; m++) {86if (!strcasecmp(m->str, t)) {87*val |= (unsigned int) m->val;88set = 1;89}90}91}92free(str);9394return set;95}9697static char *hci_uint2str(hci_map *m, unsigned int val)98{99char *str = malloc(50);100char *ptr = str;101102if (!str)103return NULL;104105*ptr = 0;106while (m->str) {107if ((unsigned int) m->val == val) {108ptr += sprintf(ptr, "%s", m->str);109break;110}111m++;112}113return str;114}115116static int hci_str2uint(hci_map *map, char *str, unsigned int *val)117{118char *t, *ptr;119hci_map *m;120int set = 0;121122if (!str)123return 0;124125str = ptr = strdup(str);126127while ((t = strsep(&ptr, ","))) {128for (m = map; m->str; m++) {129if (!strcasecmp(m->str,t)) {130*val = (unsigned int) m->val;131set = 1;132break;133}134}135}136free(str);137138return set;139}140141char *hci_bustostr(int bus)142{143switch (bus) {144case HCI_VIRTUAL:145return "VIRTUAL";146case HCI_USB:147return "USB";148case HCI_PCCARD:149return "PCCARD";150case HCI_UART:151return "UART";152case HCI_RS232:153return "RS232";154case HCI_PCI:155return "PCI";156case HCI_SDIO:157return "SDIO";158default:159return "UNKNOWN";160}161}162163char *hci_dtypetostr(int type)164{165return hci_bustostr(type & 0x0f);166}167168char *hci_typetostr(int type)169{170switch (type) {171case HCI_BREDR:172return "BR/EDR";173case HCI_AMP:174return "AMP";175default:176return "UNKNOWN";177}178}179180/* HCI dev flags mapping */181static hci_map dev_flags_map[] = {182{ "UP", HCI_UP },183{ "INIT", HCI_INIT },184{ "RUNNING", HCI_RUNNING },185{ "RAW", HCI_RAW },186{ "PSCAN", HCI_PSCAN },187{ "ISCAN", HCI_ISCAN },188{ "INQUIRY", HCI_INQUIRY },189{ "AUTH", HCI_AUTH },190{ "ENCRYPT", HCI_ENCRYPT },191{ NULL }192};193194char *hci_dflagstostr(uint32_t flags)195{196char *str = bt_malloc(50);197char *ptr = str;198hci_map *m = dev_flags_map;199200if (!str)201return NULL;202203*ptr = 0;204205if (!hci_test_bit(HCI_UP, &flags))206ptr += sprintf(ptr, "DOWN ");207208while (m->str) {209if (hci_test_bit(m->val, &flags))210ptr += sprintf(ptr, "%s ", m->str);211m++;212}213return str;214}215216/* HCI packet type mapping */217static hci_map pkt_type_map[] = {218{ "DM1", HCI_DM1 },219{ "DM3", HCI_DM3 },220{ "DM5", HCI_DM5 },221{ "DH1", HCI_DH1 },222{ "DH3", HCI_DH3 },223{ "DH5", HCI_DH5 },224{ "HV1", HCI_HV1 },225{ "HV2", HCI_HV2 },226{ "HV3", HCI_HV3 },227{ "2-DH1", HCI_2DH1 },228{ "2-DH3", HCI_2DH3 },229{ "2-DH5", HCI_2DH5 },230{ "3-DH1", HCI_3DH1 },231{ "3-DH3", HCI_3DH3 },232{ "3-DH5", HCI_3DH5 },233{ NULL }234};235236static hci_map sco_ptype_map[] = {237{ "HV1", 0x0001 },238{ "HV2", 0x0002 },239{ "HV3", 0x0004 },240{ "EV3", HCI_EV3 },241{ "EV4", HCI_EV4 },242{ "EV5", HCI_EV5 },243{ "2-EV3", HCI_2EV3 },244{ "2-EV5", HCI_2EV5 },245{ "3-EV3", HCI_3EV3 },246{ "3-EV5", HCI_3EV5 },247{ NULL }248};249250char *hci_ptypetostr(unsigned int ptype)251{252return hci_bit2str(pkt_type_map, ptype);253}254255int hci_strtoptype(char *str, unsigned int *val)256{257return hci_str2bit(pkt_type_map, str, val);258}259260char *hci_scoptypetostr(unsigned int ptype)261{262return hci_bit2str(sco_ptype_map, ptype);263}264265int hci_strtoscoptype(char *str, unsigned int *val)266{267return hci_str2bit(sco_ptype_map, str, val);268}269270/* Link policy mapping */271static hci_map link_policy_map[] = {272{ "NONE", 0 },273{ "RSWITCH", HCI_LP_RSWITCH },274{ "HOLD", HCI_LP_HOLD },275{ "SNIFF", HCI_LP_SNIFF },276{ "PARK", HCI_LP_PARK },277{ NULL }278};279280char *hci_lptostr(unsigned int lp)281{282return hci_bit2str(link_policy_map, lp);283}284285int hci_strtolp(char *str, unsigned int *val)286{287return hci_str2bit(link_policy_map, str, val);288}289290/* Link mode mapping */291static hci_map link_mode_map[] = {292{ "NONE", 0 },293{ "ACCEPT", HCI_LM_ACCEPT },294{ "MASTER", HCI_LM_MASTER },295{ "AUTH", HCI_LM_AUTH },296{ "ENCRYPT", HCI_LM_ENCRYPT },297{ "TRUSTED", HCI_LM_TRUSTED },298{ "RELIABLE", HCI_LM_RELIABLE },299{ "SECURE", HCI_LM_SECURE },300{ NULL }301};302303char *hci_lmtostr(unsigned int lm)304{305char *s, *str = bt_malloc(50);306if (!str)307return NULL;308309*str = 0;310if (!(lm & HCI_LM_MASTER))311strcpy(str, "SLAVE ");312313s = hci_bit2str(link_mode_map, lm);314if (!s) {315bt_free(str);316return NULL;317}318319strcat(str, s);320free(s);321return str;322}323324int hci_strtolm(char *str, unsigned int *val)325{326return hci_str2bit(link_mode_map, str, val);327}328329/* Command mapping */330static hci_map commands_map[] = {331{ "Inquiry", 0 },332{ "Inquiry Cancel", 1 },333{ "Periodic Inquiry Mode", 2 },334{ "Exit Periodic Inquiry Mode", 3 },335{ "Create Connection", 4 },336{ "Disconnect", 5 },337{ "Add SCO Connection", 6 },338{ "Cancel Create Connection", 7 },339340{ "Accept Connection Request", 8 },341{ "Reject Connection Request", 9 },342{ "Link Key Request Reply", 10 },343{ "Link Key Request Negative Reply", 11 },344{ "PIN Code Request Reply", 12 },345{ "PIN Code Request Negative Reply", 13 },346{ "Change Connection Packet Type", 14 },347{ "Authentication Requested", 15 },348349{ "Set Connection Encryption", 16 },350{ "Change Connection Link Key", 17 },351{ "Master Link Key", 18 },352{ "Remote Name Request", 19 },353{ "Cancel Remote Name Request", 20 },354{ "Read Remote Supported Features", 21 },355{ "Read Remote Extended Features", 22 },356{ "Read Remote Version Information", 23 },357358{ "Read Clock Offset", 24 },359{ "Read LMP Handle", 25 },360{ "Reserved", 26 },361{ "Reserved", 27 },362{ "Reserved", 28 },363{ "Reserved", 29 },364{ "Reserved", 30 },365{ "Reserved", 31 },366367{ "Reserved", 32 },368{ "Hold Mode", 33 },369{ "Sniff Mode", 34 },370{ "Exit Sniff Mode", 35 },371{ "Park State", 36 },372{ "Exit Park State", 37 },373{ "QoS Setup", 38 },374{ "Role Discovery", 39 },375376{ "Switch Role", 40 },377{ "Read Link Policy Settings", 41 },378{ "Write Link Policy Settings", 42 },379{ "Read Default Link Policy Settings", 43 },380{ "Write Default Link Policy Settings", 44 },381{ "Flow Specification", 45 },382{ "Set Event Mask", 46 },383{ "Reset", 47 },384385{ "Set Event Filter", 48 },386{ "Flush", 49 },387{ "Read PIN Type", 50 },388{ "Write PIN Type", 51 },389{ "Create New Unit Key", 52 },390{ "Read Stored Link Key", 53 },391{ "Write Stored Link Key", 54 },392{ "Delete Stored Link Key", 55 },393394{ "Write Local Name", 56 },395{ "Read Local Name", 57 },396{ "Read Connection Accept Timeout", 58 },397{ "Write Connection Accept Timeout", 59 },398{ "Read Page Timeout", 60 },399{ "Write Page Timeout", 61 },400{ "Read Scan Enable", 62 },401{ "Write Scan Enable", 63 },402403{ "Read Page Scan Activity", 64 },404{ "Write Page Scan Activity", 65 },405{ "Read Inquiry Scan Activity", 66 },406{ "Write Inquiry Scan Activity", 67 },407{ "Read Authentication Enable", 68 },408{ "Write Authentication Enable", 69 },409{ "Read Encryption Mode", 70 },410{ "Write Encryption Mode", 71 },411412{ "Read Class Of Device", 72 },413{ "Write Class Of Device", 73 },414{ "Read Voice Setting", 74 },415{ "Write Voice Setting", 75 },416{ "Read Automatic Flush Timeout", 76 },417{ "Write Automatic Flush Timeout", 77 },418{ "Read Num Broadcast Retransmissions", 78 },419{ "Write Num Broadcast Retransmissions", 79 },420421{ "Read Hold Mode Activity", 80 },422{ "Write Hold Mode Activity", 81 },423{ "Read Transmit Power Level", 82 },424{ "Read Synchronous Flow Control Enable", 83 },425{ "Write Synchronous Flow Control Enable", 84 },426{ "Set Host Controller To Host Flow Control", 85 },427{ "Host Buffer Size", 86 },428{ "Host Number Of Completed Packets", 87 },429430{ "Read Link Supervision Timeout", 88 },431{ "Write Link Supervision Timeout", 89 },432{ "Read Number of Supported IAC", 90 },433{ "Read Current IAC LAP", 91 },434{ "Write Current IAC LAP", 92 },435{ "Read Page Scan Period Mode", 93 },436{ "Write Page Scan Period Mode", 94 },437{ "Read Page Scan Mode", 95 },438439{ "Write Page Scan Mode", 96 },440{ "Set AFH Channel Classification", 97 },441{ "Reserved", 98 },442{ "Reserved", 99 },443{ "Read Inquiry Scan Type", 100 },444{ "Write Inquiry Scan Type", 101 },445{ "Read Inquiry Mode", 102 },446{ "Write Inquiry Mode", 103 },447448{ "Read Page Scan Type", 104 },449{ "Write Page Scan Type", 105 },450{ "Read AFH Channel Assessment Mode", 106 },451{ "Write AFH Channel Assessment Mode", 107 },452{ "Reserved", 108 },453{ "Reserved", 109 },454{ "Reserved", 110 },455{ "Reserved", 111 },456457{ "Reserved", 112 },458{ "Reserved", 113 },459{ "Reserved", 114 },460{ "Read Local Version Information", 115 },461{ "Read Local Supported Commands", 116 },462{ "Read Local Supported Features", 117 },463{ "Read Local Extended Features", 118 },464{ "Read Buffer Size", 119 },465466{ "Read Country Code", 120 },467{ "Read BD ADDR", 121 },468{ "Read Failed Contact Counter", 122 },469{ "Reset Failed Contact Counter", 123 },470{ "Get Link Quality", 124 },471{ "Read RSSI", 125 },472{ "Read AFH Channel Map", 126 },473{ "Read BD Clock", 127 },474475{ "Read Loopback Mode", 128 },476{ "Write Loopback Mode", 129 },477{ "Enable Device Under Test Mode", 130 },478{ "Setup Synchronous Connection", 131 },479{ "Accept Synchronous Connection", 132 },480{ "Reject Synchronous Connection", 133 },481{ "Reserved", 134 },482{ "Reserved", 135 },483484{ "Read Extended Inquiry Response", 136 },485{ "Write Extended Inquiry Response", 137 },486{ "Refresh Encryption Key", 138 },487{ "Reserved", 139 },488{ "Sniff Subrating", 140 },489{ "Read Simple Pairing Mode", 141 },490{ "Write Simple Pairing Mode", 142 },491{ "Read Local OOB Data", 143 },492493{ "Read Inquiry Response Transmit Power Level", 144 },494{ "Write Inquiry Transmit Power Level", 145 },495{ "Read Default Erroneous Data Reporting", 146 },496{ "Write Default Erroneous Data Reporting", 147 },497{ "Reserved", 148 },498{ "Reserved", 149 },499{ "Reserved", 150 },500{ "IO Capability Request Reply", 151 },501502{ "User Confirmation Request Reply", 152 },503{ "User Confirmation Request Negative Reply", 153 },504{ "User Passkey Request Reply", 154 },505{ "User Passkey Request Negative Reply", 155 },506{ "Remote OOB Data Request Reply", 156 },507{ "Write Simple Pairing Debug Mode", 157 },508{ "Enhanced Flush", 158 },509{ "Remote OOB Data Request Negative Reply", 159 },510511{ "Reserved", 160 },512{ "Reserved", 161 },513{ "Send Keypress Notification", 162 },514{ "IO Capability Request Negative Reply", 163 },515{ "Read Encryption Key Size", 164 },516{ "Reserved", 165 },517{ "Reserved", 166 },518{ "Reserved", 167 },519520{ "Create Physical Link", 168 },521{ "Accept Physical Link", 169 },522{ "Disconnect Physical Link", 170 },523{ "Create Logical Link", 171 },524{ "Accept Logical Link", 172 },525{ "Disconnect Logical Link", 173 },526{ "Logical Link Cancel", 174 },527{ "Flow Specification Modify", 175 },528529{ "Read Logical Link Accept Timeout", 176 },530{ "Write Logical Link Accept Timeout", 177 },531{ "Set Event Mask Page 2", 178 },532{ "Read Location Data", 179 },533{ "Write Location Data", 180 },534{ "Read Local AMP Info", 181 },535{ "Read Local AMP_ASSOC", 182 },536{ "Write Remote AMP_ASSOC", 183 },537538{ "Read Flow Control Mode", 184 },539{ "Write Flow Control Mode", 185 },540{ "Read Data Block Size", 186 },541{ "Reserved", 187 },542{ "Reserved", 188 },543{ "Enable AMP Receiver Reports", 189 },544{ "AMP Test End", 190 },545{ "AMP Test Command", 191 },546547{ "Read Enhanced Transmit Power Level", 192 },548{ "Reserved", 193 },549{ "Read Best Effort Flush Timeout", 194 },550{ "Write Best Effort Flush Timeout", 195 },551{ "Short Range Mode", 196 },552{ "Read LE Host Support", 197 },553{ "Write LE Host Support", 198 },554{ "Reserved", 199 },555556{ "LE Set Event Mask", 200 },557{ "LE Read Buffer Size", 201 },558{ "LE Read Local Supported Features", 202 },559{ "Reserved", 203 },560{ "LE Set Random Address", 204 },561{ "LE Set Advertising Parameters", 205 },562{ "LE Read Advertising Channel TX Power", 206 },563{ "LE Set Advertising Data", 207 },564565{ "LE Set Scan Response Data", 208 },566{ "LE Set Advertise Enable", 209 },567{ "LE Set Scan Parameters", 210 },568{ "LE Set Scan Enable", 211 },569{ "LE Create Connection", 212 },570{ "LE Create Connection Cancel", 213 },571{ "LE Read White List Size", 214 },572{ "LE Clear White List", 215 },573574{ "LE Add Device To White List", 216 },575{ "LE Remove Device From White List", 217 },576{ "LE Connection Update", 218 },577{ "LE Set Host Channel Classification", 219 },578{ "LE Read Channel Map", 220 },579{ "LE Read Remote Used Features", 221 },580{ "LE Encrypt", 222 },581{ "LE Rand", 223 },582583{ "LE Start Encryption", 224 },584{ "LE Long Term Key Request Reply", 225 },585{ "LE Long Term Key Request Negative Reply", 226 },586{ "LE Read Supported States", 227 },587{ "LE Receiver Test", 228 },588{ "LE Transmitter Test", 229 },589{ "LE Test End", 230 },590{ "Reserved", 231 },591592{ NULL }593};594595char *hci_cmdtostr(unsigned int cmd)596{597return hci_uint2str(commands_map, cmd);598}599600char *hci_commandstostr(uint8_t *commands, char *pref, int width)601{602unsigned int maxwidth = width - 3;603hci_map *m;604char *off, *ptr, *str;605int size = 10;606607m = commands_map;608609while (m->str) {610if (commands[m->val / 8] & (1 << (m->val % 8)))611size += strlen(m->str) + (pref ? strlen(pref) : 0) + 3;612m++;613}614615str = bt_malloc(size);616if (!str)617return NULL;618619ptr = str; *ptr = '\0';620621if (pref)622ptr += sprintf(ptr, "%s", pref);623624off = ptr;625626m = commands_map;627628while (m->str) {629if (commands[m->val / 8] & (1 << (m->val % 8))) {630if (strlen(off) + strlen(m->str) > maxwidth) {631ptr += sprintf(ptr, "\n%s", pref ? pref : "");632off = ptr;633}634ptr += sprintf(ptr, "'%s' ", m->str);635}636m++;637}638639return str;640}641642/* Version mapping */643static hci_map ver_map[] = {644{ "1.0b", 0x00 },645{ "1.1", 0x01 },646{ "1.2", 0x02 },647{ "2.0", 0x03 },648{ "2.1", 0x04 },649{ "3.0", 0x05 },650{ "4.0", 0x06 },651{ NULL }652};653654char *hci_vertostr(unsigned int ver)655{656return hci_uint2str(ver_map, ver);657}658659int hci_strtover(char *str, unsigned int *ver)660{661return hci_str2uint(ver_map, str, ver);662}663664char *lmp_vertostr(unsigned int ver)665{666return hci_uint2str(ver_map, ver);667}668669int lmp_strtover(char *str, unsigned int *ver)670{671return hci_str2uint(ver_map, str, ver);672}673674static hci_map pal_map[] = {675{ "3.0", 0x01 },676{ NULL }677};678679char *pal_vertostr(unsigned int ver)680{681return hci_uint2str(pal_map, ver);682}683684int pal_strtover(char *str, unsigned int *ver)685{686return hci_str2uint(pal_map, str, ver);687}688689/* LMP features mapping */690static hci_map lmp_features_map[8][9] = {691{ /* Byte 0 */692{ "<3-slot packets>", LMP_3SLOT }, /* Bit 0 */693{ "<5-slot packets>", LMP_5SLOT }, /* Bit 1 */694{ "<encryption>", LMP_ENCRYPT }, /* Bit 2 */695{ "<slot offset>", LMP_SOFFSET }, /* Bit 3 */696{ "<timing accuracy>", LMP_TACCURACY }, /* Bit 4 */697{ "<role switch>", LMP_RSWITCH }, /* Bit 5 */698{ "<hold mode>", LMP_HOLD }, /* Bit 6 */699{ "<sniff mode>", LMP_SNIFF }, /* Bit 7 */700{ NULL }701},702{ /* Byte 1 */703{ "<park state>", LMP_PARK }, /* Bit 0 */704{ "<RSSI>", LMP_RSSI }, /* Bit 1 */705{ "<channel quality>", LMP_QUALITY }, /* Bit 2 */706{ "<SCO link>", LMP_SCO }, /* Bit 3 */707{ "<HV2 packets>", LMP_HV2 }, /* Bit 4 */708{ "<HV3 packets>", LMP_HV3 }, /* Bit 5 */709{ "<u-law log>", LMP_ULAW }, /* Bit 6 */710{ "<A-law log>", LMP_ALAW }, /* Bit 7 */711{ NULL }712},713{ /* Byte 2 */714{ "<CVSD>", LMP_CVSD }, /* Bit 0 */715{ "<paging scheme>", LMP_PSCHEME }, /* Bit 1 */716{ "<power control>", LMP_PCONTROL }, /* Bit 2 */717{ "<transparent SCO>", LMP_TRSP_SCO }, /* Bit 3 */718{ "<broadcast encrypt>",LMP_BCAST_ENC }, /* Bit 7 */719{ NULL }720},721{ /* Byte 3 */722{ "<no. 24>", 0x01 }, /* Bit 0 */723{ "<EDR ACL 2 Mbps>", LMP_EDR_ACL_2M }, /* Bit 1 */724{ "<EDR ACL 3 Mbps>", LMP_EDR_ACL_3M }, /* Bit 2 */725{ "<enhanced iscan>", LMP_ENH_ISCAN }, /* Bit 3 */726{ "<interlaced iscan>", LMP_ILACE_ISCAN }, /* Bit 4 */727{ "<interlaced pscan>", LMP_ILACE_PSCAN }, /* Bit 5 */728{ "<inquiry with RSSI>",LMP_RSSI_INQ }, /* Bit 6 */729{ "<extended SCO>", LMP_ESCO }, /* Bit 7 */730{ NULL }731},732{ /* Byte 4 */733{ "<EV4 packets>", LMP_EV4 }, /* Bit 0 */734{ "<EV5 packets>", LMP_EV5 }, /* Bit 1 */735{ "<no. 34>", 0x04 }, /* Bit 2 */736{ "<AFH cap. slave>", LMP_AFH_CAP_SLV }, /* Bit 3 */737{ "<AFH class. slave>", LMP_AFH_CLS_SLV }, /* Bit 4 */738{ "<BR/EDR not supp.>", LMP_NO_BREDR }, /* Bit 5 */739{ "<LE support>", LMP_LE }, /* Bit 6 */740{ "<3-slot EDR ACL>", LMP_EDR_3SLOT }, /* Bit 7 */741{ NULL }742},743{ /* Byte 5 */744{ "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */745{ "<sniff subrating>", LMP_SNIFF_SUBR }, /* Bit 1 */746{ "<pause encryption>", LMP_PAUSE_ENC }, /* Bit 2 */747{ "<AFH cap. master>", LMP_AFH_CAP_MST }, /* Bit 3 */748{ "<AFH class. master>",LMP_AFH_CLS_MST }, /* Bit 4 */749{ "<EDR eSCO 2 Mbps>", LMP_EDR_ESCO_2M }, /* Bit 5 */750{ "<EDR eSCO 3 Mbps>", LMP_EDR_ESCO_3M }, /* Bit 6 */751{ "<3-slot EDR eSCO>", LMP_EDR_3S_ESCO }, /* Bit 7 */752{ NULL }753},754{ /* Byte 6 */755{ "<extended inquiry>", LMP_EXT_INQ }, /* Bit 0 */756{ "<LE and BR/EDR>", LMP_LE_BREDR }, /* Bit 1 */757{ "<no. 50>", 0x04 }, /* Bit 2 */758{ "<simple pairing>", LMP_SIMPLE_PAIR }, /* Bit 3 */759{ "<encapsulated PDU>", LMP_ENCAPS_PDU }, /* Bit 4 */760{ "<err. data report>", LMP_ERR_DAT_REP }, /* Bit 5 */761{ "<non-flush flag>", LMP_NFLUSH_PKTS }, /* Bit 6 */762{ "<no. 55>", 0x80 }, /* Bit 7 */763{ NULL }764},765{ /* Byte 7 */766{ "<LSTO>", LMP_LSTO }, /* Bit 1 */767{ "<inquiry TX power>", LMP_INQ_TX_PWR }, /* Bit 1 */768{ "<EPC>", LMP_EPC }, /* Bit 2 */769{ "<no. 59>", 0x08 }, /* Bit 3 */770{ "<no. 60>", 0x10 }, /* Bit 4 */771{ "<no. 61>", 0x20 }, /* Bit 5 */772{ "<no. 62>", 0x40 }, /* Bit 6 */773{ "<extended features>",LMP_EXT_FEAT }, /* Bit 7 */774{ NULL }775},776};777778char *lmp_featurestostr(uint8_t *features, char *pref, int width)779{780unsigned int maxwidth = width - 1;781char *off, *ptr, *str;782int i, size = 10;783784for (i = 0; i < 8; i++) {785hci_map *m = lmp_features_map[i];786787while (m->str) {788if (m->val & features[i])789size += strlen(m->str) +790(pref ? strlen(pref) : 0) + 1;791m++;792}793}794795str = bt_malloc(size);796if (!str)797return NULL;798799ptr = str; *ptr = '\0';800801if (pref)802ptr += sprintf(ptr, "%s", pref);803804off = ptr;805806for (i = 0; i < 8; i++) {807hci_map *m = lmp_features_map[i];808809while (m->str) {810if (m->val & features[i]) {811if (strlen(off) + strlen(m->str) > maxwidth) {812ptr += sprintf(ptr, "\n%s",813pref ? pref : "");814off = ptr;815}816ptr += sprintf(ptr, "%s ", m->str);817}818m++;819}820}821822return str;823}824825/* HCI functions that do not require open device */826int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg),827long arg)828{829struct hci_dev_list_req *dl;830struct hci_dev_req *dr;831int dev_id = -1;832int i, sk, err = 0;833834sk = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);835if (sk < 0)836return -1;837838dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));839if (!dl) {840err = errno;841goto done;842}843844memset(dl, 0, HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));845846dl->dev_num = HCI_MAX_DEV;847dr = dl->dev_req;848849if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) {850err = errno;851goto free;852}853854for (i = 0; i < dl->dev_num; i++, dr++) {855if (hci_test_bit(flag, &dr->dev_opt))856if (!func || func(sk, dr->dev_id, arg)) {857dev_id = dr->dev_id;858break;859}860}861862if (dev_id < 0)863err = ENODEV;864865free:866free(dl);867868done:869close(sk);870errno = err;871872return dev_id;873}874875static int __other_bdaddr(int dd, int dev_id, long arg)876{877struct hci_dev_info di = { .dev_id = dev_id };878879if (ioctl(dd, HCIGETDEVINFO, (void *) &di))880return 0;881882if (hci_test_bit(HCI_RAW, &di.flags))883return 0;884885return bacmp((bdaddr_t *) arg, &di.bdaddr);886}887888static int __same_bdaddr(int dd, int dev_id, long arg)889{890struct hci_dev_info di = { .dev_id = dev_id };891892if (ioctl(dd, HCIGETDEVINFO, (void *) &di))893return 0;894895return !bacmp((bdaddr_t *) arg, &di.bdaddr);896}897898int hci_get_route(bdaddr_t *bdaddr)899{900return hci_for_each_dev(HCI_UP, __other_bdaddr,901(long) (bdaddr ? bdaddr : BDADDR_ANY));902}903904int hci_devid(const char *str)905{906bdaddr_t ba;907int id = -1;908909if (!strncmp(str, "hci", 3) && strlen(str) >= 4) {910id = atoi(str + 3);911if (hci_devba(id, &ba) < 0)912return -1;913} else {914errno = ENODEV;915str2ba(str, &ba);916id = hci_for_each_dev(HCI_UP, __same_bdaddr, (long) &ba);917}918919return id;920}921922int hci_devinfo(int dev_id, struct hci_dev_info *di)923{924int dd, err, ret;925926dd = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);927if (dd < 0)928return dd;929930memset(di, 0, sizeof(struct hci_dev_info));931932di->dev_id = dev_id;933ret = ioctl(dd, HCIGETDEVINFO, (void *) di);934935err = errno;936close(dd);937errno = err;938939return ret;940}941942int hci_devba(int dev_id, bdaddr_t *bdaddr)943{944struct hci_dev_info di;945946memset(&di, 0, sizeof(di));947948if (hci_devinfo(dev_id, &di))949return -1;950951if (!hci_test_bit(HCI_UP, &di.flags)) {952errno = ENETDOWN;953return -1;954}955956bacpy(bdaddr, &di.bdaddr);957958return 0;959}960961int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap,962inquiry_info **ii, long flags)963{964struct hci_inquiry_req *ir;965uint8_t num_rsp = nrsp;966void *buf;967int dd, size, err, ret = -1;968969if (nrsp <= 0) {970num_rsp = 0;971nrsp = 255;972}973974if (dev_id < 0) {975dev_id = hci_get_route(NULL);976if (dev_id < 0) {977errno = ENODEV;978return -1;979}980}981982dd = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);983if (dd < 0)984return dd;985986buf = malloc(sizeof(*ir) + (sizeof(inquiry_info) * (nrsp)));987if (!buf)988goto done;989990ir = buf;991ir->dev_id = dev_id;992ir->num_rsp = num_rsp;993ir->length = len;994ir->flags = flags;995996if (lap) {997memcpy(ir->lap, lap, 3);998} else {999ir->lap[0] = 0x33;1000ir->lap[1] = 0x8b;1001ir->lap[2] = 0x9e;1002}10031004ret = ioctl(dd, HCIINQUIRY, (unsigned long) buf);1005if (ret < 0)1006goto free;10071008size = sizeof(inquiry_info) * ir->num_rsp;10091010if (!*ii)1011*ii = malloc(size);10121013if (*ii) {1014memcpy((void *) *ii, buf + sizeof(*ir), size);1015ret = ir->num_rsp;1016} else1017ret = -1;10181019free:1020free(buf);10211022done:1023err = errno;1024close(dd);1025errno = err;10261027return ret;1028}10291030/* Open HCI device.1031* Returns device descriptor (dd). */1032int hci_open_dev(int dev_id)1033{1034struct sockaddr_hci a;1035int dd, err;10361037/* Create HCI socket */1038dd = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);1039if (dd < 0)1040return dd;10411042/* Bind socket to the HCI device */1043memset(&a, 0, sizeof(a));1044a.hci_family = AF_BLUETOOTH;1045a.hci_dev = dev_id;1046if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0)1047goto failed;10481049return dd;10501051failed:1052err = errno;1053close(dd);1054errno = err;10551056return -1;1057}10581059int hci_close_dev(int dd)1060{1061return close(dd);1062}10631064/* HCI functions that require open device1065* dd - Device descriptor returned by hci_open_dev. */10661067int hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param)1068{1069uint8_t type = HCI_COMMAND_PKT;1070hci_command_hdr hc;1071struct iovec iv[3];1072int ivn;10731074hc.opcode = htobs(cmd_opcode_pack(ogf, ocf));1075hc.plen= plen;10761077iv[0].iov_base = &type;1078iv[0].iov_len = 1;1079iv[1].iov_base = &hc;1080iv[1].iov_len = HCI_COMMAND_HDR_SIZE;1081ivn = 2;10821083if (plen) {1084iv[2].iov_base = param;1085iv[2].iov_len = plen;1086ivn = 3;1087}10881089while (writev(dd, iv, ivn) < 0) {1090if (errno == EAGAIN || errno == EINTR)1091continue;1092return -1;1093}1094return 0;1095}10961097int hci_send_req(int dd, struct hci_request *r, int to)1098{1099unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;1100uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf));1101struct hci_filter nf, of;1102socklen_t olen;1103hci_event_hdr *hdr;1104int err, try;11051106olen = sizeof(of);1107if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &olen) < 0)1108return -1;11091110hci_filter_clear(&nf);1111hci_filter_set_ptype(HCI_EVENT_PKT, &nf);1112hci_filter_set_event(EVT_CMD_STATUS, &nf);1113hci_filter_set_event(EVT_CMD_COMPLETE, &nf);1114hci_filter_set_event(EVT_LE_META_EVENT, &nf);1115hci_filter_set_event(r->event, &nf);1116hci_filter_set_opcode(opcode, &nf);1117if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0)1118return -1;11191120if (hci_send_cmd(dd, r->ogf, r->ocf, r->clen, r->cparam) < 0)1121goto failed;11221123try = 10;1124while (try--) {1125evt_cmd_complete *cc;1126evt_cmd_status *cs;1127evt_remote_name_req_complete *rn;1128evt_le_meta_event *me;1129remote_name_req_cp *cp;1130int len;11311132if (to) {1133struct pollfd p;1134int n;11351136p.fd = dd; p.events = POLLIN;1137while ((n = poll(&p, 1, to)) < 0) {1138if (errno == EAGAIN || errno == EINTR)1139continue;1140goto failed;1141}11421143if (!n) {1144errno = ETIMEDOUT;1145goto failed;1146}11471148to -= 10;1149if (to < 0)1150to = 0;11511152}11531154while ((len = read(dd, buf, sizeof(buf))) < 0) {1155if (errno == EAGAIN || errno == EINTR)1156continue;1157goto failed;1158}11591160hdr = (void *) (buf + 1);1161ptr = buf + (1 + HCI_EVENT_HDR_SIZE);1162len -= (1 + HCI_EVENT_HDR_SIZE);11631164switch (hdr->evt) {1165case EVT_CMD_STATUS:1166cs = (void *) ptr;11671168if (cs->opcode != opcode)1169continue;11701171if (r->event != EVT_CMD_STATUS) {1172if (cs->status) {1173errno = EIO;1174goto failed;1175}1176break;1177}11781179r->rlen = MIN(len, r->rlen);1180memcpy(r->rparam, ptr, r->rlen);1181goto done;11821183case EVT_CMD_COMPLETE:1184cc = (void *) ptr;11851186if (cc->opcode != opcode)1187continue;11881189ptr += EVT_CMD_COMPLETE_SIZE;1190len -= EVT_CMD_COMPLETE_SIZE;11911192r->rlen = MIN(len, r->rlen);1193memcpy(r->rparam, ptr, r->rlen);1194goto done;11951196case EVT_REMOTE_NAME_REQ_COMPLETE:1197if (hdr->evt != r->event)1198break;11991200rn = (void *) ptr;1201cp = r->cparam;12021203if (bacmp(&rn->bdaddr, &cp->bdaddr))1204continue;12051206r->rlen = MIN(len, r->rlen);1207memcpy(r->rparam, ptr, r->rlen);1208goto done;12091210case EVT_LE_META_EVENT:1211me = (void *) ptr;12121213if (me->subevent != r->event)1214continue;12151216len -= 1;1217r->rlen = MIN(len, r->rlen);1218memcpy(r->rparam, me->data, r->rlen);1219goto done;12201221default:1222if (hdr->evt != r->event)1223break;12241225r->rlen = MIN(len, r->rlen);1226memcpy(r->rparam, ptr, r->rlen);1227goto done;1228}1229}1230errno = ETIMEDOUT;12311232failed:1233err = errno;1234setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));1235errno = err;1236return -1;12371238done:1239setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));1240return 0;1241}12421243int hci_create_connection(int dd, const bdaddr_t *bdaddr, uint16_t ptype,1244uint16_t clkoffset, uint8_t rswitch,1245uint16_t *handle, int to)1246{1247evt_conn_complete rp;1248create_conn_cp cp;1249struct hci_request rq;12501251memset(&cp, 0, sizeof(cp));1252bacpy(&cp.bdaddr, bdaddr);1253cp.pkt_type = ptype;1254cp.pscan_rep_mode = 0x02;1255cp.clock_offset = clkoffset;1256cp.role_switch = rswitch;12571258memset(&rq, 0, sizeof(rq));1259rq.ogf = OGF_LINK_CTL;1260rq.ocf = OCF_CREATE_CONN;1261rq.event = EVT_CONN_COMPLETE;1262rq.cparam = &cp;1263rq.clen = CREATE_CONN_CP_SIZE;1264rq.rparam = &rp;1265rq.rlen = EVT_CONN_COMPLETE_SIZE;12661267if (hci_send_req(dd, &rq, to) < 0)1268return -1;12691270if (rp.status) {1271errno = EIO;1272return -1;1273}12741275*handle = rp.handle;1276return 0;1277}12781279int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to)1280{1281evt_disconn_complete rp;1282disconnect_cp cp;1283struct hci_request rq;12841285memset(&cp, 0, sizeof(cp));1286cp.handle = handle;1287cp.reason = reason;12881289memset(&rq, 0, sizeof(rq));1290rq.ogf = OGF_LINK_CTL;1291rq.ocf = OCF_DISCONNECT;1292rq.event = EVT_DISCONN_COMPLETE;1293rq.cparam = &cp;1294rq.clen = DISCONNECT_CP_SIZE;1295rq.rparam = &rp;1296rq.rlen = EVT_DISCONN_COMPLETE_SIZE;12971298if (hci_send_req(dd, &rq, to) < 0)1299return -1;13001301if (rp.status) {1302errno = EIO;1303return -1;1304}1305return 0;1306}13071308int hci_le_add_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to)1309{1310struct hci_request rq;1311le_add_device_to_white_list_cp cp;1312uint8_t status;13131314memset(&cp, 0, sizeof(cp));1315cp.bdaddr_type = type;1316bacpy(&cp.bdaddr, bdaddr);13171318memset(&rq, 0, sizeof(rq));1319rq.ogf = OGF_LE_CTL;1320rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;1321rq.cparam = &cp;1322rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;1323rq.rparam = &status;1324rq.rlen = 1;13251326if (hci_send_req(dd, &rq, to) < 0)1327return -1;13281329if (status) {1330errno = EIO;1331return -1;1332}13331334return 0;1335}13361337int hci_le_rm_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to)1338{1339struct hci_request rq;1340le_remove_device_from_white_list_cp cp;1341uint8_t status;13421343memset(&cp, 0, sizeof(cp));1344cp.bdaddr_type = type;1345bacpy(&cp.bdaddr, bdaddr);13461347memset(&rq, 0, sizeof(rq));1348rq.ogf = OGF_LE_CTL;1349rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;1350rq.cparam = &cp;1351rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;1352rq.rparam = &status;1353rq.rlen = 1;13541355if (hci_send_req(dd, &rq, to) < 0)1356return -1;13571358if (status) {1359errno = EIO;1360return -1;1361}13621363return 0;1364}13651366int hci_le_read_white_list_size(int dd, uint8_t *size, int to)1367{1368struct hci_request rq;1369le_read_white_list_size_rp rp;13701371memset(&rp, 0, sizeof(rp));1372memset(&rq, 0, sizeof(rq));13731374rq.ogf = OGF_LE_CTL;1375rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;1376rq.rparam = &rp;1377rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;13781379if (hci_send_req(dd, &rq, to) < 0)1380return -1;13811382if (rp.status) {1383errno = EIO;1384return -1;1385}13861387if (size)1388*size = rp.size;13891390return 0;1391}13921393int hci_le_clear_white_list(int dd, int to)1394{1395struct hci_request rq;1396uint8_t status;13971398memset(&rq, 0, sizeof(rq));1399rq.ogf = OGF_LE_CTL;1400rq.ocf = OCF_LE_CLEAR_WHITE_LIST;1401rq.rparam = &status;1402rq.rlen = 1;14031404if (hci_send_req(dd, &rq, to) < 0)1405return -1;14061407if (status) {1408errno = EIO;1409return -1;1410}14111412return 0;1413}14141415int hci_read_local_name(int dd, int len, char *name, int to)1416{1417read_local_name_rp rp;1418struct hci_request rq;14191420memset(&rq, 0, sizeof(rq));1421rq.ogf = OGF_HOST_CTL;1422rq.ocf = OCF_READ_LOCAL_NAME;1423rq.rparam = &rp;1424rq.rlen = READ_LOCAL_NAME_RP_SIZE;14251426if (hci_send_req(dd, &rq, to) < 0)1427return -1;14281429if (rp.status) {1430errno = EIO;1431return -1;1432}14331434rp.name[247] = '\0';1435strncpy(name, (char *) rp.name, len);1436return 0;1437}14381439int hci_write_local_name(int dd, const char *name, int to)1440{1441change_local_name_cp cp;1442struct hci_request rq;14431444memset(&cp, 0, sizeof(cp));1445strncpy((char *) cp.name, name, sizeof(cp.name));14461447memset(&rq, 0, sizeof(rq));1448rq.ogf = OGF_HOST_CTL;1449rq.ocf = OCF_CHANGE_LOCAL_NAME;1450rq.cparam = &cp;1451rq.clen = CHANGE_LOCAL_NAME_CP_SIZE;14521453if (hci_send_req(dd, &rq, to) < 0)1454return -1;14551456return 0;1457}14581459int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr,1460uint8_t pscan_rep_mode,1461uint16_t clkoffset,1462int len, char *name, int to)1463{1464evt_remote_name_req_complete rn;1465remote_name_req_cp cp;1466struct hci_request rq;14671468memset(&cp, 0, sizeof(cp));1469bacpy(&cp.bdaddr, bdaddr);1470cp.pscan_rep_mode = pscan_rep_mode;1471cp.clock_offset = clkoffset;14721473memset(&rq, 0, sizeof(rq));1474rq.ogf = OGF_LINK_CTL;1475rq.ocf = OCF_REMOTE_NAME_REQ;1476rq.cparam = &cp;1477rq.clen = REMOTE_NAME_REQ_CP_SIZE;1478rq.event = EVT_REMOTE_NAME_REQ_COMPLETE;1479rq.rparam = &rn;1480rq.rlen = EVT_REMOTE_NAME_REQ_COMPLETE_SIZE;14811482if (hci_send_req(dd, &rq, to) < 0)1483return -1;14841485if (rn.status) {1486errno = EIO;1487return -1;1488}14891490rn.name[247] = '\0';1491strncpy(name, (char *) rn.name, len);1492return 0;1493}14941495int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name,1496int to)1497{1498return hci_read_remote_name_with_clock_offset(dd, bdaddr, 0x02, 0x0000,1499len, name, to);1500}15011502int hci_read_remote_name_cancel(int dd, const bdaddr_t *bdaddr, int to)1503{1504remote_name_req_cancel_cp cp;1505struct hci_request rq;15061507memset(&cp, 0, sizeof(cp));1508bacpy(&cp.bdaddr, bdaddr);15091510memset(&rq, 0, sizeof(rq));1511rq.ogf = OGF_LINK_CTL;1512rq.ocf = OCF_REMOTE_NAME_REQ_CANCEL;1513rq.cparam = &cp;1514rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE;15151516if (hci_send_req(dd, &rq, to) < 0)1517return -1;15181519return 0;1520}15211522int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver,1523int to)1524{1525evt_read_remote_version_complete rp;1526read_remote_version_cp cp;1527struct hci_request rq;15281529memset(&cp, 0, sizeof(cp));1530cp.handle = handle;15311532memset(&rq, 0, sizeof(rq));1533rq.ogf = OGF_LINK_CTL;1534rq.ocf = OCF_READ_REMOTE_VERSION;1535rq.event = EVT_READ_REMOTE_VERSION_COMPLETE;1536rq.cparam = &cp;1537rq.clen = READ_REMOTE_VERSION_CP_SIZE;1538rq.rparam = &rp;1539rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE;15401541if (hci_send_req(dd, &rq, to) < 0)1542return -1;15431544if (rp.status) {1545errno = EIO;1546return -1;1547}15481549ver->manufacturer = btohs(rp.manufacturer);1550ver->lmp_ver = rp.lmp_ver;1551ver->lmp_subver = btohs(rp.lmp_subver);1552return 0;1553}15541555int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to)1556{1557evt_read_remote_features_complete rp;1558read_remote_features_cp cp;1559struct hci_request rq;15601561memset(&cp, 0, sizeof(cp));1562cp.handle = handle;15631564memset(&rq, 0, sizeof(rq));1565rq.ogf = OGF_LINK_CTL;1566rq.ocf = OCF_READ_REMOTE_FEATURES;1567rq.event = EVT_READ_REMOTE_FEATURES_COMPLETE;1568rq.cparam = &cp;1569rq.clen = READ_REMOTE_FEATURES_CP_SIZE;1570rq.rparam = &rp;1571rq.rlen = EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE;15721573if (hci_send_req(dd, &rq, to) < 0)1574return -1;15751576if (rp.status) {1577errno = EIO;1578return -1;1579}15801581if (features)1582memcpy(features, rp.features, 8);15831584return 0;1585}15861587int hci_read_remote_ext_features(int dd, uint16_t handle, uint8_t page,1588uint8_t *max_page, uint8_t *features,1589int to)1590{1591evt_read_remote_ext_features_complete rp;1592read_remote_ext_features_cp cp;1593struct hci_request rq;15941595memset(&cp, 0, sizeof(cp));1596cp.handle = handle;1597cp.page_num = page;15981599memset(&rq, 0, sizeof(rq));1600rq.ogf = OGF_LINK_CTL;1601rq.ocf = OCF_READ_REMOTE_EXT_FEATURES;1602rq.event = EVT_READ_REMOTE_EXT_FEATURES_COMPLETE;1603rq.cparam = &cp;1604rq.clen = READ_REMOTE_EXT_FEATURES_CP_SIZE;1605rq.rparam = &rp;1606rq.rlen = EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE;16071608if (hci_send_req(dd, &rq, to) < 0)1609return -1;16101611if (rp.status) {1612errno = EIO;1613return -1;1614}16151616if (max_page)1617*max_page = rp.max_page_num;16181619if (features)1620memcpy(features, rp.features, 8);16211622return 0;1623}16241625int hci_read_clock_offset(int dd, uint16_t handle, uint16_t *clkoffset, int to)1626{1627evt_read_clock_offset_complete rp;1628read_clock_offset_cp cp;1629struct hci_request rq;16301631memset(&cp, 0, sizeof(cp));1632cp.handle = handle;16331634memset(&rq, 0, sizeof(rq));1635rq.ogf = OGF_LINK_CTL;1636rq.ocf = OCF_READ_CLOCK_OFFSET;1637rq.event = EVT_READ_CLOCK_OFFSET_COMPLETE;1638rq.cparam = &cp;1639rq.clen = READ_CLOCK_OFFSET_CP_SIZE;1640rq.rparam = &rp;1641rq.rlen = EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE;16421643if (hci_send_req(dd, &rq, to) < 0)1644return -1;16451646if (rp.status) {1647errno = EIO;1648return -1;1649}16501651*clkoffset = rp.clock_offset;1652return 0;1653}16541655int hci_read_local_version(int dd, struct hci_version *ver, int to)1656{1657read_local_version_rp rp;1658struct hci_request rq;16591660memset(&rq, 0, sizeof(rq));1661rq.ogf = OGF_INFO_PARAM;1662rq.ocf = OCF_READ_LOCAL_VERSION;1663rq.rparam = &rp;1664rq.rlen = READ_LOCAL_VERSION_RP_SIZE;16651666if (hci_send_req(dd, &rq, to) < 0)1667return -1;16681669if (rp.status) {1670errno = EIO;1671return -1;1672}16731674ver->manufacturer = btohs(rp.manufacturer);1675ver->hci_ver = rp.hci_ver;1676ver->hci_rev = btohs(rp.hci_rev);1677ver->lmp_ver = rp.lmp_ver;1678ver->lmp_subver = btohs(rp.lmp_subver);1679return 0;1680}16811682int hci_read_local_commands(int dd, uint8_t *commands, int to)1683{1684read_local_commands_rp rp;1685struct hci_request rq;16861687memset(&rq, 0, sizeof(rq));1688rq.ogf = OGF_INFO_PARAM;1689rq.ocf = OCF_READ_LOCAL_COMMANDS;1690rq.rparam = &rp;1691rq.rlen = READ_LOCAL_COMMANDS_RP_SIZE;16921693if (hci_send_req(dd, &rq, to) < 0)1694return -1;16951696if (rp.status) {1697errno = EIO;1698return -1;1699}17001701if (commands)1702memcpy(commands, rp.commands, 64);17031704return 0;1705}17061707int hci_read_local_features(int dd, uint8_t *features, int to)1708{1709read_local_features_rp rp;1710struct hci_request rq;17111712memset(&rq, 0, sizeof(rq));1713rq.ogf = OGF_INFO_PARAM;1714rq.ocf = OCF_READ_LOCAL_FEATURES;1715rq.rparam = &rp;1716rq.rlen = READ_LOCAL_FEATURES_RP_SIZE;17171718if (hci_send_req(dd, &rq, to) < 0)1719return -1;17201721if (rp.status) {1722errno = EIO;1723return -1;1724}17251726if (features)1727memcpy(features, rp.features, 8);17281729return 0;1730}17311732int hci_read_local_ext_features(int dd, uint8_t page, uint8_t *max_page,1733uint8_t *features, int to)1734{1735read_local_ext_features_cp cp;1736read_local_ext_features_rp rp;1737struct hci_request rq;17381739cp.page_num = page;17401741memset(&rq, 0, sizeof(rq));1742rq.ogf = OGF_INFO_PARAM;1743rq.ocf = OCF_READ_LOCAL_EXT_FEATURES;1744rq.cparam = &cp;1745rq.clen = READ_LOCAL_EXT_FEATURES_CP_SIZE;1746rq.rparam = &rp;1747rq.rlen = READ_LOCAL_EXT_FEATURES_RP_SIZE;17481749if (hci_send_req(dd, &rq, to) < 0)1750return -1;17511752if (rp.status) {1753errno = EIO;1754return -1;1755}17561757if (max_page)1758*max_page = rp.max_page_num;17591760if (features)1761memcpy(features, rp.features, 8);17621763return 0;1764}17651766int hci_read_bd_addr(int dd, bdaddr_t *bdaddr, int to)1767{1768read_bd_addr_rp rp;1769struct hci_request rq;17701771memset(&rq, 0, sizeof(rq));1772rq.ogf = OGF_INFO_PARAM;1773rq.ocf = OCF_READ_BD_ADDR;1774rq.rparam = &rp;1775rq.rlen = READ_BD_ADDR_RP_SIZE;17761777if (hci_send_req(dd, &rq, to) < 0)1778return -1;17791780if (rp.status) {1781errno = EIO;1782return -1;1783}17841785if (bdaddr)1786bacpy(bdaddr, &rp.bdaddr);17871788return 0;1789}17901791int hci_read_class_of_dev(int dd, uint8_t *cls, int to)1792{1793read_class_of_dev_rp rp;1794struct hci_request rq;17951796memset(&rq, 0, sizeof(rq));1797rq.ogf = OGF_HOST_CTL;1798rq.ocf = OCF_READ_CLASS_OF_DEV;1799rq.rparam = &rp;1800rq.rlen = READ_CLASS_OF_DEV_RP_SIZE;18011802if (hci_send_req(dd, &rq, to) < 0)1803return -1;18041805if (rp.status) {1806errno = EIO;1807return -1;1808}18091810memcpy(cls, rp.dev_class, 3);1811return 0;1812}18131814int hci_write_class_of_dev(int dd, uint32_t cls, int to)1815{1816write_class_of_dev_cp cp;1817struct hci_request rq;18181819memset(&rq, 0, sizeof(rq));1820cp.dev_class[0] = cls & 0xff;1821cp.dev_class[1] = (cls >> 8) & 0xff;1822cp.dev_class[2] = (cls >> 16) & 0xff;1823rq.ogf = OGF_HOST_CTL;1824rq.ocf = OCF_WRITE_CLASS_OF_DEV;1825rq.cparam = &cp;1826rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE;1827return hci_send_req(dd, &rq, to);1828}18291830int hci_read_voice_setting(int dd, uint16_t *vs, int to)1831{1832read_voice_setting_rp rp;1833struct hci_request rq;18341835memset(&rq, 0, sizeof(rq));1836rq.ogf = OGF_HOST_CTL;1837rq.ocf = OCF_READ_VOICE_SETTING;1838rq.rparam = &rp;1839rq.rlen = READ_VOICE_SETTING_RP_SIZE;18401841if (hci_send_req(dd, &rq, to) < 0)1842return -1;18431844if (rp.status) {1845errno = EIO;1846return -1;1847}18481849*vs = rp.voice_setting;1850return 0;1851}18521853int hci_write_voice_setting(int dd, uint16_t vs, int to)1854{1855write_voice_setting_cp cp;1856struct hci_request rq;18571858memset(&rq, 0, sizeof(rq));1859cp.voice_setting = vs;1860rq.ogf = OGF_HOST_CTL;1861rq.ocf = OCF_WRITE_VOICE_SETTING;1862rq.cparam = &cp;1863rq.clen = WRITE_VOICE_SETTING_CP_SIZE;18641865return hci_send_req(dd, &rq, to);1866}18671868int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to)1869{1870read_current_iac_lap_rp rp;1871struct hci_request rq;18721873memset(&rq, 0, sizeof(rq));1874rq.ogf = OGF_HOST_CTL;1875rq.ocf = OCF_READ_CURRENT_IAC_LAP;1876rq.rparam = &rp;1877rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE;18781879if (hci_send_req(dd, &rq, to) < 0)1880return -1;18811882if (rp.status) {1883errno = EIO;1884return -1;1885}18861887*num_iac = rp.num_current_iac;1888memcpy(lap, rp.lap, rp.num_current_iac * 3);1889return 0;1890}18911892int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to)1893{1894write_current_iac_lap_cp cp;1895struct hci_request rq;18961897memset(&cp, 0, sizeof(cp));1898cp.num_current_iac = num_iac;1899memcpy(&cp.lap, lap, num_iac * 3);19001901memset(&rq, 0, sizeof(rq));1902rq.ogf = OGF_HOST_CTL;1903rq.ocf = OCF_WRITE_CURRENT_IAC_LAP;1904rq.cparam = &cp;1905rq.clen = num_iac * 3 + 1;19061907return hci_send_req(dd, &rq, to);1908}19091910int hci_read_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to)1911{1912read_stored_link_key_cp cp;1913struct hci_request rq;19141915memset(&cp, 0, sizeof(cp));1916bacpy(&cp.bdaddr, bdaddr);1917cp.read_all = all;19181919memset(&rq, 0, sizeof(rq));1920rq.ogf = OGF_HOST_CTL;1921rq.ocf = OCF_READ_STORED_LINK_KEY;1922rq.cparam = &cp;1923rq.clen = READ_STORED_LINK_KEY_CP_SIZE;19241925return hci_send_req(dd, &rq, to);1926}19271928int hci_write_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t *key, int to)1929{1930unsigned char cp[WRITE_STORED_LINK_KEY_CP_SIZE + 6 + 16];1931struct hci_request rq;19321933memset(&cp, 0, sizeof(cp));1934cp[0] = 1;1935bacpy((bdaddr_t *) (cp + 1), bdaddr);1936memcpy(cp + 7, key, 16);19371938memset(&rq, 0, sizeof(rq));1939rq.ogf = OGF_HOST_CTL;1940rq.ocf = OCF_WRITE_STORED_LINK_KEY;1941rq.cparam = &cp;1942rq.clen = WRITE_STORED_LINK_KEY_CP_SIZE + 6 + 16;19431944return hci_send_req(dd, &rq, to);1945}19461947int hci_delete_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to)1948{1949delete_stored_link_key_cp cp;1950struct hci_request rq;19511952memset(&cp, 0, sizeof(cp));1953bacpy(&cp.bdaddr, bdaddr);1954cp.delete_all = all;19551956memset(&rq, 0, sizeof(rq));1957rq.ogf = OGF_HOST_CTL;1958rq.ocf = OCF_DELETE_STORED_LINK_KEY;1959rq.cparam = &cp;1960rq.clen = DELETE_STORED_LINK_KEY_CP_SIZE;19611962return hci_send_req(dd, &rq, to);1963}19641965int hci_authenticate_link(int dd, uint16_t handle, int to)1966{1967auth_requested_cp cp;1968evt_auth_complete rp;1969struct hci_request rq;19701971cp.handle = handle;19721973rq.ogf = OGF_LINK_CTL;1974rq.ocf = OCF_AUTH_REQUESTED;1975rq.event = EVT_AUTH_COMPLETE;1976rq.cparam = &cp;1977rq.clen = AUTH_REQUESTED_CP_SIZE;1978rq.rparam = &rp;1979rq.rlen = EVT_AUTH_COMPLETE_SIZE;19801981if (hci_send_req(dd, &rq, to) < 0)1982return -1;19831984if (rp.status) {1985errno = EIO;1986return -1;1987}19881989return 0;1990}19911992int hci_encrypt_link(int dd, uint16_t handle, uint8_t encrypt, int to)1993{1994set_conn_encrypt_cp cp;1995evt_encrypt_change rp;1996struct hci_request rq;19971998cp.handle = handle;1999cp.encrypt = encrypt;20002001rq.ogf = OGF_LINK_CTL;2002rq.ocf = OCF_SET_CONN_ENCRYPT;2003rq.event = EVT_ENCRYPT_CHANGE;2004rq.cparam = &cp;2005rq.clen = SET_CONN_ENCRYPT_CP_SIZE;2006rq.rparam = &rp;2007rq.rlen = EVT_ENCRYPT_CHANGE_SIZE;20082009if (hci_send_req(dd, &rq, to) < 0)2010return -1;20112012if (rp.status) {2013errno = EIO;2014return -1;2015}20162017return 0;2018}20192020int hci_change_link_key(int dd, uint16_t handle, int to)2021{2022change_conn_link_key_cp cp;2023evt_change_conn_link_key_complete rp;2024struct hci_request rq;20252026cp.handle = handle;20272028rq.ogf = OGF_LINK_CTL;2029rq.ocf = OCF_CHANGE_CONN_LINK_KEY;2030rq.event = EVT_CHANGE_CONN_LINK_KEY_COMPLETE;2031rq.cparam = &cp;2032rq.clen = CHANGE_CONN_LINK_KEY_CP_SIZE;2033rq.rparam = &rp;2034rq.rlen = EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE;20352036if (hci_send_req(dd, &rq, to) < 0)2037return -1;20382039if (rp.status) {2040errno = EIO;2041return -1;2042}20432044return 0;2045}20462047int hci_switch_role(int dd, bdaddr_t *bdaddr, uint8_t role, int to)2048{2049switch_role_cp cp;2050evt_role_change rp;2051struct hci_request rq;20522053bacpy(&cp.bdaddr, bdaddr);2054cp.role = role;2055rq.ogf = OGF_LINK_POLICY;2056rq.ocf = OCF_SWITCH_ROLE;2057rq.cparam = &cp;2058rq.clen = SWITCH_ROLE_CP_SIZE;2059rq.rparam = &rp;2060rq.rlen = EVT_ROLE_CHANGE_SIZE;2061rq.event = EVT_ROLE_CHANGE;20622063if (hci_send_req(dd, &rq, to) < 0)2064return -1;20652066if (rp.status) {2067errno = EIO;2068return -1;2069}20702071return 0;2072}20732074int hci_park_mode(int dd, uint16_t handle, uint16_t max_interval,2075uint16_t min_interval, int to)2076{2077park_mode_cp cp;2078evt_mode_change rp;2079struct hci_request rq;20802081memset(&cp, 0, sizeof (cp));2082cp.handle = handle;2083cp.max_interval = max_interval;2084cp.min_interval = min_interval;20852086memset(&rq, 0, sizeof (rq));2087rq.ogf = OGF_LINK_POLICY;2088rq.ocf = OCF_PARK_MODE;2089rq.event = EVT_MODE_CHANGE;2090rq.cparam = &cp;2091rq.clen = PARK_MODE_CP_SIZE;2092rq.rparam = &rp;2093rq.rlen = EVT_MODE_CHANGE_SIZE;20942095if (hci_send_req(dd, &rq, to) < 0)2096return -1;20972098if (rp.status) {2099errno = EIO;2100return -1;2101}21022103return 0;2104}21052106int hci_exit_park_mode(int dd, uint16_t handle, int to)2107{2108exit_park_mode_cp cp;2109evt_mode_change rp;2110struct hci_request rq;21112112memset(&cp, 0, sizeof (cp));2113cp.handle = handle;21142115memset (&rq, 0, sizeof (rq));2116rq.ogf = OGF_LINK_POLICY;2117rq.ocf = OCF_EXIT_PARK_MODE;2118rq.event = EVT_MODE_CHANGE;2119rq.cparam = &cp;2120rq.clen = EXIT_PARK_MODE_CP_SIZE;2121rq.rparam = &rp;2122rq.rlen = EVT_MODE_CHANGE_SIZE;21232124if (hci_send_req(dd, &rq, to) < 0)2125return -1;21262127if (rp.status) {2128errno = EIO;2129return -1;2130}21312132return 0;2133}21342135int hci_read_inquiry_scan_type(int dd, uint8_t *type, int to)2136{2137read_inquiry_scan_type_rp rp;2138struct hci_request rq;21392140memset(&rq, 0, sizeof(rq));2141rq.ogf = OGF_HOST_CTL;2142rq.ocf = OCF_READ_INQUIRY_SCAN_TYPE;2143rq.rparam = &rp;2144rq.rlen = READ_INQUIRY_SCAN_TYPE_RP_SIZE;21452146if (hci_send_req(dd, &rq, to) < 0)2147return -1;21482149if (rp.status) {2150errno = EIO;2151return -1;2152}21532154*type = rp.type;2155return 0;2156}21572158int hci_write_inquiry_scan_type(int dd, uint8_t type, int to)2159{2160write_inquiry_scan_type_cp cp;2161write_inquiry_scan_type_rp rp;2162struct hci_request rq;21632164memset(&cp, 0, sizeof(cp));2165cp.type = type;21662167memset(&rq, 0, sizeof(rq));2168rq.ogf = OGF_HOST_CTL;2169rq.ocf = OCF_WRITE_INQUIRY_SCAN_TYPE;2170rq.cparam = &cp;2171rq.clen = WRITE_INQUIRY_SCAN_TYPE_CP_SIZE;2172rq.rparam = &rp;2173rq.rlen = WRITE_INQUIRY_SCAN_TYPE_RP_SIZE;21742175if (hci_send_req(dd, &rq, to) < 0)2176return -1;21772178if (rp.status) {2179errno = EIO;2180return -1;2181}21822183return 0;2184}21852186int hci_read_inquiry_mode(int dd, uint8_t *mode, int to)2187{2188read_inquiry_mode_rp rp;2189struct hci_request rq;21902191memset(&rq, 0, sizeof(rq));2192rq.ogf = OGF_HOST_CTL;2193rq.ocf = OCF_READ_INQUIRY_MODE;2194rq.rparam = &rp;2195rq.rlen = READ_INQUIRY_MODE_RP_SIZE;21962197if (hci_send_req(dd, &rq, to) < 0)2198return -1;21992200if (rp.status) {2201errno = EIO;2202return -1;2203}22042205*mode = rp.mode;2206return 0;2207}22082209int hci_write_inquiry_mode(int dd, uint8_t mode, int to)2210{2211write_inquiry_mode_cp cp;2212write_inquiry_mode_rp rp;2213struct hci_request rq;22142215memset(&cp, 0, sizeof(cp));2216cp.mode = mode;22172218memset(&rq, 0, sizeof(rq));2219rq.ogf = OGF_HOST_CTL;2220rq.ocf = OCF_WRITE_INQUIRY_MODE;2221rq.cparam = &cp;2222rq.clen = WRITE_INQUIRY_MODE_CP_SIZE;2223rq.rparam = &rp;2224rq.rlen = WRITE_INQUIRY_MODE_RP_SIZE;22252226if (hci_send_req(dd, &rq, to) < 0)2227return -1;22282229if (rp.status) {2230errno = EIO;2231return -1;2232}22332234return 0;2235}22362237int hci_read_afh_mode(int dd, uint8_t *mode, int to)2238{2239read_afh_mode_rp rp;2240struct hci_request rq;22412242memset(&rq, 0, sizeof(rq));2243rq.ogf = OGF_HOST_CTL;2244rq.ocf = OCF_READ_AFH_MODE;2245rq.rparam = &rp;2246rq.rlen = READ_AFH_MODE_RP_SIZE;22472248if (hci_send_req(dd, &rq, to) < 0)2249return -1;22502251if (rp.status) {2252errno = EIO;2253return -1;2254}22552256*mode = rp.mode;2257return 0;2258}22592260int hci_write_afh_mode(int dd, uint8_t mode, int to)2261{2262write_afh_mode_cp cp;2263write_afh_mode_rp rp;2264struct hci_request rq;22652266memset(&cp, 0, sizeof(cp));2267cp.mode = mode;22682269memset(&rq, 0, sizeof(rq));2270rq.ogf = OGF_HOST_CTL;2271rq.ocf = OCF_WRITE_AFH_MODE;2272rq.cparam = &cp;2273rq.clen = WRITE_AFH_MODE_CP_SIZE;2274rq.rparam = &rp;2275rq.rlen = WRITE_AFH_MODE_RP_SIZE;22762277if (hci_send_req(dd, &rq, to) < 0)2278return -1;22792280if (rp.status) {2281errno = EIO;2282return -1;2283}22842285return 0;2286}22872288int hci_read_ext_inquiry_response(int dd, uint8_t *fec, uint8_t *data, int to)2289{2290read_ext_inquiry_response_rp rp;2291struct hci_request rq;22922293memset(&rq, 0, sizeof(rq));2294rq.ogf = OGF_HOST_CTL;2295rq.ocf = OCF_READ_EXT_INQUIRY_RESPONSE;2296rq.rparam = &rp;2297rq.rlen = READ_EXT_INQUIRY_RESPONSE_RP_SIZE;22982299if (hci_send_req(dd, &rq, to) < 0)2300return -1;23012302if (rp.status) {2303errno = EIO;2304return -1;2305}23062307*fec = rp.fec;2308memcpy(data, rp.data, HCI_MAX_EIR_LENGTH);23092310return 0;2311}23122313int hci_write_ext_inquiry_response(int dd, uint8_t fec, uint8_t *data, int to)2314{2315write_ext_inquiry_response_cp cp;2316write_ext_inquiry_response_rp rp;2317struct hci_request rq;23182319memset(&cp, 0, sizeof(cp));2320cp.fec = fec;2321memcpy(cp.data, data, HCI_MAX_EIR_LENGTH);23222323memset(&rq, 0, sizeof(rq));2324rq.ogf = OGF_HOST_CTL;2325rq.ocf = OCF_WRITE_EXT_INQUIRY_RESPONSE;2326rq.cparam = &cp;2327rq.clen = WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE;2328rq.rparam = &rp;2329rq.rlen = WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE;23302331if (hci_send_req(dd, &rq, to) < 0)2332return -1;23332334if (rp.status) {2335errno = EIO;2336return -1;2337}23382339return 0;2340}23412342int hci_read_simple_pairing_mode(int dd, uint8_t *mode, int to)2343{2344read_simple_pairing_mode_rp rp;2345struct hci_request rq;23462347memset(&rq, 0, sizeof(rq));2348rq.ogf = OGF_HOST_CTL;2349rq.ocf = OCF_READ_SIMPLE_PAIRING_MODE;2350rq.rparam = &rp;2351rq.rlen = READ_SIMPLE_PAIRING_MODE_RP_SIZE;23522353if (hci_send_req(dd, &rq, to) < 0)2354return -1;23552356if (rp.status) {2357errno = EIO;2358return -1;2359}23602361*mode = rp.mode;2362return 0;2363}23642365int hci_write_simple_pairing_mode(int dd, uint8_t mode, int to)2366{2367write_simple_pairing_mode_cp cp;2368write_simple_pairing_mode_rp rp;2369struct hci_request rq;23702371memset(&cp, 0, sizeof(cp));2372cp.mode = mode;23732374memset(&rq, 0, sizeof(rq));2375rq.ogf = OGF_HOST_CTL;2376rq.ocf = OCF_WRITE_SIMPLE_PAIRING_MODE;2377rq.cparam = &cp;2378rq.clen = WRITE_SIMPLE_PAIRING_MODE_CP_SIZE;2379rq.rparam = &rp;2380rq.rlen = WRITE_SIMPLE_PAIRING_MODE_RP_SIZE;23812382if (hci_send_req(dd, &rq, to) < 0)2383return -1;23842385if (rp.status) {2386errno = EIO;2387return -1;2388}23892390return 0;2391}23922393int hci_read_local_oob_data(int dd, uint8_t *hash, uint8_t *randomizer, int to)2394{2395read_local_oob_data_rp rp;2396struct hci_request rq;23972398memset(&rq, 0, sizeof(rq));2399rq.ogf = OGF_HOST_CTL;2400rq.ocf = OCF_READ_LOCAL_OOB_DATA;2401rq.rparam = &rp;2402rq.rlen = READ_LOCAL_OOB_DATA_RP_SIZE;24032404if (hci_send_req(dd, &rq, to) < 0)2405return -1;24062407if (rp.status) {2408errno = EIO;2409return -1;2410}24112412memcpy(hash, rp.hash, 16);2413memcpy(randomizer, rp.randomizer, 16);2414return 0;2415}24162417int hci_read_inq_response_tx_power_level(int dd, int8_t *level, int to)2418{2419read_inq_response_tx_power_level_rp rp;2420struct hci_request rq;24212422memset(&rq, 0, sizeof(rq));2423rq.ogf = OGF_HOST_CTL;2424rq.ocf = OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL;2425rq.rparam = &rp;2426rq.rlen = READ_INQ_RESPONSE_TX_POWER_LEVEL_RP_SIZE;24272428if (hci_send_req(dd, &rq, to) < 0)2429return -1;24302431if (rp.status) {2432errno = EIO;2433return -1;2434}24352436*level = rp.level;2437return 0;2438}24392440int hci_read_inquiry_transmit_power_level(int dd, int8_t *level, int to)2441{2442return hci_read_inq_response_tx_power_level(dd, level, to);2443}24442445int hci_write_inquiry_transmit_power_level(int dd, int8_t level, int to)2446{2447write_inquiry_transmit_power_level_cp cp;2448write_inquiry_transmit_power_level_rp rp;2449struct hci_request rq;24502451memset(&cp, 0, sizeof(cp));2452cp.level = level;24532454memset(&rq, 0, sizeof(rq));2455rq.ogf = OGF_HOST_CTL;2456rq.ocf = OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL;2457rq.cparam = &cp;2458rq.clen = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_CP_SIZE;2459rq.rparam = &rp;2460rq.rlen = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE;24612462if (hci_send_req(dd, &rq, to) < 0)2463return -1;24642465if (rp.status) {2466errno = EIO;2467return -1;2468}24692470return 0;2471}24722473int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type,2474int8_t *level, int to)2475{2476read_transmit_power_level_cp cp;2477read_transmit_power_level_rp rp;2478struct hci_request rq;24792480memset(&cp, 0, sizeof(cp));2481cp.handle = handle;2482cp.type = type;24832484memset(&rq, 0, sizeof(rq));2485rq.ogf = OGF_HOST_CTL;2486rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL;2487rq.cparam = &cp;2488rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE;2489rq.rparam = &rp;2490rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE;24912492if (hci_send_req(dd, &rq, to) < 0)2493return -1;24942495if (rp.status) {2496errno = EIO;2497return -1;2498}24992500*level = rp.level;2501return 0;2502}25032504int hci_read_link_policy(int dd, uint16_t handle, uint16_t *policy, int to)2505{2506read_link_policy_rp rp;2507struct hci_request rq;25082509memset(&rq, 0, sizeof(rq));2510rq.ogf = OGF_LINK_POLICY;2511rq.ocf = OCF_READ_LINK_POLICY;2512rq.cparam = &handle;2513rq.clen = 2;2514rq.rparam = &rp;2515rq.rlen = READ_LINK_POLICY_RP_SIZE;25162517if (hci_send_req(dd, &rq, to) < 0)2518return -1;25192520if (rp.status) {2521errno = EIO;2522return -1;2523}25242525*policy = rp.policy;2526return 0;2527}25282529int hci_write_link_policy(int dd, uint16_t handle, uint16_t policy, int to)2530{2531write_link_policy_cp cp;2532write_link_policy_rp rp;2533struct hci_request rq;25342535memset(&cp, 0, sizeof(cp));2536cp.handle = handle;2537cp.policy = policy;25382539memset(&rq, 0, sizeof(rq));2540rq.ogf = OGF_LINK_POLICY;2541rq.ocf = OCF_WRITE_LINK_POLICY;2542rq.cparam = &cp;2543rq.clen = WRITE_LINK_POLICY_CP_SIZE;2544rq.rparam = &rp;2545rq.rlen = WRITE_LINK_POLICY_RP_SIZE;25462547if (hci_send_req(dd, &rq, to) < 0)2548return -1;25492550if (rp.status) {2551errno = EIO;2552return -1;2553}25542555return 0;2556}25572558int hci_read_link_supervision_timeout(int dd, uint16_t handle,2559uint16_t *timeout, int to)2560{2561read_link_supervision_timeout_rp rp;2562struct hci_request rq;25632564memset(&rq, 0, sizeof(rq));2565rq.ogf = OGF_HOST_CTL;2566rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT;2567rq.cparam = &handle;2568rq.clen = 2;2569rq.rparam = &rp;2570rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE;25712572if (hci_send_req(dd, &rq, to) < 0)2573return -1;25742575if (rp.status) {2576errno = EIO;2577return -1;2578}25792580*timeout = rp.timeout;2581return 0;2582}25832584int hci_write_link_supervision_timeout(int dd, uint16_t handle,2585uint16_t timeout, int to)2586{2587write_link_supervision_timeout_cp cp;2588write_link_supervision_timeout_rp rp;2589struct hci_request rq;25902591memset(&cp, 0, sizeof(cp));2592cp.handle = handle;2593cp.timeout = timeout;25942595memset(&rq, 0, sizeof(rq));2596rq.ogf = OGF_HOST_CTL;2597rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT;2598rq.cparam = &cp;2599rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE;2600rq.rparam = &rp;2601rq.rlen = WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE;26022603if (hci_send_req(dd, &rq, to) < 0)2604return -1;26052606if (rp.status) {2607errno = EIO;2608return -1;2609}26102611return 0;2612}26132614int hci_set_afh_classification(int dd, uint8_t *map, int to)2615{2616set_afh_classification_cp cp;2617set_afh_classification_rp rp;2618struct hci_request rq;26192620memset(&cp, 0, sizeof(cp));2621memcpy(cp.map, map, 10);26222623memset(&rq, 0, sizeof(rq));2624rq.ogf = OGF_HOST_CTL;2625rq.ocf = OCF_SET_AFH_CLASSIFICATION;2626rq.cparam = &cp;2627rq.clen = SET_AFH_CLASSIFICATION_CP_SIZE;2628rq.rparam = &rp;2629rq.rlen = SET_AFH_CLASSIFICATION_RP_SIZE;26302631if (hci_send_req(dd, &rq, to) < 0)2632return -1;26332634if (rp.status) {2635errno = EIO;2636return -1;2637}26382639return 0;2640}26412642int hci_read_link_quality(int dd, uint16_t handle, uint8_t *link_quality,2643int to)2644{2645read_link_quality_rp rp;2646struct hci_request rq;26472648memset(&rq, 0, sizeof(rq));2649rq.ogf = OGF_STATUS_PARAM;2650rq.ocf = OCF_READ_LINK_QUALITY;2651rq.cparam = &handle;2652rq.clen = 2;2653rq.rparam = &rp;2654rq.rlen = READ_LINK_QUALITY_RP_SIZE;26552656if (hci_send_req(dd, &rq, to) < 0)2657return -1;26582659if (rp.status) {2660errno = EIO;2661return -1;2662}26632664*link_quality = rp.link_quality;2665return 0;2666}26672668int hci_read_rssi(int dd, uint16_t handle, int8_t *rssi, int to)2669{2670read_rssi_rp rp;2671struct hci_request rq;26722673memset(&rq, 0, sizeof(rq));2674rq.ogf = OGF_STATUS_PARAM;2675rq.ocf = OCF_READ_RSSI;2676rq.cparam = &handle;2677rq.clen = 2;2678rq.rparam = &rp;2679rq.rlen = READ_RSSI_RP_SIZE;26802681if (hci_send_req(dd, &rq, to) < 0)2682return -1;26832684if (rp.status) {2685errno = EIO;2686return -1;2687}26882689*rssi = rp.rssi;2690return 0;2691}26922693int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map,2694int to)2695{2696read_afh_map_rp rp;2697struct hci_request rq;26982699memset(&rq, 0, sizeof(rq));2700rq.ogf = OGF_STATUS_PARAM;2701rq.ocf = OCF_READ_AFH_MAP;2702rq.cparam = &handle;2703rq.clen = 2;2704rq.rparam = &rp;2705rq.rlen = READ_AFH_MAP_RP_SIZE;27062707if (hci_send_req(dd, &rq, to) < 0)2708return -1;27092710if (rp.status) {2711errno = EIO;2712return -1;2713}27142715*mode = rp.mode;2716memcpy(map, rp.map, 10);2717return 0;2718}27192720int hci_read_clock(int dd, uint16_t handle, uint8_t which, uint32_t *clock,2721uint16_t *accuracy, int to)2722{2723read_clock_cp cp;2724read_clock_rp rp;2725struct hci_request rq;27262727memset(&cp, 0, sizeof(cp));2728cp.handle = handle;2729cp.which_clock = which;27302731memset(&rq, 0, sizeof(rq));2732rq.ogf = OGF_STATUS_PARAM;2733rq.ocf = OCF_READ_CLOCK;2734rq.cparam = &cp;2735rq.clen = READ_CLOCK_CP_SIZE;2736rq.rparam = &rp;2737rq.rlen = READ_CLOCK_RP_SIZE;27382739if (hci_send_req(dd, &rq, to) < 0)2740return -1;27412742if (rp.status) {2743errno = EIO;2744return -1;2745}27462747*clock = rp.clock;2748*accuracy = rp.accuracy;2749return 0;2750}27512752int hci_le_set_scan_enable(int dd, uint8_t enable, uint8_t filter_dup, int to)2753{2754struct hci_request rq;2755le_set_scan_enable_cp scan_cp;2756uint8_t status;27572758memset(&scan_cp, 0, sizeof(scan_cp));2759scan_cp.enable = enable;2760scan_cp.filter_dup = filter_dup;27612762memset(&rq, 0, sizeof(rq));2763rq.ogf = OGF_LE_CTL;2764rq.ocf = OCF_LE_SET_SCAN_ENABLE;2765rq.cparam = &scan_cp;2766rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE;2767rq.rparam = &status;2768rq.rlen = 1;27692770if (hci_send_req(dd, &rq, to) < 0)2771return -1;27722773if (status) {2774errno = EIO;2775return -1;2776}27772778return 0;2779}27802781int hci_le_set_scan_parameters(int dd, uint8_t type,2782uint16_t interval, uint16_t window,2783uint8_t own_type, uint8_t filter, int to)2784{2785struct hci_request rq;2786le_set_scan_parameters_cp param_cp;2787uint8_t status;27882789memset(¶m_cp, 0, sizeof(param_cp));2790param_cp.type = type;2791param_cp.interval = interval;2792param_cp.window = window;2793param_cp.own_bdaddr_type = own_type;2794param_cp.filter = filter;27952796memset(&rq, 0, sizeof(rq));2797rq.ogf = OGF_LE_CTL;2798rq.ocf = OCF_LE_SET_SCAN_PARAMETERS;2799rq.cparam = ¶m_cp;2800rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE;2801rq.rparam = &status;2802rq.rlen = 1;28032804if (hci_send_req(dd, &rq, to) < 0)2805return -1;28062807if (status) {2808errno = EIO;2809return -1;2810}28112812return 0;2813}28142815int hci_le_set_advertise_enable(int dd, uint8_t enable, int to)2816{2817struct hci_request rq;2818le_set_advertise_enable_cp adv_cp;2819uint8_t status;28202821memset(&adv_cp, 0, sizeof(adv_cp));2822adv_cp.enable = enable;28232824memset(&rq, 0, sizeof(rq));2825rq.ogf = OGF_LE_CTL;2826rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;2827rq.cparam = &adv_cp;2828rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;2829rq.rparam = &status;2830rq.rlen = 1;28312832if (hci_send_req(dd, &rq, to) < 0)2833return -1;28342835if (status) {2836errno = EIO;2837return -1;2838}28392840return 0;2841}28422843int hci_le_create_conn(int dd, uint16_t interval, uint16_t window,2844uint8_t initiator_filter, uint8_t peer_bdaddr_type,2845bdaddr_t peer_bdaddr, uint8_t own_bdaddr_type,2846uint16_t min_interval, uint16_t max_interval,2847uint16_t latency, uint16_t supervision_timeout,2848uint16_t min_ce_length, uint16_t max_ce_length,2849uint16_t *handle, int to)2850{2851struct hci_request rq;2852le_create_connection_cp create_conn_cp;2853evt_le_connection_complete conn_complete_rp;28542855memset(&create_conn_cp, 0, sizeof(create_conn_cp));2856create_conn_cp.interval = interval;2857create_conn_cp.window = window;2858create_conn_cp.initiator_filter = initiator_filter;2859create_conn_cp.peer_bdaddr_type = peer_bdaddr_type;2860create_conn_cp.peer_bdaddr = peer_bdaddr;2861create_conn_cp.own_bdaddr_type = own_bdaddr_type;2862create_conn_cp.min_interval = min_interval;2863create_conn_cp.max_interval = max_interval;2864create_conn_cp.latency = latency;2865create_conn_cp.supervision_timeout = supervision_timeout;2866create_conn_cp.min_ce_length = min_ce_length;2867create_conn_cp.max_ce_length = max_ce_length;28682869memset(&rq, 0, sizeof(rq));2870rq.ogf = OGF_LE_CTL;2871rq.ocf = OCF_LE_CREATE_CONN;2872rq.event = EVT_LE_CONN_COMPLETE;2873rq.cparam = &create_conn_cp;2874rq.clen = LE_CREATE_CONN_CP_SIZE;2875rq.rparam = &conn_complete_rp;2876rq.rlen = EVT_CONN_COMPLETE_SIZE;28772878if (hci_send_req(dd, &rq, to) < 0)2879return -1;28802881if (conn_complete_rp.status) {2882errno = EIO;2883return -1;2884}28852886if (handle)2887*handle = conn_complete_rp.handle;28882889return 0;2890}28912892int hci_le_conn_update(int dd, uint16_t handle, uint16_t min_interval,2893uint16_t max_interval, uint16_t latency,2894uint16_t supervision_timeout, int to)2895{2896evt_le_connection_update_complete evt;2897le_connection_update_cp cp;2898struct hci_request rq;28992900memset(&cp, 0, sizeof(cp));2901cp.handle = handle;2902cp.min_interval = min_interval;2903cp.max_interval = max_interval;2904cp.latency = latency;2905cp.supervision_timeout = supervision_timeout;2906cp.min_ce_length = htobs(0x0001);2907cp.max_ce_length = htobs(0x0001);29082909memset(&rq, 0, sizeof(rq));2910rq.ogf = OGF_LE_CTL;2911rq.ocf = OCF_LE_CONN_UPDATE;2912rq.cparam = &cp;2913rq.clen = LE_CONN_UPDATE_CP_SIZE;2914rq.event = EVT_LE_CONN_UPDATE_COMPLETE;2915rq.rparam = &evt;2916rq.rlen = sizeof(evt);29172918if (hci_send_req(dd, &rq, to) < 0)2919return -1;29202921if (evt.status) {2922errno = EIO;2923return -1;2924}29252926return 0;2927}292829292930