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

📄 hciattach.c

📁 基于LINUX内核驱动的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
		return -1;	}	/* Read reply */	if ((n = read_hci_event(fd, resp, 4)) < 0) {		fprintf(stderr, "Failed to reset chip\n");		return -1;	}	if (u->bdaddr != NULL) {		/* Set BD_ADDR */		memset(cmd, 0, sizeof(cmd));		memset(resp, 0, sizeof(resp));		cmd[0] = HCI_COMMAND_PKT;		cmd[1] = 0x01;		cmd[2] = 0xfc;		cmd[3] = 0x06;		str2ba(u->bdaddr, (bdaddr_t *) (cmd + 4));		/* Send command */		if (write(fd, cmd, 10) != 10) {			fprintf(stderr, "Failed to write BD_ADDR command\n");			return -1;		}		/* Read reply */		if ((n = read_hci_event(fd, resp, 10)) < 0) {			fprintf(stderr, "Failed to set BD_ADDR\n");			return -1;		}	}	/* Read the local version info */	memset(cmd, 0, sizeof(cmd));	memset(resp, 0, sizeof(resp));	cmd[0] = HCI_COMMAND_PKT;	cmd[1] = 0x01;	cmd[2] = 0x10;	cmd[3] = 0x00;	/* Send command */	if (write(fd, cmd, 4) != 4) {		fprintf(stderr, "Failed to write \"read local version\" "			"command\n");		return -1;	}	/* Read reply */	if ((n = read_hci_event(fd, resp, 4)) < 0) {		fprintf(stderr, "Failed to read local version\n");		return -1;	}	/* Read the local supported commands info */	memset(cmd, 0, sizeof(cmd));	memset(resp, 0, sizeof(resp));	cmd[0] = HCI_COMMAND_PKT;	cmd[1] = 0x02;	cmd[2] = 0x10;	cmd[3] = 0x00;	/* Send command */	if (write(fd, cmd, 4) != 4) {		fprintf(stderr, "Failed to write \"read local supported "						"commands\" command\n");		return -1;	}	/* Read reply */	if ((n = read_hci_event(fd, resp, 4)) < 0) {		fprintf(stderr, "Failed to read local supported commands\n");		return -1;	}	/* Set the baud rate */	memset(cmd, 0, sizeof(cmd));	memset(resp, 0, sizeof(resp));	cmd[0] = HCI_COMMAND_PKT;	cmd[1] = 0x18;	cmd[2] = 0xfc;	cmd[3] = 0x02;	switch (u->speed) {	case 57600:		cmd[4] = 0x00;		cmd[5] = 0xe6;		break;	case 230400:		cmd[4] = 0x22;		cmd[5] = 0xfa;		break;	case 460800:		cmd[4] = 0x22;		cmd[5] = 0xfd;		break;	case 921600:		cmd[4] = 0x55;		cmd[5] = 0xff;		break;	default:		/* Default is 115200 */		cmd[4] = 0x00;		cmd[5] = 0xf3;		break;	}	fprintf(stderr, "Baud rate parameters: DHBR=0x%2x,DLBR=0x%2x\n",		cmd[4], cmd[5]);	/* Send command */	if (write(fd, cmd, 6) != 6) {		fprintf(stderr, "Failed to write \"set baud rate\" command\n");		return -1;	}	if ((n = read_hci_event(fd, resp, 6)) < 0) {		fprintf(stderr, "Failed to set baud rate\n");		return -1;	}	return 0;}struct uart_t uart[] = {	{ "any",        0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, NULL     },	{ "ericsson",   0x0000, 0x0000, HCI_UART_H4,   57600,  115200, FLOW_CTL, NULL, ericsson },	{ "digi",       0x0000, 0x0000, HCI_UART_H4,   9600,   115200, FLOW_CTL, NULL, digi     },	{ "texas",      0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, texas    },	{ "bcsp",       0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0,        NULL, bcsp     },	/* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */	{ "xircom",     0x0105, 0x080a, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, NULL     },	/* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */	{ "csr",        0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, csr      },	/* BrainBoxes PCMCIA card (BL620) */	{ "bboxes",     0x0160, 0x0002, HCI_UART_H4,   115200, 460800, FLOW_CTL, NULL, csr      },	/* Silicon Wave kits */	{ "swave",      0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, swave    },	/* ST Microelectronics minikits based on STLC2410/STLC2415 */	{ "st",         0x0000, 0x0000, HCI_UART_H4,    57600, 115200, FLOW_CTL, NULL, st       },	/* ST Microelectronics minikits based on STLC2500 */	{ "stlc2500",   0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL, "00:80:E1:00:AB:BA", stlc2500  },	/* Philips generic Ericsson IP core based */	{ "philips",    0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, NULL     },	/* Philips BGB2xx Module */	{ "bgb2xx",    0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL, "BD:B2:10:00:AB:BA", bgb2xx   },	/* Sphinx Electronics PICO Card */	{ "picocard",   0x025e, 0x1000, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, NULL     },	/* Inventel BlueBird Module */	{ "inventel",   0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, NULL     },	/* COM One Platinium Bluetooth PC Card */	{ "comone",     0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0,        NULL, bcsp     },	/* TDK Bluetooth PC Card and IBM Bluetooth PC Card II */	{ "tdk",        0x0105, 0x4254, HCI_UART_BCSP, 115200, 115200, 0,        NULL, bcsp     },	/* Socket Bluetooth CF Card (Rev G) */	{ "socket",     0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0,        NULL, bcsp     },	/* 3Com Bluetooth Card (Version 3.0) */	{ "3com",       0x0101, 0x0041, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, csr      },	/* AmbiCom BT2000C Bluetooth PC/CF Card */	{ "bt2000c",    0x022d, 0x2000, HCI_UART_H4,    57600, 460800, FLOW_CTL, NULL, csr      },	/* Zoom Bluetooth PCMCIA Card */	{ "zoom",       0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0,        NULL, bcsp     },	/* Sitecom CN-504 PCMCIA Card */	{ "sitecom",    0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0,        NULL, bcsp     },	/* Billionton PCBTC1 PCMCIA Card */	{ "billionton", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0,        NULL, bcsp     },	/* Broadcom BCM2035 */	{ "bcm2035",    0x0A5C, 0x2035, HCI_UART_H4,   115200, 460800, FLOW_CTL, NULL, bcm2035  },	{ NULL, 0 }};struct uart_t * get_by_id(int m_id, int p_id){	int i;	for (i = 0; uart[i].type; i++) {		if (uart[i].m_id == m_id && uart[i].p_id == p_id)			return &uart[i];	}	return NULL;}struct uart_t * get_by_type(char *type){	int i;	for (i = 0; uart[i].type; i++) {		if (!strcmp(uart[i].type, type))			return &uart[i];	}	return NULL;}/* Initialize UART driver */int init_uart(char *dev, struct uart_t *u, int send_break){	struct termios ti;	int fd, i;	fd = open(dev, O_RDWR | O_NOCTTY);	if (fd < 0) {		perror("Can't open serial port");		return -1;	}	tcflush(fd, TCIOFLUSH);	if (tcgetattr(fd, &ti) < 0) {		perror("Can't get port settings");		return -1;	}	cfmakeraw(&ti);	ti.c_cflag |= CLOCAL;	if (u->flags & FLOW_CTL)		ti.c_cflag |= CRTSCTS;	else		ti.c_cflag &= ~CRTSCTS;	if (tcsetattr(fd, TCSANOW, &ti) < 0) {		perror("Can't set port settings");		return -1;	}	/* Set initial baudrate */	if (set_speed(fd, &ti, u->init_speed) < 0) {		perror("Can't set initial baud rate");		return -1;	}	tcflush(fd, TCIOFLUSH);	if (send_break) {		tcsendbreak(fd, 0);		usleep(500000);	}	if (u->init && u->init(fd, u, &ti) < 0)		return -1;	tcflush(fd, TCIOFLUSH);	/* Set actual baudrate */	if (set_speed(fd, &ti, u->speed) < 0) {		perror("Can't set baud rate");		return -1;	}	/* Set TTY to N_HCI line discipline */	i = N_HCI;	if (ioctl(fd, TIOCSETD, &i) < 0) {		perror("Can't set line discipline");		return -1;	}	if (ioctl(fd, HCIUARTSETPROTO, u->proto) < 0) {		perror("Can't set device");		return -1;	}	return fd;}static void usage(void){	printf("hciattach - HCI UART driver initialization utility\n");	printf("Usage:\n");	printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] <tty> <type | id> [speed] [flow|noflow] [bdaddr]\n");	printf("\thciattach -l\n");}int main(int argc, char *argv[]){	struct uart_t *u = NULL;	int detach, printpid, opt, i, n, ld, err;	int to = 5; 	int init_speed = 0;	int send_break = 0;	pid_t pid;	struct sigaction sa;	struct pollfd p;	char dev[PATH_MAX];	detach = 1;	printpid = 0;	while ((opt=getopt(argc, argv, "bnpt:s:l")) != EOF) {		switch(opt) {		case 'b':			send_break = 1;			break;		case 'n':			detach = 0;			break;		case 'p':			printpid = 1;			break;		case 't':			to = atoi(optarg);			break;		case 's':			init_speed = atoi(optarg);			break;		case 'l':			for (i = 0; uart[i].type; i++) {				printf("%-10s0x%04x,0x%04x\n", uart[i].type,							uart[i].m_id, uart[i].p_id);			}			exit(0);		default:			usage();			exit(1);		}	}	n = argc - optind;	if (n < 2) {		usage();		exit(1);	}	for (n = 0; optind < argc; n++, optind++) {		char *opt;		opt = argv[optind];		switch(n) {		case 0:			dev[0] = 0;			if (!strchr(opt, '/'))				strcpy(dev, "/dev/");			strcat(dev, opt);			break;		case 1:			if (strchr(argv[optind], ',')) {				int m_id, p_id;				sscanf(argv[optind], "%x,%x", &m_id, &p_id);				u = get_by_id(m_id, p_id);			} else {				u = get_by_type(opt);			}			if (!u) {				fprintf(stderr, "Unknown device type or id\n");				exit(1);			}						break;		case 2:			u->speed = atoi(argv[optind]);			break;		case 3:			if (!strcmp("flow", argv[optind]))				u->flags |=  FLOW_CTL;			else				u->flags &= ~FLOW_CTL;			break;		case 4:			u->bdaddr = argv[optind];			break;		}	}	if (!u) {		fprintf(stderr, "Unknown device type or id\n");		exit(1);	}	/* If user specified a initial speed, use that instead of	   the hardware's default */	if (init_speed)		u->init_speed = init_speed;	memset(&sa, 0, sizeof(sa));	sa.sa_flags   = SA_NOCLDSTOP;	sa.sa_handler = sig_alarm;	sigaction(SIGALRM, &sa, NULL);	/* 5 seconds should be enough for initialization */	alarm(to);	n = init_uart(dev, u, send_break);	if (n < 0) {		perror("Can't initialize device"); 		exit(1);	}	alarm(0);	memset(&sa, 0, sizeof(sa));	sa.sa_flags   = SA_NOCLDSTOP;	sa.sa_handler = SIG_IGN;	sigaction(SIGCHLD, &sa, NULL);	sigaction(SIGPIPE, &sa, NULL);	sa.sa_handler = sig_term;	sigaction(SIGTERM, &sa, NULL);	sigaction(SIGINT,  &sa, NULL);	sa.sa_handler = sig_hup;	sigaction(SIGHUP, &sa, NULL);	if (detach) {		if ((pid = fork())) {			if (printpid)				printf("%d\n", pid);			return 0;		}		for (i = 0; i < 20; i++)			if (i != n)				close(i);	}	p.fd = n;	p.events = POLLERR | POLLHUP;	while (!__io_canceled) {		p.revents = 0;		err = poll(&p, 1, 500);		if (err < 0 && errno == EINTR)			continue;		if (err)			break;	}	/* Restore TTY line discipline */	ld = N_TTY;	if (ioctl(n, TIOCSETD, &ld) < 0) {		perror("Can't restore line discipline");		exit(1);	}	return 0;}

⌨️ 快捷键说明

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