📄 bluetty.c
字号:
/* shutdown any in-flight urbs that we know about */ usb_kill_urb (bluetooth->read_urb); usb_kill_urb (bluetooth->interrupt_in_urb); } up(&bluetooth->lock);}static int bluetooth_write (struct tty_struct * tty, const unsigned char *buf, int count){ struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); struct urb *urb = NULL; unsigned char *temp_buffer = NULL; const unsigned char *current_buffer; unsigned char *urb_buffer; int i; int retval = 0; if (!bluetooth) { return -ENODEV; } dbg("%s - %d byte(s)", __FUNCTION__, count); if (!bluetooth->open_count) { dbg ("%s - device not opened", __FUNCTION__); return -EINVAL; } if (count == 0) { dbg("%s - write request of 0 bytes", __FUNCTION__); return 0; } if (count == 1) { dbg("%s - write request only included type %d", __FUNCTION__, buf[0]); return 1; }#ifdef DEBUG printk (KERN_DEBUG __FILE__ ": %s - length = %d, data = ", __FUNCTION__, count); for (i = 0; i < count; ++i) { printk ("%.2x ", buf[i]); } printk ("\n");#endif current_buffer = buf; switch (*current_buffer) { /* First byte indicates the type of packet */ case CMD_PKT: /* dbg("%s- Send cmd_pkt len:%d", __FUNCTION__, count);*/ retval = bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, ¤t_buffer[1], count-1); if (retval) { goto exit; } retval = count; break; case ACL_PKT: ++current_buffer; --count; urb_buffer = kmalloc (count, GFP_ATOMIC); if (!urb_buffer) { dev_err(&bluetooth->dev->dev, "out of memory\n"); retval = -ENOMEM; goto exit; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { dev_err(&bluetooth->dev->dev, "no more free urbs\n"); kfree(urb_buffer); retval = -ENOMEM; goto exit; } memcpy (urb_buffer, current_buffer, count); /* build up our urb */ usb_fill_bulk_urb(urb, bluetooth->dev, usb_sndbulkpipe(bluetooth->dev, bluetooth->bulk_out_endpointAddress), urb_buffer, count, bluetooth_write_bulk_callback, bluetooth); /* send it down the pipe */ retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) { dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, retval); goto exit; } /* we are done with this urb, so let the host driver * really free it when it is finished with it */ usb_free_urb (urb); retval = count + 1; break; default : dbg("%s - unsupported (at this time) write type", __FUNCTION__); retval = -EINVAL; break; }exit: kfree (temp_buffer); return retval;} static int bluetooth_write_room (struct tty_struct *tty) { dbg("%s", __FUNCTION__); /* * We really can take anything the user throws at us * but let's pick a nice big number to tell the tty * layer that we have lots of free space */ return 2048;}static int bluetooth_chars_in_buffer (struct tty_struct *tty) { dbg("%s", __FUNCTION__); /* * We can't really account for how much data we * have sent out, but hasn't made it through to the * device, so just tell the tty layer that everything * is flushed. */ return 0;}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("%s", __FUNCTION__); if (!bluetooth->open_count) { dbg ("%s - device not open", __FUNCTION__); return; } dbg("%s unsupported (at this time)", __FUNCTION__); 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("%s", __FUNCTION__); if (!bluetooth->open_count) { dbg ("%s - device not open", __FUNCTION__); return; } dbg("%s unsupported (at this time)", __FUNCTION__);}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("%s - cmd 0x%.4x", __FUNCTION__, cmd); if (!bluetooth->open_count) { dbg ("%s - device not open", __FUNCTION__); 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("%s", __FUNCTION__); if (!bluetooth->open_count) { dbg ("%s - device not open", __FUNCTION__); return; } /* FIXME!!! */ return;}#ifdef BTBUGGYHARDWAREvoid 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("%s", __FUNCTION__); if (!bluetooth->open_count) { dbg ("%s - device not open", __FUNCTION__); return; } if (bluetooth->read_urb) { usb_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 ("%s - failed submitting read urb, error %d", __FUNCTION__, 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("%s", __FUNCTION__); if (!bluetooth->open_count) { dbg ("%s - device not open", __FUNCTION__); return; } if ((bluetooth->read_urb) && (bluetooth->read_urb->actual_length)) usb_kill_urb(bluetooth->read_urb);}#endif/***************************************************************************** * urb callback functions *****************************************************************************/static void bluetooth_int_callback (struct urb *urb, struct pt_regs *regs){ 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; int status; dbg("%s", __FUNCTION__); if (!bluetooth) { dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); return; } switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } if (!count) { dbg("%s - zero length int", __FUNCTION__); goto exit; }#ifdef DEBUG if (count) { printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, 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; goto exit; }#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("%s - exceeded EVENT_BUFFER_SIZE", __FUNCTION__); bluetooth->int_packet_pos = 0; goto exit; } 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 goto exit; if (packet_size + EVENT_HDR_SIZE < bluetooth->int_packet_pos) { err("%s - packet was too long", __FUNCTION__); bluetooth->int_packet_pos = 0; goto exit; } 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; }exit: status = usb_submit_urb (urb, GFP_ATOMIC); if (status) err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, status);}static void bluetooth_ctrl_callback (struct urb *urb, struct pt_regs *regs){ struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__); dbg("%s", __FUNCTION__); if (!bluetooth) { dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); return; } if (urb->status) { dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); return; }}static void bluetooth_read_bulk_callback (struct urb *urb, struct pt_regs *regs){ 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("%s", __FUNCTION__); if (!bluetooth) { dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); return; } if (urb->status) { dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); if (urb->status == -ENOENT) { dbg("%s - URB canceled, won't reschedule", __FUNCTION__); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -