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

📄 bluetooth.c

📁 blue tooth protocol stack source code
💻 C
📖 第 1 页 / 共 5 页
字号:
		copy_from_user(&ping+8, (u8*)arg+8, ping.len);		printk("len: %d\n", ping.len);		return l2ca_ping(ping.bd, ping.data, ping.len);	}	case BTGETINFO:	{		u8 bd[6];		u16 type;		/* first byte contains length of whole hci message */		copy_from_user(&bd, (u8*)arg, 6);		copy_from_user(&type, (u8*)arg + 6, 2);		BT_DRIVER("BTGETINFO: Type %d\n", type);		return l2ca_getinfo(bd, type);	}	/* force m/s switch as server */	case BTSETMSSWITCH:	{		u8 enable;		GET_USER(tmp, (s32*)arg);		enable = (u8)(tmp & 0xff);				BT_DRIVER("BTSETMSSWITCH: %d\n", enable);		hci_force_msswitch(enable);		return 0;	}	/* Set max number of connections */	case BTSETMAXCONNECTIONS:		GET_USER(tmp, (s32*)arg);		BT_DRIVER("BTSETMAXCONNECTIONS: %d\n", tmp);		return hci_set_max_connections(tmp);	case BTSETBCSPMODE:		GET_USER(tmp, (s32*)arg);		BT_DRIVER("BTSETBCSPMODE: %d\n", tmp);				tmp = bt_use_bcsp(tmp);		put_user(tmp, (s32*)arg);		return 0;	case BT_SET_DFU_MODE:		GET_USER(tmp, (s32*)arg);		BT_DRIVER("BT_SET_DFU_MODE: %d\n", tmp);		tmp = bt_dfu_mode(tmp);		put_user(tmp, (s32*)arg);		return 0;#ifdef CONFIG_BLUETOOTH_CSR	/* | ps_key (u16) | rw_mode (u16) | len (u16) | params (u16[])| */	case BT_CSR_PSKEY:	{		u16 u16_size = CSR_PSKEY_MSGHDR_SIZE + CSR_PSKEY_MAXPARAMS;		u16 msg[size];				copy_from_user(msg, (u8*)arg, u16_size*sizeof(u16));		BT_DRIVER("BT_CSR_PSKEY [ps:%d type:%d]\n", msg[0], msg[1]);		csr_pskey(msg[0], msg[1], &msg[3], msg[2]);				copy_to_user((s32*)arg, msg, u16_size*sizeof(u16));		return 0;	}#endif /* CONFIG_BLUETOOTH_CSR */#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP	case BTINITBCSP:		BT_DRIVER("BTINITBCSP\n");		if (bcsp_init() < 0) {			printk("Sync failed\n");			return -ETIMEDOUT;		}		return 0;	case BT_SEND_DFU_COMMAND:        {                int ret;                s32 dfu_len;		if (!bt_use_bcsp(-1))			return -EPERM;		GET_USER(dfu_len, (s32*)arg);                if (dfu_len > sizeof dfu_data)                        return -EINVAL;                copy_from_user(dfu_data, (s32*)arg + 1, dfu_len);                ret = bcsp_sequence_send(dfu_data, dfu_len, BCSP_DFU_CHN);                if (ret < 0)                        return ret;                return 0;        }	case BT_RETRIEVE_DFU_RESPONSE:        {                s32 dfu_len;		if (!bt_use_bcsp(-1))			return -EPERM;		GET_USER(dfu_len, (s32*)arg);                if (dfu_len > sizeof dfu_data)                        return -EINVAL;                                        dfu_len = hci_read_dfu((u8*)((s32*)arg + 1), dfu_len);                if (dfu_len < 0)                        return dfu_len;		put_user(dfu_len, (s32*)arg);                return 0;        }#endif /* CONFIG_BLUETOOTH_SUPPORT_BCSP */	default:				return -ENOIOCTLCMD;	}	return 0;}static s32bt_ioctl(struct tty_struct *tty, struct file * file,	 u32 cmd, unsigned long arg){	s32 tmp;//	printk(__FUNCTION__ ": [%s:%x] lock !\n", current->comm, cmd);	down(&ioctl_sem);//	printk(__FUNCTION__ ": [%s:%x] running...\n", current->comm, cmd);	tmp = __bt_ioctl(tty, file, cmd, arg);	up(&ioctl_sem);	return tmp;}static voidbt_throttle(struct tty_struct * tty){	BT_DRIVER(__FUNCTION__ ": Nothing done\n");}static voidbt_unthrottle(struct tty_struct * tty){	BT_DRIVER(__FUNCTION__ ": Nothing done\n");}static voidbt_set_termios(struct tty_struct *tty, struct termios *old_termios){	BT_DRIVER(__FUNCTION__ ": Forwarding to serial driver\n");	/* modify serial tty not bt tty */	if (sertty != NULL)		sertty->driver.set_termios(sertty, old_termios);	else		D_ERR(__FUNCTION__ ": No sertty set!!\n");}static void bt_start(struct tty_struct *tty){	BT_DRIVER(__FUNCTION__ ": Nothing done\n");}static voidbt_stop(struct tty_struct *tty){	BT_DRIVER(__FUNCTION__ ": Nothing done\n");}voidbt_hangup(struct tty_struct *tty){	BT_DRIVER(__FUNCTION__ ": Line %d (nothing done) pid %d (%s)\n",		  GET_TTYLINE(tty), current->pid, current->comm);}/********************************************//* STACK BOTTOM FUNCTIONS (LINE DISCIPLINE) *//********************************************//* * TTY callbacks */#ifdef __USE_OLD_SYMTAB__/*****************************************************************************//* LINUX 2.0.X SPECIFIC CODE                                                 *//*****************************************************************************/static s32 bt_tty_read(struct tty_struct *tty, struct file *file,                       __u8 * buf, u32 nr)#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)#endif{	/* should not read data directly over serial tty */	BT_LDISC(__FUNCTION__ ": Disabled\n");	return 0;}#ifdef __USE_OLD_SYMTAB__/*****************************************************************************//* LINUX 2.0.X SPECIFIC CODE                                                 *//*****************************************************************************/static s32bt_tty_write(struct tty_struct *tty, struct file *file, const __u8 * data,             u32 count)#else/*****************************************************************************//* LINUX 2.2.X SPECIFIC CODE                                                 *//*****************************************************************************/static ssize_tbt_tty_write(struct tty_struct * tty, struct file * file, const u8 * data,	     size_t count)#endif{	/* should simply discard data since ttySx only exists for internal use	 */	BT_LDISC(__FUNCTION__ ": (%d) done!\n", count);  	return tty->driver.write(tty, 1/*from user*/, data, count);}static s32bt_tty_ioctl(struct tty_struct *tty, struct file * file,	     u32 cmd, unsigned long arg){	switch (cmd) {	default:		/* forward rest to n_tty line discipline, it takes care of		   termios settings etc, the rest goes to the tty driver 		   (serial driver) */		BT_LDISC(__FUNCTION__ ": Forwarding ioctl 0x%x to n_tty line disc\n", cmd);		return n_tty_ioctl(tty, file, cmd, arg);	}	return -ENOIOCTLCMD;}#ifdef __USE_OLD_SYMTAB__/*****************************************************************************//* LINUX 2.0.X SPECIFIC CODE                                                 *//*****************************************************************************/static s32bt_tty_select(struct tty_struct *tty, struct inode *inode,	      struct file *filp, s32 sel_type, select_table * wait){	BT_LDISC(__FUNCTION__ ": Nothing done!\n");	return 0;}#else/*****************************************************************************//* LINUX 2.2.X SPECIFIC CODE                                                 *//*****************************************************************************/static u32 bt_tty_poll(struct tty_struct *tty,		       struct file *file,		       struct poll_table_struct *wait){	BT_LDISC(__FUNCTION__ ": Nothing done!\n");	return 0;}#endifstatic s32bt_tty_open(struct tty_struct *tty){	BT_LDISC(__FUNCTION__ "\n");	DSYS("Setting BT driver to use serial tty\n");	sertty = tty;	return 0;}static voidbt_tty_close(struct tty_struct *tty){	struct tty_struct *upper_tty;	s32 line = 0;		/* Now hangup all active upper tty:s */		while (line < BT_NBR_DATAPORTS)	{		if ((SESSIONSTATE(line) == BT_ACTIVE) ||		    (SESSIONSTATE(line) == BT_UPPERCONNECTED))		{			BT_LDISC("Hanging up line %d\n", line);			upper_tty = GET_UPPERTTY(line);			if (upper_tty)				tty_hangup(upper_tty);		}		line++;	}	sertty = NULL;}/* * Callback function from tty driver. Return the amount of space left * in the receiver's buffer to decide if remote transmitter is to be * throttled. */static s32bt_tty_room(struct tty_struct *tty){	BT_LDISC(__FUNCTION__ ": Return 65536!\n");	return 65536;	    /* We can handle an infinite amount of data. :-) */}/* * This function is called by the tty driver when the transmit buffer has * additional space.  */static voidbt_tty_wakeup(struct tty_struct *tty){	printk(__FUNCTION__ ": Nothing done\n");}void bt_reset_phys_hw(void){#ifdef __CRIS__#ifdef CONFIG_BLUETOOTH_CSR	int do_reset = 1;#else	int do_reset = 0;#endif#if defined(CONFIG_BLUETOOTH_RESET_PA7)	BT_DRIVER(__FUNCTION__ ": Resetting Bluetooth hardware using pin PA7 (Active %s)\n", (do_reset ? "High" : "Low"));	REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, 7, do_reset);	udelay(1000);	REG_SHADOW_SET(R_PORT_PA_DATA, port_pa_data_shadow, 7, !do_reset);#elif defined(CONFIG_BLUETOOTH_RESET_PB5)	BT_DRIVER(__FUNCTION__ ": Resetting Bluetooth hardware using pin PB5 (Active %s)\n", (do_reset ? "High" : "Low"));	REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 5, do_reset);	udelay(1000);	REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 5, !do_reset);#elif defined(CONFIG_BLUETOOTH_RESET_G10)	BT_DRIVER(__FUNCTION__ ": Resetting Bluetooth hardware using pin G10 (Active %s)\n", (do_reset ? "High" : "Low"));	REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 10, do_reset);	udelay(1000);	REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 10, !do_reset);#elif defined(CONFIG_BLUETOOTH_RESET_G11)	BT_DRIVER(__FUNCTION__ ": Resetting Bluetooth hardware using pin G11 (Active %s)\n", (do_reset ? "High" : "Low"));	REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 11, do_reset);	udelay(1000);	REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 11, !do_reset);#else	D_ERR(__FUNCTION__ ": Resetting Bluetooth hardware: No reset pin defined\n");#endif#else	BT_DRIVER(__FUNCTION__ ": Do not know how to reset the Bluetooth hardware!\n");#endif /* __CRIS__ */}/************************//* glue layer functions *//************************//* * HCI calls this function to write to lower layer driver */s32bt_write_lower_driver(u8 *data, s32 len)#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP{        if (bt_use_bcsp(-1))                return bcsp_write_top(data, len);        else                return bt_write_lower_driver_real(data, len);}s32bt_write_lower_driver_real(u8 *data, s32 len)#endif{	if (len < 0) { /* (!) */		D_ERR(__FUNCTION__ ": Can't write negative length...\n");		return 0;	}		/* get lower layer tty and call its write function directly 	   without using its registered line discipline */	BT_DATA("<--|X|    %3d\n", len);	if (sertty) {		s32 tmp;		s32 sent;				if ((tmp = sertty->driver.write_room(sertty)) < len) {			printk(__FUNCTION__ ": ser tx buffers can't send all, wait (%d/%d)\n",			       tmp, len);			return 0;		} else {			bt_flash_led();			BT_DATADUMP("<--|X|", (u8*)data, len);			sent = sertty->driver.write(sertty, 0, data, len);		}				if (sent != len) {			printk(__FUNCTION__ ": Only sent %d of total %d\n", 			       sent, len);			/* fixme -- discard packet and add tx error in stat */		}		len -= sent;		return sent;	} else {		D_ERR(__FUNCTION__ ": No sertty is set\n");	}	return 0;}/* * Callback function when data is available at the tty driver. * Context: timer task or (less likely) hard interrupt. */ static voidbt_receive_lower_stack(struct tty_struct *tty, const __u8 *data,		       char *flags, s32 count){	BT_DATA("-->|X|    %3d\n", count);	BT_DATADUMP("-->|X|", (u8*)data, count);	bt_flash_led();#ifdef CONFIG_BLUETOOTH_USE_INBUFFER	/* store in bt inbuffer and schedule a hci receive task if none is started  */	bt_handle_indata(data, count);#else	/* process data right away */	bt_receive_data((u8*)data, count);#endif /* CONFIG_BLUETOOTH_USE_INBUFFER */}/*  * Upper tty writes to top of stack (BT drivers write())  */static s32bt_write_top(struct tty_struct * tty, s32 from_user,	     const u8 *buf, s32 count){	s32 line = GET_TTYLINE(tty);	s32 bytes_sent;	u32 rfcomm_conid;	struct bt_session *bt;	BT_DATA("   |X|<-- %3d [%d]\n", count, line);	BT_DATADUMP("|X|<--", (u8*)buf, count);	bt = (bt_session *)tty->driver_data;		if ((bt->rfcomm != NULL) && (bt->rfcomm->magic != RFCOMM_MAGIC)) {		D_ERR(__FUNCTION__ ": rfcomm magic failed (0x%x != 0x%x)\n", 		      bt->rfcomm->magic, RFCOMM_MAGIC);		return 0;	}	if (SESSIONSTATE(line) != BT_ACTIVE) {		D_WARN(__FUNCTION__ ": Line %d is not in active state\n",		       line);		return 0;	}	rfcomm_conid = CREATE_RFCOMM_ID(line, bt->dlci);		if (from_user) {		/* Our tmp_bt_buf is only one page, but nothing prevents the		 * caller from giving us more than that to send. Make sure we		 * don't try to write beyond the end of tmp_bt_buf.		 */		count = MIN(count, PAGE_SIZE);		copy_from_user(tmp_bt_buf, buf, count);		bytes_sent = rfcomm_send_data(rfcomm_conid, tmp_bt_buf, count);	} else {		bytes_sent = rfcomm_send_data(rfcomm_conid, (u8*)buf, count);	}	bt_stat.bytes_sent += bytes_sent;	return bytes_sent;}/* * RFCOMM calls this function to write to higher layer  * "application" e.g ttyBT */s32bt_receive_top(u32 con_id, u8 *data, s32 len) {	struct tty_struct *upper_tty;	u32 line;	line = GET_LINE(con_id);		/* get upper tty and call its ldisc->receive_buf */	BT_DATA("   |X|--> %3d [%d]\n", len, line);	BT_DATADUMP("|X|-->", data, len);		if (SESSIONSTATE(line) != BT_ACTIVE) {		/* change debug macro... */

⌨️ 快捷键说明

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