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

📄 hciattach_tialt.c

📁 这是Linux环境下的蓝牙源代码
💻 C
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2005-2008  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 as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <syslog.h>#include <termios.h>#include <time.h>#include <sys/time.h>#include <sys/poll.h>#include <sys/param.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/uio.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#define FAILIF(x, args...) do {   \	if (x) {					  \		fprintf(stderr, ##args);  \		return -1;				  \	}							  \} while(0)typedef struct {	uint8_t uart_prefix;	hci_event_hdr hci_hdr;	evt_cmd_complete cmd_complete;	uint8_t status;	uint8_t data[16];} __attribute__((packed)) command_complete_t;extern int read_hci_event(int fd, unsigned char* buf, int size);static int read_command_complete(int fd, unsigned short opcode, unsigned char len) {	command_complete_t resp;	/* Read reply. */	FAILIF(read_hci_event(fd, (unsigned char *)&resp, sizeof(resp)) < 0,		   "Failed to read response");		/* Parse speed-change reply */	FAILIF(resp.uart_prefix != HCI_EVENT_PKT,		   "Error in response: not an event packet, but 0x%02x!\n", 		   resp.uart_prefix);	FAILIF(resp.hci_hdr.evt != EVT_CMD_COMPLETE, /* event must be event-complete */		   "Error in response: not a cmd-complete event, "		   "but 0x%02x!\n", resp.hci_hdr.evt);	FAILIF(resp.hci_hdr.plen < 4, /* plen >= 4 for EVT_CMD_COMPLETE */		   "Error in response: plen is not >= 4, but 0x%02x!\n",		   resp.hci_hdr.plen);	/* cmd-complete event: opcode */	FAILIF(resp.cmd_complete.opcode != (uint16_t)opcode,		   "Error in response: opcode is 0x%04x, not 0x%04x!",		   resp.cmd_complete.opcode, opcode);	return resp.status == 0 ? 0 : -1;}typedef struct {	uint8_t uart_prefix;	hci_command_hdr hci_hdr;	uint32_t speed;} __attribute__((packed)) texas_speed_change_cmd_t;static int texas_change_speed(int fd, uint32_t speed) {		return 0;	/* Send a speed-change request */	texas_speed_change_cmd_t cmd;	int n;	cmd.uart_prefix = HCI_COMMAND_PKT;	cmd.hci_hdr.opcode = 0xff36;	cmd.hci_hdr.plen = sizeof(uint32_t);	cmd.speed = speed;	fprintf(stdout, "Setting speed to %d\n", speed);	n = write(fd, &cmd, sizeof(cmd));	if (n < 0) {		perror("Failed to write speed-set command");		return -1;	}	n = write(fd, &cmd, sizeof(cmd));	if (n < 0) {		perror("Failed to write command.");		return -1;	}	if (n < (int)sizeof(cmd)) {		fprintf(stderr, "Wanted to write %d bytes, could only write %d. "				"Stop\n", (int)sizeof(cmd), n);		return -1;	}	/* Parse speed-change reply */	if (read_command_complete(fd, 0xff36, 4) < 0) {		return -1;	}	fprintf(stdout, "Speed changed to %d.\n", speed);}static int texas_load_firmware(int fd, const char *firmware) {	fprintf(stdout, "Opening firmware file: %s\n", firmware);	int fw = open(firmware, O_RDONLY);	FAILIF(fw < 0, 		   "Could not open firmware file %s: %s (%d).\n",		   firmware, strerror(errno), errno);	fprintf(stdout, "Uploading firmware...\n");	do {		int nr;		/* Read each command and wait for a response. */		unsigned char cmdp[1 + sizeof(hci_command_hdr)];		nr = read(fw, cmdp, sizeof(cmdp));		if (!nr)			break;		hci_command_hdr *cmd = (hci_command_hdr *)(cmdp + 1);		FAILIF(nr != sizeof(cmdp), "Could not read H4 + HCI header!\n");		FAILIF(*cmdp != HCI_COMMAND_PKT, "Command is not an H4 command packet!\n");				unsigned char data[1024];		FAILIF(read(fw, data, cmd->plen) != cmd->plen,			   "Could not read %d bytes of data for command with opcode %04x!\n",			   cmd->plen,			   cmd->opcode);						{#if 0			fprintf(stdout, "\topcode 0x%04x (%d bytes of data).\n", 					cmd->opcode, 					cmd->plen);#endif			struct iovec iov_cmd[2];			iov_cmd[0].iov_base = cmdp;			iov_cmd[0].iov_len	= sizeof(cmdp);			iov_cmd[1].iov_base = data;			iov_cmd[1].iov_len	= cmd->plen;			int nw = writev(fd, iov_cmd, 2);			FAILIF(nw != sizeof(cmd) +	cmd->plen, 				   "Could not send entire command (sent only %d bytes)!\n",				   nw);		}		/* Wait for response */		if (read_command_complete(fd, 								  cmd->opcode,								  cmd->plen) < 0) {			return -1;		}				} while(1);	fprintf(stdout, "Firmware upload successful.\n");	close(fw);	return 0;}int texasalt_init(int fd, int speed, struct termios *ti){	struct timespec tm = {0, 50000};	char cmd[4];	unsigned char resp[100];		/* Response */	int n;	memset(resp,'\0', 100);	/* It is possible to get software version with manufacturer specific 	   HCI command HCI_VS_TI_Version_Number. But the only thing you get more	   is if this is point-to-point or point-to-multipoint module */	/* Get Manufacturer and LMP version */	cmd[0] = HCI_COMMAND_PKT;	cmd[1] = 0x01;	cmd[2] = 0x10;	cmd[3] = 0x00;	do {		n = write(fd, cmd, 4);		if (n < 0) {			perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)");			return -1;		}		if (n < 4) {			fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n);			return -1;		}		/* Read reply. */		if (read_hci_event(fd, resp, 100) < 0) {			perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)");			return -1;		}		/* Wait for command complete event for our Opcode */	} while (resp[4] != cmd[1] && resp[5] != cmd[2]);	/* Verify manufacturer */	if ((resp[11] & 0xFF) != 0x0d)		fprintf(stderr,"WARNING : module's manufacturer is not Texas Instrument\n");	/* Print LMP version */	fprintf(stderr, "Texas module LMP version : 0x%02x\n", resp[10] & 0xFF);	/* Print LMP subversion */	{		unsigned short lmp_subv = resp[13] | (resp[14] << 8);		unsigned short brf_chip = (lmp_subv & 0x7c00) >> 10;		static const char *c_brf_chip[5] = {			"unknown",			"unknown",			"brf6100",			"brf6150",			"brf6300"		};		fprintf(stderr, "Texas module LMP sub-version : 0x%04x\n", lmp_subv);		fprintf(stderr,				"\tinternal version freeze: %d\n"				"\tsoftware version: %d\n"				"\tchip: %s (%d)\n",				lmp_subv & 0x7f,				((lmp_subv & 0x8000) >> (15-3)) | ((lmp_subv & 0x380) >> 7),				((brf_chip > 4) ? "unknown" : c_brf_chip[brf_chip]),				brf_chip);		char fw[100];		sprintf(fw, "/etc/firmware/%s.bin", c_brf_chip[brf_chip]);		texas_load_firmware(fd, fw);		texas_change_speed(fd, speed);	}	nanosleep(&tm, NULL);	return 0;}

⌨️ 快捷键说明

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