BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS

Dependencies:   FatFileSystem mbed

Fork of BTstack by Norimasa Okamoto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbbt.cpp Source File

usbbt.cpp

00001 #include "usbbt.h"
00002 //#define __DEBUG
00003 #include "mydbg.h"
00004 #include "Utils.h"
00005 
00006 usbbt::usbbt(int dongle)
00007     : m_dongle(dongle),m_pEpIntIn(NULL),m_pEpBulkIn(NULL),m_pEpBulkOut(NULL),
00008     m_int_seq(0),m_bulk_seq(0)
00009 {
00010 
00011 }
00012 
00013 int usbbt::setup(int timeout)
00014 {
00015     for(int i = 0; i < 2; i++) {
00016         m_pDev = m_pHost->getDeviceByClass(0xe0, m_dongle); 
00017         if (m_pDev || i > 0) {
00018             break;
00019         }
00020         UsbErr rc = Usb_poll();
00021         if (rc == USBERR_PROCESSING) {
00022             VERBOSE("%p USBERR_PROCESSING\n", this);
00023             return -1;
00024         }
00025     }
00026     DBG("m_pDev=%p\n", m_pDev);
00027     if (m_pDev == NULL) {
00028         VERBOSE("%p Bluetooth dongle(%d) NOT FOUND\n", this, m_dongle);
00029         return -1;
00030     }
00031     DBG_ASSERT(m_pDev);
00032 
00033     ParseConfiguration();
00034     return 0;
00035 }
00036 
00037 int usbbt::ParseConfiguration()
00038 {
00039   UsbErr rc;
00040   uint8_t ConfigDesc[9];
00041   int index = 0;
00042   DBG_ASSERT(m_pDev);
00043   rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
00044   DBG_ASSERT(rc == USBERR_OK);
00045   DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
00046   DBG_ASSERT(ConfigDesc[0] == 9);
00047   DBG_ASSERT(ConfigDesc[1] == 0x02);
00048   int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
00049   DBG("TotalLength: %d\n", wTotalLength);
00050   int bConfigValue = ConfigDesc[5];
00051   DBG_ASSERT(bConfigValue == 1);
00052   DBG("ConfigValue: %d\n", bConfigValue);
00053   VERBOSE("MaxPower: %d mA\n", ConfigDesc[8]*2);   
00054 
00055   uint8_t* buf = new uint8_t[wTotalLength];
00056   DBG_ASSERT(buf);
00057   rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
00058   DBG_ASSERT(rc == USBERR_OK);
00059   DBG_ASSERT(ConfigDesc[1] == 0x02);
00060   for (int pos = 0; pos < wTotalLength; pos += buf[pos]) {
00061       DBG_BYTES("CFG", buf+pos, buf[pos]);
00062       int type = buf[pos+1];
00063       if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04
00064         DBG("InterfaceNumber: %d\n", buf[pos+2]);
00065         DBG("AlternateSetting: %d\n", buf[pos+3]);
00066         DBG("NumEndpoint: %d\n", buf[pos+4]);
00067         VERBOSE("InterfaceClass: %02X\n", buf[pos+5]);
00068         VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]);
00069         VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]);
00070         DBG_ASSERT(buf[pos+6] == 0x01);
00071         DBG_ASSERT(buf[pos+7] == 0x01);
00072       } 
00073       if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) {
00074           DBG_ASSERT(buf[pos] == 7);
00075           uint8_t att = buf[pos+3];
00076           uint8_t ep = buf[pos+2];
00077           bool dir = ep & 0x80; // true=IN
00078           uint16_t size = LE16(buf+pos+4);
00079           DBG("EndpointAddress: %02X\n", ep);
00080           DBG("Attribute: %02X\n", att);
00081           DBG("MaxPacketSize: %d\n", size); 
00082           UsbEndpoint* pEp = new UsbEndpoint(m_pDev, ep, dir, att == 3 ? USB_INT : USB_BULK, size);
00083           DBG_ASSERT(pEp);
00084           if (att == 3) { // interrupt
00085               if (m_pEpIntIn == NULL) {
00086                   m_pEpIntIn = pEp;
00087               }
00088           } else if (att == 2) { // bulk
00089               if (dir) {
00090                   if (m_pEpBulkIn == NULL) {
00091                       m_pEpBulkIn = pEp;
00092                   }
00093               } else {
00094                   if (m_pEpBulkOut == NULL) {
00095                       m_pEpBulkOut = pEp;
00096                   }
00097               } 
00098           }
00099       }
00100       if (m_pEpIntIn && m_pEpBulkIn && m_pEpBulkOut) { // cut off
00101           break;
00102       }
00103   }
00104   delete[] buf;
00105   DBG_ASSERT(m_pEpIntIn);
00106   DBG_ASSERT(m_pEpBulkIn);
00107   DBG_ASSERT(m_pEpBulkOut);
00108   return 0;   
00109 }
00110 
00111 int usbbt::send_packet(uint8_t packet_type, uint8_t* packet, int size)
00112 {
00113     //DBG("\npacket_type=%d\n", packet_type);
00114     //DBG_HEX(packet, size);
00115 
00116     int rc;
00117     switch(packet_type){
00118         case HCI_COMMAND_DATA_PACKET:
00119             DBG_ASSERT(m_pDev);
00120             DBG_BYTES("\nCMD", packet, size);
00121             rc = m_pDev->controlSend(
00122                     USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE, 
00123                     0, 0, 0, packet, size);
00124             DBG_ASSERT(rc == USBERR_OK);
00125             return 0;
00126         case HCI_ACL_DATA_PACKET:
00127             DBG_ASSERT(m_pEpBulkOut);
00128             DBG_BYTES("\nACL", packet, size);
00129             rc = m_pEpBulkOut->transfer(packet, size);
00130             DBG_ASSERT(rc == USBERR_PROCESSING);
00131             while(m_pEpBulkOut->status() == USBERR_PROCESSING){
00132                 wait_us(1);
00133             }
00134             return 0;
00135         default:
00136             DBG_ASSERT(0);
00137             return -1;
00138     }
00139 }
00140 
00141 
00142 void usbbt::poll()
00143 {
00144     //DBG("m_int_seq=%d\n", m_int_seq);
00145     int rc, len;
00146     switch(m_int_seq) {
00147         case 0:
00148             m_int_seq++;
00149             break;
00150         case 1:
00151             rc = m_pEpIntIn->transfer(m_int_buf, sizeof(m_int_buf));
00152             DBG_ASSERT(rc == USBERR_PROCESSING);
00153             m_int_seq++;
00154             break;
00155         case 2:
00156             len = m_pEpIntIn->status();
00157             if (len == USBERR_PROCESSING) {
00158                 break;
00159             }
00160             if (len >= 0) {
00161                 //DBG("len=%d\n", len);
00162                 //DBG_HEX(m_int_buf, len);
00163                 onPacket(HCI_EVENT_PACKET, m_int_buf, len);
00164                 m_int_seq = 0;
00165                 break;
00166             }
00167             DBG_ASSERT(0);
00168             break;
00169     } 
00170 
00171     switch(m_bulk_seq) {
00172         case 0:
00173             m_bulk_seq++;
00174             break;
00175         case 1:
00176             rc = m_pEpBulkIn->transfer(m_bulk_buf, sizeof(m_bulk_buf));
00177             DBG_ASSERT(rc == USBERR_PROCESSING);
00178             m_bulk_seq++;
00179             break;
00180         case 2:
00181             len = m_pEpBulkIn->status();
00182             if (len == USBERR_PROCESSING) {
00183                 break;
00184             }
00185             if (len >= 0) {
00186                 //DBG("len=%d\n", len);
00187                 //DBG_HEX(m_bulk_buf, len);
00188                 onPacket(HCI_ACL_DATA_PACKET, m_bulk_buf, len);
00189                 m_bulk_seq = 0;
00190                 break;
00191             }
00192             DBG_ASSERT(0);
00193             break;
00194     } 
00195 }
00196 
00197 void usbbt::onPacket(uint8_t packet_type, uint8_t* packet, uint16_t size)
00198 {
00199   DBG("\npacket_type=%d packet=%p size=%d\n", packet_type, packet, size);
00200   DBG_HEX(packet, size);
00201 
00202   if(m_pCbItem && m_pCbMeth)
00203     (m_pCbItem->*m_pCbMeth)(packet_type, packet, size);
00204   else if(m_pCb)
00205     m_pCb(packet_type, packet, size);
00206 }
00207 
00208 void usbbt::setOnPacket( void (*pMethod)(uint8_t, uint8_t*, uint16_t) )
00209 {
00210   m_pCb = pMethod;
00211   m_pCbItem = NULL;
00212   m_pCbMeth = NULL;
00213 }
00214 
00215 void usbbt::clearOnPacket()
00216 {
00217   m_pCb = NULL;
00218   m_pCbItem = NULL;
00219   m_pCbMeth = NULL;
00220 }