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

📄 bluetty.c

📁 linux qt class 类的函数定义
💻 C
📖 第 1 页 / 共 3 页
字号:
		return -ENODEV;
	}

	dbg(__FUNCTION__ " - %d byte(s)", count);

	if (!bluetooth->open_count) {
		dbg (__FUNCTION__ " - device not opened");
		return -EINVAL;
	}

	if (count == 0) {
		dbg(__FUNCTION__ " - write request of 0 bytes");
		return 0;
	}
	if (count == 1) {
		dbg(__FUNCTION__ " - write request only included type %d", buf[0]);
		return 1;
	}

#ifdef DEBUG
	printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", count);
	for (i = 0; i < count; ++i) {
		printk ("%.2x ", buf[i]);
	}
	printk ("\n");
#endif

	if (from_user) {
		temp_buffer = kmalloc (count, GFP_KERNEL);
		if (temp_buffer == NULL) {
			err (__FUNCTION__ "- out of memory.");
			retval = -ENOMEM;
			goto exit;
		}
		if (copy_from_user (temp_buffer, buf, count)) {
			retval = -EFAULT;
			goto exit;
		}
		current_buffer = temp_buffer;
	} else {
		current_buffer = buf;
	}

	switch (*current_buffer) {
		/* First byte indicates the type of packet */
		case CMD_PKT:
			/* dbg(__FUNCTION__ "- Send cmd_pkt len:%d", count);*/

			retval = bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, &current_buffer[1], count-1);
			if (retval) {
				goto exit;
			}
			retval = count;
			break;

		case ACL_PKT:
			current_position = current_buffer;
			++current_position;
			--count;
			bytes_sent = 0;

			while (count > 0) {
				urb = NULL;

				/* try to find a free urb in our list */
				for (i = 0; i < NUM_BULK_URBS; ++i) {
					if (bluetooth->write_urb_pool[i]->status != -EINPROGRESS) {
						urb = bluetooth->write_urb_pool[i];
						break;
					}
				}
				if (urb == NULL) {
					dbg (__FUNCTION__ " - no free urbs");
					retval = bytes_sent;
					goto exit;
				}
				

				buffer_size = min (count, bluetooth->bulk_out_buffer_size);
				memcpy (urb->transfer_buffer, current_position, buffer_size);

				/* build up our urb */
				FILL_BULK_URB (urb, bluetooth->dev, usb_sndbulkpipe(bluetooth->dev, bluetooth->bulk_out_endpointAddress),
						urb->transfer_buffer, buffer_size, bluetooth_write_bulk_callback, bluetooth);
				urb->transfer_flags |= USB_QUEUE_BULK;

				/* send it down the pipe */
				retval = usb_submit_urb(urb, GFP_KERNEL);
				if (retval) {
					dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with error = %d", retval);
					goto exit;
				}
#ifdef BTBUGGYHARDWARE
				/* A workaround for the stalled data bug */
				/* May or may not be needed...*/
				if (count != 0) {
					udelay(500);
				}
#endif
				current_position += buffer_size;
				bytes_sent += buffer_size;
				count -= buffer_size;
			}

			retval = bytes_sent + 1;
			break;
		
		default :
			dbg(__FUNCTION__" - unsupported (at this time) write type");
			retval = -EINVAL;
			break;
	}

exit:
	if (temp_buffer != NULL)
		kfree (temp_buffer);

	return retval;
} 


static int bluetooth_write_room (struct tty_struct *tty) 
{
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
	int room = 0;
	int i;

	if (!bluetooth) {
		return -ENODEV;
	}

	dbg(__FUNCTION__);

	if (!bluetooth->open_count) {
		dbg (__FUNCTION__ " - device not open");
		return -EINVAL;
	}

	for (i = 0; i < NUM_BULK_URBS; ++i) {
		if (bluetooth->write_urb_pool[i]->status != -EINPROGRESS) {
			room += bluetooth->bulk_out_buffer_size;
		}
	}

	dbg(__FUNCTION__ " - returns %d", room);
	return room;
}


static int bluetooth_chars_in_buffer (struct tty_struct *tty) 
{
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
	int chars = 0;
	int i;

	if (!bluetooth) {
		return -ENODEV;
	}

	if (!bluetooth->open_count) {
		dbg (__FUNCTION__ " - device not open");
		return -EINVAL;
	}

	for (i = 0; i < NUM_BULK_URBS; ++i) {
		if (bluetooth->write_urb_pool[i]->status == -EINPROGRESS) {
			chars += bluetooth->write_urb_pool[i]->transfer_buffer_length;
		}
	}

	dbg (__FUNCTION__ " - returns %d", chars);
	return chars;
}


static void bluetooth_throttle (struct tty_struct * tty)
{
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);

	if (!bluetooth) {
		return;
	}

	dbg(__FUNCTION__);

	if (!bluetooth->open_count) {
		dbg (__FUNCTION__ " - device not open");
		return;
	}
	
	dbg(__FUNCTION__ " unsupported (at this time)");

	return;
}


static void bluetooth_unthrottle (struct tty_struct * tty)
{
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);

	if (!bluetooth) {
		return;
	}

	dbg(__FUNCTION__);

	if (!bluetooth->open_count) {
		dbg (__FUNCTION__ " - device not open");
		return;
	}

	dbg(__FUNCTION__ " unsupported (at this time)");
}


static int bluetooth_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
{
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);

	if (!bluetooth) {
		return -ENODEV;
	}

	dbg(__FUNCTION__ " - cmd 0x%.4x", cmd);

	if (!bluetooth->open_count) {
		dbg (__FUNCTION__ " - device not open");
		return -ENODEV;
	}

	/* FIXME!!! */
	return -ENOIOCTLCMD;
}


