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

📄 bluetooth.c

📁 bluetooth 驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * bluetooth.c -- Linux kernel integration code for bluetooth stack * * Copyright (C) 2000, 2001  Axis Communications AB * * Author: Mattias Agren <mattias.agren@axis.com> * * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. * * Exceptionally, Axis Communications AB grants discretionary and * conditional permissions for additional use of the text contained * in the company's release of the AXIS OpenBT Stack under the * provisions set forth hereunder. * * Provided that, if you use the AXIS OpenBT Stack with other files, * that do not implement functionality as specified in the Bluetooth * System specification, to produce an executable, this does not by * itself cause the resulting executable to be covered by the GNU * General Public License. Your use of that executable is in no way * restricted on account of using the AXIS OpenBT Stack code with it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the provisions of the GNU * General Public License. * * $Id: bluetooth.c,v 1.207 2001/10/16 16:12:14 anderstj Exp $ * *//****************** INCLUDE FILES SECTION ***********************************/#include <linux/bluetooth/sysdep-2.1.h>#include <linux/config.h>#include <linux/termios.h>#include <linux/tty.h>#include <linux/module.h>#include <linux/malloc.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/timer.h>/* Make sure KERNEL_VERSION() is defined */#ifndef KERNEL_VERSION#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)# ifdef MODULE#  define module_init(x) int init_module(void) { return x(); }#  define module_exit(x) void cleanup_module(void) { x(); }# else#  define module_init(x) int x##_module(void) { return x(); }#  define module_exit(x) void x##_module(void) { x(); }# endif# define __init# define __exit#else# include <linux/init.h># if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)#  include <linux/kcomp.h># endif#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)# include <linux/interrupt.h>#endif#include <linux/bluetooth/bluetooth.h>#include <linux/bluetooth/btcommon.h>#include <linux/bluetooth/btmem.h>#include <linux/bluetooth/hci.h>#include <linux/bluetooth/hci_internal.h>#include <linux/bluetooth/l2cap.h>#include <linux/bluetooth/rfcomm.h>#include <linux/bluetooth/tcs.h>#include <linux/bluetooth/sdp.h>#include <linux/bluetooth/sec_client.h>#include <linux/bluetooth/bt_errno.h>#include <linux/bluetooth/test.h>#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP#include <linux/bluetooth/bcsp.h>#endif#ifdef CONFIG_BLUETOOTH_USE_TCI#include <linux/bluetooth/tci.h>#endif#ifdef CONFIG_BLUETOOTH_PROC#include <linux/bluetooth/bt_proc.h>#endif#ifdef __CRIS__#include <asm/io.h>#endif/****************** DEBUG CONSTANT AND MACRO SECTION ************************/#if BT_DRIVER_DEBUG#define BT_DRIVER(fmt...) printk(BT_DBG_STR"(driver) " fmt)#else#define BT_DRIVER(fmt...)#endif /* BT_DRIVER_DEBUG */#if BT_DATADUMP_DEBUG#define BT_DATADUMP(str, data, len) print_data(str, data, len)#else#define BT_DATADUMP(str, data, len)#endif#if BT_DATA_DEBUG#if BT_USE_TIMESTAMPS#define BT_DATA(fmt...) do {print_time(1);printk(BT_DBG_STR"DATA " fmt);} while (0)#else#define BT_DATA(fmt...) printk(BT_DBG_STR"DATA " fmt)#endif#else /* BT_DATA_DEBUG */#define BT_DATA(fmt...)#endif /* BT_DATA_DEBUG */#if BT_LDISC_DEBUG#define BT_LDISC(fmt...) printk(BT_DBG_STR"(ldisc) " fmt)#else#define BT_LDISC(fmt...)#endif /* BT_LDISC_DEBUG */#ifndef BT_DATADUMP#define BT_DATADUMP(str, data, len)#endif/****************** CONSTANT AND MACRO SECTION ******************************/#define BLUETOOTH_TYPE_DATA 1#define BLUETOOTH_TYPE_DATA_VOICE 2#define BT_TTY_DRIVER_MAGIC 0xb100b100 /* check if free...*/#define BT_TTY_MAJOR 124 /* Experimental use */#define BT_PARANOIA_CHECK 0/****************** TYPE DEFINITION SECTION *********************************/#ifdef CONFIG_BLUETOOTH_USE_INBUFFER/* This buffer is used decrease overruns on serial port. Copies data in   interrupt context and schedules a task which consumes data at 'safe' time */#define BT_INBUFFER_SIZE 4000typedef struct bt_inbuffer{	u8* head;     /* Start of data buffer */	u8* tail;     /* End of data buffer */ 	u8* put;      /* Points to where new data is inserted */	u8* get;      /* This is where the receive task consumes data */	u8 data[BT_INBUFFER_SIZE];} bt_inbuffer;#endif/****************** LOCAL FUNCTION DECLARATION SECTION **********************/#ifdef __CRIS__#define BT_FLASH_LED_TIME   (HZ/50) /* 20 ms */ #define BT_FLASH_LED_PAUSE (HZ/100) /* 10 ms */#define NO_BLUETOOTH_ACTIVITY 0#define BLUETOOTH_ACTIVITY    1static struct timer_list bt_clear_led_timer;static int bt_led_next_time;static int bt_led_active;static void bt_clear_led(unsigned long dummy);static void bt_set_leds(int active);#endifstatic void bt_flash_led(void);#ifdef CONFIG_BLUETOOTH_USE_INBUFFERstruct tq_struct bt_receive_task;bt_inbuffer hci_data;static void hci_receive_data_task(void);static void bt_handle_indata(const __u8 *data, s32 count);#endifstatic void bt_receive_data(u8* data, u32 count);static void bt_show_version(void);static s32 bt_init_stack(void);static s32 bt_ctrl_init(void);static s32 bt_connect(u8 *bd_addr, u32 con_id);static s32 bt_disconnect(u32 con_id);static const u8* psmname(u16 psm);static void wq_timeout(unsigned long ptr);static s32 bt_execute_sdp_request(bt_sdp_request *sdpRequest);#ifdef __USE_OLD_SYMTAB__/* * LINUX 2.0.X SPECIFIC CODE */static s32 bt_tty_read(struct tty_struct *, struct file *, __u8 *, u32);/* not needed since we write directly to ttyS0->driver->write (rs_write) */static s32 bt_tty_write(struct tty_struct *, struct file *, const __u8 *, u32);static s32 bt_tty_select(struct tty_struct *tty, struct inode *inode,                         struct file *filp, s32 sel_type, select_table *wait);#else/* * LINUX 2.2.X SPECIFIC CODE */static ssize_t bt_tty_read(struct tty_struct *tty, struct file *file,			   u8 *buf, size_t nr);static ssize_t bt_tty_write(struct tty_struct *tty, struct file *file,			    const u8 *buf, size_t nr);static u32 bt_tty_poll(struct tty_struct *tty, struct file *file,		       struct poll_table_struct *wait);#endifstatic s32 bt_tty_ioctl(struct tty_struct *, struct file *, u32, unsigned long);static s32 bt_tty_open(struct tty_struct *);static void bt_tty_close(struct tty_struct *);static s32 bt_tty_room(struct tty_struct *tty);/* glue */static s32 bt_write_top(struct tty_struct * tty, s32 from_user,			const u8 *buf, s32 count);static void bt_receive_lower_stack(struct tty_struct *tty, const __u8 * cp,				   char *fp, s32 count);static void bt_tty_wakeup(struct tty_struct *tty);static void bt_reset_session(s32 line);//#define BT_USELINEBUF/* windoz fix... */#ifdef BT_USELINEBUFvoid bt_reset_linebuf(void);void bt_linebuf_add(s32 line, u8 *data, s32 len);void bt_linebuf_send(s32 line);#endif/****************** GLOBAL VARIABLE DECLARATION SECTION *********************/extern hci_controller hci_ctrl;/****************** LOCAL VARIABLE DECLARATION SECTION **********************/#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)static struct semaphore ioctl_sem = MUTEX;#elsestatic struct semaphore ioctl_sem;#endif /* LINUX_VERSION_CODE */static struct bt_ctrl_struct bt_ctrl;/* some defines for easier reading */#define BTCTRL bt_ctrl /* the name of the struct that holds all data */#define GET_UPPERTTY(line) (BTCTRL.session[line].upper_tty)#define SESSIONSTATE(line) (BTCTRL.session[line].state)#define NBR_ACTIVE BTCTRL.nbr_active#define NBR_UPPER BTCTRL.nbr_upper#define NBR_CTRL_FDS BTCTRL.ctrl_tty_countstruct bt_stat_struct bt_stat;static struct tty_driver bt_driver;static s32 bluetooth_refcount;static struct tty_struct *sertty;static s32 bt_stack_initiated = 0;/* used when copying data from user level */static u8 *tmp_bt_buf = NULL;static struct tty_struct *bt_table[BT_NBR_PORTS];static struct termios *bt_termios[BT_NBR_PORTS]; static struct termios *bt_termios_locked[BT_NBR_PORTS];#ifdef BT_USELINEBUF/* temp buffer used to store data received at upper tty when line is not    active yet */#define TTY_LINEBUFLEN 256#define TTY_NOLINE 256 /* valid line range 0-255 *//* only works for 1 line at a time (to preserve memory)    whole buffer is sent to upper tty once tty line goes active */typedef struct tty_linebuffer {	s32 line;	u32 cur_len;	u8 data[TTY_LINEBUFLEN];} tty_linebuffer;static tty_linebuffer tty_linebuf;#endif /* BT_USELINEBUF */static struct timer_list bt_timer;#define BT_CON_TIMEOUT (10*HZ)/****************** FUNCTION DEFINITION SECTION *****************************//*Short description of new stack integration in kernel----------------------------------------------------1) PPP over serial (standard way):   user app (pppd)       / \-------| |------------------       \ /  -------------  |   tty      |  |           <----> line discipline (PPP)  -------------  | tty driver | (serial driver)  -------------       / \-------| |------------------       \ /       UART2) PPP over bluetooth:  user app (pppd)       / \-------| |------------------       \ / ttyBT0   --------------   | tty | ldisc-> PPP ldisc-----------------------------------------------   | tty driver | (bluetooth driver)   -------------   |            | <-------           |  BT STACK  | <-----  |            ADDED   |            | <---  | |    -------------      | | |   |   ttyS0    |     V V V   |       ldisc->  BT ldisc -----------------------------------------------   | tty driver | (serial driver)   -------------        / \--------| |------------------        \ /       UARTttySx is a standard serial port tty.ttyBTx has a separate major nbr and has been registered to use bt driver as tty driver.ttySx is opened initially from a bluetooth control-applicationwhich sets the bt line discipline and keeps the tty open.When ttyBT is opened from pppd it is set to use ppp discipline which in turn uses the driver registered in its tty i.e the bt driver.At the stack top it acts like a serial driver for pppAt the bottom the stack acts like any line discipline used from the standard serial tty.- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -             - Glue Layers for stack -                 "APPLICATION" (here:ttyBT)       --------------------------------------------- TOP   | bt_recieve_top()  |    bt_write_top()     |       ---------------------------------------------                ^                       |                |                       V                        T H E  S T A C K                                                           ^                       |                |                       V        ---------------------------------------------------- BOTTOM | bt_receive_lower_stack()| bt_write_lower_driver()|        ----------------------------------------------------              "PHYSICAL DRIVER" (here:serial driver)- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *//***********************************//* STACK TOP (TTY DRIVER FUNCTIONS)*//***********************************/static s32bt_open(struct tty_struct *tty, struct file * filp){	s32 line = GET_TTYLINE(tty);	s32 ret_val;		BT_DRIVER(__FUNCTION__ ": Line %d\n", line);			ret_val = bt_register_tty(tty) ;	if (ret_val < 0)		return ret_val;		MOD_INC_USE_COUNT;	/* store calling tty in control block */	return ret_val;}static voidbt_close(struct tty_struct *tty, struct file * filp){	s32 line = GET_TTYLINE(tty);	BT_DRIVER(__FUNCTION__ ": Line %d\n", line);	/* FIXME - flush channels etc */	/* close rfcomm channel associated with this tty ?? */	if (bt_unregister_tty(tty, line) < 0)		return ;	MOD_DEC_USE_COUNT;}static voidbt_put_char(struct tty_struct *tty, u8 ch){	BT_DRIVER(__FUNCTION__ ": %c\n", ch);	bt_write_top(tty, 0, &ch, 1);}static voidbt_flush_chars(struct tty_struct *tty){	BT_DRIVER(__FUNCTION__ "\n");	if (sertty != NULL && sertty->driver.flush_chars)		sertty->driver.flush_chars(sertty);}static s32 bt_write_room(struct tty_struct *tty){	s32 n = buf_write_room();	BT_DRIVER(__FUNCTION__ ": %d\n", n);	return n;}static s32bt_chars_in_buffer(struct tty_struct *tty){	u16 n = buf_byte_count(GET_TTYLINE(tty));	BT_DRIVER(__FUNCTION__ ": %d\n", n);	return n;}static voidbt_flush_buffer(struct tty_struct *tty){	/* Clearing the buffers here may lead to them being cleared before	   they are sent when diconnecting a connection */	BT_DRIVER(__FUNCTION__ ": Ignored\n");#if 0	bt_tx_buf* tx_buf;	while ((tx_buf = get_bt_buf())) {		unsubscribe_bt_buf(tx_buf);	}#endif}static s32__bt_ioctl(struct tty_struct *tty, struct file * file,	 u32 cmd, unsigned long arg){	s32 tmp;	u32 utmp;	s32 err = 0;	s32 size = _IOC_SIZE(cmd);	bt_connection btcon;	u8 bd_addr[6];#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP	static u8 dfu_data[2044];#endif	/* The direction is a bitmask, and VERIFY_WRITE catches R/W transfer.	   The ioctl direction is user-oriented, while verify_area is kernel-	   oriented, so the concept of "read" and "write" is reversed */	if (_IOC_DIR(cmd) & _IOC_READ) {		err = verify_area(VERIFY_WRITE, (void*)arg, size);		if (err) {			BT_DRIVER("verify_area(VERIFY_WRITE) error:%d\n", err);			return err;		}

⌨️ 快捷键说明

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