From a48d8b4639f36e6fc2d7e87cac92e178674caaa1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 8 Mar 2002 21:10:06 +0000 Subject: Initial revision --- src/hci.c | 624 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 624 insertions(+) create mode 100644 src/hci.c (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c new file mode 100644 index 00000000..e9693d3e --- /dev/null +++ b/src/hci.c @@ -0,0 +1,624 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef struct { + char *str; unsigned int val; +} hci_map; + +static char * hci_uint2str(hci_map *m, unsigned int val) +{ + static char str[50]; + char *ptr = str; + + *ptr = 0; + while (m->str) { + if ((unsigned int) m->val & val) + ptr += sprintf(ptr, "%s ", m->str); + m++; + } + return str; +} + +int hci_str2uint(hci_map *map, char *str, unsigned int *val) +{ + char *t, *ptr; + hci_map *m; + int set; + + if (!str) + return 0; + + str = ptr = strdup(str); + *val = set = 0; + + while ((t=strsep(&ptr, ","))) { + for (m=map; m->str; m++) { + if (!strcasecmp(m->str,t)) { + *val |= (unsigned int) m->val; + set = 1; + } + } + } + free(str); + + return set; +} + +char *hci_dtypetostr(int type) +{ + switch (type) { + case HCI_VHCI: + return "VHCI"; + case HCI_USB: + return "USB "; + case HCI_PCCARD: + return "PCCARD"; + case HCI_UART: + return "UART"; + default: + return "UKNW"; + } +} + +/* HCI dev flags mapping */ +hci_map dev_flags_map[] = { + { "UP", HCI_UP }, + { "INIT", HCI_INIT }, + { "RUNNING", HCI_RUNNING }, + { "RAW", HCI_RAW }, + { "PSCAN", HCI_PSCAN }, + { "ISCAN", HCI_ISCAN }, + { "IQUIRY", HCI_INQUIRY }, + { "AUTH", HCI_AUTH }, + { "ENCRYPT", HCI_ENCRYPT }, + { NULL } +}; +char *hci_dflagstostr(uint32_t flags) +{ + static char str[50]; + char *ptr = str; + hci_map *m = dev_flags_map; + + *ptr = 0; + + if (!hci_test_bit(HCI_UP, &flags)) + ptr += sprintf(ptr, "DOWN "); + + while (m->str) { + if (hci_test_bit(m->val, &flags)) + ptr += sprintf(ptr, "%s ", m->str); + m++; + } + return str; +} + +/* HCI packet type mapping */ +hci_map pkt_type_map[] = { + { "DM1", HCI_DM1 }, + { "DM3", HCI_DM3 }, + { "DM5", HCI_DM5 }, + { "DH1", HCI_DH1 }, + { "DH3", HCI_DH3 }, + { "DH5", HCI_DH5 }, + { "HV1", HCI_HV1 }, + { "HV2", HCI_HV2 }, + { "HV3", HCI_HV3 }, + { NULL } +}; +char *hci_ptypetostr(unsigned int ptype) +{ + return hci_uint2str(pkt_type_map, ptype); +} +int hci_strtoptype(char *str, unsigned int *val) +{ + return hci_str2uint(pkt_type_map, str, val); +} + +/* Link policy mapping */ +hci_map link_policy_map[] = { + { "NONE", 0 }, + { "RSWITCH", HCI_LP_RSWITCH }, + { "HOLD", HCI_LP_HOLD }, + { "SNIFF", HCI_LP_SNIFF }, + { "PARK", HCI_LP_PARK }, + { NULL } +}; +char *hci_lptostr(unsigned int lp) +{ + return hci_uint2str(link_policy_map, lp); +} +int hci_strtolp(char *str, unsigned int *val) +{ + return hci_str2uint(link_policy_map, str, val); +} + +/* Link mode mapping */ +hci_map link_mode_map[] = { + { "NONE", 0 }, + { "ACCEPT", HCI_LM_ACCEPT }, + { "MASTER", HCI_LM_MASTER }, + { "AUTH", HCI_LM_AUTH }, + { "ENCRYPT", HCI_LM_ENCRYPT}, + { "TRUSTED", HCI_LM_TRUSTED}, + { NULL } +}; +char *hci_lmtostr(unsigned int lm) +{ + static char str[50]; + + str[0] = 0; + if (!(lm & HCI_LM_MASTER)) + strcpy(str, "SLAVE "); + + strcat(str, hci_uint2str(link_mode_map, lm)); + return str; +} +int hci_strtolm(char *str, unsigned int *val) +{ + return hci_str2uint(link_mode_map, str, val); +} + +/* HCI functions that do not require open device */ + +int hci_devinfo(int dev_id, struct hci_dev_info *di) +{ + int s, err; + + s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (s < 0) + return s; + + di->dev_id = dev_id; + err = ioctl(s, HCIGETDEVINFO, (void *) di); + close(s); + + return err; +} + +inquiry_info *hci_inquiry(int dev_id, int len, int *num_rsp, uint8_t *lap, long flags) +{ + struct hci_inquiry_req *ir; + char *buf, *ptr; + int s, err, size; + + if (!*num_rsp) + *num_rsp = 200; // enough ? + + size = sizeof(*ir) + (sizeof(inquiry_info) * (*num_rsp)); + if (!(buf = malloc(size))) + return NULL; + + ir = (void *)buf; + ir->dev_id = dev_id; + ir->num_rsp = *num_rsp; + ir->length = len; + ir->flags = flags; + + if (lap) { + memcpy(ir->lap, lap, 3); + } else { + ir->lap[0] = 0x33; + ir->lap[1] = 0x8b; + ir->lap[2] = 0x9e; + } + + if ((s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) + goto failed; + if (ioctl(s, HCIINQUIRY, (unsigned long)buf) < 0) + goto failed; + + size = sizeof(inquiry_info) * ir->num_rsp; + if (!(ptr = malloc(size))) + goto failed; + + memcpy(ptr, buf + sizeof(*ir), size); + *num_rsp = ir->num_rsp; + + free(buf); + close(s); + return (void *) ptr; + +failed: + err = errno; + free(buf); + close(s); + errno = err; + return NULL; +} + +/* Open HCI device. + * Returns device descriptor (dd). */ +int hci_open_dev(int dev_id) +{ + struct sockaddr_hci a; + int dd, err; + + /* Create HCI socket */ + dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (dd < 0) + return dd; + + /* Bind socket to the HCI device */ + a.hci_family = AF_BLUETOOTH; + a.hci_dev = dev_id; + if (bind(dd, (struct sockaddr *)&a, sizeof(a)) < 0) + goto failed; + + return dd; + +failed: + err = errno; + close(dd); + errno = err; + return -1; +} + +int hci_close_dev(int dd) +{ + return close(dd); +} + +/* HCI functions that require open device + * dd - Device descriptor returned by hci_dev_open. */ + +int hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + uint8_t type = HCI_COMMAND_PKT; + hci_command_hdr hc; + struct iovec iv[3]; + int ivn; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + iv[0].iov_base = &type; + iv[0].iov_len = 1; + iv[1].iov_base = &hc; + iv[1].iov_len = HCI_COMMAND_HDR_SIZE; + ivn = 2; + + if (plen) { + iv[2].iov_base = param; + iv[2].iov_len = plen; + ivn = 3; + } + + while (writev(dd, iv, ivn) < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + return -1; + } + return 0; +} + +int hci_send_req(int dd, struct hci_request *r, int to) +{ + unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + struct hci_filter nf, of; + hci_event_hdr *hdr; + int err, len, try; + + len = sizeof(of); + if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &len) < 0) + return -1; + + hci_filter_clear(&nf); + hci_filter_set_ptype(HCI_EVENT_PKT, &nf); + hci_filter_set_event(EVT_CMD_STATUS, &nf); + hci_filter_set_event(EVT_CMD_COMPLETE, &nf); + hci_filter_set_event(r->event, &nf); + hci_filter_set_opcode(opcode, &nf); + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) + return -1; + + if (hci_send_cmd(dd, r->ogf, r->ocf, r->clen, r->cparam) < 0) + goto failed; + + try = 10; + while (try--) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + + if (to) { + struct pollfd p; + int n; + + p.fd = dd; p.events = POLLIN; + while ((n = poll(&p, 1, to)) < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + goto failed; + } + + if (!n) { + errno = ETIMEDOUT; + goto failed; + } + + to -= 10; + if (to < 0) to = 0; + + } + + while ((len = read(dd, buf, sizeof(buf))) < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + goto failed; + } + + hdr = (void *)(buf + 1); + ptr = buf + (1 + HCI_EVENT_HDR_SIZE); + len -= (1 + HCI_EVENT_HDR_SIZE); + + switch (hdr->evt) { + case EVT_CMD_STATUS: + cs = (void *)ptr; + + if (cs->opcode != opcode) + continue; + + if (cs->status) { + errno = EIO; + goto failed; + } + break; + + case EVT_CMD_COMPLETE: + cc = (void *)ptr; + + if (cc->opcode != opcode) + continue; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + memcpy(r->rparam, ptr, r->rlen); + goto done; + + default: + if (hdr->evt != r->event) + break; + + r->rlen = MIN(len, r->rlen); + memcpy(r->rparam, ptr, r->rlen); + goto done; + } + } + errno = ETIMEDOUT; + +failed: + err = errno; + setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of)); + errno = err; + return -1; + +done: + setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of)); + return 0; +} + +int hci_create_connection(int dd, bdaddr_t *ba, int ptype, int rswitch, int to) +{ + evt_conn_complete rp; + create_conn_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, ba); + cp.pkt_type = ptype; + cp.role_switch = rswitch; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_CREATE_CONN; + rq.event = EVT_CONN_COMPLETE; + rq.cparam = &cp; + rq.clen = CREATE_CONN_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CONN_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return rp.handle; +} + +int hci_disconnect(int dd, int hndl, int res, int to) +{ + evt_disconn_complete rp; + disconnect_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = hndl; + cp.reason = res; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.event = EVT_DISCONN_COMPLETE; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_DISCONN_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + return 0; +} + +int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +{ + evt_remote_name_req_complete rn; + remote_name_req_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, ba); + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_REMOTE_NAME_REQ; + rq.cparam = &cp; + rq.clen = REMOTE_NAME_REQ_CP_SIZE; + rq.event = EVT_REMOTE_NAME_REQ_COMPLETE; + rq.rparam = &rn; + rq.rlen = EVT_REMOTE_NAME_REQ_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rn.status) { + errno = EIO; + return -1; + } + + rn.name[247] = '\0'; + strncpy(name, rn.name, len); + return 0; +} + +int hci_read_remote_features(int dd, int hndl, uint8_t *features, int to) +{ + evt_read_remote_features_complete rp; + read_remote_features_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = hndl; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_READ_REMOTE_FEATURES; + rq.event = EVT_READ_REMOTE_FEATURES_COMPLETE; + rq.cparam = &cp; + rq.clen = READ_REMOTE_FEATURES_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(features, rp.features, 8); + return 0; +} + +int hci_read_remote_version(int dd, int hndl, struct hci_version *ver, int to) +{ + evt_read_remote_version_complete rp; + read_remote_version_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = hndl; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_READ_REMOTE_VERSION; + rq.event = EVT_READ_REMOTE_VERSION_COMPLETE; + rq.cparam = &cp; + rq.clen = READ_REMOTE_VERSION_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + ver->manufacturer = btohs(rp.manufacturer); + ver->lmp_ver = rp.lmp_ver; + ver->lmp_subver = btohs(rp.lmp_subver); + return 0; +} + +int hci_read_local_version(int dd, struct hci_version *ver, int to) +{ + read_local_version_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + ver->manufacturer = btohs(rp.manufacturer); + ver->hci_ver = rp.lmp_ver; + ver->hci_rev = btohs(rp.hci_rev); + ver->lmp_ver = rp.lmp_ver; + ver->lmp_subver = btohs(rp.lmp_subver); + + return 0; +} -- cgit From 9ff2c721bb4ff84ad15e4593404bf47941315337 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 19 Mar 2002 17:35:54 +0000 Subject: Added hci_local_name function. --- src/hci.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index e9693d3e..1e20243b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -503,6 +503,29 @@ int hci_disconnect(int dd, int hndl, int res, int to) return 0; } +int hci_local_name(int dd, int len, char *name, int to) +{ + read_local_name_rp rp; + struct hci_request rq; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_NAME; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_NAME_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + rp.name[247] = '\0'; + strncpy(name, rp.name, len); + return 0; +} + int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) { evt_remote_name_req_complete rn; -- cgit From a51747b602f9cd03c7431788f80431c1710f5827 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 21 Mar 2002 23:20:32 +0000 Subject: Additional strtoXX and XXtostr functions. --- src/hci.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 8 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 1e20243b..cd65a296 100644 --- a/src/hci.c +++ b/src/hci.c @@ -51,7 +51,7 @@ typedef struct { char *str; unsigned int val; } hci_map; -static char * hci_uint2str(hci_map *m, unsigned int val) +static char *hci_bit2str(hci_map *m, unsigned int val) { static char str[50]; char *ptr = str; @@ -65,7 +65,7 @@ static char * hci_uint2str(hci_map *m, unsigned int val) return str; } -int hci_str2uint(hci_map *map, char *str, unsigned int *val) +static int hci_str2bit(hci_map *map, char *str, unsigned int *val) { char *t, *ptr; hci_map *m; @@ -90,6 +90,46 @@ int hci_str2uint(hci_map *map, char *str, unsigned int *val) return set; } +static char *hci_uint2str(hci_map *m, unsigned int val) +{ + static char str[50]; + char *ptr = str; + + *ptr = 0; + while (m->str) { + if ((unsigned int) m->val == val) { + ptr += sprintf(ptr, "%s", m->str); + break; + } + m++; + } + return str; +} + +static int hci_str2uint(hci_map *map, char *str, unsigned int *val) +{ + char *t, *ptr; + hci_map *m; + int set = 0; + + if (!str) + return 0; + + str = ptr = strdup(str); + + while ((t=strsep(&ptr, ","))) { + for (m=map; m->str; m++) { + if (!strcasecmp(m->str,t)) { + *val = (unsigned int) m->val; set = 1; + break; + } + } + } + free(str); + + return set; +} + char *hci_dtypetostr(int type) { switch (type) { @@ -153,11 +193,11 @@ hci_map pkt_type_map[] = { }; char *hci_ptypetostr(unsigned int ptype) { - return hci_uint2str(pkt_type_map, ptype); + return hci_bit2str(pkt_type_map, ptype); } int hci_strtoptype(char *str, unsigned int *val) { - return hci_str2uint(pkt_type_map, str, val); + return hci_str2bit(pkt_type_map, str, val); } /* Link policy mapping */ @@ -171,11 +211,11 @@ hci_map link_policy_map[] = { }; char *hci_lptostr(unsigned int lp) { - return hci_uint2str(link_policy_map, lp); + return hci_bit2str(link_policy_map, lp); } int hci_strtolp(char *str, unsigned int *val) { - return hci_str2uint(link_policy_map, str, val); + return hci_str2bit(link_policy_map, str, val); } /* Link mode mapping */ @@ -196,12 +236,38 @@ char *hci_lmtostr(unsigned int lm) if (!(lm & HCI_LM_MASTER)) strcpy(str, "SLAVE "); - strcat(str, hci_uint2str(link_mode_map, lm)); + strcat(str, hci_bit2str(link_mode_map, lm)); return str; } int hci_strtolm(char *str, unsigned int *val) { - return hci_str2uint(link_mode_map, str, val); + return hci_str2bit(link_mode_map, str, val); +} + +/* Version mapping */ +hci_map ver_map[] = { + { "1.0b", 0x00 }, + { "1.1", 0x01 }, + { NULL } +}; +char *hci_vertostr(unsigned int ver) +{ + char *str = hci_uint2str(ver_map, ver); + return *str ? str : "n/a"; +} +int hci_strtover(char *str, unsigned int *ver) +{ + return hci_str2uint(ver_map, str, ver); +} + +char *lmp_vertostr(unsigned int ver) +{ + char *str = hci_uint2str(ver_map, ver); + return *str ? str : "n/a"; +} +int lmp_strtover(char *str, unsigned int *ver) +{ + return hci_str2uint(ver_map, str, ver); } /* HCI functions that do not require open device */ -- cgit From 0a6472fe170438016c23c71d9129e627f26cd398 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:45:46 +0000 Subject: Fixed compiler options and warnings. Proper parameter types. Cleanup. --- src/hci.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index cd65a296..3e1dd52e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -511,7 +511,7 @@ done: return 0; } -int hci_create_connection(int dd, bdaddr_t *ba, int ptype, int rswitch, int to) +int hci_create_connection(int dd, bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) { evt_conn_complete rp; create_conn_cp cp; @@ -519,8 +519,9 @@ int hci_create_connection(int dd, bdaddr_t *ba, int ptype, int rswitch, int to) memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); - cp.pkt_type = ptype; - cp.role_switch = rswitch; + cp.pkt_type = ptype; + cp.clock_offset = clkoffset; + cp.role_switch = rswitch; rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_CREATE_CONN; @@ -538,18 +539,19 @@ int hci_create_connection(int dd, bdaddr_t *ba, int ptype, int rswitch, int to) return -1; } - return rp.handle; + *handle = rp.handle; + return 0; } -int hci_disconnect(int dd, int hndl, int res, int to) +int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) { evt_disconn_complete rp; disconnect_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = hndl; - cp.reason = res; + cp.handle = handle; + cp.reason = reason; rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_DISCONNECT; @@ -622,14 +624,14 @@ int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) return 0; } -int hci_read_remote_features(int dd, int hndl, uint8_t *features, int to) +int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) { evt_read_remote_features_complete rp; read_remote_features_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = hndl; + cp.handle = handle; rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_FEATURES; @@ -651,14 +653,14 @@ int hci_read_remote_features(int dd, int hndl, uint8_t *features, int to) return 0; } -int hci_read_remote_version(int dd, int hndl, struct hci_version *ver, int to) +int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, int to) { evt_read_remote_version_complete rp; read_remote_version_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = hndl; + cp.handle = handle; rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_VERSION; -- cgit From 87f8b3bc7c1967cef913de6b23bbdebb8f98d19e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 25 Mar 2002 19:12:16 +0000 Subject: Fix static allocations. --- src/hci.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 3e1dd52e..fb7a2780 100644 --- a/src/hci.c +++ b/src/hci.c @@ -53,9 +53,12 @@ typedef struct { static char *hci_bit2str(hci_map *m, unsigned int val) { - static char str[50]; + char *str = malloc(50); char *ptr = str; + if (!str) + return NULL; + *ptr = 0; while (m->str) { if ((unsigned int) m->val & val) @@ -71,10 +74,10 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) hci_map *m; int set; + str = ptr = strdup(str); if (!str) return 0; - str = ptr = strdup(str); *val = set = 0; while ((t=strsep(&ptr, ","))) { @@ -92,9 +95,12 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) static char *hci_uint2str(hci_map *m, unsigned int val) { - static char str[50]; + char *str = malloc(50); char *ptr = str; + if (!str) + return NULL; + *ptr = 0; while (m->str) { if ((unsigned int) m->val == val) { @@ -161,10 +167,13 @@ hci_map dev_flags_map[] = { }; char *hci_dflagstostr(uint32_t flags) { - static char str[50]; + char *str = malloc(50); char *ptr = str; hci_map *m = dev_flags_map; + if (!str) + return NULL; + *ptr = 0; if (!hci_test_bit(HCI_UP, &flags)) @@ -230,13 +239,22 @@ hci_map link_mode_map[] = { }; char *hci_lmtostr(unsigned int lm) { - static char str[50]; + char *s, *str = malloc(50); + if (!str) + return NULL; - str[0] = 0; + *str = 0; if (!(lm & HCI_LM_MASTER)) strcpy(str, "SLAVE "); - strcat(str, hci_bit2str(link_mode_map, lm)); + s = hci_bit2str(link_mode_map, lm); + if (!s) { + free(str); + return NULL; + } + + strcat(str, s); + free(s); return str; } int hci_strtolm(char *str, unsigned int *val) @@ -706,7 +724,7 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) } ver->manufacturer = btohs(rp.manufacturer); - ver->hci_ver = rp.lmp_ver; + ver->hci_ver = rp.hci_ver; ver->hci_rev = btohs(rp.hci_rev); ver->lmp_ver = rp.lmp_ver; ver->lmp_subver = btohs(rp.lmp_subver); -- cgit From b442a036129e5bfe44eb95ef036bdb13f2eba009 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 26 Mar 2002 19:25:05 +0000 Subject: Check for null string in strtobit. --- src/hci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index fb7a2780..544607b9 100644 --- a/src/hci.c +++ b/src/hci.c @@ -74,8 +74,7 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) hci_map *m; int set; - str = ptr = strdup(str); - if (!str) + if (!str || !(str = ptr = strdup(str))) return 0; *val = set = 0; -- cgit From 00012f0fe236ff884d28c12781398183dac51b7f Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 10 Apr 2002 18:20:36 +0000 Subject: hci_req initialization fixes. --- src/hci.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 544607b9..a3ffe28b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -593,10 +593,12 @@ int hci_local_name(int dd, int len, char *name, int to) read_local_name_rp rp; struct hci_request rq; - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LOCAL_NAME; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_NAME; + rq.cparam = NULL; + rq.clen = 0; rq.rparam = &rp; - rq.rlen = READ_LOCAL_NAME_RP_SIZE; + rq.rlen = READ_LOCAL_NAME_RP_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -620,8 +622,8 @@ int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_REMOTE_NAME_REQ; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_REMOTE_NAME_REQ; rq.cparam = &cp; rq.clen = REMOTE_NAME_REQ_CP_SIZE; rq.event = EVT_REMOTE_NAME_REQ_COMPLETE; @@ -706,13 +708,12 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) read_local_version_rp rp; struct hci_request rq; - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_INFO_PARAM; - rq.ocf = OCF_READ_LOCAL_VERSION; + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; rq.cparam = NULL; - rq.clen = 0; + rq.clen = 0; rq.rparam = &rp; - rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; if (hci_send_req(dd, &rq, 1000) < 0) return -1; -- cgit From 8dab9b0bcab616bde55a3a137bd6fb8818ced4a5 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 11 Apr 2002 16:56:10 +0000 Subject: Added LMP features to sting translation function and table. --- src/hci.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index a3ffe28b..af494c15 100644 --- a/src/hci.c +++ b/src/hci.c @@ -53,7 +53,7 @@ typedef struct { static char *hci_bit2str(hci_map *m, unsigned int val) { - char *str = malloc(50); + char *str = malloc(120); char *ptr = str; if (!str) @@ -287,6 +287,71 @@ int lmp_strtover(char *str, unsigned int *ver) return hci_str2uint(ver_map, str, ver); } +/* LMP features mapping */ +hci_map lmp_features_map[][9] = { + { /* byte 0 */ + { "<3-slot packets>", LMP_3SLOT }, + { "<5-slot packets>", LMP_5SLOT }, + { "", LMP_ENCRYPT }, + { "", LMP_SOFFSET }, + { "", LMP_TACCURACY}, + { "", LMP_RSWITCH }, + { "", LMP_HOLD }, + { "", LMP_SNIFF }, + { NULL } + }, + { /* byte 1 */ + { "", LMP_PARK }, + { "", LMP_RSSI }, + { "", LMP_QUALITY }, + { "", LMP_SCO }, + { "", LMP_HV2 }, + { "", LMP_HV3 }, + { "", LMP_ULAW }, + { "", LMP_ALAW }, + { NULL } + }, + { /* byte 2 */ + { "", LMP_CVSD }, + { "", LMP_PSCHEME }, + { "", LMP_PCONTROL }, + { "", LMP_TRSP_SCO }, + { NULL } + }, + {{ NULL }} +}; + +char *lmp_featurestostr(uint8_t *features, char *pref, int width) +{ + char *ptr, *str = malloc(400); + int i, w; + + if (!str) + return NULL; + + ptr = str; *ptr = 0; + + if (pref) + ptr += sprintf(ptr, "%s", pref); + + for(i=0, w=0; lmp_features_map[i][0].str; i++) { + hci_map *m; + + m = lmp_features_map[i]; + while (m->str) { + if ((unsigned int) m->val & (unsigned int) features[i]) + ptr += sprintf(ptr, "%s ", m->str); + m++; + + w = (w + 1) & width; + if (!w) + ptr += sprintf(ptr, "\n%s", pref); + } + } + + return str; +} + /* HCI functions that do not require open device */ int hci_devinfo(int dev_id, struct hci_dev_info *di) -- cgit From 083ac35c0e178f548da930e91fe4154a4993af0e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 11 Apr 2002 18:19:58 +0000 Subject: Added hci_class_of_dev function. hci_req initialization cleanup. --- src/hci.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index af494c15..9418eb42 100644 --- a/src/hci.c +++ b/src/hci.c @@ -605,6 +605,7 @@ int hci_create_connection(int dd, bdaddr_t *ba, uint16_t ptype, uint16_t clkoffs cp.clock_offset = clkoffset; cp.role_switch = rswitch; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_CREATE_CONN; rq.event = EVT_CONN_COMPLETE; @@ -635,6 +636,7 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) cp.handle = handle; cp.reason = reason; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_DISCONNECT; rq.event = EVT_DISCONN_COMPLETE; @@ -658,10 +660,9 @@ int hci_local_name(int dd, int len, char *name, int to) read_local_name_rp rp; struct hci_request rq; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LOCAL_NAME; - rq.cparam = NULL; - rq.clen = 0; rq.rparam = &rp; rq.rlen = READ_LOCAL_NAME_RP_SIZE; @@ -687,6 +688,7 @@ int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_REMOTE_NAME_REQ; rq.cparam = &cp; @@ -717,6 +719,7 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) memset(&cp, 0, sizeof(cp)); cp.handle = handle; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_FEATURES; rq.event = EVT_READ_REMOTE_FEATURES_COMPLETE; @@ -746,6 +749,7 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in memset(&cp, 0, sizeof(cp)); cp.handle = handle; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_VERSION; rq.event = EVT_READ_REMOTE_VERSION_COMPLETE; @@ -773,10 +777,9 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) read_local_version_rp rp; struct hci_request rq; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_INFO_PARAM; rq.ocf = OCF_READ_LOCAL_VERSION; - rq.cparam = NULL; - rq.clen = 0; rq.rparam = &rp; rq.rlen = READ_LOCAL_VERSION_RP_SIZE; @@ -796,3 +799,26 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) return 0; } + +int hci_class_of_dev(int dd, uint8_t *class, int to) +{ + read_class_of_dev_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_CLASS_OF_DEV; + rq.rparam = &rp; + rq.rlen = READ_CLASS_OF_DEV_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(class, rp.dev_class, 3); + return 0; +} -- cgit From e6564963d4e3c7efe92e30c00fa289dd5a964f28 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 15 Apr 2002 16:55:14 +0000 Subject: lmp_featuretostr fixes --- src/hci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 9418eb42..6af14864 100644 --- a/src/hci.c +++ b/src/hci.c @@ -339,13 +339,13 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) m = lmp_features_map[i]; while (m->str) { - if ((unsigned int) m->val & (unsigned int) features[i]) + if ((unsigned int) m->val & (unsigned int) features[i]) { ptr += sprintf(ptr, "%s ", m->str); + w = (w + 1) & width; + if (!w) + ptr += sprintf(ptr, "\n%s", pref ? pref : ""); + } m++; - - w = (w + 1) & width; - if (!w) - ptr += sprintf(ptr, "\n%s", pref); } } -- cgit From bf19cd7953fbc8cc916b9514d8f11fc8557f0cec Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 17 May 2002 17:12:30 +0000 Subject: Add hci_devba function --- src/hci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 6af14864..426eb91e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -369,6 +369,22 @@ int hci_devinfo(int dev_id, struct hci_dev_info *di) return err; } +int hci_devba(int dev_id, bdaddr_t *ba) +{ + struct hci_dev_info di; + + if (hci_devinfo(dev_id, &di)) + return -1; + + if (!hci_test_bit(HCI_UP, &di.flags)) { + errno = ENETDOWN; + return -1; + } + + bacpy(ba, &di.bdaddr); + return 0; +} + inquiry_info *hci_inquiry(int dev_id, int len, int *num_rsp, uint8_t *lap, long flags) { struct hci_inquiry_req *ir; -- cgit From 4837bd7e9ba55361aeca45610a160dd107d5be2f Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 16:46:54 +0000 Subject: Fix inquiry function to return errors and accept user buffers. New functions hci_for_each_dev and hci_get_route. --- src/hci.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 28 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 426eb91e..bc645686 100644 --- a/src/hci.c +++ b/src/hci.c @@ -354,6 +354,59 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) /* HCI functions that do not require open device */ +int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg) +{ + struct hci_dev_list_req *dl; + struct hci_dev_req *dr; + int dev_id = -1; + int s, i; + + s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (s < 0) + return -1; + + dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); + if (!dl) { + close(s); + return -1; + } + + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(s, HCIGETDEVLIST, (void *)dl)) + goto done; + + for (i=0; i < dl->dev_num; i++, dr++) { + if (hci_test_bit(flag, &dr->dev_opt)) + if (!func || func(s, dr->dev_id, arg)) { + dev_id = dr->dev_id; + break; + } + } + +done: + close(s); + free(dl); + return dev_id; +} + +static int __other_bdaddr(int s, int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + return 0; + return bacmp((bdaddr_t *)arg, &di.bdaddr); +} + +int hci_get_route(bdaddr_t *bdaddr) +{ + if (bdaddr) + return hci_for_each_dev(HCI_UP, __other_bdaddr, (long) bdaddr); + else + return hci_for_each_dev(HCI_UP, NULL, 0); +} + int hci_devinfo(int dev_id, struct hci_dev_info *di) { int s, err; @@ -385,22 +438,33 @@ int hci_devba(int dev_id, bdaddr_t *ba) return 0; } -inquiry_info *hci_inquiry(int dev_id, int len, int *num_rsp, uint8_t *lap, long flags) +int hci_inquiry(int dev_id, int len, int nrsp, uint8_t *lap, inquiry_info **ii, long flags) { struct hci_inquiry_req *ir; - char *buf, *ptr; - int s, err, size; + void *buf; + int s, err; - if (!*num_rsp) - *num_rsp = 200; // enough ? + if (nrsp <= 0) + nrsp = 200; // enough ? - size = sizeof(*ir) + (sizeof(inquiry_info) * (*num_rsp)); - if (!(buf = malloc(size))) - return NULL; + if (dev_id < 0 && (dev_id = hci_get_route(NULL)) < 0) { + errno = ENODEV; + return -1; + } + + s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (s < 0) + return -1; + + buf = malloc(sizeof(*ir) + (sizeof(inquiry_info) * (nrsp))); + if (!buf) { + close(s); + return -1; + } - ir = (void *)buf; + ir = buf; ir->dev_id = dev_id; - ir->num_rsp = *num_rsp; + ir->num_rsp = nrsp; ir->length = len; ir->flags = flags; @@ -412,28 +476,23 @@ inquiry_info *hci_inquiry(int dev_id, int len, int *num_rsp, uint8_t *lap, long ir->lap[2] = 0x9e; } - if ((s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) - goto failed; - if (ioctl(s, HCIINQUIRY, (unsigned long)buf) < 0) - goto failed; - - size = sizeof(inquiry_info) * ir->num_rsp; - if (!(ptr = malloc(size))) - goto failed; + err = ioctl(s, HCIINQUIRY, (unsigned long) buf); + close(s); - memcpy(ptr, buf + sizeof(*ir), size); - *num_rsp = ir->num_rsp; + if (!err) { + int size = sizeof(inquiry_info) * ir->num_rsp; - free(buf); - close(s); - return (void *) ptr; + if (!*ii) + *ii = (void *) malloc(size); -failed: - err = errno; + if (*ii) { + memcpy((void *) *ii, buf + sizeof(*ir), size); + err = ir->num_rsp; + } else + err = -1; + } free(buf); - close(s); - errno = err; - return NULL; + return err; } /* Open HCI device. @@ -838,3 +897,4 @@ int hci_class_of_dev(int dd, uint8_t *class, int to) memcpy(class, rp.dev_class, 3); return 0; } + -- cgit From d316a5fbab4a41ce3f8321eef407db9c53b57e85 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 18:15:13 +0000 Subject: Added hci_devid function. --- src/hci.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index bc645686..f72ef760 100644 --- a/src/hci.c +++ b/src/hci.c @@ -399,6 +399,14 @@ static int __other_bdaddr(int s, int dev_id, long arg) return bacmp((bdaddr_t *)arg, &di.bdaddr); } +static int __same_bdaddr(int s, int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + return 0; + return !bacmp((bdaddr_t *)arg, &di.bdaddr); +} + int hci_get_route(bdaddr_t *bdaddr) { if (bdaddr) @@ -407,6 +415,11 @@ int hci_get_route(bdaddr_t *bdaddr) return hci_for_each_dev(HCI_UP, NULL, 0); } +int hci_devid(bdaddr_t *bdaddr) +{ + return hci_for_each_dev(HCI_UP, __same_bdaddr, (long) bdaddr); +} + int hci_devinfo(int dev_id, struct hci_dev_info *di) { int s, err; -- cgit From 9942261d0febb9ef243ffe810421451e97925e68 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 18:32:44 +0000 Subject: improved hci_devid --- src/hci.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index f72ef760..c0be8df2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -415,9 +415,20 @@ int hci_get_route(bdaddr_t *bdaddr) return hci_for_each_dev(HCI_UP, NULL, 0); } -int hci_devid(bdaddr_t *bdaddr) +int hci_devid(char *str) { - return hci_for_each_dev(HCI_UP, __same_bdaddr, (long) bdaddr); + bdaddr_t ba; + int id = -1; + + if (!strncmp(str, "hci", 3) && strlen(str) >= 4) { + id = atoi(str + 3); + if (hci_devba(id, &ba) < 0) + return -1; + } else { + str2ba(str, &ba); + id = hci_for_each_dev(HCI_UP, __same_bdaddr, (long) &ba); + } + return id; } int hci_devinfo(int dev_id, struct hci_dev_info *di) -- cgit From e549aca0820bd58dc7b714f365ff0c46a941dc65 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 18:48:36 +0000 Subject: Return correct error if adds was not found. --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index c0be8df2..1424ddcd 100644 --- a/src/hci.c +++ b/src/hci.c @@ -425,6 +425,7 @@ int hci_devid(char *str) if (hci_devba(id, &ba) < 0) return -1; } else { + errno = ENODEV; str2ba(str, &ba); id = hci_for_each_dev(HCI_UP, __same_bdaddr, (long) &ba); } -- cgit From 803bf105508009f7efc87276a539dda244527690 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 21 Aug 2002 16:38:15 +0000 Subject: implement hci_{read, write}_current_iac_lap() --- src/hci.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 1424ddcd..40a19fb2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -923,3 +923,42 @@ int hci_class_of_dev(int dd, uint8_t *class, int to) return 0; } +int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) +{ + read_current_iac_lap_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_CURRENT_IAC_LAP; + rq.rparam = &rp; + rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; + if (0 > hci_send_req(dd, &rq, to)) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + *num_iac = rp.num_current_iac; + memcpy(lap, rp.lap, 3*rp.num_current_iac); + return 0; +} + +int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) +{ + write_current_iac_lap_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.num_current_iac = num_iac; + memcpy(&cp.lap, lap, 3*num_iac); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; + rq.cparam = &cp; + rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + if (0 > hci_send_req(dd, &rq, to)) + return -1; + return 0; +} -- cgit From 9aa01920bf2e6f3b9b23b44d7c5e48dadc2f8da8 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2002 09:19:29 +0000 Subject: implement hci_{read, write}_class_of_dev() --- src/hci.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 40a19fb2..6b60477a 100644 --- a/src/hci.c +++ b/src/hci.c @@ -900,7 +900,7 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) return 0; } -int hci_class_of_dev(int dd, uint8_t *class, int to) +int hci_read_class_of_dev(int dd, uint8_t *cls, int to) { read_class_of_dev_rp rp; struct hci_request rq; @@ -919,10 +919,26 @@ int hci_class_of_dev(int dd, uint8_t *class, int to) return -1; } - memcpy(class, rp.dev_class, 3); + memcpy(cls, rp.dev_class, 3); return 0; } +int hci_write_class_of_dev(int dd, uint32_t cls, int to) +{ + write_class_of_dev_cp cp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + cp.dev_class[0] = cls & 0xff; + cp.dev_class[1] = (cls >> 8) & 0xff; + cp.dev_class[2] = (cls >> 16) & 0xff; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CLASS_OF_DEV; + rq.cparam = &cp; + rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; + return hci_send_req(dd, &rq, 1000); +} + int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) { read_current_iac_lap_rp rp; -- cgit From e329c9ff80a76cb34ff616bce80df0d161731d0b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2002 10:04:18 +0000 Subject: hci_write_local_name() --- src/hci.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 6b60477a..7f2c1745 100644 --- a/src/hci.c +++ b/src/hci.c @@ -755,7 +755,7 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) return 0; } -int hci_local_name(int dd, int len, char *name, int to) +int hci_read_local_name(int dd, int len, char *name, int to) { read_local_name_rp rp; struct hci_request rq; @@ -779,7 +779,24 @@ int hci_local_name(int dd, int len, char *name, int to) return 0; } -int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +int hci_write_local_name(int dd, char *name, int to) +{ + change_local_name_cp cp; + struct hci_request rq; + + strncpy(cp.name, name, sizeof(cp.name)); + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_CHANGE_LOCAL_NAME; + rq.cparam = &cp; + rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + return 0; +} + +int hci_read_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; -- cgit From 66d1c38bdf157527c00cf7bde69e1de7bdd3ea28 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2002 17:17:57 +0000 Subject: resurrect hci_local_name(); fix whitespace --- src/hci.c | 113 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 59 insertions(+), 54 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 7f2c1745..a9d3268d 100644 --- a/src/hci.c +++ b/src/hci.c @@ -755,6 +755,11 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) return 0; } +int hci_local_name(int dd, int len, char *name, int to) +{ + return hci_read_local_name(dd, len, name, to); +} + int hci_read_local_name(int dd, int len, char *name, int to) { read_local_name_rp rp; @@ -781,19 +786,19 @@ int hci_read_local_name(int dd, int len, char *name, int to) int hci_write_local_name(int dd, char *name, int to) { - change_local_name_cp cp; - struct hci_request rq; + change_local_name_cp cp; + struct hci_request rq; - strncpy(cp.name, name, sizeof(cp.name)); - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_CHANGE_LOCAL_NAME; - rq.cparam = &cp; - rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; + strncpy(cp.name, name, sizeof(cp.name)); + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_CHANGE_LOCAL_NAME; + rq.cparam = &cp; + rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; - if (hci_send_req(dd, &rq, to) < 0) - return -1; - return 0; + if (hci_send_req(dd, &rq, to) < 0) + return -1; + return 0; } int hci_read_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) @@ -942,56 +947,56 @@ int hci_read_class_of_dev(int dd, uint8_t *cls, int to) int hci_write_class_of_dev(int dd, uint32_t cls, int to) { - write_class_of_dev_cp cp; - struct hci_request rq; + write_class_of_dev_cp cp; + struct hci_request rq; - memset(&rq, 0, sizeof(rq)); - cp.dev_class[0] = cls & 0xff; - cp.dev_class[1] = (cls >> 8) & 0xff; - cp.dev_class[2] = (cls >> 16) & 0xff; - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CLASS_OF_DEV; - rq.cparam = &cp; - rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; - return hci_send_req(dd, &rq, 1000); + memset(&rq, 0, sizeof(rq)); + cp.dev_class[0] = cls & 0xff; + cp.dev_class[1] = (cls >> 8) & 0xff; + cp.dev_class[2] = (cls >> 16) & 0xff; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CLASS_OF_DEV; + rq.cparam = &cp; + rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; + return hci_send_req(dd, &rq, 1000); } int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) { - read_current_iac_lap_rp rp; - struct hci_request rq; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_CURRENT_IAC_LAP; - rq.rparam = &rp; - rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; - if (0 > hci_send_req(dd, &rq, to)) - return -1; - if (rp.status) { - errno = EIO; - return -1; - } - *num_iac = rp.num_current_iac; - memcpy(lap, rp.lap, 3*rp.num_current_iac); - return 0; + read_current_iac_lap_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_CURRENT_IAC_LAP; + rq.rparam = &rp; + rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; + if (0 > hci_send_req(dd, &rq, to)) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + *num_iac = rp.num_current_iac; + memcpy(lap, rp.lap, 3*rp.num_current_iac); + return 0; } int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) { - write_current_iac_lap_cp cp; - struct hci_request rq; - - memset(&cp, 0, sizeof(cp)); - cp.num_current_iac = num_iac; - memcpy(&cp.lap, lap, 3*num_iac); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; - rq.cparam = &cp; - rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; - if (0 > hci_send_req(dd, &rq, to)) - return -1; - return 0; + write_current_iac_lap_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.num_current_iac = num_iac; + memcpy(&cp.lap, lap, 3*num_iac); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; + rq.cparam = &cp; + rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + if (0 > hci_send_req(dd, &rq, to)) + return -1; + return 0; } -- cgit From 96cd06b189af2a09bde5d752552f58fd495d5646 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 18 Sep 2002 00:37:04 +0000 Subject: resurrect hci_remote_name() --- src/hci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index a9d3268d..af0ffd65 100644 --- a/src/hci.c +++ b/src/hci.c @@ -801,6 +801,11 @@ int hci_write_local_name(int dd, char *name, int to) return 0; } +int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +{ + return hci_read_remote_name(dd, ba, len, name, to); +} + int hci_read_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) { evt_remote_name_req_complete rn; -- cgit From 79cd53450eeb6555077f7ede0b5e02a23d7bebe8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 22 Sep 2002 23:59:17 +0000 Subject: Add HCI_PCI to the device types --- src/hci.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index af0ffd65..dcc24666 100644 --- a/src/hci.c +++ b/src/hci.c @@ -146,6 +146,10 @@ char *hci_dtypetostr(int type) return "PCCARD"; case HCI_UART: return "UART"; + case HCI_RS232: + return "RS232"; + case HCI_PCI: + return "PCI"; default: return "UKNW"; } -- cgit From a1e51b622a5d7dad098ed0b856c37c18da495692 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Nov 2002 21:54:27 +0000 Subject: Fix hci_for_each_dev() to work on big endian machines. --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index dcc24666..89d481b4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -369,7 +369,7 @@ int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg if (s < 0) return -1; - dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); + dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); if (!dl) { close(s); return -1; -- cgit From a0a3d96eed5f186278ea931953d4bcb6cd99cc7a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 2 Dec 2002 20:24:17 +0000 Subject: Fix a typo --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 89d481b4..42de36e5 100644 --- a/src/hci.c +++ b/src/hci.c @@ -163,7 +163,7 @@ hci_map dev_flags_map[] = { { "RAW", HCI_RAW }, { "PSCAN", HCI_PSCAN }, { "ISCAN", HCI_ISCAN }, - { "IQUIRY", HCI_INQUIRY }, + { "INQUIRY", HCI_INQUIRY }, { "AUTH", HCI_AUTH }, { "ENCRYPT", HCI_ENCRYPT }, { NULL } -- cgit From d6cbeb4c61f5dc0c0d04dd022139b44f81964b18 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Dec 2002 13:18:53 +0000 Subject: Support for voice setting --- src/hci.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 42de36e5..b8bbc0c2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -970,6 +970,43 @@ int hci_write_class_of_dev(int dd, uint32_t cls, int to) return hci_send_req(dd, &rq, 1000); } +int hci_read_voice_setting(int dd, uint16_t *vs, int to) +{ + read_voice_setting_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_VOICE_SETTING; + rq.rparam = &rp; + rq.rlen = READ_VOICE_SETTING_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *vs = rp.voice_setting; + return 0; +} + +int hci_write_voice_setting(int dd, uint16_t vs, int to) +{ + write_voice_setting_cp cp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + cp.voice_setting = vs; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_VOICE_SETTING; + rq.cparam = &cp; + rq.clen = WRITE_VOICE_SETTING_CP_SIZE; + return hci_send_req(dd, &rq, 1000); +} + int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) { read_current_iac_lap_rp rp; -- cgit From 6a1cfd82efe91f0dc81ca4e3ea50e8c2077f415e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 24 Jan 2003 09:41:07 +0000 Subject: Don't ignore the timeout parameter --- src/hci.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index b8bbc0c2..ddc15672 100644 --- a/src/hci.c +++ b/src/hci.c @@ -914,7 +914,7 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) rq.rparam = &rp; rq.rlen = READ_LOCAL_VERSION_RP_SIZE; - if (hci_send_req(dd, &rq, 1000) < 0) + if (hci_send_req(dd, &rq, to) < 0) return -1; if (rp.status) { @@ -967,7 +967,7 @@ int hci_write_class_of_dev(int dd, uint32_t cls, int to) rq.ocf = OCF_WRITE_CLASS_OF_DEV; rq.cparam = &cp; rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; - return hci_send_req(dd, &rq, 1000); + return hci_send_req(dd, &rq, to); } int hci_read_voice_setting(int dd, uint16_t *vs, int to) @@ -1004,7 +1004,7 @@ int hci_write_voice_setting(int dd, uint16_t vs, int to) rq.ocf = OCF_WRITE_VOICE_SETTING; rq.cparam = &cp; rq.clen = WRITE_VOICE_SETTING_CP_SIZE; - return hci_send_req(dd, &rq, 1000); + return hci_send_req(dd, &rq, to); } int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) @@ -1017,14 +1017,17 @@ int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) rq.ocf = OCF_READ_CURRENT_IAC_LAP; rq.rparam = &rp; rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; - if (0 > hci_send_req(dd, &rq, to)) + + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; } + *num_iac = rp.num_current_iac; - memcpy(lap, rp.lap, 3*rp.num_current_iac); + memcpy(lap, rp.lap, rp.num_current_iac * 3); return 0; } @@ -1035,14 +1038,12 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) memset(&cp, 0, sizeof(cp)); cp.num_current_iac = num_iac; - memcpy(&cp.lap, lap, 3*num_iac); + memcpy(&cp.lap, lap, num_iac * 3); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; rq.cparam = &cp; rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; - if (0 > hci_send_req(dd, &rq, to)) - return -1; - return 0; + return hci_send_req(dd, &rq, to); } -- cgit From 109bfa547ab9e24672472371e2183dcec24d0058 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 11 Feb 2003 10:22:23 +0000 Subject: add const to fn sigs; fns to auth and enc links --- src/hci.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index ddc15672..abcfb447 100644 --- a/src/hci.c +++ b/src/hci.c @@ -419,7 +419,7 @@ int hci_get_route(bdaddr_t *bdaddr) return hci_for_each_dev(HCI_UP, NULL, 0); } -int hci_devid(char *str) +int hci_devid(const char *str) { bdaddr_t ba; int id = -1; @@ -467,7 +467,7 @@ int hci_devba(int dev_id, bdaddr_t *ba) return 0; } -int hci_inquiry(int dev_id, int len, int nrsp, uint8_t *lap, inquiry_info **ii, long flags) +int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info **ii, long flags) { struct hci_inquiry_req *ir; void *buf; @@ -697,7 +697,7 @@ done: return 0; } -int hci_create_connection(int dd, bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) +int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) { evt_conn_complete rp; create_conn_cp cp; @@ -788,7 +788,7 @@ int hci_read_local_name(int dd, int len, char *name, int to) return 0; } -int hci_write_local_name(int dd, char *name, int to) +int hci_write_local_name(int dd, const char *name, int to) { change_local_name_cp cp; struct hci_request rq; @@ -805,12 +805,12 @@ int hci_write_local_name(int dd, char *name, int to) return 0; } -int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +int hci_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to) { return hci_read_remote_name(dd, ba, len, name, to); } -int hci_read_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +int hci_read_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; @@ -1047,3 +1047,30 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; return hci_send_req(dd, &rq, to); } + +int hci_authenticate_link(int dd, uint16_t handle, int to) +{ + auth_requested_cp cp; + struct hci_request rq; + + cp.handle = handle; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_AUTH_REQUESTED; + rq.cparam = &cp; + rq.clen = AUTH_REQUESTED_CP_SIZE; + return hci_send_req(dd, &rq, to); +} + +int hci_encrypt_link(int dd, uint16_t handle, int on, int to) +{ + set_conn_encrypt_cp cp; + struct hci_request rq; + + cp.handle = handle; + cp.encrypt = on; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.cparam = &cp; + rq.clen = SET_CONN_ENCRYPT_CP_SIZE; + return hci_send_req(dd, &rq, to); +} -- cgit From 8ab4acd91521e11b769c8b1d2c89a40cf9077396 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 21 Mar 2003 14:13:46 +0000 Subject: Use R1 for default value of pscan_rep_mode --- src/hci.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index abcfb447..312c748e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -703,11 +703,12 @@ int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t c create_conn_cp cp; struct hci_request rq; - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.bdaddr, ba); - cp.pkt_type = ptype; - cp.clock_offset = clkoffset; - cp.role_switch = rswitch; + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, ba); + cp.pkt_type = ptype; + cp.pscan_rep_mode = 0x01; + cp.clock_offset = clkoffset; + cp.role_switch = rswitch; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; -- cgit From bfcbbde6d7baebca27c6e93f02f6279e5f36c866 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 21 Mar 2003 14:26:12 +0000 Subject: Use R1 for default value of pscan_rep_mode --- src/hci.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 312c748e..5c58b129 100644 --- a/src/hci.c +++ b/src/hci.c @@ -800,7 +800,7 @@ int hci_write_local_name(int dd, const char *name, int to) rq.ocf = OCF_CHANGE_LOCAL_NAME; rq.cparam = &cp; rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; - + if (hci_send_req(dd, &rq, to) < 0) return -1; return 0; @@ -819,6 +819,7 @@ int hci_read_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); + cp.pscan_rep_mode = 0x01; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; @@ -847,10 +848,10 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) evt_read_remote_features_complete rp; read_remote_features_cp cp; struct hci_request rq; - + memset(&cp, 0, sizeof(cp)); cp.handle = handle; - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_FEATURES; @@ -859,15 +860,15 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) rq.clen = READ_REMOTE_FEATURES_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE; - + if (hci_send_req(dd, &rq, to) < 0) return -1; - + if (rp.status) { errno = EIO; return -1; } - + memcpy(features, rp.features, 8); return 0; } @@ -877,10 +878,10 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in evt_read_remote_version_complete rp; read_remote_version_cp cp; struct hci_request rq; - + memset(&cp, 0, sizeof(cp)); cp.handle = handle; - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_VERSION; @@ -889,15 +890,15 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in rq.clen = READ_REMOTE_VERSION_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE; - + if (hci_send_req(dd, &rq, to) < 0) return -1; - + if (rp.status) { errno = EIO; return -1; } - + ver->manufacturer = btohs(rp.manufacturer); ver->lmp_ver = rp.lmp_ver; ver->lmp_subver = btohs(rp.lmp_subver); @@ -928,7 +929,6 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) ver->hci_rev = btohs(rp.hci_rev); ver->lmp_ver = rp.lmp_ver; ver->lmp_subver = btohs(rp.lmp_subver); - return 0; } -- cgit From 1c9576607a611e033e0bac0f56d91146c120a16d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Mar 2003 08:00:36 +0000 Subject: Support for reading the clock offset --- src/hci.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 5c58b129..9a5c7dfe 100644 --- a/src/hci.c +++ b/src/hci.c @@ -905,6 +905,36 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in return 0; } +int hci_read_clock_offset(int dd, uint16_t handle, uint16_t *clkoffset, int to) +{ + evt_read_clock_offset_complete rp; + read_clock_offset_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_READ_CLOCK_OFFSET; + rq.event = EVT_READ_CLOCK_OFFSET_COMPLETE; + rq.cparam = &cp; + rq.clen = READ_CLOCK_OFFSET_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *clkoffset = rp.clock_offset; + return 0; +} + int hci_read_local_version(int dd, struct hci_version *ver, int to) { read_local_version_rp rp; -- cgit From 6cd70af01a46b7e543c50d0646b877c38b3257f4 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 19 May 2003 17:47:22 +0000 Subject: fix auth and encrypt --- src/hci.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 9a5c7dfe..e6cf48c4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1082,6 +1082,7 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) int hci_authenticate_link(int dd, uint16_t handle, int to) { auth_requested_cp cp; + evt_auth_complete rp; struct hci_request rq; cp.handle = handle; @@ -1089,12 +1090,22 @@ int hci_authenticate_link(int dd, uint16_t handle, int to) rq.ocf = OCF_AUTH_REQUESTED; rq.cparam = &cp; rq.clen = AUTH_REQUESTED_CP_SIZE; - return hci_send_req(dd, &rq, to); + rq.rparam = &rp; + rq.event = EVT_AUTH_COMPLETE; + rq.rlen = EVT_AUTH_COMPLETE_SIZE; + if (hci_send_req(dd, &rq, to) < 0) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } int hci_encrypt_link(int dd, uint16_t handle, int on, int to) { set_conn_encrypt_cp cp; + evt_encrypt_change rp; struct hci_request rq; cp.handle = handle; @@ -1103,5 +1114,14 @@ int hci_encrypt_link(int dd, uint16_t handle, int on, int to) rq.ocf = OCF_SET_CONN_ENCRYPT; rq.cparam = &cp; rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - return hci_send_req(dd, &rq, to); + rq.event = EVT_ENCRYPT_CHANGE; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; + rq.rparam = &rp; + if (hci_send_req(dd, &rq, to) < 0) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } -- cgit From 2c375c1f2c5cff353e2f767ac14f8251452392e9 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 20 May 2003 11:33:53 +0000 Subject: add role switch --- src/hci.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index e6cf48c4..6d313d21 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1125,3 +1125,27 @@ int hci_encrypt_link(int dd, uint16_t handle, int on, int to) } return 0; } + +int hci_switch_role(int dd, bdaddr_t peer, int role, int to) +{ + switch_role_cp cp; + evt_role_change rp; + struct hci_request rq; + + cp.bdaddr = peer; + cp.role = role; + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_SWITCH_ROLE; + rq.cparam = &cp; + rq.clen = SWITCH_ROLE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_ROLE_CHANGE_SIZE; + rq.event = EVT_ROLE_CHANGE; + if (hci_send_req(dd, &rq, to) < 0) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + return 0; +} -- cgit From 78410fbc646a08b98487096e93e7bde4189314ae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jun 2003 13:09:02 +0000 Subject: Add functions for park mode --- src/hci.c | 226 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 143 insertions(+), 83 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 6d313d21..676b8af8 100644 --- a/src/hci.c +++ b/src/hci.c @@ -39,9 +39,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -699,9 +699,9 @@ done: int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) { - evt_conn_complete rp; - create_conn_cp cp; - struct hci_request rq; + evt_conn_complete rp; + create_conn_cp cp; + struct hci_request rq; memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); @@ -711,21 +711,21 @@ int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t c cp.role_switch = rswitch; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_CREATE_CONN; - rq.event = EVT_CONN_COMPLETE; - rq.cparam = &cp; - rq.clen = CREATE_CONN_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_CONN_COMPLETE_SIZE; - - if (hci_send_req(dd, &rq, to) < 0) - return -1; - - if (rp.status) { - errno = EIO; - return -1; - } + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_CREATE_CONN; + rq.event = EVT_CONN_COMPLETE; + rq.cparam = &cp; + rq.clen = CREATE_CONN_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CONN_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } *handle = rp.handle; return 0; @@ -733,31 +733,31 @@ int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t c int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) { - evt_disconn_complete rp; - disconnect_cp cp; - struct hci_request rq; + evt_disconn_complete rp; + disconnect_cp cp; + struct hci_request rq; - memset(&cp, 0, sizeof(cp)); - cp.handle = handle; - cp.reason = reason; + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.reason = reason; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_DISCONNECT; - rq.event = EVT_DISCONN_COMPLETE; - rq.cparam = &cp; - rq.clen = DISCONNECT_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_DISCONN_COMPLETE_SIZE; - - if (hci_send_req(dd, &rq, to) < 0) - return -1; - - if (rp.status) { - errno = EIO; - return -1; - } - return 0; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.event = EVT_DISCONN_COMPLETE; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_DISCONN_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } int hci_local_name(int dd, int len, char *name, int to) @@ -775,7 +775,7 @@ int hci_read_local_name(int dd, int len, char *name, int to) rq.ocf = OCF_READ_LOCAL_NAME; rq.rparam = &rp; rq.rlen = READ_LOCAL_NAME_RP_SIZE; - + if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -796,10 +796,10 @@ int hci_write_local_name(int dd, const char *name, int to) strncpy(cp.name, name, sizeof(cp.name)); memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_CHANGE_LOCAL_NAME; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_CHANGE_LOCAL_NAME; rq.cparam = &cp; - rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; + rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -862,11 +862,11 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) rq.rlen = EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE; if (hci_send_req(dd, &rq, to) < 0) - return -1; + return -1; if (rp.status) { - errno = EIO; - return -1; + errno = EIO; + return -1; } memcpy(features, rp.features, 8); @@ -955,10 +955,10 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) } ver->manufacturer = btohs(rp.manufacturer); - ver->hci_ver = rp.hci_ver; - ver->hci_rev = btohs(rp.hci_rev); - ver->lmp_ver = rp.lmp_ver; - ver->lmp_subver = btohs(rp.lmp_subver); + ver->hci_ver = rp.hci_ver; + ver->hci_rev = btohs(rp.hci_rev); + ver->lmp_ver = rp.lmp_ver; + ver->lmp_subver = btohs(rp.lmp_subver); return 0; } @@ -994,10 +994,10 @@ int hci_write_class_of_dev(int dd, uint32_t cls, int to) cp.dev_class[0] = cls & 0xff; cp.dev_class[1] = (cls >> 8) & 0xff; cp.dev_class[2] = (cls >> 16) & 0xff; - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CLASS_OF_DEV; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CLASS_OF_DEV; rq.cparam = &cp; - rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; + rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; return hci_send_req(dd, &rq, to); } @@ -1020,8 +1020,8 @@ int hci_read_voice_setting(int dd, uint16_t *vs, int to) return -1; } - *vs = rp.voice_setting; - return 0; + *vs = rp.voice_setting; + return 0; } int hci_write_voice_setting(int dd, uint16_t vs, int to) @@ -1031,10 +1031,10 @@ int hci_write_voice_setting(int dd, uint16_t vs, int to) memset(&rq, 0, sizeof(rq)); cp.voice_setting = vs; - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_VOICE_SETTING; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_VOICE_SETTING; rq.cparam = &cp; - rq.clen = WRITE_VOICE_SETTING_CP_SIZE; + rq.clen = WRITE_VOICE_SETTING_CP_SIZE; return hci_send_req(dd, &rq, to); } @@ -1044,10 +1044,10 @@ int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) struct hci_request rq; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_CURRENT_IAC_LAP; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_CURRENT_IAC_LAP; rq.rparam = &rp; - rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; + rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -1072,10 +1072,10 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) memcpy(&cp.lap, lap, num_iac * 3); memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; rq.cparam = &cp; - rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; return hci_send_req(dd, &rq, to); } @@ -1086,13 +1086,13 @@ int hci_authenticate_link(int dd, uint16_t handle, int to) struct hci_request rq; cp.handle = handle; - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_AUTH_REQUESTED; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_AUTH_REQUESTED; rq.cparam = &cp; - rq.clen = AUTH_REQUESTED_CP_SIZE; + rq.clen = AUTH_REQUESTED_CP_SIZE; rq.rparam = &rp; - rq.event = EVT_AUTH_COMPLETE; - rq.rlen = EVT_AUTH_COMPLETE_SIZE; + rq.event = EVT_AUTH_COMPLETE; + rq.rlen = EVT_AUTH_COMPLETE_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; if (rp.status) { @@ -1108,14 +1108,14 @@ int hci_encrypt_link(int dd, uint16_t handle, int on, int to) evt_encrypt_change rp; struct hci_request rq; - cp.handle = handle; + cp.handle = handle; cp.encrypt = on; - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_ENCRYPT; rq.cparam = &cp; - rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - rq.event = EVT_ENCRYPT_CHANGE; - rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; + rq.clen = SET_CONN_ENCRYPT_CP_SIZE; + rq.event = EVT_ENCRYPT_CHANGE; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; rq.rparam = &rp; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -1133,19 +1133,79 @@ int hci_switch_role(int dd, bdaddr_t peer, int role, int to) struct hci_request rq; cp.bdaddr = peer; - cp.role = role; - rq.ogf = OGF_LINK_POLICY; - rq.ocf = OCF_SWITCH_ROLE; + cp.role = role; + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_SWITCH_ROLE; + rq.cparam = &cp; + rq.clen = SWITCH_ROLE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_ROLE_CHANGE_SIZE; + rq.event = EVT_ROLE_CHANGE; + if (hci_send_req(dd, &rq, to) < 0) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + return 0; +} + +int hci_park_mode (int dd, uint16_t handle, uint16_t max_interval, uint16_t min_interval, int to) +{ + park_mode_cp cp; + evt_mode_change rp; + struct hci_request rq; + + memset(&cp, 0, sizeof (cp)); + cp.handle = handle; + cp.max_interval = max_interval; + cp.min_interval = min_interval; + + memset(&rq, 0, sizeof (rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_PARK_MODE; + rq.event = EVT_MODE_CHANGE; rq.cparam = &cp; - rq.clen = SWITCH_ROLE_CP_SIZE; + rq.clen = PARK_MODE_CP_SIZE; rq.rparam = &rp; - rq.rlen = EVT_ROLE_CHANGE_SIZE; - rq.event = EVT_ROLE_CHANGE; + rq.rlen = EVT_MODE_CHANGE_SIZE; + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; } + + return 0; +} + +int hci_exit_park_mode(int dd, uint16_t handle, int to) +{ + exit_park_mode_cp cp; + evt_mode_change rp; + struct hci_request rq; + + memset(&cp, 0, sizeof (cp)); + cp.handle = handle; + + memset (&rq, 0, sizeof (rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_EXIT_PARK_MODE; + rq.event = EVT_MODE_CHANGE; + rq.cparam = &cp; + rq.clen = EXIT_PARK_MODE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_MODE_CHANGE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } -- cgit From 5624d6cc20e5fb63d4b34b672b2421eb38b849e5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jun 2003 21:17:37 +0000 Subject: Add functions for park mode --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 676b8af8..b01dec97 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1150,7 +1150,7 @@ int hci_switch_role(int dd, bdaddr_t peer, int role, int to) return 0; } -int hci_park_mode (int dd, uint16_t handle, uint16_t max_interval, uint16_t min_interval, int to) +int hci_park_mode(int dd, uint16_t handle, uint16_t max_interval, uint16_t min_interval, int to) { park_mode_cp cp; evt_mode_change rp; -- cgit From bdcb3c69d6ad2a308c0b636e0a697f1f261d97b9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 14 Aug 2003 16:50:33 +0000 Subject: Remove useless white space --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index b01dec97..f22fcbfc 100644 --- a/src/hci.c +++ b/src/hci.c @@ -141,7 +141,7 @@ char *hci_dtypetostr(int type) case HCI_VHCI: return "VHCI"; case HCI_USB: - return "USB "; + return "USB"; case HCI_PCCARD: return "PCCARD"; case HCI_UART: -- cgit From 2f6b4e4f5e4da2cea6af279b262f81e9d52e78e4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 3 Sep 2003 10:50:40 +0000 Subject: Add link manager version parameter for Bluetooth 1.2 --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index f22fcbfc..818c04e5 100644 --- a/src/hci.c +++ b/src/hci.c @@ -269,6 +269,7 @@ int hci_strtolm(char *str, unsigned int *val) hci_map ver_map[] = { { "1.0b", 0x00 }, { "1.1", 0x01 }, + { "1.2", 0x02 }, { NULL } }; char *hci_vertostr(unsigned int ver) -- cgit From aac33d6b2e0c3c7b021478feb320afd8c812bda9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 11:36:20 +0000 Subject: Add decoding of Bluetooth 1.2 features --- src/hci.c | 68 ++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 20 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 818c04e5..61bdd1a6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -295,32 +295,60 @@ int lmp_strtover(char *str, unsigned int *ver) /* LMP features mapping */ hci_map lmp_features_map[][9] = { { /* byte 0 */ - { "<3-slot packets>", LMP_3SLOT }, - { "<5-slot packets>", LMP_5SLOT }, - { "", LMP_ENCRYPT }, - { "", LMP_SOFFSET }, - { "", LMP_TACCURACY}, - { "", LMP_RSWITCH }, - { "", LMP_HOLD }, - { "", LMP_SNIFF }, + { "<3-slot packets>", LMP_3SLOT }, + { "<5-slot packets>", LMP_5SLOT }, + { "", LMP_ENCRYPT }, + { "", LMP_SOFFSET }, + { "", LMP_TACCURACY }, + { "", LMP_RSWITCH }, + { "", LMP_HOLD }, + { "", LMP_SNIFF }, { NULL } }, { /* byte 1 */ - { "", LMP_PARK }, - { "", LMP_RSSI }, - { "", LMP_QUALITY }, - { "", LMP_SCO }, - { "", LMP_HV2 }, - { "", LMP_HV3 }, - { "", LMP_ULAW }, - { "", LMP_ALAW }, + { "", LMP_PARK }, + { "", LMP_RSSI }, + { "", LMP_QUALITY }, + { "", LMP_SCO }, + { "", LMP_HV2 }, + { "", LMP_HV3 }, + { "", LMP_ULAW }, + { "", LMP_ALAW }, { NULL } }, { /* byte 2 */ - { "", LMP_CVSD }, - { "", LMP_PSCHEME }, - { "", LMP_PCONTROL }, - { "", LMP_TRSP_SCO }, + { "", LMP_CVSD }, + { "", LMP_PSCHEME }, + { "", LMP_PCONTROL }, + { "", LMP_TRSP_SCO }, + { "",LMP_BCAST_ENC }, + { NULL } + }, + { /* byte 3 */ + { "", LMP_ENH_ISCAN }, + { "", LMP_ILACE_ISCAN }, + { "", LMP_ILACE_PSCAN }, + { "",LMP_RSSI_INQ }, + { "", LMP_ESCO }, + { NULL } + }, + { /* byte 4 */ + { "", LMP_EV4 }, + { "", LMP_EV5 }, + { "", LMP_AFH_CAP_SLV }, + { "", LMP_AFH_CLS_SLV }, + { NULL } + }, + { /* byte 5 */ + { "", LMP_AFH_CAP_MST }, + { "",LMP_AFH_CLS_MST }, + { NULL } + }, + { /* byte 6 */ + { NULL } + }, + { /* byte 7 */ + { "",LMP_EXT_FEAT }, { NULL } }, {{ NULL }} -- cgit From 6b5b6093a75df05d27571d192d4ef2fb56bfc6e2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 20 Nov 2003 08:50:42 +0000 Subject: Fix lmp_featurestostr() --- src/hci.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 61bdd1a6..8100d227 100644 --- a/src/hci.c +++ b/src/hci.c @@ -293,7 +293,7 @@ int lmp_strtover(char *str, unsigned int *ver) } /* LMP features mapping */ -hci_map lmp_features_map[][9] = { +hci_map lmp_features_map[8][9] = { { /* byte 0 */ { "<3-slot packets>", LMP_3SLOT }, { "<5-slot packets>", LMP_5SLOT }, @@ -351,7 +351,6 @@ hci_map lmp_features_map[][9] = { { "",LMP_EXT_FEAT }, { NULL } }, - {{ NULL }} }; char *lmp_featurestostr(uint8_t *features, char *pref, int width) @@ -367,7 +366,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) if (pref) ptr += sprintf(ptr, "%s", pref); - for(i=0, w=0; lmp_features_map[i][0].str; i++) { + for(i=0, w=0; i<8; i++) { hci_map *m; m = lmp_features_map[i]; @@ -381,7 +380,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) m++; } } - + return str; } -- cgit From 4d97c2497c2bee809432ea3e48676fa61538bbef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 16:48:38 +0000 Subject: Use R2 for default value of pscan_rep_mode --- src/hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 8100d227..3778f064 100644 --- a/src/hci.c +++ b/src/hci.c @@ -734,7 +734,7 @@ int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t c memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); cp.pkt_type = ptype; - cp.pscan_rep_mode = 0x01; + cp.pscan_rep_mode = 0x02; cp.clock_offset = clkoffset; cp.role_switch = rswitch; @@ -847,7 +847,7 @@ int hci_read_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); - cp.pscan_rep_mode = 0x01; + cp.pscan_rep_mode = 0x02; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; -- cgit From 51e671b116fe121053444c4817e38ad07e9586f8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 19:50:46 +0000 Subject: Use $(top_builddir) as include root directory --- src/hci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 3778f064..1530f395 100644 --- a/src/hci.c +++ b/src/hci.c @@ -43,9 +43,9 @@ #include #include -#include -#include -#include +#include +#include +#include typedef struct { char *str; unsigned int val; -- cgit From 764abe23a0d4ede999f1f34ee0e310c0eeaaff79 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 05:11:38 +0000 Subject: Update copyright information --- src/hci.c | 155 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 86 insertions(+), 69 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 1530f395..e2184cbb 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1,30 +1,37 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ + +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -64,7 +71,7 @@ static char *hci_bit2str(hci_map *m, unsigned int val) if ((unsigned int) m->val & val) ptr += sprintf(ptr, "%s ", m->str); m++; - } + } return str; } @@ -79,14 +86,14 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) *val = set = 0; - while ((t=strsep(&ptr, ","))) { - for (m=map; m->str; m++) { - if (!strcasecmp(m->str,t)) { + while ((t = strsep(&ptr, ","))) { + for (m = map; m->str; m++) { + if (!strcasecmp(m->str, t)) { *val |= (unsigned int) m->val; set = 1; } } - } + } free(str); return set; @@ -107,7 +114,7 @@ static char *hci_uint2str(hci_map *m, unsigned int val) break; } m++; - } + } return str; } @@ -122,14 +129,14 @@ static int hci_str2uint(hci_map *map, char *str, unsigned int *val) str = ptr = strdup(str); - while ((t=strsep(&ptr, ","))) { - for (m=map; m->str; m++) { + while ((t = strsep(&ptr, ","))) { + for (m = map; m->str; m++) { if (!strcasecmp(m->str,t)) { *val = (unsigned int) m->val; set = 1; break; } } - } + } free(str); return set; @@ -156,7 +163,7 @@ char *hci_dtypetostr(int type) } /* HCI dev flags mapping */ -hci_map dev_flags_map[] = { +static hci_map dev_flags_map[] = { { "UP", HCI_UP }, { "INIT", HCI_INIT }, { "RUNNING", HCI_RUNNING }, @@ -168,6 +175,7 @@ hci_map dev_flags_map[] = { { "ENCRYPT", HCI_ENCRYPT }, { NULL } }; + char *hci_dflagstostr(uint32_t flags) { char *str = malloc(50); @@ -191,7 +199,7 @@ char *hci_dflagstostr(uint32_t flags) } /* HCI packet type mapping */ -hci_map pkt_type_map[] = { +static hci_map pkt_type_map[] = { { "DM1", HCI_DM1 }, { "DM3", HCI_DM3 }, { "DM5", HCI_DM5 }, @@ -203,17 +211,19 @@ hci_map pkt_type_map[] = { { "HV3", HCI_HV3 }, { NULL } }; + char *hci_ptypetostr(unsigned int ptype) { return hci_bit2str(pkt_type_map, ptype); } + int hci_strtoptype(char *str, unsigned int *val) { return hci_str2bit(pkt_type_map, str, val); } /* Link policy mapping */ -hci_map link_policy_map[] = { +static hci_map link_policy_map[] = { { "NONE", 0 }, { "RSWITCH", HCI_LP_RSWITCH }, { "HOLD", HCI_LP_HOLD }, @@ -221,17 +231,19 @@ hci_map link_policy_map[] = { { "PARK", HCI_LP_PARK }, { NULL } }; + char *hci_lptostr(unsigned int lp) { return hci_bit2str(link_policy_map, lp); } + int hci_strtolp(char *str, unsigned int *val) { return hci_str2bit(link_policy_map, str, val); } /* Link mode mapping */ -hci_map link_mode_map[] = { +static hci_map link_mode_map[] = { { "NONE", 0 }, { "ACCEPT", HCI_LM_ACCEPT }, { "MASTER", HCI_LM_MASTER }, @@ -240,6 +252,7 @@ hci_map link_mode_map[] = { { "TRUSTED", HCI_LM_TRUSTED}, { NULL } }; + char *hci_lmtostr(unsigned int lm) { char *s, *str = malloc(50); @@ -260,23 +273,26 @@ char *hci_lmtostr(unsigned int lm) free(s); return str; } + int hci_strtolm(char *str, unsigned int *val) { return hci_str2bit(link_mode_map, str, val); } /* Version mapping */ -hci_map ver_map[] = { +static hci_map ver_map[] = { { "1.0b", 0x00 }, { "1.1", 0x01 }, { "1.2", 0x02 }, { NULL } }; + char *hci_vertostr(unsigned int ver) { char *str = hci_uint2str(ver_map, ver); return *str ? str : "n/a"; } + int hci_strtover(char *str, unsigned int *ver) { return hci_str2uint(ver_map, str, ver); @@ -287,13 +303,14 @@ char *lmp_vertostr(unsigned int ver) char *str = hci_uint2str(ver_map, ver); return *str ? str : "n/a"; } + int lmp_strtover(char *str, unsigned int *ver) { return hci_str2uint(ver_map, str, ver); } /* LMP features mapping */ -hci_map lmp_features_map[8][9] = { +static hci_map lmp_features_map[8][9] = { { /* byte 0 */ { "<3-slot packets>", LMP_3SLOT }, { "<5-slot packets>", LMP_5SLOT }, @@ -341,7 +358,7 @@ hci_map lmp_features_map[8][9] = { }, { /* byte 5 */ { "", LMP_AFH_CAP_MST }, - { "",LMP_AFH_CLS_MST }, + { "",LMP_AFH_CLS_MST }, { NULL } }, { /* byte 6 */ @@ -366,7 +383,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) if (pref) ptr += sprintf(ptr, "%s", pref); - for(i=0, w=0; i<8; i++) { + for (i = 0, w = 0; i < 8; i++) { hci_map *m; m = lmp_features_map[i]; @@ -386,7 +403,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) /* HCI functions that do not require open device */ -int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg) +int hci_for_each_dev(int flag, int (*func)(int s, int dev_id, long arg), long arg) { struct hci_dev_list_req *dl; struct hci_dev_req *dr; @@ -402,13 +419,13 @@ int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg close(s); return -1; } - + dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; if (ioctl(s, HCIGETDEVLIST, (void *)dl)) goto done; - + for (i=0; i < dl->dev_num; i++, dr++) { if (hci_test_bit(flag, &dr->dev_opt)) if (!func || func(s, dr->dev_id, arg)) { @@ -417,7 +434,7 @@ int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg } } -done: +done: close(s); free(dl); return dev_id; @@ -426,17 +443,17 @@ done: static int __other_bdaddr(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void *) &di)) return 0; - return bacmp((bdaddr_t *)arg, &di.bdaddr); + return bacmp((bdaddr_t *) arg, &di.bdaddr); } static int __same_bdaddr(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void *) &di)) return 0; - return !bacmp((bdaddr_t *)arg, &di.bdaddr); + return !bacmp((bdaddr_t *) arg, &di.bdaddr); } int hci_get_route(bdaddr_t *bdaddr) @@ -502,7 +519,7 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info int s, err; if (nrsp <= 0) - nrsp = 200; // enough ? + nrsp = 200; /* enough ? */ if (dev_id < 0 && (dev_id = hci_get_route(NULL)) < 0) { errno = ENODEV; @@ -563,11 +580,11 @@ int hci_open_dev(int dev_id) dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (dd < 0) return dd; - + /* Bind socket to the HCI device */ a.hci_family = AF_BLUETOOTH; a.hci_dev = dev_id; - if (bind(dd, (struct sockaddr *)&a, sizeof(a)) < 0) + if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0) goto failed; return dd; @@ -645,7 +662,7 @@ int hci_send_req(int dd, struct hci_request *r, int to) while (try--) { evt_cmd_complete *cc; evt_cmd_status *cs; - + if (to) { struct pollfd p; int n; @@ -661,7 +678,7 @@ int hci_send_req(int dd, struct hci_request *r, int to) errno = ETIMEDOUT; goto failed; } - + to -= 10; if (to < 0) to = 0; @@ -673,17 +690,17 @@ int hci_send_req(int dd, struct hci_request *r, int to) goto failed; } - hdr = (void *)(buf + 1); + hdr = (void *) (buf + 1); ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); switch (hdr->evt) { case EVT_CMD_STATUS: - cs = (void *)ptr; - + cs = (void *) ptr; + if (cs->opcode != opcode) continue; - + if (cs->status) { errno = EIO; goto failed; @@ -691,11 +708,11 @@ int hci_send_req(int dd, struct hci_request *r, int to) break; case EVT_CMD_COMPLETE: - cc = (void *)ptr; + cc = (void *) ptr; if (cc->opcode != opcode) continue; - + ptr += EVT_CMD_COMPLETE_SIZE; len -= EVT_CMD_COMPLETE_SIZE; @@ -706,7 +723,7 @@ int hci_send_req(int dd, struct hci_request *r, int to) default: if (hdr->evt != r->event) break; - + r->rlen = MIN(len, r->rlen); memcpy(r->rparam, ptr, r->rlen); goto done; @@ -994,21 +1011,21 @@ int hci_read_class_of_dev(int dd, uint8_t *cls, int to) { read_class_of_dev_rp rp; struct hci_request rq; - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_CLASS_OF_DEV; rq.rparam = &rp; rq.rlen = READ_CLASS_OF_DEV_RP_SIZE; - + if (hci_send_req(dd, &rq, to) < 0) return -1; - + if (rp.status) { errno = EIO; return -1; } - + memcpy(cls, rp.dev_class, 3); return 0; } @@ -1070,7 +1087,7 @@ int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) { read_current_iac_lap_rp rp; struct hci_request rq; - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_CURRENT_IAC_LAP; @@ -1094,11 +1111,11 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) { write_current_iac_lap_cp cp; struct hci_request rq; - + memset(&cp, 0, sizeof(cp)); cp.num_current_iac = num_iac; memcpy(&cp.lap, lap, num_iac * 3); - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; -- cgit From 40f6099fd4ffe323a369dd63652570404f4ddc02 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 11:40:10 +0000 Subject: Add bit numbers to the features table --- src/hci.c | 82 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index e2184cbb..2c19b78d 100644 --- a/src/hci.c +++ b/src/hci.c @@ -311,61 +311,61 @@ int lmp_strtover(char *str, unsigned int *ver) /* LMP features mapping */ static hci_map lmp_features_map[8][9] = { - { /* byte 0 */ - { "<3-slot packets>", LMP_3SLOT }, - { "<5-slot packets>", LMP_5SLOT }, - { "", LMP_ENCRYPT }, - { "", LMP_SOFFSET }, - { "", LMP_TACCURACY }, - { "", LMP_RSWITCH }, - { "", LMP_HOLD }, - { "", LMP_SNIFF }, + { /* Byte 0 */ + { "<3-slot packets>", LMP_3SLOT }, /* Bit 0 */ + { "<5-slot packets>", LMP_5SLOT }, /* Bit 1 */ + { "", LMP_ENCRYPT }, /* Bit 2 */ + { "", LMP_SOFFSET }, /* Bit 3 */ + { "", LMP_TACCURACY }, /* Bit 4 */ + { "", LMP_RSWITCH }, /* Bit 5 */ + { "", LMP_HOLD }, /* Bit 6 */ + { "", LMP_SNIFF }, /* Bit 7 */ { NULL } }, - { /* byte 1 */ - { "", LMP_PARK }, - { "", LMP_RSSI }, - { "", LMP_QUALITY }, - { "", LMP_SCO }, - { "", LMP_HV2 }, - { "", LMP_HV3 }, - { "", LMP_ULAW }, - { "", LMP_ALAW }, + { /* Byte 1 */ + { "", LMP_PARK }, /* Bit 0 */ + { "", LMP_RSSI }, /* Bit 1 */ + { "", LMP_QUALITY }, /* Bit 2 */ + { "", LMP_SCO }, /* Bit 3 */ + { "", LMP_HV2 }, /* Bit 4 */ + { "", LMP_HV3 }, /* Bit 5 */ + { "", LMP_ULAW }, /* Bit 6 */ + { "", LMP_ALAW }, /* Bit 7 */ { NULL } }, - { /* byte 2 */ - { "", LMP_CVSD }, - { "", LMP_PSCHEME }, - { "", LMP_PCONTROL }, - { "", LMP_TRSP_SCO }, - { "",LMP_BCAST_ENC }, + { /* Byte 2 */ + { "", LMP_CVSD }, /* Bit 0 */ + { "", LMP_PSCHEME }, /* Bit 1 */ + { "", LMP_PCONTROL }, /* Bit 2 */ + { "", LMP_TRSP_SCO }, /* Bit 3 */ + { "",LMP_BCAST_ENC }, /* Bit 7 */ { NULL } }, - { /* byte 3 */ - { "", LMP_ENH_ISCAN }, - { "", LMP_ILACE_ISCAN }, - { "", LMP_ILACE_PSCAN }, - { "",LMP_RSSI_INQ }, - { "", LMP_ESCO }, + { /* Byte 3 */ + { "", LMP_ENH_ISCAN }, /* Bit 3 */ + { "", LMP_ILACE_ISCAN }, /* Bit 4 */ + { "", LMP_ILACE_PSCAN }, /* Bit 5 */ + { "",LMP_RSSI_INQ }, /* Bit 6 */ + { "", LMP_ESCO }, /* Bit 7 */ { NULL } }, - { /* byte 4 */ - { "", LMP_EV4 }, - { "", LMP_EV5 }, - { "", LMP_AFH_CAP_SLV }, - { "", LMP_AFH_CLS_SLV }, + { /* Byte 4 */ + { "", LMP_EV4 }, /* Bit 0 */ + { "", LMP_EV5 }, /* Bit 1 */ + { "", LMP_AFH_CAP_SLV }, /* Bit 3 */ + { "", LMP_AFH_CLS_SLV }, /* Bit 4 */ { NULL } }, - { /* byte 5 */ - { "", LMP_AFH_CAP_MST }, - { "",LMP_AFH_CLS_MST }, + { /* Byte 5 */ + { "", LMP_AFH_CAP_MST }, /* Bit 3 */ + { "",LMP_AFH_CLS_MST }, /* Bit 4 */ { NULL } }, - { /* byte 6 */ + { /* Byte 6 */ { NULL } }, - { /* byte 7 */ - { "",LMP_EXT_FEAT }, + { /* Byte 7 */ + { "",LMP_EXT_FEAT }, /* Bit 7 */ { NULL } }, }; -- cgit From 6caf64335ab07e1bd138e11a1823ba9baa209fef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 12:09:53 +0000 Subject: Add features and packet types from EDR prototyping specification --- src/hci.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 2c19b78d..f1e278cb 100644 --- a/src/hci.c +++ b/src/hci.c @@ -200,15 +200,35 @@ char *hci_dflagstostr(uint32_t flags) /* HCI packet type mapping */ static hci_map pkt_type_map[] = { - { "DM1", HCI_DM1 }, - { "DM3", HCI_DM3 }, - { "DM5", HCI_DM5 }, - { "DH1", HCI_DH1 }, - { "DH3", HCI_DH3 }, - { "DH5", HCI_DH5 }, - { "HV1", HCI_HV1 }, - { "HV2", HCI_HV2 }, - { "HV3", HCI_HV3 }, + { "DM1", HCI_DM1 }, + { "DM3", HCI_DM3 }, + { "DM5", HCI_DM5 }, + { "DH1", HCI_DH1 }, + { "DH3", HCI_DH3 }, + { "DH5", HCI_DH5 }, + { "HV1", HCI_HV1 }, + { "HV2", HCI_HV2 }, + { "HV3", HCI_HV3 }, + { "2-DH1", HCI_2DH1 }, + { "2-DH3", HCI_2DH3 }, + { "2-DH5", HCI_2DH5 }, + { "3-DH1", HCI_3DH1 }, + { "3-DH3", HCI_3DH3 }, + { "3-DH5", HCI_3DH5 }, + { NULL } +}; + +static hci_map sco_ptype_map[] = { + { "HV1", 0x0001 }, + { "HV2", 0x0002 }, + { "HV3", 0x0004 }, + { "EV3", HCI_EV3 }, + { "EV4", HCI_EV4 }, + { "EV5", HCI_EV5 }, + { "2-EV3", HCI_2EV3 }, + { "2-EV5", HCI_2EV5 }, + { "3-EV3", HCI_3EV3 }, + { "3-EV5", HCI_3EV5 }, { NULL } }; @@ -222,6 +242,16 @@ int hci_strtoptype(char *str, unsigned int *val) return hci_str2bit(pkt_type_map, str, val); } +char *hci_scoptypetostr(unsigned int ptype) +{ + return hci_bit2str(sco_ptype_map, ptype); +} + +int hci_strtoscoptype(char *str, unsigned int *val) +{ + return hci_str2bit(sco_ptype_map, str, val); +} + /* Link policy mapping */ static hci_map link_policy_map[] = { { "NONE", 0 }, @@ -342,6 +372,8 @@ static hci_map lmp_features_map[8][9] = { { NULL } }, { /* Byte 3 */ + { "", LMP_EDR_ACL_2M }, /* Bit 1 */ + { "", LMP_EDR_ACL_3M }, /* Bit 2 */ { "", LMP_ENH_ISCAN }, /* Bit 3 */ { "", LMP_ILACE_ISCAN }, /* Bit 4 */ { "", LMP_ILACE_PSCAN }, /* Bit 5 */ @@ -354,11 +386,16 @@ static hci_map lmp_features_map[8][9] = { { "", LMP_EV5 }, /* Bit 1 */ { "", LMP_AFH_CAP_SLV }, /* Bit 3 */ { "", LMP_AFH_CLS_SLV }, /* Bit 4 */ + { "<3-slot EDR ACL>", LMP_EDR_3SLOT }, /* Bit 7 */ { NULL } }, { /* Byte 5 */ + { "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */ { "", LMP_AFH_CAP_MST }, /* Bit 3 */ { "",LMP_AFH_CLS_MST }, /* Bit 4 */ + { "", LMP_EDR_ESCO_2M }, /* Bit 5 */ + { "", LMP_EDR_ESCO_3M }, /* Bit 6 */ + { "<3-slot EDR eSCO>", LMP_EDR_3S_ESCO }, /* Bit 7 */ { NULL } }, { /* Byte 6 */ -- cgit From 9717723fd7bdc64648c258967911d0932248cf1f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 14:10:03 +0000 Subject: Better display of decoded LMP features --- src/hci.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index f1e278cb..5acbe7cd 100644 --- a/src/hci.c +++ b/src/hci.c @@ -409,8 +409,8 @@ static hci_map lmp_features_map[8][9] = { char *lmp_featurestostr(uint8_t *features, char *pref, int width) { - char *ptr, *str = malloc(400); - int i, w; + char *off, *ptr, *str = malloc(400); + int i; if (!str) return NULL; @@ -420,16 +420,19 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) if (pref) ptr += sprintf(ptr, "%s", pref); - for (i = 0, w = 0; i < 8; i++) { + off = ptr; + + for (i = 0; i < 8; i++) { hci_map *m; m = lmp_features_map[i]; while (m->str) { if ((unsigned int) m->val & (unsigned int) features[i]) { - ptr += sprintf(ptr, "%s ", m->str); - w = (w + 1) & width; - if (!w) + if (strlen(off) + strlen(m->str) > width - 1) { ptr += sprintf(ptr, "\n%s", pref ? pref : ""); + off = ptr; + } + ptr += sprintf(ptr, "%s ", m->str); } m++; } -- cgit From a867781820a4b7a85031c54fe38399c33affdb9c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 6 Oct 2004 17:39:53 +0000 Subject: Add support for the kernel security manager --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 5acbe7cd..43baa7b7 100644 --- a/src/hci.c +++ b/src/hci.c @@ -173,6 +173,7 @@ static hci_map dev_flags_map[] = { { "INQUIRY", HCI_INQUIRY }, { "AUTH", HCI_AUTH }, { "ENCRYPT", HCI_ENCRYPT }, + { "SECMGR", HCI_SECMGR }, { NULL } }; -- cgit From cc0deab6cac822b062e1c6ab7322d1e1d75d463e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 06:44:47 +0000 Subject: Cleanup the API to prevent endian bugs --- src/hci.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 43baa7b7..ffa453f3 100644 --- a/src/hci.c +++ b/src/hci.c @@ -537,7 +537,7 @@ int hci_devinfo(int dev_id, struct hci_dev_info *di) return err; } -int hci_devba(int dev_id, bdaddr_t *ba) +int hci_devba(int dev_id, bdaddr_t *bdaddr) { struct hci_dev_info di; @@ -549,7 +549,7 @@ int hci_devba(int dev_id, bdaddr_t *ba) return -1; } - bacpy(ba, &di.bdaddr); + bacpy(bdaddr, &di.bdaddr); return 0; } @@ -783,14 +783,14 @@ done: return 0; } -int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) +int hci_create_connection(int dd, const bdaddr_t *bdaddr, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) { evt_conn_complete rp; create_conn_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - bacpy(&cp.bdaddr, ba); + bacpy(&cp.bdaddr, bdaddr); cp.pkt_type = ptype; cp.pscan_rep_mode = 0x02; cp.clock_offset = clkoffset; @@ -892,19 +892,19 @@ int hci_write_local_name(int dd, const char *name, int to) return 0; } -int hci_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to) +int hci_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) { - return hci_read_remote_name(dd, ba, len, name, to); + return hci_read_remote_name(dd, bdaddr, len, name, to); } -int hci_read_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to) +int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - bacpy(&cp.bdaddr, ba); + bacpy(&cp.bdaddr, bdaddr); cp.pscan_rep_mode = 0x02; memset(&rq, 0, sizeof(rq)); @@ -1121,6 +1121,7 @@ int hci_write_voice_setting(int dd, uint16_t vs, int to) rq.ocf = OCF_WRITE_VOICE_SETTING; rq.cparam = &cp; rq.clen = WRITE_VOICE_SETTING_CP_SIZE; + return hci_send_req(dd, &rq, to); } @@ -1162,6 +1163,7 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; rq.cparam = &cp; rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + return hci_send_req(dd, &rq, to); } @@ -1179,32 +1181,37 @@ int hci_authenticate_link(int dd, uint16_t handle, int to) rq.rparam = &rp; rq.event = EVT_AUTH_COMPLETE; rq.rlen = EVT_AUTH_COMPLETE_SIZE; + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; } + return 0; } -int hci_encrypt_link(int dd, uint16_t handle, int on, int to) +int hci_encrypt_link(int dd, uint16_t handle, uint8_t encrypt, int to) { set_conn_encrypt_cp cp; evt_encrypt_change rp; struct hci_request rq; cp.handle = handle; - cp.encrypt = on; - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_ENCRYPT; - rq.cparam = &cp; - rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - rq.event = EVT_ENCRYPT_CHANGE; - rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; - rq.rparam = &rp; + cp.encrypt = encrypt; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.cparam = &cp; + rq.clen = SET_CONN_ENCRYPT_CP_SIZE; + rq.event = EVT_ENCRYPT_CHANGE; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; + rq.rparam = &rp; + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; @@ -1212,13 +1219,13 @@ int hci_encrypt_link(int dd, uint16_t handle, int on, int to) return 0; } -int hci_switch_role(int dd, bdaddr_t peer, int role, int to) +int hci_switch_role(int dd, bdaddr_t *bdaddr, uint8_t role, int to) { switch_role_cp cp; evt_role_change rp; struct hci_request rq; - cp.bdaddr = peer; + bacpy(&cp.bdaddr, bdaddr); cp.role = role; rq.ogf = OGF_LINK_POLICY; rq.ocf = OCF_SWITCH_ROLE; @@ -1227,12 +1234,15 @@ int hci_switch_role(int dd, bdaddr_t peer, int role, int to) rq.rparam = &rp; rq.rlen = EVT_ROLE_CHANGE_SIZE; rq.event = EVT_ROLE_CHANGE; + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; } + return 0; } -- cgit From 1a04074615c182634202f03fd74a73f62107b93c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 07:36:45 +0000 Subject: Add functions for reading and writing the inquiry mode --- src/hci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index ffa453f3..3ab433f0 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1305,3 +1305,54 @@ int hci_exit_park_mode(int dd, uint16_t handle, int to) return 0; } + +int hci_read_inquiry_mode(int dd, uint8_t *mode, int to) +{ + read_inquiry_mode_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_INQUIRY_MODE; + rq.rparam = &rp; + rq.rlen = READ_INQUIRY_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *mode = rp.mode; + return 0; +} + +int hci_write_inquiry_mode(int dd, uint8_t mode, int to) +{ + write_inquiry_mode_cp cp; + write_inquiry_mode_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.mode = mode; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQUIRY_MODE; + rq.cparam = &cp; + rq.clen = WRITE_INQUIRY_MODE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_INQUIRY_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} -- cgit From 1eccad4e5bd6f163a44e7b6e772993db5a37cf69 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 26 Oct 2004 21:30:57 +0000 Subject: Correct typo in comment --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 3ab433f0..d3892bbc 100644 --- a/src/hci.c +++ b/src/hci.c @@ -643,7 +643,7 @@ int hci_close_dev(int dd) } /* HCI functions that require open device - * dd - Device descriptor returned by hci_dev_open. */ + * dd - Device descriptor returned by hci_open_dev. */ int hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) { -- cgit From 9427f5dc51c6962692eecd7250f2a1130dbc49ad Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Nov 2004 11:21:34 +0000 Subject: Add hci_change_link_key() function --- src/hci.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index d3892bbc..23f890a6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1174,12 +1174,13 @@ int hci_authenticate_link(int dd, uint16_t handle, int to) struct hci_request rq; cp.handle = handle; + rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_AUTH_REQUESTED; + rq.event = EVT_AUTH_COMPLETE; rq.cparam = &cp; rq.clen = AUTH_REQUESTED_CP_SIZE; rq.rparam = &rp; - rq.event = EVT_AUTH_COMPLETE; rq.rlen = EVT_AUTH_COMPLETE_SIZE; if (hci_send_req(dd, &rq, to) < 0) @@ -1201,13 +1202,14 @@ int hci_encrypt_link(int dd, uint16_t handle, uint8_t encrypt, int to) cp.handle = handle; cp.encrypt = encrypt; + rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.event = EVT_ENCRYPT_CHANGE; rq.cparam = &cp; rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - rq.event = EVT_ENCRYPT_CHANGE; - rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; rq.rparam = &rp; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -1216,6 +1218,34 @@ int hci_encrypt_link(int dd, uint16_t handle, uint8_t encrypt, int to) errno = EIO; return -1; } + + return 0; +} + +int hci_change_link_key(int dd, uint16_t handle, int to) +{ + change_conn_link_key_cp cp; + evt_change_conn_link_key_complete rp; + struct hci_request rq; + + cp.handle = handle; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_CHANGE_CONN_LINK_KEY; + rq.event = EVT_CHANGE_CONN_LINK_KEY_COMPLETE; + rq.cparam = &cp; + rq.clen = CHANGE_CONN_LINK_KEY_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } -- cgit From 52e03fab5cb877505e6a4c391b5b0456726ed162 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 8 Nov 2004 13:37:59 +0000 Subject: Add version identifier for Bluetooth 2.0 --- src/hci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 23f890a6..5895563e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -312,9 +312,10 @@ int hci_strtolm(char *str, unsigned int *val) /* Version mapping */ static hci_map ver_map[] = { - { "1.0b", 0x00 }, - { "1.1", 0x01 }, - { "1.2", 0x02 }, + { "1.0b", 0x00 }, + { "1.1", 0x01 }, + { "1.2", 0x02 }, + { "2.0", 0x03 }, { NULL } }; -- cgit From 0bae50cd5c691f338f6fa820a8b803a45c0de181 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 21:33:17 +0000 Subject: Add hci_{read|write}_afh_mode() functions --- src/hci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 5895563e..9ebd5a23 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1387,3 +1387,54 @@ int hci_write_inquiry_mode(int dd, uint8_t mode, int to) return 0; } + +int hci_read_afh_mode(int dd, uint8_t *mode, int to) +{ + read_afh_mode_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_AFH_MODE; + rq.rparam = &rp; + rq.rlen = READ_AFH_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *mode = rp.mode; + return 0; +} + +int hci_write_afh_mode(int dd, uint8_t mode, int to) +{ + write_afh_mode_cp cp; + write_afh_mode_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.mode = mode; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_AFH_MODE; + rq.cparam = &cp; + rq.clen = WRITE_AFH_MODE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_AFH_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} -- cgit From 213febe584cdd8c7b5fd2defc2d56f0c84677e51 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 22:29:55 +0000 Subject: Add hci_read_afh_map() function --- src/hci.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 9ebd5a23..ee8dce2f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1438,3 +1438,29 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } + +int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int to) +{ + read_afh_map_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_AFH_MAP; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_AFH_MAP_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *mode = rp.mode; + memcpy(map, rp.map, 10); + return 0; +} -- cgit From 0792c0b319112503dd5129f05536f3c6ae4c746c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 22:52:40 +0000 Subject: Add hci_set_afh_classification() function --- src/hci.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index ee8dce2f..19ee3c4c 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1439,6 +1439,34 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } +int hci_set_afh_classification(int dd, uint8_t *map, int to) +{ + set_afh_classification_cp cp; + set_afh_classification_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + memcpy(cp.map, map, 10); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_SET_AFH_CLASSIFICATION; + rq.cparam = &cp; + rq.clen = SET_AFH_CLASSIFICATION_CP_SIZE; + rq.rparam = &rp; + rq.rlen = SET_AFH_CLASSIFICATION_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int to) { read_afh_map_rp rp; -- cgit From 6c2fed4529b256285e495ccdb066de331db42ff4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 20:05:05 +0000 Subject: Remove deprecated functions --- src/hci.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 19ee3c4c..5d11309f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -55,7 +55,8 @@ #include typedef struct { - char *str; unsigned int val; + char *str; + unsigned int val; } hci_map; static char *hci_bit2str(hci_map *m, unsigned int val) @@ -255,11 +256,11 @@ int hci_strtoscoptype(char *str, unsigned int *val) /* Link policy mapping */ static hci_map link_policy_map[] = { - { "NONE", 0 }, - { "RSWITCH", HCI_LP_RSWITCH }, - { "HOLD", HCI_LP_HOLD }, - { "SNIFF", HCI_LP_SNIFF }, - { "PARK", HCI_LP_PARK }, + { "NONE", 0 }, + { "RSWITCH", HCI_LP_RSWITCH }, + { "HOLD", HCI_LP_HOLD }, + { "SNIFF", HCI_LP_SNIFF }, + { "PARK", HCI_LP_PARK }, { NULL } }; @@ -275,12 +276,14 @@ int hci_strtolp(char *str, unsigned int *val) /* Link mode mapping */ static hci_map link_mode_map[] = { - { "NONE", 0 }, - { "ACCEPT", HCI_LM_ACCEPT }, - { "MASTER", HCI_LM_MASTER }, - { "AUTH", HCI_LM_AUTH }, - { "ENCRYPT", HCI_LM_ENCRYPT}, - { "TRUSTED", HCI_LM_TRUSTED}, + { "NONE", 0 }, + { "ACCEPT", HCI_LM_ACCEPT }, + { "MASTER", HCI_LM_MASTER }, + { "AUTH", HCI_LM_AUTH }, + { "ENCRYPT", HCI_LM_ENCRYPT }, + { "TRUSTED", HCI_LM_TRUSTED }, + { "RELIABLE", HCI_LM_RELIABLE }, + { "SECURE", HCI_LM_SECURE }, { NULL } }; @@ -847,11 +850,6 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) return 0; } -int hci_local_name(int dd, int len, char *name, int to) -{ - return hci_read_local_name(dd, len, name, to); -} - int hci_read_local_name(int dd, int len, char *name, int to) { read_local_name_rp rp; @@ -893,11 +891,6 @@ int hci_write_local_name(int dd, const char *name, int to) return 0; } -int hci_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) -{ - return hci_read_remote_name(dd, bdaddr, len, name, to); -} - int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) { evt_remote_name_req_complete rn; -- cgit From 32c8a21b7da2397da204015f4bf45983226cbed9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 20:16:40 +0000 Subject: Add function for reading the RSSI and the link quality --- src/hci.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 5d11309f..63a79d06 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1460,6 +1460,56 @@ int hci_set_afh_classification(int dd, uint8_t *map, int to) return 0; } +int hci_read_link_quality(int dd, uint16_t handle, uint8_t *link_quality, int to) +{ + read_link_quality_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_LINK_QUALITY; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_LINK_QUALITY_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *link_quality = rp.link_quality; + return 0; +} + +int hci_read_rssi(int dd, uint16_t handle, int8_t *rssi, int to) +{ + read_rssi_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_RSSI_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *rssi = rp.rssi; + return 0; +} + int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int to) { read_afh_map_rp rp; -- cgit From 3d400b430ca82b915570be699d98b10648c593ac Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:37:58 +0000 Subject: Add link supervision timeout functions --- src/hci.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 63a79d06..10f4fcb6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1432,6 +1432,60 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } +int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout, int to) +{ + read_link_supervision_timeout_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *timeout = rp.link_sup_to; + return 0; +} + +int hci_write_link_supervision_timeout(int dd, uint16_t handle, uint16_t timeout, int to) +{ + write_link_supervision_timeout_cp cp; + write_link_supervision_timeout_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.link_sup_to = timeout; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cp; + rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_set_afh_classification(int dd, uint8_t *map, int to) { set_afh_classification_cp cp; -- cgit From 864124c296636015f90e26512143cf2c297ed6d2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:46:41 +0000 Subject: The link supervision timeout is host control --- src/hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 10f4fcb6..ca53105e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1438,7 +1438,7 @@ int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout struct hci_request rq; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; rq.cparam = &handle; rq.clen = 2; @@ -1468,7 +1468,7 @@ int hci_write_link_supervision_timeout(int dd, uint16_t handle, uint16_t timeout cp.link_sup_to = timeout; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cp; rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; -- cgit From 84cc44acd712f84ff544b7e1b96d1410c732dc8c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:57:36 +0000 Subject: Add function for reading the transmit power level --- src/hci.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index ca53105e..8e0b7938 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1432,6 +1432,36 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } +int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, uint8_t *level, int to) +{ + read_transmit_power_level_cp cp; + read_transmit_power_level_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.type = type; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; + rq.rparam = &rp; + rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *level = rp.level; + return 0; +} + int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout, int to) { read_link_supervision_timeout_rp rp; -- cgit From badafc6e227a175022370017008f0d839ec90b25 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Jan 2005 08:10:42 +0000 Subject: Add functions hci_{local|remote}_name() --- src/hci.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 8e0b7938..87f4874b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1619,3 +1619,13 @@ int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int t memcpy(map, rp.map, 10); return 0; } + +int hci_local_name(int dd, int len, char *name, int to) +{ + return hci_read_local_name(dd, len, name, to); +} + +int hci_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) +{ + return hci_read_remote_name(dd, bdaddr, len, name, to); +} -- cgit From 1e2dec5679c175fc52d2e19ebe06b9e1a7b05461 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Jan 2005 21:36:28 +0000 Subject: Add hci_read_clock() function --- src/hci.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 87f4874b..387560aa 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1620,6 +1620,37 @@ int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int t return 0; } +int hci_read_clock(int dd, uint16_t handle, uint8_t which, uint32_t *clock, uint16_t *accuracy, int to) +{ + read_clock_cp cp; + read_clock_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.which_clock = which; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_CLOCK; + rq.cparam = &cp; + rq.clen = READ_CLOCK_CP_SIZE; + rq.rparam = &rp; + rq.rlen = READ_CLOCK_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *clock = rp.clock; + *accuracy = rp.accuracy; + return 0; +} + int hci_local_name(int dd, int len, char *name, int to) { return hci_read_local_name(dd, len, name, to); -- cgit From 816b0a911d833aeb2b8af041b55c7b7c66e43588 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 23:14:46 +0000 Subject: Update the copyright year --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 387560aa..a68f0122 100644 --- a/src/hci.c +++ b/src/hci.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From e6589c0f2a6d1dd3060a86a27d859c8fb08bf278 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Jan 2005 03:24:48 +0000 Subject: Add functions for reading the BD_ADDR and the features --- src/hci.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index a68f0122..822c7db4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1042,6 +1042,52 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) return 0; } +int hci_read_local_features(int dd, uint8_t *features, int to) +{ + read_local_features_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_FEATURES; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_FEATURES_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(features, rp.features, 8); + return 0; +} + +int hci_read_bd_addr(int dd, bdaddr_t *bdaddr, int to) +{ + read_bd_addr_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.rparam = &rp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + bacpy(bdaddr, &rp.bdaddr); + return 0; +} + int hci_read_class_of_dev(int dd, uint8_t *cls, int to) { read_class_of_dev_rp rp; -- cgit From 601655969dc1dc85696f8aa94cf68a6433228be7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Jan 2005 23:30:04 +0000 Subject: Skip devices in raw mode --- src/hci.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 822c7db4..088574f1 100644 --- a/src/hci.c +++ b/src/hci.c @@ -453,51 +453,58 @@ int hci_for_each_dev(int flag, int (*func)(int s, int dev_id, long arg), long ar struct hci_dev_list_req *dl; struct hci_dev_req *dr; int dev_id = -1; - int s, i; + int i, sk; - s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (s < 0) + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) return -1; dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); if (!dl) { - close(s); + close(sk); return -1; } dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(s, HCIGETDEVLIST, (void *)dl)) + if (ioctl(sk, HCIGETDEVLIST, (void *) dl)) goto done; - for (i=0; i < dl->dev_num; i++, dr++) { + for (i = 0; i < dl->dev_num; i++, dr++) { if (hci_test_bit(flag, &dr->dev_opt)) - if (!func || func(s, dr->dev_id, arg)) { + if (!func || func(sk, dr->dev_id, arg)) { dev_id = dr->dev_id; break; } } done: - close(s); + close(sk); free(dl); return dev_id; } -static int __other_bdaddr(int s, int dev_id, long arg) +static int __other_bdaddr(int sk, int dev_id, long arg) { - struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(s, HCIGETDEVINFO, (void *) &di)) + struct hci_dev_info di = { dev_id: dev_id }; + + if (ioctl(sk, HCIGETDEVINFO, (void *) &di)) return 0; + + if (hci_test_bit(HCI_RAW, &di.flags)) + return 0; + return bacmp((bdaddr_t *) arg, &di.bdaddr); } -static int __same_bdaddr(int s, int dev_id, long arg) +static int __same_bdaddr(int sk, int dev_id, long arg) { - struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(s, HCIGETDEVINFO, (void *) &di)) + struct hci_dev_info di = { dev_id: dev_id }; + + if (ioctl(sk, HCIGETDEVINFO, (void *) &di)) return 0; + return !bacmp((bdaddr_t *) arg, &di.bdaddr); } -- cgit From c608311e7472325514f0578a20d59efc86792e39 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Feb 2005 04:17:16 +0000 Subject: Add function for getting the remote name with a clock offset --- src/hci.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 088574f1..37715613 100644 --- a/src/hci.c +++ b/src/hci.c @@ -898,7 +898,7 @@ int hci_write_local_name(int dd, const char *name, int to) return 0; } -int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) +int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint16_t clkoffset, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; @@ -907,6 +907,7 @@ int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, in memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, bdaddr); cp.pscan_rep_mode = 0x02; + cp.clock_offset = clkoffset; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; @@ -930,6 +931,11 @@ int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, in return 0; } +int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) +{ + return hci_read_remote_name_with_clock_offset(dd, bdaddr, 0x0000, len, name, to); +} + int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) { evt_read_remote_features_complete rp; -- cgit From ce742d95634d8a666a0f4df610c8eac4419d7716 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 02:36:27 +0000 Subject: Fix IAC support --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 37715613..82bdbffc 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1215,7 +1215,7 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; rq.cparam = &cp; - rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + rq.clen = num_iac * 3 + 1; return hci_send_req(dd, &rq, to); } -- cgit From db01d7596aa2ba2e40df5d3c7ef9b7cd0489ecad Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 02:37:49 +0000 Subject: The transmit power level is a signed integer --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 82bdbffc..83f09d9f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1491,7 +1491,7 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } -int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, uint8_t *level, int to) +int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to) { read_transmit_power_level_cp cp; read_transmit_power_level_rp rp; -- cgit From 1ec0481800a50aa14afe0513f69b4c7c04d5962a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 11:42:03 +0000 Subject: Support pscan_rep_mode for remote name request --- src/hci.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 83f09d9f..a0c0775e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -886,7 +886,9 @@ int hci_write_local_name(int dd, const char *name, int to) change_local_name_cp cp; struct hci_request rq; + memset(&cp, 0, sizeof(cp)); strncpy(cp.name, name, sizeof(cp.name)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_CHANGE_LOCAL_NAME; @@ -895,10 +897,11 @@ int hci_write_local_name(int dd, const char *name, int to) if (hci_send_req(dd, &rq, to) < 0) return -1; + return 0; } -int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint16_t clkoffset, int len, char *name, int to) +int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint8_t pscan_rep_mode, uint16_t clkoffset, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; @@ -906,7 +909,7 @@ int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint1 memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, bdaddr); - cp.pscan_rep_mode = 0x02; + cp.pscan_rep_mode = pscan_rep_mode; cp.clock_offset = clkoffset; memset(&rq, 0, sizeof(rq)); @@ -933,7 +936,27 @@ int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint1 int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) { - return hci_read_remote_name_with_clock_offset(dd, bdaddr, 0x0000, len, name, to); + return hci_read_remote_name_with_clock_offset(dd, bdaddr, 0x02, 0x0000, len, name, to); +} + +int hci_read_remote_name_cancel(int dd, const bdaddr_t *bdaddr, int to) +{ + remote_name_req_cancel_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_REMOTE_NAME_REQ_CANCEL; + rq.cparam = &cp; + rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + return 0; } int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) -- cgit From 607eee46b4e197ef0b3e73359b89daa0a8705516 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 13:09:06 +0000 Subject: Fix buffer allocation for features to string conversion --- src/hci.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index a0c0775e..ddcd680b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -414,9 +414,20 @@ static hci_map lmp_features_map[8][9] = { char *lmp_featurestostr(uint8_t *features, char *pref, int width) { - char *off, *ptr, *str = malloc(400); - int i; + char *off, *ptr, *str; + int i, size = 0; + for (i = 0; i < 8; i++) { + hci_map *m = lmp_features_map[i]; + + while (m->str) { + if ((unsigned int) m->val & (unsigned int) features[i]) + size += strlen(m->str) + (pref ? strlen(pref) : 0) + 1; + m++; + } + } + + str = malloc(size); if (!str) return NULL; @@ -427,10 +438,9 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) off = ptr; - for (i = 0; i < 8; i++) { - hci_map *m; + for (i = 0; i < 8; i++) { + hci_map *m = lmp_features_map[i]; - m = lmp_features_map[i]; while (m->str) { if ((unsigned int) m->val & (unsigned int) features[i]) { if (strlen(off) + strlen(m->str) > width - 1) { -- cgit From be2d979b6a592484862e78bed355d079f7eeb1e6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 23:14:52 +0000 Subject: Add funtions for reading local supported commands and extended features --- src/hci.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index ddcd680b..6e1067c4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1088,6 +1088,29 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) return 0; } +int hci_read_local_commands(int dd, uint8_t *commands, int to) +{ + read_local_commands_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_COMMANDS; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_COMMANDS_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(commands, rp.commands, 64); + return 0; +} + int hci_read_local_features(int dd, uint8_t *features, int to) { read_local_features_rp rp; @@ -1111,6 +1134,35 @@ int hci_read_local_features(int dd, uint8_t *features, int to) return 0; } +int hci_read_local_ext_features(int dd, uint8_t page, uint8_t *max_page, uint8_t *features, int to) +{ + read_local_ext_features_cp cp; + read_local_ext_features_rp rp; + struct hci_request rq; + + cp.page_num = page; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_EXT_FEATURES; + rq.cparam = &cp; + rq.clen = READ_LOCAL_EXT_FEATURES_CP_SIZE; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_EXT_FEATURES_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *max_page = rp.max_page_num; + memcpy(features, rp.features, 8); + return 0; +} + int hci_read_bd_addr(int dd, bdaddr_t *bdaddr, int to) { read_bd_addr_rp rp; -- cgit From 0887d119a0b61e38cbd3d30e207c09eb5a5ff463 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 23:31:54 +0000 Subject: Add function for remote extended features --- src/hci.c | 54 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 11 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 6e1067c4..e04e55a8 100644 --- a/src/hci.c +++ b/src/hci.c @@ -969,6 +969,38 @@ int hci_read_remote_name_cancel(int dd, const bdaddr_t *bdaddr, int to) return 0; } +int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, int to) +{ + evt_read_remote_version_complete rp; + read_remote_version_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_READ_REMOTE_VERSION; + rq.event = EVT_READ_REMOTE_VERSION_COMPLETE; + rq.cparam = &cp; + rq.clen = READ_REMOTE_VERSION_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + ver->manufacturer = btohs(rp.manufacturer); + ver->lmp_ver = rp.lmp_ver; + ver->lmp_subver = btohs(rp.lmp_subver); + return 0; +} + int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) { evt_read_remote_features_complete rp; @@ -999,23 +1031,24 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) return 0; } -int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, int to) +int hci_read_remote_ext_features(int dd, uint16_t handle, uint8_t page, uint8_t *max_page, uint8_t *features, int to) { - evt_read_remote_version_complete rp; - read_remote_version_cp cp; + evt_read_remote_ext_features_complete rp; + read_remote_ext_features_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = handle; + cp.handle = handle; + cp.page_num = page; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_READ_REMOTE_VERSION; - rq.event = EVT_READ_REMOTE_VERSION_COMPLETE; + rq.ocf = OCF_READ_REMOTE_EXT_FEATURES; + rq.event = EVT_READ_REMOTE_EXT_FEATURES_COMPLETE; rq.cparam = &cp; - rq.clen = READ_REMOTE_VERSION_CP_SIZE; + rq.clen = READ_REMOTE_EXT_FEATURES_CP_SIZE; rq.rparam = &rp; - rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE; + rq.rlen = EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -1025,9 +1058,8 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in return -1; } - ver->manufacturer = btohs(rp.manufacturer); - ver->lmp_ver = rp.lmp_ver; - ver->lmp_subver = btohs(rp.lmp_subver); + *max_page = rp.max_page_num; + memcpy(features, rp.features, 8); return 0; } -- cgit From f1684dcb1badc1dfba7ad4133b8d6cac3e77c759 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 22:00:32 +0000 Subject: Support inquiry with unlimited number of responses --- src/hci.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index e04e55a8..6e7fa987 100644 --- a/src/hci.c +++ b/src/hci.c @@ -577,11 +577,14 @@ int hci_devba(int dev_id, bdaddr_t *bdaddr) int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info **ii, long flags) { struct hci_inquiry_req *ir; + uint8_t num_rsp = nrsp; void *buf; int s, err; - if (nrsp <= 0) - nrsp = 200; /* enough ? */ + if (nrsp <= 0) { + num_rsp = 0; + nrsp = 255; + } if (dev_id < 0 && (dev_id = hci_get_route(NULL)) < 0) { errno = ENODEV; @@ -600,7 +603,7 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info ir = buf; ir->dev_id = dev_id; - ir->num_rsp = nrsp; + ir->num_rsp = num_rsp; ir->length = len; ir->flags = flags; -- cgit From 48954bd49fdd7189bb725038801f3ca0ff2f4d12 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 1 May 2005 14:52:53 +0000 Subject: Add functions for stored link keys --- src/hci.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 6e7fa987..60898e9b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1340,6 +1340,61 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) return hci_send_req(dd, &rq, to); } +int hci_read_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to) +{ + read_stored_link_key_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + cp.read_all = all; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_STORED_LINK_KEY; + rq.cparam = &cp; + rq.clen = READ_STORED_LINK_KEY_CP_SIZE; + + return hci_send_req(dd, &rq, to); +} + +int hci_write_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t *key, int to) +{ + unsigned char cp[WRITE_STORED_LINK_KEY_CP_SIZE + 6 + 16]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 1; + bacpy((bdaddr_t *) (cp + 1), bdaddr); + memcpy(cp + 7, key, 16); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_STORED_LINK_KEY; + rq.cparam = &cp; + rq.clen = WRITE_STORED_LINK_KEY_CP_SIZE + 6 + 16; + + return hci_send_req(dd, &rq, to); +} + +int hci_delete_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to) +{ + delete_stored_link_key_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + cp.delete_all = all; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_DELETE_STORED_LINK_KEY; + rq.cparam = &cp; + rq.clen = DELETE_STORED_LINK_KEY_CP_SIZE; + + return hci_send_req(dd, &rq, to); +} + int hci_authenticate_link(int dd, uint16_t handle, int to) { auth_requested_cp cp; -- cgit From f38a7523b3e2ec2109cd5c5f65803da5a354da03 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Jun 2005 13:53:08 +0000 Subject: Add support for reading and writing the inquiry scan type --- src/hci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 60898e9b..b52b53fa 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1564,6 +1564,57 @@ int hci_exit_park_mode(int dd, uint16_t handle, int to) return 0; } +int hci_read_inquiry_scan_type(int dd, uint8_t *type, int to) +{ + read_inquiry_scan_type_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_INQUIRY_SCAN_TYPE; + rq.rparam = &rp; + rq.rlen = READ_INQUIRY_SCAN_TYPE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *type = rp.type; + return 0; +} + +int hci_write_inquiry_scan_type(int dd, uint8_t type, int to) +{ + write_inquiry_scan_type_cp cp; + write_inquiry_scan_type_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.type = type; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQUIRY_SCAN_TYPE; + rq.cparam = &cp; + rq.clen = WRITE_INQUIRY_SCAN_TYPE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_INQUIRY_SCAN_TYPE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_inquiry_mode(int dd, uint8_t *mode, int to) { read_inquiry_mode_rp rp; -- cgit From 631f20f4f87398b68b658acc3c374c6b36c1b7eb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 21 Jun 2005 16:40:29 +0000 Subject: Fix some errno usages --- src/hci.c | 109 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 48 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index b52b53fa..db6e6da1 100644 --- a/src/hci.c +++ b/src/hci.c @@ -33,18 +33,14 @@ #endif #include -#include -#include -#include -#include -#include -#include #include -#include #include +#include +#include +#include +#include #include -#include #include #include #include @@ -458,28 +454,26 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) /* HCI functions that do not require open device */ -int hci_for_each_dev(int flag, int (*func)(int s, int dev_id, long arg), long arg) +int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long arg) { struct hci_dev_list_req *dl; struct hci_dev_req *dr; int dev_id = -1; - int i, sk; + int i, sk, err; sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) return -1; dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); - if (!dl) { - close(sk); - return -1; - } + if (!dl) + goto done; dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; if (ioctl(sk, HCIGETDEVLIST, (void *) dl)) - goto done; + goto free; for (i = 0; i < dl->dev_num; i++, dr++) { if (hci_test_bit(flag, &dr->dev_opt)) @@ -489,17 +483,25 @@ int hci_for_each_dev(int flag, int (*func)(int s, int dev_id, long arg), long ar } } + if (dev_id < 0) + errno = ENODEV; + +free: + free(dl); + done: + err = errno; close(sk); - free(dl); + errno = err; + return dev_id; } -static int __other_bdaddr(int sk, int dev_id, long arg) +static int __other_bdaddr(int dd, int dev_id, long arg) { struct hci_dev_info di = { dev_id: dev_id }; - if (ioctl(sk, HCIGETDEVINFO, (void *) &di)) + if (ioctl(dd, HCIGETDEVINFO, (void *) &di)) return 0; if (hci_test_bit(HCI_RAW, &di.flags)) @@ -508,11 +510,11 @@ static int __other_bdaddr(int sk, int dev_id, long arg) return bacmp((bdaddr_t *) arg, &di.bdaddr); } -static int __same_bdaddr(int sk, int dev_id, long arg) +static int __same_bdaddr(int dd, int dev_id, long arg) { struct hci_dev_info di = { dev_id: dev_id }; - if (ioctl(sk, HCIGETDEVINFO, (void *) &di)) + if (ioctl(dd, HCIGETDEVINFO, (void *) &di)) return 0; return !bacmp((bdaddr_t *) arg, &di.bdaddr); @@ -540,22 +542,26 @@ int hci_devid(const char *str) str2ba(str, &ba); id = hci_for_each_dev(HCI_UP, __same_bdaddr, (long) &ba); } + return id; } int hci_devinfo(int dev_id, struct hci_dev_info *di) { - int s, err; + int dd, err, ret; - s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (s < 0) - return s; + dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (dd < 0) + return dd; di->dev_id = dev_id; - err = ioctl(s, HCIGETDEVINFO, (void *) di); - close(s); + ret = ioctl(dd, HCIGETDEVINFO, (void *) di); + + err = errno; + close(dd); + errno = err; - return err; + return ret; } int hci_devba(int dev_id, bdaddr_t *bdaddr) @@ -571,6 +577,7 @@ int hci_devba(int dev_id, bdaddr_t *bdaddr) } bacpy(bdaddr, &di.bdaddr); + return 0; } @@ -579,7 +586,7 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info struct hci_inquiry_req *ir; uint8_t num_rsp = nrsp; void *buf; - int s, err; + int dd, size, err, ret = -1; if (nrsp <= 0) { num_rsp = 0; @@ -591,15 +598,13 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info return -1; } - s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (s < 0) - return -1; + dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (dd < 0) + return dd; buf = malloc(sizeof(*ir) + (sizeof(inquiry_info) * (nrsp))); - if (!buf) { - close(s); - return -1; - } + if (!buf) + goto done; ir = buf; ir->dev_id = dev_id; @@ -615,23 +620,30 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info ir->lap[2] = 0x9e; } - err = ioctl(s, HCIINQUIRY, (unsigned long) buf); - close(s); + ret = ioctl(dd, HCIINQUIRY, (unsigned long) buf); + if (ret < 0) + goto free; - if (!err) { - int size = sizeof(inquiry_info) * ir->num_rsp; + size = sizeof(inquiry_info) * ir->num_rsp; - if (!*ii) - *ii = (void *) malloc(size); + if (!*ii) + *ii = malloc(size); - if (*ii) { - memcpy((void *) *ii, buf + sizeof(*ir), size); - err = ir->num_rsp; - } else - err = -1; - } + if (*ii) { + memcpy((void *) *ii, buf + sizeof(*ir), size); + ret = ir->num_rsp; + } else + ret = -1; + +free: free(buf); - return err; + +done: + err = errno; + close(dd); + errno = err; + + return ret; } /* Open HCI device. @@ -658,6 +670,7 @@ failed: err = errno; close(dd); errno = err; + return -1; } -- cgit From e27896801ac0514289f57def3a8b5c1491d316c6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jul 2005 19:54:42 +0000 Subject: Fix some GCC 4.0 warnings --- src/hci.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index db6e6da1..59f2afa7 100644 --- a/src/hci.c +++ b/src/hci.c @@ -717,8 +717,9 @@ int hci_send_req(int dd, struct hci_request *r, int to) unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr; uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); struct hci_filter nf, of; + socklen_t len; hci_event_hdr *hdr; - int err, len, try; + int err, try; len = sizeof(of); if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &len) < 0) @@ -903,7 +904,7 @@ int hci_read_local_name(int dd, int len, char *name, int to) } rp.name[247] = '\0'; - strncpy(name, rp.name, len); + strncpy(name, (char *) rp.name, len); return 0; } @@ -913,7 +914,7 @@ int hci_write_local_name(int dd, const char *name, int to) struct hci_request rq; memset(&cp, 0, sizeof(cp)); - strncpy(cp.name, name, sizeof(cp.name)); + strncpy((char *) cp.name, name, sizeof(cp.name)); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; @@ -956,7 +957,7 @@ int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint8 } rn.name[247] = '\0'; - strncpy(name, rn.name, len); + strncpy(name, (char *) rn.name, len); return 0; } -- cgit From b809fb039119546a8b5b4fbb4bcbfbad6666cf24 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 9 Jul 2005 17:09:10 +0000 Subject: Fix the routing for dealing with raw devices --- src/hci.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 59f2afa7..0aca162f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -522,10 +522,8 @@ static int __same_bdaddr(int dd, int dev_id, long arg) int hci_get_route(bdaddr_t *bdaddr) { - if (bdaddr) - return hci_for_each_dev(HCI_UP, __other_bdaddr, (long) bdaddr); - else - return hci_for_each_dev(HCI_UP, NULL, 0); + return hci_for_each_dev(HCI_UP, __other_bdaddr, + (long) (bdaddr ? bdaddr : BDADDR_ANY)); } int hci_devid(const char *str) @@ -593,9 +591,12 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info nrsp = 255; } - if (dev_id < 0 && (dev_id = hci_get_route(NULL)) < 0) { - errno = ENODEV; - return -1; + if (dev_id < 0) { + dev_id = hci_get_route(NULL); + if (dev_id < 0) { + errno = ENODEV; + return -1; + } } dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); -- cgit From e602dbfade3e4ef56ef04a81489ba0374133a313 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 04:26:53 +0000 Subject: Cleanup --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 0aca162f..2447ae9b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -472,7 +472,7 @@ int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long a dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(sk, HCIGETDEVLIST, (void *) dl)) + if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) goto free; for (i = 0; i < dl->dev_num; i++, dr++) { -- cgit From 9409e3e8e152290e253889df6922c56ef606b62b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 07:33:57 +0000 Subject: Update lmp_featurestostr() function --- src/hci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 2447ae9b..c42d81c4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -411,13 +411,13 @@ static hci_map lmp_features_map[8][9] = { char *lmp_featurestostr(uint8_t *features, char *pref, int width) { char *off, *ptr, *str; - int i, size = 0; + int i, size = 10; for (i = 0; i < 8; i++) { hci_map *m = lmp_features_map[i]; while (m->str) { - if ((unsigned int) m->val & (unsigned int) features[i]) + if (m->val & features[i]) size += strlen(m->str) + (pref ? strlen(pref) : 0) + 1; m++; } @@ -427,7 +427,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) if (!str) return NULL; - ptr = str; *ptr = 0; + ptr = str; *ptr = '\0'; if (pref) ptr += sprintf(ptr, "%s", pref); @@ -438,7 +438,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) hci_map *m = lmp_features_map[i]; while (m->str) { - if ((unsigned int) m->val & (unsigned int) features[i]) { + if (m->val & features[i]) { if (strlen(off) + strlen(m->str) > width - 1) { ptr += sprintf(ptr, "\n%s", pref ? pref : ""); off = ptr; -- cgit From f544b5e43cc3c64d43e73a3fbfc5fd045b6de00c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Aug 2005 00:54:48 +0000 Subject: Add functions for the extended inquiry response --- src/hci.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index c42d81c4..f92aa4f2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1732,6 +1732,60 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } +int hci_read_ext_inquiry_response(int dd, uint8_t *fec, uint8_t *data, int to) +{ + read_ext_inquiry_response_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_EXT_INQUIRY_RESPONSE; + rq.rparam = &rp; + rq.rlen = READ_EXT_INQUIRY_RESPONSE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *fec = rp.fec; + memcpy(data, rp.data, 240); + + return 0; +} + +int hci_write_ext_inquiry_response(int dd, uint8_t fec, uint8_t *data, int to) +{ + write_ext_inquiry_response_cp cp; + write_ext_inquiry_response_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.fec = fec; + memcpy(cp.data, data, 240); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_EXT_INQUIRY_RESPONSE; + rq.cparam = &cp; + rq.clen = WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to) { read_transmit_power_level_cp cp; -- cgit From f50545eae585ba4b3eac5d8764827342ae214843 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 27 Aug 2005 10:53:49 +0000 Subject: Add extended inquiry features bit --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index f92aa4f2..dd3d0d74 100644 --- a/src/hci.c +++ b/src/hci.c @@ -400,6 +400,7 @@ static hci_map lmp_features_map[8][9] = { { NULL } }, { /* Byte 6 */ + { "", LMP_EXT_INQ }, /* Bit 0 */ { NULL } }, { /* Byte 7 */ -- cgit From b48bccaf6c89da2af3a20617f4a496be4a633c5b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Sep 2005 16:14:55 +0000 Subject: Add support for identification of supported commands --- src/hci.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 193 insertions(+), 6 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index dd3d0d74..a9c482a2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -98,7 +98,7 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) static char *hci_uint2str(hci_map *m, unsigned int val) { - char *str = malloc(50); + char *str = bt_malloc(50); char *ptr = str; if (!str) @@ -309,6 +309,195 @@ int hci_strtolm(char *str, unsigned int *val) return hci_str2bit(link_mode_map, str, val); } +/* Command mapping */ +static hci_map commands_map[] = { + { "Inquiry", 0 }, + { "Inquiry Cancel", 1 }, + { "Periodic Inquiry Mode", 2 }, + { "Exit Periodic Inquiry Mode", 3 }, + { "Create Connection", 4 }, + { "Disconnect", 5 }, + { "Add SCO Connection", 6 }, + { "Cancel Create Connection", 7 }, + { "Accept Connection Request", 8 }, + { "Reject Connection Request", 9 }, + { "Link Key Request Reply", 10 }, + { "Link Key Request Negative Reply", 11 }, + { "PIN Code Request Reply", 12 }, + { "PIN Code Request Negative Reply", 13 }, + { "Change Connection Packet Type", 14 }, + { "Authentication Requested", 15 }, + { "Set Connection Encryption", 16 }, + { "Change Connection Link Key", 17 }, + { "Master Link Key", 18 }, + { "Remote Name Request", 19 }, + { "Cancel Remote Name Request", 20 }, + { "Read Remote Supported Features", 21 }, + { "Read Remote Extended Features", 22 }, + { "Read Remote Version Information", 23 }, + { "Read Clock Offset", 24 }, + { "Read LMP Handle", 25 }, + { "Reserved", 26 }, + { "Reserved", 27 }, + { "Reserved", 28 }, + { "Reserved", 29 }, + { "Reserved", 30 }, + { "Reserved", 31 }, + { "Reserved", 32 }, + { "Hold Mode", 33 }, + { "Sniff Mode", 34 }, + { "Exit Sniff Mode", 35 }, + { "Park State", 36 }, + { "Exit Park State", 37 }, + { "QoS Setup", 38 }, + { "Role Discovery", 39 }, + { "Switch Role", 40 }, + { "Read Link Policy Settings", 41 }, + { "Write Link Policy Settings", 42 }, + { "Read Default Link Policy Settings", 43 }, + { "Write Default Link Policy Settings", 44 }, + { "Flow Specification", 45 }, + { "Set Event Mask", 46 }, + { "Reset", 47 }, + { "Set Event Filter", 48 }, + { "Flush", 49 }, + { "Read PIN Type", 50 }, + { "Write PIN Type", 51 }, + { "Create New Unit Key", 52 }, + { "Read Stored Link Key", 53 }, + { "Write Stored Link Key", 54 }, + { "Delete Stored Link Key", 55 }, + { "Write Local Name", 56 }, + { "Read Local Name", 57 }, + { "Read Connection Accept Timeout", 58 }, + { "Write Connection Accept Timeout", 59 }, + { "Read Page Timeout", 60 }, + { "Write Page Timeout", 61 }, + { "Read Scan Enable", 62 }, + { "Write Scan Enable", 63 }, + { "Read Page Scan Activity", 64 }, + { "Write Page Scan Activity", 65 }, + { "Read Inquiry Scan Activity", 66 }, + { "Write Inquiry Scan Activity", 67 }, + { "Read Authentication Enable", 68 }, + { "Write Authentication Enable", 69 }, + { "Read Encryption Mode", 70 }, + { "Write Encryption Mode", 71 }, + { "Read Class Of Device", 72 }, + { "Write Class Of Device", 73 }, + { "Read Voice Setting", 74 }, + { "Write Voice Setting", 75 }, + { "Read Automatic Flush Timeout", 76 }, + { "Write Automatic Flush Timeout", 77 }, + { "Read Num Broadcast Retransmissions", 78 }, + { "Write Num Broadcast Retransmissions", 79 }, + { "Read Hold Mode Activity", 80 }, + { "Write Hold Mode Activity", 81 }, + { "Read Transmit Power Level", 82 }, + { "Read Synchronous Flow Control Enable", 83 }, + { "Write Synchronous Flow Control Enable", 84 }, + { "Set Host Controller To Host Flow Control", 85 }, + { "Host Buffer Size", 86 }, + { "Host Number Of Completed Packets", 87 }, + { "Read Link Supervision Timeout", 88 }, + { "Write Link Supervision Timeout", 89 }, + { "Read Number of Supported IAC", 90 }, + { "Read Current IAC LAP", 91 }, + { "Write Current IAC LAP", 92 }, + { "Reserved", 93 }, + { "Reserved", 94 }, + { "Read Page Scan Mode", 95 }, + { "Write Page Scan Mode", 96 }, + { "Set AFH Channel Classification", 97 }, + { "reserved", 98 }, + { "reserved", 99 }, + { "Read Inquiry Scan Type", 100 }, + { "Write Inquiry Scan Type", 101 }, + { "Read Inquiry Mode", 102 }, + { "Write Inquiry Mode", 103 }, + { "Read Page Scan Type", 104 }, + { "Write Page Scan Type", 105 }, + { "Read AFH Channel Assessment Mode", 106 }, + { "Write AFH Channel Assessment Mode", 107 }, + { "Reserved", 108 }, + { "Reserved", 109 }, + { "Reserved", 110 }, + { "Reserved", 111 }, + { "Reserved", 112 }, + { "Reserved", 113 }, + { "Reserved", 114 }, + { "Read Loacal Version Information", 115 }, + { "Reserved", 116 }, + { "Read Local Supported Features", 117 }, + { "Read Local Extended Features", 118 }, + { "Read Buffer Sizer", 119 }, + { "Read Country Code", 120 }, + { "Read BD ADDR", 121 }, + { "Read Failed Contact Counter", 122 }, + { "Reset Failed Contact Counter", 123 }, + { "Get Link Quality", 124 }, + { "Read RSSI", 125 }, + { "Read AFH Channel Map", 126 }, + { "Read BD Clock", 127 }, + { "Read Loopback Mode", 128 }, + { "Write Loopback Mode", 129 }, + { "Enable Device Under Test Mode", 130 }, + { "Setup Synchronous Connection", 131 }, + { "Accept Synchronous Connection", 132 }, + { "Reject Synchronous Connection", 133 }, + { "Reserved", 134 }, + { "Reserved", 135 }, + { "Read Extended Inquiry Response", 136 }, + { "Write Extended Inquiry Response", 137 }, + { NULL } +}; + +char *hci_cmdtostr(unsigned int cmd) +{ + return hci_uint2str(commands_map, cmd); +} + +char *hci_commandstostr(uint8_t *commands, char *pref, int width) +{ + hci_map *m; + char *off, *ptr, *str; + int size = 10; + + m = commands_map; + + while (m->str) { + if (hci_test_bit(m->val, commands)) + size += strlen(m->str) + (pref ? strlen(pref) : 0) + 3; + m++; + } + + str = bt_malloc(size); + if (!str) + return NULL; + + ptr = str; *ptr = '\0'; + + if (pref) + ptr += sprintf(ptr, "%s", pref); + + off = ptr; + + m = commands_map; + + while (m->str) { + if (hci_test_bit(m->val, commands)) { + if (strlen(off) + strlen(m->str) > width - 3) { + ptr += sprintf(ptr, "\n%s", pref ? pref : ""); + off = ptr; + } + ptr += sprintf(ptr, "'%s' ", m->str); + } + m++; + } + + return str; +} + /* Version mapping */ static hci_map ver_map[] = { { "1.0b", 0x00 }, @@ -320,8 +509,7 @@ static hci_map ver_map[] = { char *hci_vertostr(unsigned int ver) { - char *str = hci_uint2str(ver_map, ver); - return *str ? str : "n/a"; + return hci_uint2str(ver_map, ver); } int hci_strtover(char *str, unsigned int *ver) @@ -331,8 +519,7 @@ int hci_strtover(char *str, unsigned int *ver) char *lmp_vertostr(unsigned int ver) { - char *str = hci_uint2str(ver_map, ver); - return *str ? str : "n/a"; + return hci_uint2str(ver_map, ver); } int lmp_strtover(char *str, unsigned int *ver) @@ -424,7 +611,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) } } - str = malloc(size); + str = bt_malloc(size); if (!str) return NULL; -- cgit From 12862715c961bf6dabce2ed4e58da58e5dfe8c6b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 22 Sep 2005 23:10:48 +0000 Subject: Fix errno overwrite problems --- src/hci.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index a9c482a2..05974432 100644 --- a/src/hci.c +++ b/src/hci.c @@ -647,21 +647,25 @@ int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long a struct hci_dev_list_req *dl; struct hci_dev_req *dr; int dev_id = -1; - int i, sk, err; + int i, sk, err = 0; sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) return -1; dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); - if (!dl) + if (!dl) { + err = errno; goto done; + } dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) + if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) { + err = errno; goto free; + } for (i = 0; i < dl->dev_num; i++, dr++) { if (hci_test_bit(flag, &dr->dev_opt)) @@ -672,13 +676,12 @@ int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long a } if (dev_id < 0) - errno = ENODEV; + err = ENODEV; free: free(dl); done: - err = errno; close(sk); errno = err; -- cgit From b60f09936298f7115d5387398d5eeb0156b08892 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 20 Oct 2005 08:55:11 +0000 Subject: Make EVT_CMD_STATUS as rp->event work --- src/hci.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 05974432..c4bb3cd3 100644 --- a/src/hci.c +++ b/src/hci.c @@ -976,7 +976,13 @@ int hci_send_req(int dd, struct hci_request *r, int to) errno = EIO; goto failed; } - break; + + if (r->event != EVT_CMD_STATUS) + break; + + r->rlen = MIN(len, r->rlen); + memcpy(r->rparam, ptr, r->rlen); + goto done; case EVT_CMD_COMPLETE: cc = (void *) ptr; -- cgit From 4fb6514cdebdeb4317ee3a5ef59abcdaf3697d2b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Oct 2005 14:27:14 +0000 Subject: Add deprecated command names from the Bluetooth 1.2 specification --- src/hci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index c4bb3cd3..c1aa9b28 100644 --- a/src/hci.c +++ b/src/hci.c @@ -404,8 +404,8 @@ static hci_map commands_map[] = { { "Read Number of Supported IAC", 90 }, { "Read Current IAC LAP", 91 }, { "Write Current IAC LAP", 92 }, - { "Reserved", 93 }, - { "Reserved", 94 }, + { "Read Page Scan Period Mode", 93 }, + { "Write Page Scan Period Mode", 94 }, { "Read Page Scan Mode", 95 }, { "Write Page Scan Mode", 96 }, { "Set AFH Channel Classification", 97 }, @@ -426,8 +426,8 @@ static hci_map commands_map[] = { { "Reserved", 112 }, { "Reserved", 113 }, { "Reserved", 114 }, - { "Read Loacal Version Information", 115 }, - { "Reserved", 116 }, + { "Read Local Version Information", 115 }, + { "Read Local Supported Commands", 116 }, { "Read Local Supported Features", 117 }, { "Read Local Extended Features", 118 }, { "Read Buffer Sizer", 119 }, -- cgit From 555ac3f21cb5f6099755d43c3c1e89a1a554b435 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Oct 2005 15:51:12 +0000 Subject: Fix typo --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index c1aa9b28..b286d46f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -430,7 +430,7 @@ static hci_map commands_map[] = { { "Read Local Supported Commands", 116 }, { "Read Local Supported Features", 117 }, { "Read Local Extended Features", 118 }, - { "Read Buffer Sizer", 119 }, + { "Read Buffer Size", 119 }, { "Read Country Code", 120 }, { "Read BD ADDR", 121 }, { "Read Failed Contact Counter", 122 }, -- cgit From 1364c63b9eea39b40ab07e0045ef26e76d1ade1a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Oct 2005 17:32:35 +0000 Subject: Decode reserved LMP feature bits --- src/hci.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index b286d46f..80813ad6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -556,10 +556,14 @@ static hci_map lmp_features_map[8][9] = { { "", LMP_PSCHEME }, /* Bit 1 */ { "", LMP_PCONTROL }, /* Bit 2 */ { "", LMP_TRSP_SCO }, /* Bit 3 */ + { "",LMP_BCAST_ENC }, /* Bit 7 */ { NULL } }, { /* Byte 3 */ + { "", 0x01 }, /* Bit 0 */ { "", LMP_EDR_ACL_2M }, /* Bit 1 */ { "", LMP_EDR_ACL_3M }, /* Bit 2 */ { "", LMP_ENH_ISCAN }, /* Bit 3 */ @@ -572,13 +576,18 @@ static hci_map lmp_features_map[8][9] = { { /* Byte 4 */ { "", LMP_EV4 }, /* Bit 0 */ { "", LMP_EV5 }, /* Bit 1 */ + { "", 0x04 }, /* Bit 2 */ { "", LMP_AFH_CAP_SLV }, /* Bit 3 */ { "", LMP_AFH_CLS_SLV }, /* Bit 4 */ + { "", 0x20 }, /* Bit 5 */ + { "", 0x40 }, /* Bit 6 */ { "<3-slot EDR ACL>", LMP_EDR_3SLOT }, /* Bit 7 */ { NULL } }, { /* Byte 5 */ { "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */ + { "", 0x02 }, /* Bit 1 */ + { "", 0x04 }, /* Bit 2 */ { "", LMP_AFH_CAP_MST }, /* Bit 3 */ { "",LMP_AFH_CLS_MST }, /* Bit 4 */ { "", LMP_EDR_ESCO_2M }, /* Bit 5 */ -- cgit From c0d524486a50e8366c12c5ebea1a4441e9db46aa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 19:25:42 +0000 Subject: Big cleanup of CVS relics --- src/hci.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 80813ad6..eeb171a1 100644 --- a/src/hci.c +++ b/src/hci.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From a097798c889cef47144b3cce2118c5d9e914864c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 2 Nov 2005 13:19:55 +0000 Subject: Remove decoding of flow control feature bits --- src/hci.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index eeb171a1..d21ef274 100644 --- a/src/hci.c +++ b/src/hci.c @@ -551,9 +551,6 @@ static hci_map lmp_features_map[8][9] = { { "", LMP_PSCHEME }, /* Bit 1 */ { "", LMP_PCONTROL }, /* Bit 2 */ { "", LMP_TRSP_SCO }, /* Bit 3 */ - { "",LMP_BCAST_ENC }, /* Bit 7 */ { NULL } }, -- cgit From 7575a227c3ad282247c288fa8def69d9dcd7603f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 21 Nov 2005 10:26:56 +0000 Subject: Add constants for sniff subrating --- src/hci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index d21ef274..a70fba9b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -444,6 +444,9 @@ static hci_map commands_map[] = { { "Reserved", 135 }, { "Read Extended Inquiry Response", 136 }, { "Write Extended Inquiry Response", 137 }, + { "Unknown", 138 }, + { "Unknown", 139 }, + { "Sniff Subrate", 140 }, { NULL } }; @@ -578,7 +581,7 @@ static hci_map lmp_features_map[8][9] = { }, { /* Byte 5 */ { "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */ - { "", 0x02 }, /* Bit 1 */ + { "", LMP_SNIFF_SUBR }, /* Bit 1 */ { "", 0x04 }, /* Bit 2 */ { "", LMP_AFH_CAP_MST }, /* Bit 3 */ { "",LMP_AFH_CLS_MST }, /* Bit 4 */ -- cgit From a1b96c15eb685081c9329531906d18fce8405af7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 09:56:12 +0000 Subject: Include sys/uio.h for writev() function --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index a70fba9b..8dd3e1c6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include -- cgit From 197a2aee34d9a1643cd474f8f167552ca6395d01 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 12:56:09 +0000 Subject: Update copyright information --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 8dd3e1c6..6a33d3c4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 1ba3b0978c73153513cfe016435e1e930038fbd4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Feb 2006 07:48:11 +0000 Subject: Add features bit for pause encryption --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 6a33d3c4..9e81653c 100644 --- a/src/hci.c +++ b/src/hci.c @@ -583,7 +583,7 @@ static hci_map lmp_features_map[8][9] = { { /* Byte 5 */ { "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */ { "", LMP_SNIFF_SUBR }, /* Bit 1 */ - { "", 0x04 }, /* Bit 2 */ + { "", LMP_PAUSE_ENC }, /* Bit 2 */ { "", LMP_AFH_CAP_MST }, /* Bit 3 */ { "",LMP_AFH_CLS_MST }, /* Bit 4 */ { "", LMP_EDR_ESCO_2M }, /* Bit 5 */ -- cgit From 93048c3a1a3f8a86d8f5be1bd3409f77e9802d6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 14 Mar 2006 18:25:35 +0000 Subject: Fix broken behavior with EVT_CMD_STATUS --- src/hci.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 9e81653c..d0c2394c 100644 --- a/src/hci.c +++ b/src/hci.c @@ -977,13 +977,13 @@ int hci_send_req(int dd, struct hci_request *r, int to) if (cs->opcode != opcode) continue; - if (cs->status) { - errno = EIO; - goto failed; - } - - if (r->event != EVT_CMD_STATUS) + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + errno = EIO; + goto failed; + } break; + } r->rlen = MIN(len, r->rlen); memcpy(r->rparam, ptr, r->rlen); -- cgit From 07e291d7269885187586106e059f29abb336cb27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Apr 2006 15:55:51 +0000 Subject: Add missing memset() for socket address --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index d0c2394c..35aa9059 100644 --- a/src/hci.c +++ b/src/hci.c @@ -856,6 +856,7 @@ int hci_open_dev(int dev_id) return dd; /* Bind socket to the HCI device */ + memset(&a, 0, sizeof(a)); a.hci_family = AF_BLUETOOTH; a.hci_dev = dev_id; if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0) -- cgit From 31530898cb8cba0952a1af0bfe8fd26806c7b075 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Jun 2006 15:41:44 +0000 Subject: Fix uninitialised value error --- src/hci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 35aa9059..d5d7124f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -762,6 +762,8 @@ int hci_devba(int dev_id, bdaddr_t *bdaddr) { struct hci_dev_info di; + memset(&di, 0, sizeof(di)); + if (hci_devinfo(dev_id, &di)) return -1; -- cgit From 5ed11d784fcfa59254246bd401d4d1142bb5b9cb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 16 Jun 2006 09:00:30 +0000 Subject: Add missing placeholders for feature bits --- src/hci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index d5d7124f..977c60eb 100644 --- a/src/hci.c +++ b/src/hci.c @@ -593,9 +593,23 @@ static hci_map lmp_features_map[8][9] = { }, { /* Byte 6 */ { "", LMP_EXT_INQ }, /* Bit 0 */ + { "", 0x02 }, /* Bit 1 */ + { "", 0x04 }, /* Bit 2 */ + { "", 0x08 }, /* Bit 3 */ + { "", 0x10 }, /* Bit 4 */ + { "", 0x20 }, /* Bit 5 */ + { "", 0x40 }, /* Bit 6 */ + { "", 0x80 }, /* Bit 7 */ { NULL } }, { /* Byte 7 */ + { "", 0x01 }, /* Bit 1 */ + { "", 0x02 }, /* Bit 1 */ + { "", 0x04 }, /* Bit 2 */ + { "", 0x08 }, /* Bit 3 */ + { "", 0x10 }, /* Bit 4 */ + { "", 0x20 }, /* Bit 5 */ + { "", 0x40 }, /* Bit 6 */ { "",LMP_EXT_FEAT }, /* Bit 7 */ { NULL } }, -- cgit From 39519245f25c517424d1f2ccbed07777c8e060fa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 8 Jul 2006 11:45:21 +0000 Subject: Add adapter type for SDIO --- src/hci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 977c60eb..6fa61831 100644 --- a/src/hci.c +++ b/src/hci.c @@ -138,8 +138,8 @@ static int hci_str2uint(hci_map *map, char *str, unsigned int *val) char *hci_dtypetostr(int type) { switch (type) { - case HCI_VHCI: - return "VHCI"; + case HCI_VIRTUAL: + return "VIRTUAL"; case HCI_USB: return "USB"; case HCI_PCCARD: @@ -150,8 +150,10 @@ char *hci_dtypetostr(int type) return "RS232"; case HCI_PCI: return "PCI"; + case HCI_SDIO: + return "SDIO"; default: - return "UKNW"; + return "UNKNOWN"; } } -- cgit From 57834785d5445439c2abbc19903566f050bc98a2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jul 2006 01:23:04 +0000 Subject: Add features bit for link supervision timeout --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 6fa61831..48989aae 100644 --- a/src/hci.c +++ b/src/hci.c @@ -605,7 +605,7 @@ static hci_map lmp_features_map[8][9] = { { NULL } }, { /* Byte 7 */ - { "", 0x01 }, /* Bit 1 */ + { "", LMP_LSTO }, /* Bit 1 */ { "", 0x02 }, /* Bit 1 */ { "", 0x04 }, /* Bit 2 */ { "", 0x08 }, /* Bit 3 */ -- cgit From 646fda930139720d7d9c45cc085ae4eb7018d8bb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Jul 2006 09:56:18 +0000 Subject: Add link supervision timeout change event --- src/hci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 48989aae..7135501b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -2058,7 +2058,7 @@ int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout return -1; } - *timeout = rp.link_sup_to; + *timeout = rp.timeout; return 0; } @@ -2069,8 +2069,8 @@ int hci_write_link_supervision_timeout(int dd, uint16_t handle, uint16_t timeout struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = handle; - cp.link_sup_to = timeout; + cp.handle = handle; + cp.timeout = timeout; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; -- cgit From 99b4c49f0afb4bb3bc92bded8ed8ab59e67a440a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 21 Aug 2006 10:32:10 +0000 Subject: Initialize hci_dev_info memory to zero before calling ioctl --- src/hci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 7135501b..caed69bf 100644 --- a/src/hci.c +++ b/src/hci.c @@ -764,6 +764,8 @@ int hci_devinfo(int dev_id, struct hci_dev_info *di) if (dd < 0) return dd; + memset(di, 0, sizeof(struct hci_dev_info)); + di->dev_id = dev_id; ret = ioctl(dd, HCIGETDEVINFO, (void *) di); -- cgit From 9b3d6f5cd180f037789e0b2af4656f55d6df2c0c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 21 Aug 2006 11:26:43 +0000 Subject: Initialize memory to zero in hci_for_each_dev --- src/hci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index caed69bf..dca4c096 100644 --- a/src/hci.c +++ b/src/hci.c @@ -680,6 +680,8 @@ int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long a goto done; } + memset(dl, 0, HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); + dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; -- cgit From 21f2a5244f0c6195e17ff71868328bc71d77f4d9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 23 Aug 2006 15:05:30 +0000 Subject: Fix malloc() versus bt_malloc() usage --- src/hci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index dca4c096..f7235f74 100644 --- a/src/hci.c +++ b/src/hci.c @@ -94,7 +94,7 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) static char *hci_uint2str(hci_map *m, unsigned int val) { - char *str = bt_malloc(50); + char *str = malloc(50); char *ptr = str; if (!str) @@ -174,7 +174,7 @@ static hci_map dev_flags_map[] = { char *hci_dflagstostr(uint32_t flags) { - char *str = malloc(50); + char *str = bt_malloc(50); char *ptr = str; hci_map *m = dev_flags_map; @@ -283,7 +283,7 @@ static hci_map link_mode_map[] = { char *hci_lmtostr(unsigned int lm) { - char *s, *str = malloc(50); + char *s, *str = bt_malloc(50); if (!str) return NULL; @@ -293,7 +293,7 @@ char *hci_lmtostr(unsigned int lm) s = hci_bit2str(link_mode_map, lm); if (!s) { - free(str); + bt_free(str); return NULL; } -- cgit From 25effaf3a661c4de960ebae7125ba56a990ad628 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 17:50:06 +0000 Subject: Update copyright information --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index f7235f74..7d30c552 100644 --- a/src/hci.c +++ b/src/hci.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 397609f69cbc21cfd87b27246f4f5ed9dada646d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 13 Feb 2007 14:44:47 +0000 Subject: Add version code for Bluetooth 2.1 --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 7d30c552..a064980f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -505,6 +505,7 @@ static hci_map ver_map[] = { { "1.1", 0x01 }, { "1.2", 0x02 }, { "2.0", 0x03 }, + { "2.1", 0x04 }, { NULL } }; -- cgit From 34c5828e678e244a28b7c3ba7078a08583273aa3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Jun 2007 11:46:22 +0000 Subject: Add definitions for inquiry power level and erroneous data --- src/hci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index a064980f..4e95a420 100644 --- a/src/hci.c +++ b/src/hci.c @@ -600,14 +600,14 @@ static hci_map lmp_features_map[8][9] = { { "", 0x04 }, /* Bit 2 */ { "", 0x08 }, /* Bit 3 */ { "", 0x10 }, /* Bit 4 */ - { "", 0x20 }, /* Bit 5 */ - { "", 0x40 }, /* Bit 6 */ + { "", LMP_ERR_DAT_REP }, /* Bit 5 */ + { "", LMP_NFLUSH_PKTS }, /* Bit 6 */ { "", 0x80 }, /* Bit 7 */ { NULL } }, { /* Byte 7 */ { "", LMP_LSTO }, /* Bit 1 */ - { "", 0x02 }, /* Bit 1 */ + { "", LMP_INQ_TX_PWR }, /* Bit 1 */ { "", 0x04 }, /* Bit 2 */ { "", 0x08 }, /* Bit 3 */ { "", 0x10 }, /* Bit 4 */ -- cgit From a9ad7c6fef3c62fa773a586d10402a343a4ee91b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Jun 2007 19:09:54 +0000 Subject: Add HCI command text descriptions --- src/hci.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 4e95a420..47359195 100644 --- a/src/hci.c +++ b/src/hci.c @@ -447,9 +447,35 @@ static hci_map commands_map[] = { { "Reserved", 135 }, { "Read Extended Inquiry Response", 136 }, { "Write Extended Inquiry Response", 137 }, - { "Unknown", 138 }, - { "Unknown", 139 }, - { "Sniff Subrate", 140 }, + { "Refresh Encryption Key", 138 }, + { "Reserved", 139 }, + { "Sniff Subrating", 140 }, + { "Unknown", 141 }, + { "Unknown", 142 }, + { "Unknown", 143 }, + { "Read Inquiry Transmit Power Level", 144 }, + { "Write Inquiry Transmit Power Level", 145 }, + { "Read Default Erroneous Data Reporting", 146 }, + { "Write Default Erroneous Data Reporting", 147 }, + { "Reserved", 148 }, + { "Reserved", 149 }, + { "Reserved", 150 }, + { "Unknown", 151 }, + { "Unknown", 152 }, + { "Unknown", 153 }, + { "Unknown", 154 }, + { "Unknown", 155 }, + { "Unknown", 156 }, + { "Enhanced Flush", 157 }, + { "Unknown", 158 }, + { "Reserved", 159 }, + { "Reserved", 160 }, + { "Unknown", 161 }, + { "Unknown", 162 }, + { "Reserved", 163 }, + { "Reserved", 164 }, + { "Reserved", 165 }, + { "Reserved", 166 }, { NULL } }; -- cgit From 08b3ddeeff510f9ac61c860a74d13575a47420b7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jul 2007 08:25:50 +0000 Subject: Update HCI command table --- src/hci.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 47359195..04da6de5 100644 --- a/src/hci.c +++ b/src/hci.c @@ -317,6 +317,7 @@ static hci_map commands_map[] = { { "Disconnect", 5 }, { "Add SCO Connection", 6 }, { "Cancel Create Connection", 7 }, + { "Accept Connection Request", 8 }, { "Reject Connection Request", 9 }, { "Link Key Request Reply", 10 }, @@ -325,6 +326,7 @@ static hci_map commands_map[] = { { "PIN Code Request Negative Reply", 13 }, { "Change Connection Packet Type", 14 }, { "Authentication Requested", 15 }, + { "Set Connection Encryption", 16 }, { "Change Connection Link Key", 17 }, { "Master Link Key", 18 }, @@ -333,6 +335,7 @@ static hci_map commands_map[] = { { "Read Remote Supported Features", 21 }, { "Read Remote Extended Features", 22 }, { "Read Remote Version Information", 23 }, + { "Read Clock Offset", 24 }, { "Read LMP Handle", 25 }, { "Reserved", 26 }, @@ -341,6 +344,7 @@ static hci_map commands_map[] = { { "Reserved", 29 }, { "Reserved", 30 }, { "Reserved", 31 }, + { "Reserved", 32 }, { "Hold Mode", 33 }, { "Sniff Mode", 34 }, @@ -349,6 +353,7 @@ static hci_map commands_map[] = { { "Exit Park State", 37 }, { "QoS Setup", 38 }, { "Role Discovery", 39 }, + { "Switch Role", 40 }, { "Read Link Policy Settings", 41 }, { "Write Link Policy Settings", 42 }, @@ -357,6 +362,7 @@ static hci_map commands_map[] = { { "Flow Specification", 45 }, { "Set Event Mask", 46 }, { "Reset", 47 }, + { "Set Event Filter", 48 }, { "Flush", 49 }, { "Read PIN Type", 50 }, @@ -365,6 +371,7 @@ static hci_map commands_map[] = { { "Read Stored Link Key", 53 }, { "Write Stored Link Key", 54 }, { "Delete Stored Link Key", 55 }, + { "Write Local Name", 56 }, { "Read Local Name", 57 }, { "Read Connection Accept Timeout", 58 }, @@ -373,6 +380,7 @@ static hci_map commands_map[] = { { "Write Page Timeout", 61 }, { "Read Scan Enable", 62 }, { "Write Scan Enable", 63 }, + { "Read Page Scan Activity", 64 }, { "Write Page Scan Activity", 65 }, { "Read Inquiry Scan Activity", 66 }, @@ -381,6 +389,7 @@ static hci_map commands_map[] = { { "Write Authentication Enable", 69 }, { "Read Encryption Mode", 70 }, { "Write Encryption Mode", 71 }, + { "Read Class Of Device", 72 }, { "Write Class Of Device", 73 }, { "Read Voice Setting", 74 }, @@ -389,6 +398,7 @@ static hci_map commands_map[] = { { "Write Automatic Flush Timeout", 77 }, { "Read Num Broadcast Retransmissions", 78 }, { "Write Num Broadcast Retransmissions", 79 }, + { "Read Hold Mode Activity", 80 }, { "Write Hold Mode Activity", 81 }, { "Read Transmit Power Level", 82 }, @@ -397,6 +407,7 @@ static hci_map commands_map[] = { { "Set Host Controller To Host Flow Control", 85 }, { "Host Buffer Size", 86 }, { "Host Number Of Completed Packets", 87 }, + { "Read Link Supervision Timeout", 88 }, { "Write Link Supervision Timeout", 89 }, { "Read Number of Supported IAC", 90 }, @@ -405,14 +416,16 @@ static hci_map commands_map[] = { { "Read Page Scan Period Mode", 93 }, { "Write Page Scan Period Mode", 94 }, { "Read Page Scan Mode", 95 }, + { "Write Page Scan Mode", 96 }, { "Set AFH Channel Classification", 97 }, - { "reserved", 98 }, - { "reserved", 99 }, + { "Reserved", 98 }, + { "Reserved", 99 }, { "Read Inquiry Scan Type", 100 }, { "Write Inquiry Scan Type", 101 }, { "Read Inquiry Mode", 102 }, { "Write Inquiry Mode", 103 }, + { "Read Page Scan Type", 104 }, { "Write Page Scan Type", 105 }, { "Read AFH Channel Assessment Mode", 106 }, @@ -421,6 +434,7 @@ static hci_map commands_map[] = { { "Reserved", 109 }, { "Reserved", 110 }, { "Reserved", 111 }, + { "Reserved", 112 }, { "Reserved", 113 }, { "Reserved", 114 }, @@ -429,6 +443,7 @@ static hci_map commands_map[] = { { "Read Local Supported Features", 117 }, { "Read Local Extended Features", 118 }, { "Read Buffer Size", 119 }, + { "Read Country Code", 120 }, { "Read BD ADDR", 121 }, { "Read Failed Contact Counter", 122 }, @@ -437,6 +452,7 @@ static hci_map commands_map[] = { { "Read RSSI", 125 }, { "Read AFH Channel Map", 126 }, { "Read BD Clock", 127 }, + { "Read Loopback Mode", 128 }, { "Write Loopback Mode", 129 }, { "Enable Device Under Test Mode", 130 }, @@ -445,6 +461,7 @@ static hci_map commands_map[] = { { "Reject Synchronous Connection", 133 }, { "Reserved", 134 }, { "Reserved", 135 }, + { "Read Extended Inquiry Response", 136 }, { "Write Extended Inquiry Response", 137 }, { "Refresh Encryption Key", 138 }, @@ -453,6 +470,7 @@ static hci_map commands_map[] = { { "Unknown", 141 }, { "Unknown", 142 }, { "Unknown", 143 }, + { "Read Inquiry Transmit Power Level", 144 }, { "Write Inquiry Transmit Power Level", 145 }, { "Read Default Erroneous Data Reporting", 146 }, @@ -461,21 +479,25 @@ static hci_map commands_map[] = { { "Reserved", 149 }, { "Reserved", 150 }, { "Unknown", 151 }, + { "Unknown", 152 }, { "Unknown", 153 }, { "Unknown", 154 }, { "Unknown", 155 }, { "Unknown", 156 }, - { "Enhanced Flush", 157 }, - { "Unknown", 158 }, - { "Reserved", 159 }, + { "Unknown", 157 }, + { "Enhanced Flush", 158 }, + { "Unknown", 159 }, + { "Reserved", 160 }, - { "Unknown", 161 }, + { "Reserved", 161 }, { "Unknown", 162 }, - { "Reserved", 163 }, + { "Unknown", 163 }, { "Reserved", 164 }, { "Reserved", 165 }, { "Reserved", 166 }, + { "Reserved", 167 }, + { NULL } }; -- cgit From a3cc218cd5f213922cd529ebfb5da5ba1b1f1aca Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 1 Aug 2007 07:29:23 +0000 Subject: Add definitions and functions for Simple Pairing --- src/hci.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 16 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 04da6de5..d3e81d2c 100644 --- a/src/hci.c +++ b/src/hci.c @@ -467,9 +467,9 @@ static hci_map commands_map[] = { { "Refresh Encryption Key", 138 }, { "Reserved", 139 }, { "Sniff Subrating", 140 }, - { "Unknown", 141 }, - { "Unknown", 142 }, - { "Unknown", 143 }, + { "Read Simple Pairing Mode", 141 }, + { "Write Simple Pairing Mode", 142 }, + { "Read Local OOB Data", 143 }, { "Read Inquiry Transmit Power Level", 144 }, { "Write Inquiry Transmit Power Level", 145 }, @@ -478,21 +478,21 @@ static hci_map commands_map[] = { { "Reserved", 148 }, { "Reserved", 149 }, { "Reserved", 150 }, - { "Unknown", 151 }, - - { "Unknown", 152 }, - { "Unknown", 153 }, - { "Unknown", 154 }, - { "Unknown", 155 }, - { "Unknown", 156 }, - { "Unknown", 157 }, + { "IO Capability Request Reply", 151 }, + + { "User Confirmation Request Reply", 152 }, + { "User Confirmation Request Negative Reply", 153 }, + { "User Passkey Request Reply", 154 }, + { "User Passkey Request Negative Reply", 155 }, + { "Remote OOB Data Request Reply", 156 }, + { "Write Simple Pairing Debug Mode", 157 }, { "Enhanced Flush", 158 }, - { "Unknown", 159 }, + { "Remote OOB Data Request Negative Reply", 159 }, { "Reserved", 160 }, { "Reserved", 161 }, - { "Unknown", 162 }, - { "Unknown", 163 }, + { "Send Keypress Notification", 162 }, + { "IO Capabilities Response Negative Reply", 163 }, { "Reserved", 164 }, { "Reserved", 165 }, { "Reserved", 166 }, @@ -646,8 +646,8 @@ static hci_map lmp_features_map[8][9] = { { "", LMP_EXT_INQ }, /* Bit 0 */ { "", 0x02 }, /* Bit 1 */ { "", 0x04 }, /* Bit 2 */ - { "", 0x08 }, /* Bit 3 */ - { "", 0x10 }, /* Bit 4 */ + { "", LMP_SIMPLE_PAIR }, /* Bit 3 */ + { "", LMP_ENCAPS_PDU }, /* Bit 4 */ { "", LMP_ERR_DAT_REP }, /* Bit 5 */ { "", LMP_NFLUSH_PKTS }, /* Bit 6 */ { "", 0x80 }, /* Bit 7 */ @@ -2060,6 +2060,81 @@ int hci_write_ext_inquiry_response(int dd, uint8_t fec, uint8_t *data, int to) return 0; } +int hci_read_simple_pairing_mode(int dd, uint8_t *mode, int to) +{ + read_simple_pairing_mode_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_SIMPLE_PAIRING_MODE; + rq.rparam = &rp; + rq.rlen = READ_SIMPLE_PAIRING_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *mode = rp.mode; + return 0; +} + +int hci_write_simple_pairing_mode(int dd, uint8_t mode, int to) +{ + write_simple_pairing_mode_cp cp; + write_simple_pairing_mode_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.mode = mode; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_SIMPLE_PAIRING_MODE; + rq.cparam = &cp; + rq.clen = WRITE_SIMPLE_PAIRING_MODE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_SIMPLE_PAIRING_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + +int hci_read_local_oob_data(int dd, uint8_t *hash, uint8_t *randomizer, int to) +{ + read_local_oob_data_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_OOB_DATA; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_OOB_DATA_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(hash, rp.hash, 16); + memcpy(randomizer, rp.randomizer, 16); + return 0; +} + int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to) { read_transmit_power_level_cp cp; -- cgit From c04e0056db8c4a8dc02b87fb647e300b26ccb207 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 29 Aug 2007 14:32:55 +0000 Subject: Fix supported commands bit calculation --- src/hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index d3e81d2c..54e57cf3 100644 --- a/src/hci.c +++ b/src/hci.c @@ -515,7 +515,7 @@ char *hci_commandstostr(uint8_t *commands, char *pref, int width) m = commands_map; while (m->str) { - if (hci_test_bit(m->val, commands)) + if (commands[m->val / 8] & (1 << (m->val % 8))) size += strlen(m->str) + (pref ? strlen(pref) : 0) + 3; m++; } @@ -534,7 +534,7 @@ char *hci_commandstostr(uint8_t *commands, char *pref, int width) m = commands_map; while (m->str) { - if (hci_test_bit(m->val, commands)) { + if (commands[m->val / 8] & (1 << (m->val % 8))) { if (strlen(off) + strlen(m->str) > width - 3) { ptr += sprintf(ptr, "\n%s", pref ? pref : ""); off = ptr; -- cgit From f4afe8ea387410929ee303a510fd7cdfd1cc7552 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Oct 2007 11:23:35 +0000 Subject: Add support for inquiry transmit power level --- src/hci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 54e57cf3..8351c475 100644 --- a/src/hci.c +++ b/src/hci.c @@ -2135,6 +2135,57 @@ int hci_read_local_oob_data(int dd, uint8_t *hash, uint8_t *randomizer, int to) return 0; } +int hci_read_inquiry_transmit_power_level(int dd, int8_t *level, int to) +{ + read_inquiry_transmit_power_level_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_INQUIRY_TRANSMIT_POWER_LEVEL; + rq.rparam = &rp; + rq.rlen = READ_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *level = rp.level; + return 0; +} + +int hci_write_inquiry_transmit_power_level(int dd, int8_t level, int to) +{ + write_inquiry_transmit_power_level_cp cp; + write_inquiry_transmit_power_level_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.level = level; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to) { read_transmit_power_level_cp cp; -- cgit From d1a192c601d9e0e0f4f0da13fadccb50904c5004 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Oct 2007 23:03:55 +0000 Subject: Fix remote name request event handling --- src/hci.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 8351c475..dbfc8ba5 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1009,7 +1009,9 @@ int hci_send_req(int dd, struct hci_request *r, int to) try = 10; while (try--) { evt_cmd_complete *cc; - evt_cmd_status *cs; + evt_cmd_status *cs; + evt_remote_name_req_complete *rn; + remote_name_req_cp *cp; if (to) { struct pollfd p; @@ -1074,6 +1076,20 @@ int hci_send_req(int dd, struct hci_request *r, int to) memcpy(r->rparam, ptr, r->rlen); goto done; + case EVT_REMOTE_NAME_REQ_COMPLETE: + if (hdr->evt != r->event) + break; + + rn = r->rparam; + cp = r->cparam; + + if (bacmp(&rn->bdaddr, &cp->bdaddr)) + continue; + + r->rlen = MIN(len, r->rlen); + memcpy(r->rparam, ptr, r->rlen); + goto done; + default: if (hdr->evt != r->event) break; -- cgit From 6c33a52af7bb9bd45c2526265e0ec91ac3f994c0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Nov 2007 12:41:14 +0000 Subject: Fix remote name request handling bug --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index dbfc8ba5..875ac9c2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1080,7 +1080,7 @@ int hci_send_req(int dd, struct hci_request *r, int to) if (hdr->evt != r->event) break; - rn = r->rparam; + rn = (void *) ptr; cp = r->cparam; if (bacmp(&rn->bdaddr, &cp->bdaddr)) -- cgit From 7208028266fc19d380ac77c97c46b6f2fdc80e1d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:11:09 +0000 Subject: Update copyright information --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 875ac9c2..dd8a6ace 100644 --- a/src/hci.c +++ b/src/hci.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From bb45b882917f26aaa26b2b903b70d622b39cce84 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 11 Jun 2008 13:12:21 +0000 Subject: It is better to include string.h instead of malloc.h --- src/hci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index dd8a6ace..280a654a 100644 --- a/src/hci.c +++ b/src/hci.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include -- cgit From a39a1b4c3e075e80d05caad61646a352693f5455 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Jun 2008 21:40:14 +0000 Subject: Add functions for reading and writing the link policy settings --- src/hci.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index 280a654a..e2c355c0 100644 --- a/src/hci.c +++ b/src/hci.c @@ -2231,6 +2231,60 @@ int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t return 0; } +int hci_read_link_policy(int dd, uint16_t handle, uint16_t *policy, int to) +{ + read_link_policy_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_READ_LINK_POLICY; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_LINK_POLICY_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *policy = rp.policy; + return 0; +} + +int hci_write_link_policy(int dd, uint16_t handle, uint16_t policy, int to) +{ + write_link_policy_cp cp; + write_link_policy_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.policy = policy; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_WRITE_LINK_POLICY; + rq.cparam = &cp; + rq.clen = WRITE_LINK_POLICY_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_LINK_POLICY_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout, int to) { read_link_supervision_timeout_rp rp; -- cgit From 3a585b6fe13ff35b6c1ecf12295b2db75e9221c2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 01:42:26 +0000 Subject: Define MIN if not available --- src/hci.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/hci.c') diff --git a/src/hci.c b/src/hci.c index e2c355c0..a72b0355 100644 --- a/src/hci.c +++ b/src/hci.c @@ -45,6 +45,10 @@ #include #include +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#endif + typedef struct { char *str; unsigned int val; -- cgit