+ btd.data = NULL;
+}
+
+int bt_HCI_command(struct usb_device *dev, int ogf, int ocf, u8 *parameters, u8 parmlength)
+{
+ int opcode;
+ static u8 buffer[0x103] ALIGNED(0x40);
+ opcode = (ocf&0x3FF) | ((ogf &0x3F)<<10);
+ buffer[0] = opcode&0xFF;
+ buffer[1] = opcode>>8;
+ buffer[2] = parmlength;
+
+ if(parameters && parmlength) {
+ memcpy (&buffer[3], parameters, parmlength);
+ } else {
+ parmlength = 0; //make sure we don't pass around junk
+ }
+ printf("paramlength(should not >0xFF !): %x\n", parmlength+3);
+
+ u8 buf[0x40];
+ memset(buf, 0, 0x40);
+ return usb_control_msg_pl(dev, 0x20, 0, 0, 0, parmlength+3, buf, 0, buffer);
+}
+
+
+int bt_HCI_recv_event(struct usb_device *dev, HCI_Event *ev)
+{
+ static u8 buffer[0x102] ALIGNED(0x40);
+ s8 res;
+
+ printf("WTF1\n");
+ res = usb_interrupt_read(dev, epi_it, buffer, sizeof(buffer), 0);
+ printf("WTF2\n");
+ ev->event_code = buffer[0];
+ ev->data_length = buffer[1];
+ ev->data = &buffer[2];
+ printf("HCI event [%d]: Code 0x%x, length %d, data:\n",res, ev->event_code, ev->data_length);
+ hexdump(ev->data, ev->data_length);
+ return res;
+}
+
+int bt_HCI_reset(struct usb_device *dev)
+{
+ return bt_HCI_command(dev, HCI_G_CONTROLLER, HCI_C_RESET, NULL, 0);
+}
+
+int bt_HCI_connect(struct usb_device *dev, u8 *bdaddr, u16 pkt_types, u8 psrm, u16 clkoff, u8 roleswitch)
+{
+ static u8 data[13];
+ int i;
+ for(i=0;i<6;i++)
+ data[i] = bdaddr[5-i];
+ data[6] = pkt_types & 0xFF;
+ data[7] = pkt_types >> 8;
+ data[8] = psrm;
+ data[9] = 0; //reserved
+ data[10] = clkoff & 0xFF;
+ data[11] = clkoff >> 8;
+ data[12] = roleswitch;
+
+ return bt_HCI_command(dev, HCI_G_LINKCONTROL, HCI_LC_CONNECT, data, sizeof(data));
+}
+
+int bt_HCI_send_ACL(struct usb_device *dev, u16 chnd, int pb, int bc, u16 length, u8 *data)
+{
+ static u8 buffer[0x100] ALIGNED(0x40);
+ printf("<ACL chnd %04x pb %d bc %d len %d data:\n",chnd,pb,bc,length);
+ hexdump(data,length);
+ chnd &= 0x0FFF;
+ chnd |= pb<<12;
+ chnd |= bc<<14;
+ memcpy(&buffer[4],data,length);
+ buffer[0] = chnd & 0xFF;
+ buffer[1] = chnd >> 8;
+ buffer[2] = length & 0xFF;
+ buffer[3] = length >>8;
+ return usb_bulk_write(dev, EP_ACL_OUT, buffer, length+4, 0);
+}
+
+int bt_HCI_recv_ACL(struct usb_device *dev, HCI_ACL_Data *acl)
+{
+ static u8 buffer[0x40] ALIGNED(0x40);
+ int res;
+
+ res = usb_bulk_read(dev, EP_ACL_IN, buffer, sizeof(buffer), 0);
+ acl->chnd = buffer[0] | (buffer[1]<<8);
+ acl->pb = (acl->chnd & 0x3000)>>12;
+ acl->bc = (acl->chnd & 0xC000)>>14;
+ acl->chnd &= 0x0FFF;
+ acl->data_length = buffer[2] | (buffer[3]<<8);
+ acl->data = &buffer[4];
+ printf(">ACL [%d]: chnd %04x pb %d bc %d len %d data:\n",res,acl->chnd, acl->pb, acl->bc, acl->data_length);
+ hexdump(acl->data, acl->data_length);
+ return res;
+}
+
+int bt_HCI_recv_ACL_async(struct usb_device *dev, HCI_ACL_Data *acl)
+{
+ static u8 buffer[0x40] ALIGNED(0x40);
+ int res;
+
+ res = usb_bulk_read(btd.data, EP_ACL_IN, buffer, sizeof(buffer), 0);
+
+ acl->chnd = buffer[0] | (buffer[1]<<8);
+ acl->pb = (acl->chnd & 0x3000)>>12;
+ acl->bc = (acl->chnd & 0xC000)>>14;
+ acl->chnd &= 0x0FFF;
+ acl->data_length = buffer[2] | (buffer[3]<<8);
+ acl->data = &buffer[4];
+ printf(">ACL [%d]: chnd %04x pb %d bc %d len %d data:\n",res,acl->chnd, acl->pb, acl->bc, acl->data_length);
+ hexdump(acl->data, acl->data_length);
+ return res;
+}
+
+int bt_L2CAP_send(struct usb_device *dev, u16 chnd, u16 cid, u16 length, u8 *data)
+{
+ static u8 buffer[0x1000] ALIGNED(0x20);
+ memcpy(&buffer[4],data,length);
+ buffer[0] = length & 0xFF;
+ buffer[1] = length >> 8;
+ buffer[2] = cid & 0xFF;
+ buffer[3] = cid >> 8;
+ return bt_HCI_send_ACL(dev, chnd, 2, 0, length+4, buffer);