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 UsbDevice.cpp Source File

UsbDevice.cpp

00001 
00002 /*
00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
00004  
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011  
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014  
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 */
00023 
00024 #include "UsbDevice.h"
00025 //#define __DEBUG
00026 #include "mydbg.h"
00027 
00028 UsbDevice::UsbDevice( UsbHostMgr* pMgr, int hub, int port, int addr ) : m_pControlEp(NULL), /*m_controlEp( this, 0x00, false, USB_CONTROL, 8 ),*/
00029 m_pMgr(pMgr), m_connected(false), m_enumerated(false), m_hub(hub), m_port(port), m_addr(addr), m_refs(0),
00030 m_vid(0), m_pid(0)
00031 {
00032     m_DeviceClass    = 0x00;
00033     m_InterfaceClass = 0x00;
00034 }
00035 
00036 UsbDevice::~UsbDevice()
00037 {
00038     DBG_ASSERT(0);
00039 
00040   if(m_pControlEp)
00041     delete m_pControlEp;
00042 }
00043 
00044 UsbErr UsbDevice::enumerate()
00045 {
00046   VERBOSE("Hub: %d Port: %d\n", m_hub, m_port);
00047   UsbErr rc;
00048   DBG("%p m_hub=%d m_port=%d\n", this, m_hub, m_port);
00049   DBG_ASSERT(m_pMgr);
00050   m_pMgr->resetPort(m_hub, m_port);
00051 
00052   wait_ms(400);
00053 
00054   uint8_t temp[8];
00055   DBG_ASSERT(m_pControlEp == NULL);   
00056   m_pControlEp = new UsbEndpoint( this, 0x00, false, USB_CONTROL, sizeof(temp), 0 );
00057   DBG_ASSERT(m_pControlEp);
00058   //EDCtrl->Control = 8 << 16;/* Put max pkt size = 8              */
00059   /* Read first 8 bytes of device desc */
00060   DBG_ASSERT(sizeof(temp) >= 8);
00061   //rc = controlReceive(
00062   //    USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, 
00063   //    (USB_DESCRIPTOR_TYPE_DEVICE << 8) |(0), 0, temp, sizeof(temp));
00064   //DBG_ASSERT(rc == USBERR_OK);
00065   rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, temp, sizeof(temp));
00066   if (rc != USBERR_OK) {
00067       DBG("rc=%d\n", rc);
00068       DBG_ASSERT(rc == USBERR_OK);
00069       return rc;
00070   }
00071   DBG_ASSERT(rc == USBERR_OK);
00072   DBG_BYTES("DeviceDescriptor first 8 bytes", temp, sizeof(temp));
00073   DBG_ASSERT(temp[0] == 18);   // bLength
00074   DBG_ASSERT(temp[1] == 0x01); // bDescriptType
00075   if (rc)
00076   {
00077     DBG("RC=%d",rc);
00078     return (rc);
00079   }
00080   uint8_t bMaxPacketSize = temp[7];
00081   DBG_ASSERT(bMaxPacketSize >= 8);
00082   DBG("Got descriptor, max ep size is %d\n", bMaxPacketSize);
00083   
00084   m_pControlEp->updateSize(bMaxPacketSize); /* Get max pkt size of endpoint 0    */
00085   rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS, m_addr, 0, NULL, 0); /* Set the device address to m_addr       */
00086   DBG_ASSERT(rc == USBERR_OK);
00087   if (rc)
00088   {
00089   //  PRINT_Err(rc);
00090     return (rc);
00091   }
00092   wait_ms(2);
00093   //EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */
00094   
00095   //Update address
00096   m_pControlEp->updateAddr(m_addr);
00097   DBG("Ep addr is now %d", m_addr);
00098   /**/
00099   
00100   //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 17); //Read full device descriptor
00101   //rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, 
00102   //    (USB_DESCRIPTOR_TYPE_DEVICE << 8)|(0), 0, 
00103   //    m_controlDataBuf, 17);
00104   uint8_t DeviceDesc[18];
00105   rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, DeviceDesc, sizeof(DeviceDesc));
00106   DBG_ASSERT(rc == USBERR_OK);
00107   DBG_BYTES("DeviceDescriptor", DeviceDesc, sizeof(DeviceDesc));
00108   DBG_ASSERT(DeviceDesc[0] == 18);
00109   DBG_ASSERT(DeviceDesc[1] == 0x01);
00110   DBG_ASSERT(DeviceDesc[17] == 1); // bNumConfiguration
00111   if (rc)
00112   {
00113     //PRINT_Err(rc);
00114     return (rc);
00115   }
00116 
00117   /*
00118   rc = SerialCheckVidPid();
00119   if (rc != OK) {
00120     PRINT_Err(rc);
00121     return (rc);
00122   }
00123   */
00124   /**/
00125   m_DeviceClass = DeviceDesc[4];
00126   VERBOSE("DeviceClass: %02X\n", m_DeviceClass);
00127  
00128   m_vid = *((uint16_t*)&DeviceDesc[8]);
00129   m_pid = *((uint16_t*)&DeviceDesc[10]);
00130   VERBOSE("Vender: %04X\n", m_vid);
00131   VERBOSE("Product: %04X\n", m_pid);
00132   int iManufacture = DeviceDesc[14];
00133   if (iManufacture) {
00134     char str[64];
00135     rc = GetString(iManufacture, str, sizeof(str)); 
00136     DBG_ASSERT(rc == USBERR_OK);
00137     VERBOSE("Manufacture: %s\n", str);
00138   }
00139   int iProduct = DeviceDesc[15];
00140   if (iProduct) {
00141     char str[64];
00142     rc = GetString(iProduct, str, sizeof(str)); 
00143     DBG_ASSERT(rc == USBERR_OK);
00144     VERBOSE("Product: %s\n", str);
00145   }
00146   if (DeviceDesc[4] == 0x09) { // Hub
00147       return hub_init();
00148   }
00149   
00150   uint8_t ConfigDesc[9];
00151   int index = 0;
00152   rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
00153   DBG_ASSERT(rc == USBERR_OK);
00154   DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
00155   DBG_ASSERT(ConfigDesc[0] == 9);
00156   DBG_ASSERT(ConfigDesc[1] == 0x02);
00157   int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
00158   DBG("TotalLength: %d\n", wTotalLength);
00159   int bConfigValue = ConfigDesc[5];
00160   DBG_ASSERT(bConfigValue == 1);
00161   DBG("ConfigValue: %d\n", bConfigValue);
00162   DBG("MaxPower: %d mA\n", ConfigDesc[8]*2);   
00163 
00164   uint8_t* buf = new uint8_t[wTotalLength];
00165   rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
00166   DBG_ASSERT(rc == USBERR_OK);
00167   DBG_ASSERT(ConfigDesc[1] == 0x02);
00168   int pos = 0;
00169   while(pos < wTotalLength) {
00170       DBG_BYTES("", buf+pos, buf[pos]);
00171       if (buf[pos+1] == 4) { // interface ?
00172           m_InterfaceClass = buf[pos+5];
00173           VERBOSE("InterfaceClass: %02X\n", m_InterfaceClass);
00174           break;
00175       }
00176       pos += buf[pos];
00177   }
00178   delete[] buf;
00179   
00180   rc = setConfiguration(1);
00181   DBG_ASSERT(rc == USBERR_OK);
00182   if (rc)
00183   {
00184    // PRINT_Err(rc);
00185    return rc;
00186   }
00187   wait_ms(100);/* Some devices may require this delay */
00188   
00189   m_enumerated = true;
00190   return USBERR_OK;
00191 }
00192 
00193 bool UsbDevice::connected()
00194 {
00195   return m_connected;
00196 }
00197 
00198 bool UsbDevice::enumerated()
00199 {
00200   return m_enumerated;
00201 }
00202 
00203 int UsbDevice::getPid()
00204 {
00205   return m_pid;
00206 }
00207 
00208 int UsbDevice::getVid()
00209 {
00210   return m_vid;
00211 }
00212 #if 0
00213 UsbErr UsbDevice::getConfigurationDescriptor(int config, uint8_t** pBuf)
00214 {
00215   DBG_ASSERT(m_controlDataBuf);
00216   //For now olny one config
00217   *pBuf = m_controlDataBuf;
00218   return USBERR_OK;
00219 }
00220 
00221 UsbErr UsbDevice::getInterfaceDescriptor(int config, int item, uint8_t** pBuf)
00222 {
00223   DBG_ASSERT(m_controlDataBuf);
00224   byte* desc_ptr = m_controlDataBuf;
00225 
00226 /*  if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION)
00227   {    
00228     return USBERR_BADCONFIG;
00229   }*/
00230   DBG_ASSERT(m_controlDataBuf);
00231   if(item>=m_controlDataBuf[4])//Interfaces count
00232     return USBERR_NOTFOUND;
00233   
00234   desc_ptr += desc_ptr[0];
00235   
00236   *pBuf = NULL;
00237   
00238   while (desc_ptr < m_controlDataBuf + *((uint16_t*)&m_controlDataBuf[2]))
00239   {
00240 
00241     switch (desc_ptr[1]) {
00242       case USB_DESCRIPTOR_TYPE_INTERFACE: 
00243         if(desc_ptr[2] == item)
00244         {
00245           *pBuf = desc_ptr;
00246           return USBERR_OK;
00247         }
00248         desc_ptr += desc_ptr[0]; // Move to next descriptor start
00249         break;
00250     }
00251       
00252   }
00253   
00254   if(*pBuf == NULL)
00255     return USBERR_NOTFOUND;
00256     
00257   return USBERR_OK;
00258 }
00259 #endif
00260 
00261 UsbErr UsbDevice::setConfiguration(int config)
00262 {
00263   DBG("config=%d\n", config);
00264   DBG_ASSERT(config == 1);    
00265   UsbErr rc = controlSend(
00266           USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, // 0x00 
00267           SET_CONFIGURATION, config, 0, 0, 0);
00268   return rc;
00269 }
00270 
00271 UsbErr UsbDevice::controlSend(byte requestType, byte request, word value, word index, const byte* buf, int len)
00272 {
00273   UsbErr rc;
00274   fillControlBuf(requestType, request, value, index, len);
00275   DBG_ASSERT(m_pControlEp);
00276   m_pControlEp->setNextToken(TD_SETUP);
00277   rc = m_pControlEp->transfer(m_controlBuf, 8);
00278   while(m_pControlEp->status() == USBERR_PROCESSING);
00279   rc = (UsbErr) MIN(0, m_pControlEp->status());
00280   if(rc)
00281     return rc;
00282   if(len)
00283   {
00284     m_pControlEp->setNextToken(TD_OUT);
00285     rc = m_pControlEp->transfer((byte*)buf, len);
00286     while(m_pControlEp->status() == USBERR_PROCESSING);
00287     rc = (UsbErr) MIN(0, m_pControlEp->status());
00288     if(rc)
00289       return rc;
00290   }
00291   m_pControlEp->setNextToken(TD_IN);
00292   rc = m_pControlEp->transfer(NULL, 0);
00293   while(m_pControlEp->status() == USBERR_PROCESSING);
00294   rc = (UsbErr) MIN(0, m_pControlEp->status());
00295   if(rc)
00296     return rc;
00297   return USBERR_OK;
00298 }
00299 
00300 UsbErr UsbDevice::controlReceive(byte requestType, byte request, word value, word index, const byte* buf, int len)
00301 {
00302   DBG("buf=%p len=%d\n", buf, len);
00303   UsbErr rc;
00304   fillControlBuf(requestType, request, value, index, len);
00305   DBG_ASSERT(m_pControlEp);
00306   m_pControlEp->setNextToken(TD_SETUP);
00307   rc = m_pControlEp->transfer(m_controlBuf, 8);
00308   while(m_pControlEp->status() == USBERR_PROCESSING);
00309   rc = (UsbErr) MIN(0, m_pControlEp->status());
00310   if(rc)
00311     return rc;
00312   if(len)
00313   {
00314     m_pControlEp->setNextToken(TD_IN);
00315     rc = m_pControlEp->transfer( (byte*) buf, len);
00316     while(m_pControlEp->status() == USBERR_PROCESSING);
00317     rc = (UsbErr) MIN(0, m_pControlEp->status());
00318     if(rc)
00319       return rc;
00320   }
00321   m_pControlEp->setNextToken(TD_OUT);
00322   rc = m_pControlEp->transfer(NULL, 0);
00323   while(m_pControlEp->status() == USBERR_PROCESSING);
00324   rc = (UsbErr) MIN(0, m_pControlEp->status());
00325   if(rc)
00326     return rc;
00327   return USBERR_OK;
00328 }
00329 
00330 UsbErr UsbDevice::GetDescriptor(int type, int index, const byte* buf, int len)
00331 {
00332   DBG("type=%02X\n", type);
00333   return controlReceive(
00334       USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, 
00335       (type << 8) |(index), 0, buf, len);
00336 
00337 }
00338 
00339 UsbErr UsbDevice::GetString(int index, char* buf, int len)
00340 {
00341   DBG("index=%d buf=%p len=%d\n", index, buf, len);
00342   DBG_ASSERT(index >= 1);
00343   uint8_t temp[4];
00344   UsbErr rc;
00345   rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, 0, temp, sizeof(temp));
00346   DBG_ASSERT(rc == USBERR_OK);
00347   DBG_BYTES("LANG_ID", temp, sizeof(temp));
00348   DBG_ASSERT(temp[0] == 4);
00349   DBG_ASSERT(temp[1] == 0x03);
00350   
00351   rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp, 2);
00352   DBG_ASSERT(rc == USBERR_OK);
00353   DBG_BYTES("length check", temp, 2);
00354   if (temp[0] == 0x00 && temp[1] == 0x00) { // for pl2303
00355       if (len > 0) {
00356           strcpy(buf, "");
00357       }
00358       return rc;
00359   }
00360   DBG_ASSERT(temp[1] == 0x03);
00361   int temp_len = temp[0];
00362     
00363   uint8_t* temp_buf = new uint8_t[temp_len];
00364   DBG_ASSERT(temp_buf);
00365   rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp_buf, temp_len);
00366   DBG_ASSERT(rc == USBERR_OK);
00367   temp_len = temp_buf[0];
00368   DBG_HEX(temp_buf, temp_len);
00369   int i = 0;
00370   for(int pos = 2; pos < temp_len; pos+= 2) {
00371     buf[i++] = temp_buf[pos];
00372     DBG_ASSERT(i < len-1);
00373   }
00374   buf[i] = '\0';
00375   delete[] temp_buf;
00376   return rc;
00377 }
00378 
00379 UsbErr UsbDevice::SetInterfaceAlternate(int interface, int alternate)
00380 {
00381     UsbErr rc = controlSend(
00382               USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE, 
00383               SET_INTERFACE, alternate, interface, NULL, 0);
00384     return rc;
00385 }
00386 
00387 void UsbDevice::fillControlBuf(byte requestType, byte request, word value, word index, int len)
00388 {
00389 #ifdef __BIG_ENDIAN
00390   #error "Must implement BE to LE conv here"
00391 #endif
00392   m_controlBuf[0] = requestType;
00393   m_controlBuf[1] = request;
00394   //We are in LE so it's fine
00395   *((word*)&m_controlBuf[2]) = value;
00396   *((word*)&m_controlBuf[4]) = index;
00397   *((word*)&m_controlBuf[6]) = (word) len;
00398 }
00399 
00400