diff options
| author | Max Krasnyansky <maxk@qualcomm.com> | 2002-06-18 16:46:54 +0000 | 
|---|---|---|
| committer | Max Krasnyansky <maxk@qualcomm.com> | 2002-06-18 16:46:54 +0000 | 
| commit | 4837bd7e9ba55361aeca45610a160dd107d5be2f (patch) | |
| tree | 475ebed6167d5899d0e044d8a64d77655014c31b | |
| parent | 5c3b76c8f08b4cb37ef417aaad1dd6c36068786f (diff) | |
Fix inquiry function to return errors and accept user buffers.
New functions hci_for_each_dev and hci_get_route.
| -rw-r--r-- | include/hci_lib.h | 5 | ||||
| -rw-r--r-- | 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); @@ -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;  } + | 
