📄 bluetooth.c
字号:
printk("cmd_pkt from interrupt!\n"); return count; } new_buffer = kmalloc (count-1, GFP_KERNEL); if (!new_buffer) { err (__FUNCTION__ "- out of memory."); return -ENOMEM; } if (from_user) copy_from_user (new_buffer, buf+1, count-1); else memcpy (new_buffer, buf+1, count-1); if (bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, new_buffer, count-1) != 0) { kfree (new_buffer); return 0; } /* need to free new_buffer somehow... FIXME */ return count; case ACL_PKT: current_position = buf; ++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"); return bytes_sent; } /* free up the last buffer that this urb used */ if (urb->transfer_buffer != NULL) { kfree(urb->transfer_buffer); urb->transfer_buffer = NULL; } buffer_size = MIN (count, bluetooth->bulk_out_buffer_size); new_buffer = kmalloc (buffer_size, GFP_KERNEL); if (new_buffer == NULL) { err(__FUNCTION__" no more kernel memory..."); return bytes_sent; } if (from_user) copy_from_user(new_buffer, current_position, buffer_size); else memcpy (new_buffer, current_position, buffer_size); /* build up our urb */ FILL_BULK_URB (urb, bluetooth->dev, usb_sndbulkpipe(bluetooth->dev, bluetooth->bulk_out_endpointAddress), new_buffer, buffer_size, bluetooth_write_bulk_callback, bluetooth); urb->transfer_flags |= USB_QUEUE_BULK; /* send it down the pipe */ status = usb_submit_urb(urb); if (status) dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);#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; } return bytes_sent + 1; default : dbg(__FUNCTION__" - unsupported (at this time) write type"); } return 0;} 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;#ifdef BTBUGGYHARDWARE if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00) && (data[2] == 0x00) && (data[3] == 0x00)) { urb->actual_length = 0; 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 resubmitting read urb, error %d", result); return; }#endif dbg(__FUNCTION__); if (!bluetooth) { dbg(__FUNCTION__ " - bad bluetooth pointer, exiting"); goto exit; } if (urb->status) { dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status); goto exit; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -