bleh, tmp commit... bt origin/bt
authorBernhard Urban <lewurm@gmx.net>
Tue, 29 Sep 2009 14:56:48 +0000 (16:56 +0200)
committerBernhard Urban <lewurm@gmx.net>
Tue, 29 Sep 2009 15:34:34 +0000 (17:34 +0200)
usb/core/core.c
usb/core/usb.c
usb/core/usb.h
usb/drivers/bt.c
usb/usbspec/usb11spec.h

index 4ab945cd9accebc263479217ce06897598d04ecb..91d9c1fcb0c2277e05142ffb43a48e96827c4562 100644 (file)
@@ -121,7 +121,7 @@ struct usb_device *usb_add_device(u8 lowspeed, u32 reg)
                return (void*) -1;
        }
 
-#define WTF
+//#define WTF
 #ifdef WTF
        volatile u8 wzf = 11;
        if(0 == wzf) {
@@ -379,7 +379,13 @@ u16 usb_submit_irp(struct usb_irp *irp)
                free(td);
 
                /* check bit 7 of bmRequestType */
-               if (bmRequestType & 0x80) { 
+               if (bmRequestType & 0x80 || bmRequestType & 0x20) { 
+                       if(bmRequestType & 0x20) {
+                               /*
+                               restlength -= 8;
+                               */
+                               td_buf_ptr += 8;
+                       }
                        /* schleife die die tds generiert */
                        while (runloop && (restlength > 0)) {
                                td = usb_create_transfer_descriptor(irp);
@@ -394,7 +400,7 @@ u16 usb_submit_irp(struct usb_irp *irp)
                                /* move pointer for next packet */
                                td_buf_ptr += irp->epsize;
 
-                               td->pid = USB_PID_IN;
+                               td->pid = bmRequestType & 0x80 ? USB_PID_IN : USB_PID_OUT;
                                td->togl = togl;
                                togl = togl ? 0 : 1;
 
@@ -411,7 +417,7 @@ u16 usb_submit_irp(struct usb_irp *irp)
                                hcdi_enqueue(td, irp->dev->ohci);
 
                                /* pruefe ob noch weitere Pakete vom Device abgeholt werden muessen */
-                               restlength = restlength - irp->epsize;
+                               restlength -= irp->epsize;
                                free(td);
                        }
                }
index c98681ba014d4ca1aa379a934693d54a41614421..34a85d15c63b3cc32a26d773f4fc5c55299a8405 100644 (file)
@@ -117,6 +117,12 @@ s8 usb_reset(struct usb_device *dev)
  */
 s8 usb_control_msg(struct usb_device *dev, u8 requesttype, u8 request,
                u16 value, u16 index, u16 length, u8 *buf, u16 timeout)
+{
+       return usb_control_msg_pl(dev, requesttype, request, value, index, length, buf, timeout, NULL);
+}
+
+s8 usb_control_msg_pl(struct usb_device *dev, u8 requesttype, u8 request,
+               u16 value, u16 index, u16 length, u8 *buf, u16 timeout, u8 *payload)
 {
        static struct usb_irp irp;
        memset(&irp, 0, sizeof(struct usb_irp));
@@ -136,6 +142,12 @@ s8 usb_control_msg(struct usb_device *dev, u8 requesttype, u8 request,
        buf[6]=(u8)(length);
        buf[7]=(u8)(length >> 8);
 
+       if(payload) {
+               u16 i;
+               for(i=8; (i-8)<length; i++)
+                       buf[i] = payload[i-8];
+       }
+
        irp.buffer = buf;
        irp.len = length;
        irp.timeout = timeout;
@@ -330,7 +342,7 @@ s8 usb_set_altinterface(struct usb_device *dev, u8 alternate)
        return 0;
 }
 
-static s8 usb_gen_rw(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout, u8 type) {
+static s8 usb_gen_rw(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout, u8 type) {
        static struct usb_irp irp;
        memset(&irp, 0, sizeof(struct usb_irp));
 
@@ -351,7 +363,7 @@ static s8 usb_gen_rw(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout
 /**
  * Write to an a bulk endpoint.
  */
-s8 usb_bulk_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
+s8 usb_bulk_write(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout)
 {
        return usb_gen_rw(dev, ep, buf, size, timeout, USB_BULK);
 }
@@ -359,7 +371,7 @@ s8 usb_bulk_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
 /**
  * Read from an bulk endpoint.
  */
-s8 usb_bulk_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
+s8 usb_bulk_read(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout)
 {
        return usb_gen_rw(dev, ep|0x80, buf, size, timeout, USB_BULK);
 }
@@ -369,7 +381,7 @@ s8 usb_bulk_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
 /**
  * Write to an interrupt endpoint.
  */
-s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
+s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout)
 {
        return usb_gen_rw(dev, ep, buf, size, timeout, USB_INTR);
 }
@@ -377,7 +389,7 @@ s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeo
 /**
  * Read from an interrupt endpoint.
  */
-s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
+s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout)
 {
        return usb_gen_rw(dev, ep|0x80, buf, size, timeout, USB_INTR);
 }
@@ -388,7 +400,7 @@ s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeou
 /**
  * Write to an isochron endpoint.
  */
-s8 usb_isochron_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
+s8 usb_isochron_write(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout)
 {
 
        return 0;
@@ -397,7 +409,7 @@ s8 usb_isochron_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeou
 /**
  * Read from an isochron endpoint.
  */
-s8 usb_isochron_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
+s8 usb_isochron_read(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout)
 {
 
 
index d5cb53b783cb1b4ad2da2440d59107e79435f700..43f155599dd11960b5a70166c51d3241e9df9378 100644 (file)
@@ -70,6 +70,7 @@ s8 usb_reset(struct usb_device *dev);
 
 /******************* Control Transfer **********************/
 s8 usb_control_msg(struct usb_device *dev, u8 requesttype, u8 request, u16 value, u16 index, u16 length, u8 *buf, u16 timeout);
+s8 usb_control_msg_pl(struct usb_device *dev, u8 requesttype, u8 request, u16 value, u16 index, u16 length, u8 *buf, u16 timeout, u8 *payload);
 s8 usb_get_descriptor(struct usb_device *dev, u8 type, u8 index, u8 *buf, u8 size);
 s8 usb_get_desc_dev_simple(struct usb_device *dev);
 s8 usb_get_desc_dev(struct usb_device *dev);
@@ -86,17 +87,17 @@ s8 usb_set_altinterface(struct usb_device *dev, u8 alternate);
 
 
 /******************* Bulk Transfer **********************/
-s8 usb_bulk_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
-s8 usb_bulk_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
+s8 usb_bulk_write(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout);
+s8 usb_bulk_read(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout);
 
 
 /******************* Interrupt Transfer **********************/
-s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
-s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
+s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout);
+s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout);
 
 
 /******************* Isochron Transfer **********************/
-s8 usb_isochron_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
-s8 usb_isochron_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
+s8 usb_isochron_write(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout);
+s8 usb_isochron_read(struct usb_device *dev, u8 ep, u8 *buf, u16 size, u8 timeout);
 
 #endif //_USB_H_
index 433182f071e524b67f678ded4dcf39e5022a4821..224f0d649e059b7ae63e0bf189a4de8482607138 100644 (file)
@@ -17,7 +17,57 @@ Copyright (C) 2009     Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
 
 #include "bt.h"
 
-struct usb_driver btdriv = {
+#define USB_CREQ_D2H 0x80
+#define USB_CREQ_STANDARD 0x00
+#define USB_CREQ_VENDOR 0x40
+#define USB_CREQ_INTERFACE 0x01
+#define USB_CREQ_ENDPOINT 0x02
+#define USB_CREQ_OTHER 0x03
+
+#define SWAB16(x) ((((x)&0xFF)<<8)|((x)>>8))
+#define EP_CONTROL 0x00
+#define EP_EVENTS 0x81
+#define EP_ACL_OUT 0x02
+#define EP_ACL_IN 0x82
+
+#define HCI_G_LINKCONTROL 1
+#define HCI_G_LINKPOLICY 2
+#define HCI_G_CONTROLLER 3
+#define HCI_G_INFORMATIONAL 4
+#define HCI_G_STATUS 5
+#define HCI_G_TESTING 6
+
+#define HCI_C_RESET 0x0003
+#define HCI_LC_CONNECT 0x0005
+
+#define HCI_PKTTYPE_DM1 0x0008
+#define HCI_PSRM_R2 2
+#define HCI_CLKOFF_INVALID 0
+#define HCI_NO_ROLESWITCH 0
+
+#define HCI_EV_CONNECTION_COMPLETE 0x03
+
+
+typedef struct {
+       u8 event_code;
+       u8 data_length;
+       u8 *data;
+} HCI_Event;
+
+typedef struct {
+       u16 chnd;
+       int pb,bc;
+       u16 data_length;
+       u8 *data;
+} HCI_ACL_Data;
+
+int bt_HCI_reset(struct usb_device *dev);
+int bt_HCI_recv_event(struct usb_device *dev, HCI_Event *ev);
+int bt_HCI_connect(struct usb_device *dev, u8 *bdaddr, u16 pkt_types, u8 psrm, u16 clkoff, u8 roleswitch);
+int bt_L2CAP_send(struct usb_device *dev, u16 chnd, u16 cid, u16 length, u8 *data);
+int bt_HCI_recv_ACL_async(struct usb_device *dev, HCI_ACL_Data *acl);
+
+struct usb_driver btd = {
        .name     = "bt",
        .probe  = usb_bt_probe,
        .check  = usb_bt_check,
@@ -30,22 +80,84 @@ u8 epi_it, epi_bk, epo_bk;
 
 void usb_bt_init()
 {
-       usb_register_driver(&btdriv);
+       usb_register_driver(&btd);
 
-       usb_set_configuration(btdriv.data, btdriv.data->conf->bConfigurationValue);
-       printf("get_conf: %d\n", usb_get_configuration(btdriv.data));
+       usb_set_configuration(btd.data, btd.data->conf->bConfigurationValue);
+       printf("get_conf: %d\n", usb_get_configuration(btd.data));
 
-       u8 buf[8];
+       u8 buf[128];
        memset(buf, 0, 8);
-       usb_control_msg(btdriv.data, 0x01, SET_INTERFACE, 0, 1, 0, buf, 0);
+       usb_control_msg(btd.data, 0x01, SET_INTERFACE, 0, 1, 0, buf, 0);
+
+       epi_it = btd.data->conf->intf->endp->bEndpointAddress & 0x7F;
+       epi_bk = btd.data->conf->intf->endp->next->bEndpointAddress & 0x7F;
+       epo_bk = btd.data->conf->intf->endp->next->next->bEndpointAddress & 0x7F;
+
+       btd.data->epSize[1] = btd.data->conf->intf->endp->wMaxPacketSize;
+       btd.data->epSize[2] = btd.data->conf->intf->endp->next->wMaxPacketSize;
+       btd.data->epSize[3] = btd.data->conf->intf->endp->next->next->wMaxPacketSize;
+       
+
+       /* shit */
+       // Bluetooth HCI reset command
+       u8 puf[8] ALIGNED(0x40);
+       memset(buf, 0, sizeof(buf));
 
-       epi_it = btdriv.data->conf->intf->endp->bEndpointAddress & 0x7F;
-       epi_bk = btdriv.data->conf->intf->endp->next->bEndpointAddress & 0x7F;
-       epo_bk = btdriv.data->conf->intf->endp->next->next->bEndpointAddress & 0x7F;
+       memset(puf, 0, sizeof(puf));
+       memcpy(puf,"\x03\x0c\x00",3);
+       // Bluetooth request to control endpoint
+       u16 ret = usb_control_msg_pl(btd.data, 0x20, 0, 0, 0, 3, buf, 0, puf);
+       printf("request control endpoint:\n");
+       hexdump((void*) buf, 11);
 
-       btdriv.data->epSize[1] = btdriv.data->conf->intf->endp->wMaxPacketSize;
-       btdriv.data->epSize[2] = btdriv.data->conf->intf->endp->next->wMaxPacketSize;
-       btdriv.data->epSize[3] = btdriv.data->conf->intf->endp->next->next->wMaxPacketSize;
+       ret = bt_HCI_reset(btd.data);
+       printf("HCI reset to *dev returned %d\n",ret);
+
+       HCI_Event hciev;
+       HCI_ACL_Data acldat;
+       ret = bt_HCI_recv_event(btd.data, &hciev);
+       printf("after recv event\n");
+
+       ret = bt_HCI_connect(btd.data, (u8*)"\x00\x17\xAB\x33\x37\x65", HCI_PKTTYPE_DM1, HCI_PSRM_R2, HCI_CLKOFF_INVALID, HCI_NO_ROLESWITCH);
+       printf("HCI connect to returned %d\n",ret);
+       ret = bt_HCI_recv_event(btd.data, &hciev);
+       while(1) {
+               ret = bt_HCI_recv_event(btd.data, &hciev);
+               if(hciev.event_code == HCI_EV_CONNECTION_COMPLETE) {
+                       break;
+               }
+       }
+       if(hciev.data[0]) {
+               printf("Connection failed!\n");
+       } else {
+               u16 chnd;
+               chnd = hciev.data[1] | (hciev.data[2]<<8);
+               printf("Connection successful! chnd: 0x%04x\n",chnd);
+               ret = bt_L2CAP_send(btd.data, chnd, 1, 8, (u8*)"\x02\x01\x04\x00\x13\x00\x41\x00");
+               printf("L2CAP send to returned %d\n", ret);
+               bt_HCI_recv_ACL_async(btd.data, &acldat);
+               bt_HCI_recv_ACL_async(btd.data, &acldat);
+
+               u8 dcid[256];
+               u8 l2pkt[256];
+               memset(dcid, 0, 256);
+               memset(l2pkt, 0, 256);
+
+               memcpy(&dcid, &acldat.data[8], 2);
+               memcpy(l2pkt, "\x04\x01\x04\x00\xAA\xAA\x00\x00", 8);
+               memcpy(&l2pkt[4], &dcid, 2);
+               ret = bt_L2CAP_send(btd.data, chnd, 1, 8, l2pkt);
+               printf("L2CAP send to returned %d\n", ret);
+               bt_HCI_recv_ACL_async(btd.data, &acldat);
+               bt_HCI_recv_ACL_async(btd.data, &acldat);
+               memcpy(l2pkt, "\x05\x01\x06\x00\xAA\xAA\x00\x00\x00\x00", 10);
+               memcpy(&l2pkt[4], &dcid, 2);
+               ret = bt_L2CAP_send(btd.data, chnd, 1, 10, l2pkt);
+               printf("L2CAP send to %d returned %d\n", btd.data, ret);
+               while(1) {
+                       bt_HCI_recv_ACL_async(btd.data, &acldat);
+               }
+       }
 }
 
 void usb_bt_probe()
@@ -60,7 +172,7 @@ void usb_bt_probe()
                }
 
                if(dev->idVendor == 0x057e && dev->idProduct == 0x0305) {
-                       btdriv.data = dev;
+                       btd.data = dev;
                }
 
                iterator=iterator->next;
@@ -73,11 +185,133 @@ void usb_bt_check()
 
 u8 usb_bt_inuse()
 {
-       return btdriv.data ? 1 : 0;
+       return btd.data ? 1 : 0;
 }
 
 void usb_bt_remove()
 {
-       btdriv.data = NULL;
+       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);
 }
 
index ba36df9a282064b873a144e5fa609d2cba2b06ba..9f9552662e6664c58f5e829f977b2a32fa3812f7 100644 (file)
@@ -112,6 +112,7 @@ struct usb_device_request_t
        unsigned short wValue;
        unsigned short wIndex;  
        unsigned short wLength;
+       u8 *payload;
 };
 
 /*-------------------------------------------