⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hci.c

📁 bluez-libs-2.17.tar.gz网上很少找到这个版本的了
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2000-2001  Qualcomm Incorporated *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> *  Copyright (C) 2002-2005  Marcel Holtmann <marcel@holtmann.org> * * *  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: hci.c,v 1.71 2005/05/01 14:52:53 holtmann Exp $ */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <fcntl.h>#include <syslog.h>#include <errno.h>#include <termios.h>#include <fcntl.h>#include <sys/param.h>#include <sys/uio.h>#include <sys/poll.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>typedef struct {	char *str;	unsigned int val;} hci_map;static char *hci_bit2str(hci_map *m, unsigned int val) {	char *str = malloc(120);	char *ptr = str;	if (!str)		return NULL;	*ptr = 0;	while (m->str) {		if ((unsigned int) m->val & val)			ptr += sprintf(ptr, "%s ", m->str);		m++;	}	return str;}static int hci_str2bit(hci_map *map, char *str, unsigned int *val){	char *t, *ptr;	hci_map *m;	int set;	if (!str || !(str = ptr = strdup(str)))		return 0;	*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;}static char *hci_uint2str(hci_map *m, unsigned int val) {	char *str = malloc(50);	char *ptr = str;	if (!str)		return NULL;	*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) {	case HCI_VHCI:		return "VHCI";	case HCI_USB:		return "USB";	case HCI_PCCARD:		return "PCCARD";	case HCI_UART:		return "UART";	case HCI_RS232:		return "RS232";	case HCI_PCI:		return "PCI";	default:		return "UKNW";	}}/* HCI dev flags mapping */static hci_map dev_flags_map[] = {	{ "UP",      HCI_UP      },	{ "INIT",    HCI_INIT    },	{ "RUNNING", HCI_RUNNING },	{ "RAW",     HCI_RAW     },	{ "PSCAN",   HCI_PSCAN   },	{ "ISCAN",   HCI_ISCAN   },	{ "INQUIRY", HCI_INQUIRY },	{ "AUTH",    HCI_AUTH    },	{ "ENCRYPT", HCI_ENCRYPT },	{ "SECMGR",  HCI_SECMGR  },	{ NULL }};char *hci_dflagstostr(uint32_t flags){	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))		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 */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  },	{ "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 }};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);}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		},	{ "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_bit2str(link_policy_map, lp);}int hci_strtolp(char *str, unsigned int *val){	return hci_str2bit(link_policy_map, str, 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	},	{ "RELIABLE",	HCI_LM_RELIABLE	},	{ "SECURE",	HCI_LM_SECURE	},	{ NULL }};char *hci_lmtostr(unsigned int lm){	char *s, *str = malloc(50);	if (!str)		return NULL;	*str = 0;	if (!(lm & HCI_LM_MASTER))		strcpy(str, "SLAVE ");	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){	return hci_str2bit(link_mode_map, str, val);}/* Version mapping */static hci_map ver_map[] = {	{ "1.0b",	0x00 },	{ "1.1",	0x01 },	{ "1.2",	0x02 },	{ "2.0",	0x03 },	{ 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);}/* LMP features mapping */static hci_map lmp_features_map[8][9] = {	{	/* Byte 0 */		{ "<3-slot packets>",	LMP_3SLOT	},	/* Bit 0 */		{ "<5-slot packets>",	LMP_5SLOT	},	/* Bit 1 */		{ "<encryption>",	LMP_ENCRYPT	},	/* Bit 2 */		{ "<slot offset>",	LMP_SOFFSET	},	/* Bit 3 */		{ "<timing accuracy>",	LMP_TACCURACY	},	/* Bit 4 */		{ "<role switch>",	LMP_RSWITCH	},	/* Bit 5 */		{ "<hold mode>",	LMP_HOLD	},	/* Bit 6 */		{ "<sniff mode>",	LMP_SNIFF	},	/* Bit 7 */		{ NULL }	},	{	/* Byte 1 */		{ "<park state>",	LMP_PARK	},	/* Bit 0 */		{ "<RSSI>",		LMP_RSSI	},	/* Bit 1 */		{ "<channel quality>",	LMP_QUALITY	},	/* Bit 2 */		{ "<SCO link>",		LMP_SCO		},	/* Bit 3 */		{ "<HV2 packets>",	LMP_HV2		},	/* Bit 4 */		{ "<HV3 packets>",	LMP_HV3		},	/* Bit 5 */		{ "<u-law log>",	LMP_ULAW	},	/* Bit 6 */		{ "<A-law log>",	LMP_ALAW	},	/* Bit 7 */		{ NULL }	},	{	/* Byte 2 */		{ "<CVSD>",		LMP_CVSD	},	/* Bit 0 */		{ "<paging scheme>",	LMP_PSCHEME	},	/* Bit 1 */		{ "<power control>",	LMP_PCONTROL	},	/* Bit 2 */		{ "<transparent SCO>",	LMP_TRSP_SCO	},	/* Bit 3 */		{ "<broadcast encrypt>",LMP_BCAST_ENC	},	/* Bit 7 */		{ NULL }	},	{	/* Byte 3 */		{ "<EDR ACL 2 Mbps>",	LMP_EDR_ACL_2M	},	/* Bit 1 */		{ "<EDR ACL 3 Mbps>",	LMP_EDR_ACL_3M	},	/* Bit 2 */		{ "<enhanced iscan>",	LMP_ENH_ISCAN	},	/* Bit 3 */		{ "<interlaced iscan>",	LMP_ILACE_ISCAN	},	/* Bit 4 */		{ "<interlaced pscan>",	LMP_ILACE_PSCAN	},	/* Bit 5 */		{ "<inquiry with RSSI>",LMP_RSSI_INQ	},	/* Bit 6 */		{ "<extended SCO>",	LMP_ESCO	},	/* Bit 7 */		{ NULL }	},	{	/* Byte 4 */		{ "<EV4 packets>",	LMP_EV4		},	/* Bit 0 */		{ "<EV5 packets>",	LMP_EV5		},	/* Bit 1 */		{ "<AFH cap. slave>",	LMP_AFH_CAP_SLV	},	/* Bit 3 */		{ "<AFH class. slave>",	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 */		{ "<AFH cap. master>",	LMP_AFH_CAP_MST	},	/* Bit 3 */		{ "<AFH class. master>",LMP_AFH_CLS_MST	},	/* Bit 4 */		{ "<EDR eSCO 2 Mbps>",	LMP_EDR_ESCO_2M	},	/* Bit 5 */		{ "<EDR eSCO 3 Mbps>",	LMP_EDR_ESCO_3M	},	/* Bit 6 */		{ "<3-slot EDR eSCO>",	LMP_EDR_3S_ESCO	},	/* Bit 7 */		{ NULL }	},	{	/* Byte 6 */		{ NULL }	},	{	/* Byte 7 */		{ "<extended features>",LMP_EXT_FEAT	},	/* Bit 7 */		{ NULL }	},};char *lmp_featurestostr(uint8_t *features, char *pref, int width){	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;	ptr = str; *ptr = 0;	if (pref)		ptr += sprintf(ptr, "%s", pref);	off = ptr;	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 (strlen(off) + strlen(m->str) > width - 1) {					ptr += sprintf(ptr, "\n%s", pref ? pref : "");					off = ptr;				}				ptr += sprintf(ptr, "%s ", m->str);			}			m++;		}	}	return str;}/* 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 i, sk;	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;	}	dl->dev_num = HCI_MAX_DEV;	dr = dl->dev_req;	if (ioctl(sk, 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(sk, dr->dev_id, arg)) {				dev_id = dr->dev_id;				break;			}	}done:	close(sk);	free(dl);	return dev_id;}static int __other_bdaddr(int sk, int dev_id, long arg){	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 sk, int dev_id, long arg){	struct hci_dev_info di = { dev_id: dev_id };	if (ioctl(sk, 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_devid(const char *str){	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 {		errno = ENODEV;		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;	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;}int hci_devba(int dev_id, bdaddr_t *bdaddr){	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(bdaddr, &di.bdaddr);	return 0;}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) {		num_rsp = 0;		nrsp = 255;	}	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 = 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;	}	err = ioctl(s, HCIINQUIRY, (unsigned long) buf);	close(s);	if (!err) {		int size = sizeof(inquiry_info) * ir->num_rsp;		if (!*ii) 			*ii = (void *) malloc(size);		if (*ii) {			memcpy((void *) *ii, buf + sizeof(*ir), size);			err = ir->num_rsp;		} else			err = -1;	}	free(buf);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -