📄 bluetooth.c
字号:
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; } copy_from_user (temp_buffer, buf, count); 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, ¤t_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); 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->active) { 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->active) { 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->active) { 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->active) { 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->active) { 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->active) { dbg (__FUNCTION__ " - device not open"); 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(__FUNCTION__); if (!bluetooth->active) { 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); 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->active) { 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) { printk ("%.2x ", data[i]); } printk ("\n"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -