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

📄 hci.c

📁 蓝牙的各种编程接口和各种按理介绍,还有一些例子和说明
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    BlueZ - Bluetooth protocol stack for Linux   Copyright (C) 2000-2001 Qualcomm Incorporated   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>   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.26 2003/02/11 10:22:24 jscrane Exp $ */#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/ioctl.h>#include <sys/socket.h>#include <asm/types.h>#include <bluetooth.h>#include <hci.h>#include <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 */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 },	{ 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 */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_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[] = {	{ "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 */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){	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 */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);}/* LMP features mapping */hci_map lmp_features_map[][9] = {	{	/* byte 0 */		{ "<3-slot packets>",   LMP_3SLOT    },		{ "<5-slot packets>",   LMP_5SLOT    },		{ "<encryption>",       LMP_ENCRYPT  },		{ "<slot offset>",      LMP_SOFFSET  },		{ "<timing accuracy>",  LMP_TACCURACY},		{ "<role switch>",      LMP_RSWITCH  },		{ "<hold mode>",        LMP_HOLD     },		{ "<sniff mode>",       LMP_SNIFF    },		{ NULL }	},	{	/* byte 1 */		{ "<park mode>",        LMP_PARK     },		{ "<RSSI>",             LMP_RSSI     },		{ "<channel quality>",  LMP_QUALITY  },		{ "<SCO link>",         LMP_SCO      },		{ "<HV2 packets>",      LMP_HV2      },		{ "<HV3 packets>",      LMP_HV3      },		{ "<u-law log>",        LMP_ULAW     },		{ "<A-law log>",        LMP_ALAW     },		{ NULL }	},	{	/* byte 2 */		{ "<CVSD>",             LMP_CVSD     },		{ "<paging scheme>",    LMP_PSCHEME  },		{ "<power control>",    LMP_PCONTROL },		{ "<transparent SCO>",  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);				w = (w + 1) & width;				if (!w)					ptr += sprintf(ptr, "\n%s", pref ? pref : "");			}			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 s, i;	s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);	if (s < 0)		return -1;	dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));	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);}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)		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 *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;}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;	int s, err;	if (nrsp <= 0)		nrsp = 200; // enough ?	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 = nrsp;	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);	return err;}/* 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 */

⌨️ 快捷键说明

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