static void bluetooth_set_termios (struct tty_struct *tty, struct termios * old)
{
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);

	if (!bluetooth) {
		return;
	}

	dbg(__FUNCTION__);

	if (!bluetooth->open_count) {
		dbg (__FUNCTION__ " - device not open");
		return;
	}

	/* FIXME!!! */

	return;
}


#ifdef BTBUGGYHARDWARE
void btusb_enable_bulk_read(struct tty_struct *tty){
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
	int result;

	if (!bluetooth) {
		return;
	}

	dbg(__FUNCTION__);

	if (!bluetooth->open_count) {
		dbg (__FUNCTION__ " - device not open");
		return;
	}

	if (bluetooth->read_urb) {
		FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, 
			      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
			      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
			      bluetooth_read_bulk_callback, bluetooth);
		result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
		if (result)
			err (__FUNCTION__ " - failed submitting read urb, error %d", result);
	}
}

void btusb_disable_bulk_read(struct tty_struct *tty){
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);

	if (!bluetooth) {
		return;
	}

	dbg(__FUNCTION__);

	if (!bluetooth->open_count) {
		dbg (__FUNCTION__ " - device not open");
		return;
	}

	if ((bluetooth->read_urb) && (bluetooth->read_urb->actual_length))
		usb_unlink_urb(bluetooth->read_urb);
}
#endif


/*****************************************************************************
 * urb callback functions
 *****************************************************************************/


static void bluetooth_int_callback (struct urb *urb)
{
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
	unsigned char *data = urb->transfer_buffer;
	unsigned int i;
	unsigned int count = urb->actual_length;
	unsigned int packet_size;

	dbg(__FUNCTION__);

	if (!bluetooth) {
		dbg(__FUNCTION__ " - bad bluetooth pointer, exiting");
		return;
	}

	if (urb->status) {
		dbg(__FUNCTION__ " - nonzero int status received: %d", urb->status);
		return;
	}

	if (!count) {
		dbg(__FUNCTION__ " - zero length int");
		return;
	}


#ifdef DEBUG
	if (count) {
		printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ "- length = %d, data = ", count);
		for (i = 0; i < count; ++i) {
			printk ("%.2x ", data[i]);
		}
		printk ("\n");
	}
#endif

#ifdef BTBUGGYHARDWARE
	if ((count >= 2) && (data[0] == 0xFF) && (data[1] == 0x00)) {
		data += 2;
		count -= 2;
	}
	if (count == 0) {
		urb->actual_length = 0;
		return;
	}
#endif
	/* We add  a packet type identifier to the beginning of each
	   HCI frame.  This makes the data in the tty look like a
	   serial USB devices.  Each HCI frame can be broken across
	   multiple URBs so we buffer them until we have a full hci
	   packet */

	if (!bluetooth->int_packet_pos) {
		bluetooth->int_buffer[0] = EVENT_PKT;
		bluetooth->int_packet_pos++;
	}
	
	if (bluetooth->int_packet_pos + count > EVENT_BUFFER_SIZE) {
		err(__FUNCTION__ " - exceeded EVENT_BUFFER_SIZE");
		bluetooth->int_packet_pos = 0;
		return;
	}

	memcpy (&bluetooth->int_buffer[bluetooth->int_packet_pos],
		urb->transfer_buffer, count);
	bluetooth->int_packet_pos += count;
	urb->actual_length = 0;

	if (bluetooth->int_packet_pos >= EVENT_HDR_SIZE)
		packet_size = bluetooth->int_buffer[2];
	else
		return;

	if (packet_size + EVENT_HDR_SIZE < bluetooth->int_packet_pos) {
		err(__FUNCTION__ " - packet was too long");
		bluetooth->int_packet_pos = 0;
		return;
	}

	if (packet_size + EVENT_HDR_SIZE == bluetooth->int_packet_pos) {
		for (i = 0; i < bluetooth->int_packet_pos; ++i) {
			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them */
			if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) {
				tty_flip_buffer_push(bluetooth->tty);
			}
			tty_insert_flip_char(bluetooth->tty, bluetooth->int_buffer[i], 0);
		}
		tty_flip_buffer_push(bluetooth->tty);

		bluetooth->int_packet_pos = 0;
	}
}


static void bluetooth_ctrl_callback (struct urb *urb)
{
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);

	dbg(__FUNCTION__);

	if (!bluetooth) {
		dbg(__FUNCTION__ " - bad bluetooth pointer, exiting");
		return;
	}

	if (urb->status) {
		dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
		return;
	}
}


static void bluetooth_read_bulk_callback (struct urb *urb)
{
	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
	unsigned char *data = urb->transfer_buffer;
	unsigned int count = urb->actual_length;
	unsigned int i;
	unsigned int packet_size;
	int result;


	dbg(__FUNCTION__);

	if (!bluetooth) {
		dbg(__FUNCTION__ " - bad bluetooth pointer, exiting");
		return;
	}

	if (urb->status) {
		dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
		if (urb->status == -ENOENT) {                   
			dbg(__FUNCTION__ " - URB canceled, won't reschedule");
			return;
		}
		goto exit;
	}

	if (!count) {
		dbg(__FUNCTION__ " - zero length read bulk");
		goto exit;
	}

#ifdef DEBUG
	if (count) {
		printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ "- length = %d, data = ", count);
		for (i = 0; i < count; ++i) {

⌨️ 快捷键说明

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