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. --- include/hci_lib.h | 5 ++- src/hci.c | 116 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 92 insertions(+), 29 deletions(-) diff --git a/include/hci_lib.h b/include/hci_lib.h index 02c56a1f..7fd95cfc 100644 --- a/include/hci_lib.h +++ b/include/hci_lib.h @@ -59,7 +59,7 @@ int hci_send_req(int dd, struct hci_request *req, int timeout); 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_disconnect(int dd, uint16_t handle, uint8_t reason, int to); -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 num_rsp, uint8_t *lap, inquiry_info **ii, long flags); int hci_devinfo(int dev_id, struct hci_dev_info *di); int hci_devba(int dev_id, bdaddr_t *ba); @@ -70,6 +70,9 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in int hci_read_local_version(int dd, struct hci_version *ver, int to); int hci_class_of_dev(int dd, uint8_t *class, int to); +int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg); +int hci_get_route(bdaddr_t *bdaddr); + char *hci_dtypetostr(int type); char *hci_dflagstostr(uint32_t flags); char *hci_ptypetostr(unsigned int ptype); 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