📄 hci_vendor.c
字号:
/****************** INCLUDE FILES SECTION ***********************************/#define __NO_VERSION__ /* don't define kernel_version in module.h */#ifdef __KERNEL__#include <linux/config.h>#include <linux/bluetooth/sysdep-2.1.h>#include <linux/malloc.h>#include <linux/timer.h>#include <linux/bluetooth/hci.h>#include <linux/bluetooth/hci_internal.h>#include <linux/bluetooth/btdebug.h>#include <linux/bluetooth/bluetooth.h>#include <linux/bluetooth/btmem.h>#include <linux/delay.h>#include <linux/interrupt.h>#else /* user mode */#include <stdlib.h>#include <string.h>#include <errno.h>#include "include/bluetooth.h"#include "include/hci.h"#include "include/hci_internal.h"#include "include/btdebug.h"#include "include/btmem.h"#endif/****************** CONSTANT AND MACRO SECTION ******************************/#ifdef CONFIG_BLUETOOTH_ERICSSON/* Ericsson defines */#define ERICSSON_SET_UART_BAUD_RATE 0x09#define ERICSSON_WRITE_BD_ADDR 0x0D#define ERICSSON_READ_REVISION_INFORMATION 0x0F#define ERICSSON_ENTER_TEST_MODE 0x11#define ERICSSON_TEST_CONTROL 0x12#define ERICSSON_TX_TEST 0x19#endif#ifdef CONFIG_BLUETOOTH_DIGIANSWER/* Digianswer defines */#endif#define BT_HW_INFO_MAX 255/****************** LOCAL VARIABLE DECLARATION SECTION **********************//* These are declared in hci.c */extern cmd_pkt c_pkt;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)extern struct wait_queue *hci_wq;extern struct wait_queue *set_baudrate_wq;#elseextern wait_queue_head_t hci_wq;extern wait_queue_head_t set_baudrate_wq;#endif /* LINUX_VERSION_CODE */extern hci_controller hci_ctrl;static u8 bt_hw_firmware_info[BT_HW_INFO_MAX+1];/****************** FUNCTION DEFINITION SECTION *****************************/#ifdef CONFIG_BLUETOOTH_ERICSSON/*****************************************************************************//********************** Ericsson functions ***********************************//*****************************************************************************/#define VENDOR " [Ericsson]"s32 hci_set_bd_addr(u8 bd[6]){ u8 tmp_bd[6]; s32 i; D_CMD(__FUNCTION__ VENDOR "\n"); for (i = 0; i < 6; i++) { tmp_bd[5-i] = bd[i]; } PRINTPKT(__FUNCTION__ VENDOR ":", bd, 6); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(ERICSSON_WRITE_BD_ADDR, MANUFACTURER_SPEC); c_pkt.len = 6; memcpy(c_pkt.data, tmp_bd, 6); return send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);} s32hci_read_firmware_rev_info(void){ D_CMD(__FUNCTION__ VENDOR "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(ERICSSON_READ_REVISION_INFORMATION, MANUFACTURER_SPEC); c_pkt.len = 0; return send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);}s32 hci_set_baudrate(u32 baudrate){ /* Due to the fact that the Ericsson module after P9A sends the reply on the new baudrate, this function can not block (Since btd sets the new physical device speed when this function returns). */ D_CMD(__FUNCTION__ VENDOR " (%u baud)\n", baudrate); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(ERICSSON_SET_UART_BAUD_RATE, MANUFACTURER_SPEC); c_pkt.len = 1; switch (baudrate) { case 9600: c_pkt.data[0] = 0x14; break; case 14400: c_pkt.data[0] = 0x05; break; case 19200: c_pkt.data[0] = 0x13; break; case 28800: c_pkt.data[0] = 0x04; break; case 38400: c_pkt.data[0] = 0x12; break; case 57600: c_pkt.data[0] = 0x03; break; case 115200: c_pkt.data[0] = 0x02; break; case 230400: c_pkt.data[0] = 0x01; break; case 460800: c_pkt.data[0] = 0x00; break; default: D_ERR(__FUNCTION__ VENDOR ": Baudrate not supported\n"); return -EINVAL; }#ifdef CONFIG_BLUETOOTH_SET_BAUDRATE_BLOCKING send_cmd_block((u8*) &c_pekt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);#else if (hci_ctrl.hc_buf.cmd_num < 1) { DSYS(__FUNCTION__ VENDOR ": sleeping\n"); interruptible_sleep_on(&set_baudrate_wq); } bt_write_lower_driver((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN); hci_ctrl.hc_buf.cmd_num--;#endif /* We don't really know if the card accepted the change, but we did succeed in trying to send it. --gmcnutt */ return 0;}voidprocess_vendor_return_param(u32 ocf, u8* r_val){ switch (ocf) { case 0x04: D_CMD(__FUNCTION__ VENDOR " Synth on set\n"); release_cmd_timer(); wake_up_interruptible(&hci_wq); break; case ERICSSON_SET_UART_BAUD_RATE: D_CMD(__FUNCTION__ VENDOR " baudrate set\n");#ifdef CONFIG_BLUETOOTH_SET_BAUDRATE_BLOCKING release_cmd_timer(); wake_up_interruptible(&hci_wq);#endif break; case ERICSSON_WRITE_BD_ADDR: D_CMD(__FUNCTION__ VENDOR " BD_ADDR set\n"); release_cmd_timer(); wake_up_interruptible(&hci_wq); break; case ERICSSON_READ_REVISION_INFORMATION: release_cmd_timer(); printk("Ericsson HW revision info: %s\n\n", r_val + 1); /* Store this for later retrieval */ strncpy(bt_hw_firmware_info, r_val + 1, BT_HW_INFO_MAX); bt_hw_firmware_info[BT_HW_INFO_MAX] = '\0'; wake_up_interruptible(&hci_wq); break; case ERICSSON_ENTER_TEST_MODE: release_cmd_timer(); if (r_val[0]) { D_ERR(__FUNCTION__ VENDOR " ENTER_TEST_MODE %s\n", get_err_msg(r_val[0])); } wake_up_interruptible(&hci_wq); break; case ERICSSON_TEST_CONTROL: release_cmd_timer(); if (r_val[0]) { D_ERR(__FUNCTION__ VENDOR " TEST_CONTROL %s\n", get_err_msg(r_val[0])); } wake_up_interruptible(&hci_wq); break; case ERICSSON_TX_TEST: release_cmd_timer(); if (r_val[0]) { D_ERR(__FUNCTION__ VENDOR " TX_TEST %s\n", get_err_msg(r_val[0])); } wake_up_interruptible(&hci_wq); break; default: release_cmd_timer(); D_ERR(__FUNCTION__ VENDOR " Manufacturer specific: Invalid reply (0x%x)\n", ocf); wake_up_interruptible(&hci_wq); break; }}voidprocess_vendor_event(u8 *buf, u32 len, u32 event_code){ D_ERR(__FUNCTION__ VENDOR " Vendor specific event not recognized.\n");}char*bt_hw_vendor(void){ return "Ericsson";}#elif defined(CONFIG_BLUETOOTH_DIGIANSWER)/*****************************************************************************//************************* Digianswer functions ******************************//*****************************************************************************/#define VENDOR " [Digianswer]"s32 hci_set_bd_addr(u8 bd[6]){ D_ERR(__FUNCTION__ VENDOR " not supported.\n"); return 0;}s32hci_read_firmware_rev_info(void){ D_ERR(__FUNCTION__ VENDOR " not supported.\n"); return 0;}s32 hci_set_baudrate(u32 baudrate){ u8 pkt[5]; s32 tmp; D_CMD(__FUNCTION__ VENDOR " (%u baud)\n", baudrate); pkt[0] = CMD_PKT; pkt[1] = 0x07; pkt[2] = 0xfc; pkt[3] = 0x01; switch (baudrate) { case 9600: pkt[4] = 0x03; break; case 19200: pkt[4] = 0x05; break; case 38400: pkt[4] = 0x07; break; case 57600: pkt[4] = 0x09; break; case 115200: pkt[4] = 0x09; break; } tmp = send_cmd(pkt, 5); start_cmd_timer(); interruptible_sleep_on(&hci_wq); return tmp;}u8*get_digi_err_code(u8 code){ switch (code) { case 0x01: return "The data packet is too large, No valid packet types\n"; case 0x02: return "The data packet is too large, Max slots exceeded\n"; case 0x10: return "No connection for data. The connection handle specified by the data packet is not in use\n"; case 0x20: return "The UCP2 synchronization signal is not right\n"; case 0xFF: return "Unspecified error\n"; default: return "Unkown error digianswer code\n"; }}voidprocess_vendor_event(u8 *buf, u32 len, u32 event_code){ D_REC(__FUNCTION__ VENDOR "\n"); if (len == 0x01) { D_REC(__FUNCTION__ VENDOR " RESET REQUEST EVENT\n"); } else { printk(get_digi_err_code(buf[0])); }}voidprocess_vendor_return_param(u32 ocf, u8* r_val){ switch (ocf) { case 0x07: D_CMD(__FUNCTION__ VENDOR " baudrate set\n"); release_cmd_timer(); wake_up_interruptible(&hci_wq); break; default: D_ERR(__FUNCTION__ VENDOR " Manufacturer specific: Invalid reply (0x%x)\n", ocf); break; }}char*bt_hw_vendor(void){ return "Digianswer";}#if RS232_SUPPORTs32 send_negotiation_pkt(void){ u8 pkt[8]; D_CTRL(__FUNCTION__ VENDOR "\n"); pkt[0] = NEG_PKT; pkt[1] = seq_nbr; seq_nbr++; pkt[2] = SET_UART(0x0, 0x0, 0x0, 0xb); pkt[3] = SET_BAUD_RATE(115200) & 0xff; pkt[4] = (SET_BAUD_RATE(115200) >> 8) & 0xff; pkt[5] = 10; /*?!? Try with this ?!?*/ pkt[6] = 0; pkt[7] = SET_PROTOCOL_MODE(0, 0, 0, 1, 0, 0); return send_cmd(pkt, 8);}#endif#elif defined(CONFIG_BLUETOOTH_CSR)/*****************************************************************************//****************************** CSR functions ********************************//*****************************************************************************/#define VENDOR " [CSR]"#define CSR_CH_ID_BCCMD 0x02#define CSR_CH_ID_HQ 0x03#define CSR_MSGTYPE_GETREQ 0x0000#define CSR_MSGTYPE_GETRESP 0x0001#define CSR_MSGTYPE_SETREQ 0x0002#define CSR_STATUS_OK 0x0000#define CSR_STATUS_NO_SUCH_VARID 0x0001#define CSR_STATUS_TOO_BIG 0x0002#define CSR_STATUS_NO_VALUE 0x0003#define CSR_STATUS_BAD_REQ 0x0004#define CSR_STATUS_NO_ACCESS 0x0005#define CSR_STATUS_READ_ONLY 0x0006#define CSR_STATUS_WRITE_ONLY 0x0007#define CSR_STATUS_ERROR 0x0008#define CSR_STATUS_PERMISSION_DENIED 0x0009#define CSR_CMD_CONFIG_UART 0x6802#define CSR_CMD_BUILD_ID 0x2819#define CSR_CMD_CHIP_VER 0x281a#define CSR_CMD_CHIP_REV 0x281b#define CSR_CMD_PS 0x7003#define CSR_PS_BDADDR 0x0001#define CSR_PS_MAX_ACL_PKT_LEN 0x0011#define CSR_PS_MAX_ACL_PKTS 0x0013#define CSR_PS_UART_CONFIG 0x0191#define CSR_PS_BAUD_RATE 0x0204#define CSR_UART_RATE_9K6 0x0027#define CSR_UART_RATE_19K2 0x004f#define CSR_UART_RATE_38K4 0x009d#define CSR_UART_RATE_57K6 0x00ec#define CSR_UART_RATE_115K2 0x01d8#define CSR_UART_RATE_230K4 0x03b0#define CSR_UART_RATE_460K8 0x075f#define CSR_UART_RATE_921K6 0x0ebf#define CSR_UART_ONE_STOP_BIT 0x0000#define CSR_UART_TWO_STOP_BITS 0x2000#define CSR_UART_NO_PARITY 0x0000#define CSR_UART_ODD_PARITY 0x4000#define CSR_UART_EVEN_PARITY 0xc000#define CSR_VARID_RSSI_REPORT 0x0801#define CSR_VARID_PACKET_STAT_REPORT 0x1001#define CSR_VARID_BITERR_REPORT 0x1006#define CSR_GET_CH_ID(msg) GET_BITS((msg)->descr, 0, 6)#define CSR_SET_CH_ID(msg, id) SET_BITS((msg)->descr, 0, 6, id)#define CSR_GET_FIRST(msg) GET_BITS((msg)->descr, 6, 1)#define CSR_SET_FIRST(msg, x) SET_BITS((msg)->descr, 6, 1, (x) != 0)#define CSR_GET_LAST(msg) GET_BITS((msg)->descr, 7, 1)#define CSR_SET_LAST(msg, x) SET_BITS((msg)->descr, 7, 1, (x) != 0)typedef struct csr_msg{ u8 descr; u8 msg[0];} __attribute__ ((packed)) csr_msg;typedef struct csr_bccmd{ u16 type; u16 len; /* in 16 bit integers */ u16 seq; u16 var_id; u16 status; u16 payload[0];} __attribute__ ((packed)) csr_bccmd; typedef struct csr_bccmd_ps{ u16 ps_key; u16 ps_len; /* len of only ps_val */ u16 unused; /* always 0x0000 */ u16 ps_val[0];} __attribute__ ((packed)) csr_bccmd_ps;typedef struct csr_rssi_rep{ u16 rssi;} __attribute__ ((packed)) csr_rssi_rep;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -