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

📄 hci_vendor.c

📁 blue tooth 核心协议栈在linux上的实现
💻 C
📖 第 1 页 / 共 3 页
字号:
typedef struct csr_packstat_rep{  	u16 n_pkts;	u16 n_good;	u16 n_corr;	u16 rssi;	u16 rssi_valid;} __attribute__ ((packed)) csr_packstat_rep;typedef struct csr_biterr_rep{  	u16 index;	u16 val_last;	u16 val_tot;} __attribute__ ((packed)) csr_biterr_rep;static u16 csr_count = 0;static s32 csr_send_general_hq(csr_bccmd *cmd);#define PSRETBUF_SIZE 10 /* should be enough for what we want to do */static u16 ps_retbuf[PSRETBUF_SIZE];#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSPvoidhci_receive_bcsp(u8 *data, u32 count){	csr_bccmd *cmd;	csr_bccmd_ps *ps;		D_REC(__FUNCTION__ "\n");	hci_ctrl.hc_buf.cmd_num = 1;  	release_cmd_timer();	cmd = (struct csr_bccmd *)data;	ps = (struct csr_bccmd_ps *)cmd->payload;	if (cmd->status == CSR_STATUS_OK) {		if (cmd->type == CSR_MSGTYPE_GETRESP) {			switch (cmd->var_id) {			case CSR_CMD_CONFIG_UART:				break;							case CSR_CMD_BUILD_ID:				/* Store this for later retrieval */				sprintf(bt_hw_firmware_info,					"\n Firmware version: %d",					cmd->payload[0]);				break;							case CSR_CMD_CHIP_VER:				break;							case CSR_CMD_CHIP_REV:				break;							case CSR_CMD_PS:				D_CMD(__FUNCTION__": ps key[0x%x]\n", 				      ps->ps_key);				PRINTPKT("", (u8*)ps->ps_val, 					 ps->ps_len*sizeof(u16));								/* Now copy this data to return buf */				memcpy(ps_retbuf, ps->ps_val, 				       ps->ps_len*sizeof(u16));				break;							default:				break;			}		} else {			DSYS(__FUNCTION__": Not a GETRESP msg\n");			print_data(__FUNCTION__, data, count);		}	} else {		D_ERR(__FUNCTION__": BCSP status error 0x%x\n", cmd->status);		print_data(__FUNCTION__, data, count);	}	wake_up_interruptible(&hci_wq);	}voidhci_receive_hq(u8 *data, u32 count){	csr_bccmd *cmd;	csr_bccmd_ps *ps;		D_REC(__FUNCTION__"\n");		/* FIXME -- is there only one cmd buffer available ? */	hci_ctrl.hc_buf.cmd_num = 1;  	release_cmd_timer();	cmd = (struct csr_bccmd *)data;	ps = (struct csr_bccmd_ps *)cmd->payload;	if (cmd->status == CSR_STATUS_OK) {		if (cmd->type == CSR_MSGTYPE_GETRESP) {				switch (cmd->var_id) {			case CSR_VARID_RSSI_REPORT:			{				csr_rssi_rep *rep;				rep = (csr_rssi_rep *)cmd->payload;				DSYS("RSSI report, rssi : %d\n", rep->rssi);				break;			}						case CSR_VARID_PACKET_STAT_REPORT:			{				csr_packstat_rep *rep;				rep = (struct csr_packstat_rep*)cmd->payload;				DSYS("Packet status report : n_pkts %d, n_good %d, n_corr %d, rssi %d, rssi_valid %d\n", rep->n_pkts, rep->n_good, rep->n_corr, rep->rssi, rep->rssi_valid);				break;			}						case CSR_VARID_BITERR_REPORT:			{				csr_biterr_rep *rep;				rep = (struct csr_biterr_rep*)cmd->payload;				DSYS("Biterror report : index %d, val_last %d, val_tot %d\n", rep->index, rep->val_last, rep->val_tot);				break;			}			default:				D_ERR("Unknown varid [0x%x]!\n", cmd->var_id);				break;			}		} else if (cmd->type == CSR_MSGTYPE_SETREQ) {			DSYS(__FUNCTION__": Received a SETREQ, sending back GETRESP\n");			print_data(__FUNCTION__, data, count);			cmd->type = CSR_MSGTYPE_GETRESP;				csr_send_general_hq(cmd);					} else if (cmd->type == CSR_MSGTYPE_GETREQ) {			DSYS(__FUNCTION__": Received a GETREQ\n");			print_data(__FUNCTION__, data, count);		} else {			DSYS(__FUNCTION__": Unknown message type\n");			print_data(__FUNCTION__, data, count);		}	} else {		D_ERR(__FUNCTION__": HQ status error 0x%x\n", cmd->status);		print_data(__FUNCTION__, data, count);	}		wake_up_interruptible(&hci_wq);	}static struct dfu_response{	struct dfu_response *next;	u32 length;	u8 data[0];} *dfu_responses = NULL;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)static struct wait_queue *dfu_wq = NULL;#elsestatic wait_queue_head_t dfu_wq;#endif /* LINUX_VERSION_CODE */voidhci_dfu_module_init(void){#ifdef __KERNEL__#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	init_waitqueue_head(&dfu_wq);#endif /* LINUX_VERSION_CODE */#endif  /*  __KERNEL__  */}voidhci_shutdown_dfu(void){	struct dfu_response *response;	while (dfu_responses) {		cli();		response = dfu_responses;		dfu_responses = response->next;		sti();		kfree(response);	}	wake_up_interruptible(&dfu_wq);}voidhci_receive_dfu(u8 *data, u32 count){	struct dfu_response *response;	if ((response = kmalloc(sizeof(*response) + count, GFP_ATOMIC))) {		response->length = count;		memcpy(response->data, data, count);		cli();		response->next = dfu_responses;		dfu_responses = response;		sti();		wake_up_interruptible(&dfu_wq);	}}s32hci_read_dfu(u8* data, u32 count){	struct dfu_response *response;	u32 length;	if (!dfu_responses)		interruptible_sleep_on(&dfu_wq);	cli();	response = dfu_responses;	dfu_responses = response->next;	sti();        if (!response)                return -EINTR;        	length = response->length;	if (count < length) {		cli();		response->next = dfu_responses;		dfu_responses = response;		sti();		printk(__FUNCTION__ ": DFU response was too big!\n");		return -E2BIG;	}	copy_to_user(data, response->data, length);	kfree(response);	return (s32)length;}s32csr_send_general_hq(csr_bccmd *cmd){	csr_msg *msg;	/* HCI Manufacturer specific header */	c_pkt.type = CMD_PKT;	c_pkt.opcode = hci_put_opcode(0x00, MANUFACTURER_SPEC);	c_pkt.len = 1 + cmd->len * 2;		msg = (csr_msg *)c_pkt.data;		/* General msg header */	CSR_SET_LAST(msg, 1); /* first and last segment */	CSR_SET_FIRST(msg, 1);	CSR_SET_CH_ID(msg, CSR_CH_ID_HQ);	memcpy(msg->msg, cmd, cmd->len * 2);	print_data(__FUNCTION__, (u8*)&c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN);		return bt_write_lower_driver((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN);}/* When using BCSP this function is used to wait for the   COMMAND_STATUS which contains cmd_num */void csr_waitcmdnum(void){	D_CMD(__FUNCTION__"\n");	hci_ctrl.hc_buf.cmd_num = 0;	/* wait for command status */	while (hci_ctrl.hc_buf.cmd_num == 0)	{		current->state = TASK_INTERRUPTIBLE;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)		schedule_timeout(HZ/100);#else		current->timeout = HZ/100;		schedule();		current->timeout = 0;#endif	}}#endif /* CONFIG_BLUETOOTH_SUPPORT_BCSP */s32 csr_pskey(u16 ps_key, u16 rw_mode, u16 *retb, u16 n_pars){	s32 tmp;	csr_msg *msg;	csr_bccmd *cmd;	csr_bccmd_ps *ps;	D_CMD(__FUNCTION__" : ps_key 0x%x [%d]\n", ps_key, rw_mode);		PRINTPKT("pars : ", (u8*)retb, n_pars*sizeof(u16));	/* HCI Manufacturer specific header */	c_pkt.type = CMD_PKT;	c_pkt.opcode = hci_put_opcode(0x00, MANUFACTURER_SPEC);	c_pkt.len = 1 + 5*sizeof(u16) + 3*sizeof(u16) + n_pars*sizeof(u16);	msg = (csr_msg *)c_pkt.data;	cmd = (csr_bccmd *)msg->msg;	ps = (csr_bccmd_ps *)cmd->payload; 	/* General msg header */	CSR_SET_LAST(msg, 1); /* first and last segment */	CSR_SET_FIRST(msg, 1);	CSR_SET_CH_ID(msg, CSR_CH_ID_BCCMD);	/* BCCMD type */	cmd->type = rw_mode;	cmd->len = 5 + 3 + n_pars;	cmd->seq = csr_count++;	cmd->var_id = CSR_CMD_PS;	cmd->status = CSR_STATUS_OK; /* always OK in SETREQ */	/* Actual PS key request */	ps->ps_key = ps_key;	ps->ps_len = n_pars; /* x 16 bits */	ps->unused = 0x0000;	if (rw_mode == CSR_MSGTYPE_GETREQ)	  memset(ps->ps_val, 0, n_pars*sizeof(u16)); /* zero params in GETREQ */	else  	  memcpy(ps->ps_val, retb, n_pars*sizeof(16)); /* copy params in SETREQ */	/* Clear return buf */	memset(ps_retbuf, 0, PSRETBUF_SIZE*2);	tmp = send_cmd_block((u8*) &c_pkt, 			     c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);	 	if (rw_mode == CSR_MSGTYPE_GETREQ)	  memcpy(retb, ps_retbuf, n_pars*sizeof(u16));		/* Signal status back in SETREQ ? */	return tmp;}s32 hci_set_bd_addr(u8 bd[6]){	csr_msg *msg;	csr_bccmd *cmd;	csr_bccmd_ps *ps;	D_CMD(__FUNCTION__"\n");	/* HCI Manufacturer specific header */	c_pkt.type = CMD_PKT;	c_pkt.opcode = hci_put_opcode(0x00, MANUFACTURER_SPEC);	c_pkt.len = 1 + 5*sizeof(u16) + 3*sizeof(u16) + 4*sizeof(u16);	msg = (csr_msg *)c_pkt.data;	cmd = (csr_bccmd *)msg->msg;	ps = (csr_bccmd_ps *)cmd->payload; 	/* General msg header */	CSR_SET_LAST(msg, 1); /* first and last segment */	CSR_SET_FIRST(msg, 1);	CSR_SET_CH_ID(msg, CSR_CH_ID_BCCMD);	/* BCCMD type */	cmd->type = CSR_MSGTYPE_SETREQ;	cmd->len = 5 + 3 + 4;	cmd->seq = csr_count++;	cmd->var_id = CSR_CMD_PS;	cmd->status = CSR_STATUS_OK; /* always OK in SETREQ */	/* Actual PS key request */	ps->ps_key = CSR_PS_BDADDR;	ps->ps_len = 4; /* x 16 bits */	ps->unused = 0x0000;	ps->ps_val[0] = ((u16)bd[3]) & 0x00ff;	ps->ps_val[1] = ((((u16)bd[4]) << 8) | ((u16)bd[5]));	ps->ps_val[2] = (u16)bd[2];	ps->ps_val[3] = (((u16)bd[0] << 8) | ((u16)bd[1]));	return send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);}s32hci_read_firmware_rev_info(void){	s32 tmp;	csr_msg *msg;	csr_bccmd *cmd;	D_CMD(__FUNCTION__ VENDOR " BuildID/ChipVer/ChipRev\n");		/* HCI Manufacturer specific header */	c_pkt.type = CMD_PKT;	c_pkt.opcode = hci_put_opcode(0x00, MANUFACTURER_SPEC);	c_pkt.len = 1 + 5*sizeof(u16) + 6*sizeof(u16);	msg = (csr_msg *)c_pkt.data;	cmd = (csr_bccmd *)msg->msg;	/* General msg header */	CSR_SET_LAST(msg, 1); /* first and last segment */	CSR_SET_FIRST(msg, 1);	CSR_SET_CH_ID(msg, CSR_CH_ID_BCCMD);	/* BCCMD type */	cmd->type = CSR_MSGTYPE_GETREQ;	cmd->len = 5 + 6;	cmd->seq = csr_count++;	cmd->var_id = CSR_CMD_BUILD_ID;	cmd->status = CSR_STATUS_OK; /* always OK in GETREQ */	memset(cmd->payload, 0, 6*sizeof(u16));	tmp = send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);	if (tmp < 0)		return tmp;	cmd->seq = csr_count++;	cmd->var_id = CSR_CMD_CHIP_VER;	memset(cmd->payload, 0, 6*sizeof(u16));	tmp = send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);	if (tmp < 0)		return tmp;	cmd->seq = csr_count++;	cmd->var_id = CSR_CMD_CHIP_REV;	memset(cmd->payload, 0, 6*sizeof(u16));	tmp = send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);	return tmp;}s32hci_set_baudrate(u32 baudrate){	s32 tmp;	csr_msg *msg;	csr_bccmd *cmd;	csr_bccmd_ps *ps;	u16 baud_divider;	D_CMD(__FUNCTION__ VENDOR " (%u baud)\n", baudrate);	switch (baudrate) {	case 9600:		baud_divider = CSR_UART_RATE_9K6;		break;	case 19200:		baud_divider = CSR_UART_RATE_19K2;		break;	case 38400:		baud_divider = CSR_UART_RATE_38K4;		break;	case 57600:		baud_divider = CSR_UART_RATE_57K6;		break;	case 115200:		baud_divider = CSR_UART_RATE_115K2;		break;	case 230400:		baud_divider = CSR_UART_RATE_230K4;

⌨️ 快捷键说明

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