Bonjour/Zerconf library

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbserialif.cpp Source File

usbserialif.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 /*
00025   USB-Serial device driver
00026   Donatien Garnier 2010
00027 */
00028 
00029 #include "usbserialif.h"
00030 #include "drv/usb/UsbEndpoint.h"
00031 
00032 #include "netCfg.h"
00033 #if NET_USB_SERIAL
00034 
00035 UsbEndpoint* pEpIn;
00036 UsbEndpoint* pEpOut;
00037 
00038 #define DONGLE_STATE_UNKNOWN 0
00039 #define DONGLE_STATE_CDFS    1
00040 #define DONGLE_STATE_SERIAL  2
00041 
00042 USB_INT08U dongleState;
00043 
00044 USB_INT32S SerialInit()
00045 {
00046   dongleState = DONGLE_STATE_UNKNOWN;
00047   Host_Init();               // Initialize the  host controller
00048   USB_INT32S rc = Host_EnumDev();       // Enumerate the device connected
00049   if (rc != OK)
00050   {
00051       fprintf(stderr, "Could not enumerate device: %d\n", rc);
00052       return rc;
00053   }
00054   return OK;
00055 }
00056 
00057 bool SerialHasToSwitch()
00058 {
00059   return (dongleState == DONGLE_STATE_CDFS);
00060 }
00061 
00062 uint16_t m_vid;
00063 uint16_t m_pid;
00064 
00065 USB_INT32S SerialSendMagic()
00066 {
00067   bool scsi = false;
00068   //Size 31
00069   const unsigned char magicHuawei[] = { 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0,    0, 0, 0, 0,    0, 0,    0x11, 0x6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00070   const unsigned char magicVoda[]   = { 0x55, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12, 0x01, 0, 0, 0, 0x80, 0, 0x06, 0x01, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00071   char* magic;
00072   USB_INT32S rc;
00073   if((m_vid == 0x12d1) && (m_pid == 0x1446))
00074   {
00075     PRINT_Log("\r\nHuawei magic packet sent.\r\n");
00076     magic = (char*) magicHuawei;
00077     scsi = true;
00078   }
00079   else if((m_vid == 0x12d1) && (m_pid == 0x1003))
00080   {
00081     PRINT_Log("\r\nHuawei magic control packet sent.\r\n");
00082     rc = Host_CtrlSend( 0 /*USB_TYPE_STANDARD | USB_RECIP_DEVICE*/, 0x03 /*USB_REQ_SET_FEATURE*/, 00000001, 0, 0, NULL);
00083   }
00084   else if(m_vid == 0x0af0)
00085   {
00086     PRINT_Log("\r\nVoda magic packet sent.\r\n");
00087     magic = (char*) magicVoda;  
00088     scsi = true;
00089   }
00090   else
00091   {
00092    return -1;
00093   }
00094   
00095   if(scsi)
00096   {
00097     rc = pEpOut->transfer((volatile USB_INT08U*)magic, 31);
00098     while(rc == PROCESSING)
00099     {
00100       rc = pEpOut->status();
00101     }  
00102   }
00103     
00104   delete pEpOut;
00105   pEpOut = NULL;
00106   return rc;
00107 }
00108 
00109 USB_INT32S SerialCheckVidPid()
00110 {
00111   volatile  USB_INT08U  *desc_ptr;
00112   desc_ptr     = TDBuffer;
00113   
00114   ser_int_found = 0;
00115   
00116   m_vid = *((USB_INT16U*)&desc_ptr[8]);
00117   m_pid = *((USB_INT16U*)&desc_ptr[10]);
00118   
00119   if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_DEVICE) {   
00120       PRINT_Log("\r\nLen = %02x\r\n",desc_ptr[0]);
00121       PRINT_Log("\r\nDesc code %02x\r\n",desc_ptr[1]);
00122       return (ERR_BAD_CONFIGURATION);
00123   }
00124   
00125   if( m_vid == 0x12d1 &&//Huawei : Change
00126       m_pid == 0x1446 )
00127   {
00128     PRINT_Log("\r\nHuawei device found in CDFS mode\r\n");
00129     dongleState = DONGLE_STATE_CDFS;
00130   }
00131   else if(  m_vid == 0x12d1 &&//Huawei : Change
00132             m_pid == 0x1001 )
00133   {
00134     PRINT_Log("\r\nHuawei device found in Serial mode\r\n");
00135     dongleState = DONGLE_STATE_SERIAL;
00136   }
00137   else if(  m_vid  == 0x0af0 &&//Voda?Qualcomm? : Change
00138             m_pid == 0x7501 )
00139   {
00140     PRINT_Log("\r\nVodafone K3760 found, checking mode...\r\n");
00141     dongleState = DONGLE_STATE_UNKNOWN;
00142   }
00143   else if(  m_vid  == 0x12d1 &&//Voda?Qualcomm? : Change
00144             m_pid == 0x1003 )
00145   {
00146     PRINT_Log("\r\nHuawei device found, checking mode...\r\n");
00147     dongleState = DONGLE_STATE_UNKNOWN;
00148   }
00149   else
00150   {
00151     PRINT_Log("\r\nDevice %04x : %04x found.\r\n",m_vid,m_pid);                
00152   }
00153   return OK;
00154 }
00155 
00156 USB_INT32S SerialParseConfig()
00157 {
00158     volatile  USB_INT08U  *desc_ptr;
00159 
00160     desc_ptr     = TDBuffer;
00161 
00162     if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) {    
00163         return (ERR_BAD_CONFIGURATION);
00164     }
00165     desc_ptr += desc_ptr[0];
00166     
00167     int epOut = 0;
00168     int epIn = 0;
00169 
00170     pEpOut = NULL;
00171     pEpIn = NULL;
00172     while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) {
00173 
00174         switch (desc_ptr[1]) {
00175             case USB_DESCRIPTOR_TYPE_INTERFACE: 
00176                  PRINT_Log("\r\nIf %02x:%02x:%02x.\r\n",desc_ptr[5],desc_ptr[6],desc_ptr[7]);
00177                  if (desc_ptr[5] == 0xFF &&             
00178                      desc_ptr[6] == 0xFF &&     
00179                      desc_ptr[7] == 0xFF ) {       
00180                    dongleState = DONGLE_STATE_SERIAL;
00181                  }
00182                  else 
00183                  if (desc_ptr[5] == 0xFF &&             
00184                      desc_ptr[6] == 0xFF &&     
00185                      desc_ptr[7] == 0xFF ) {       
00186                    dongleState = DONGLE_STATE_CDFS;
00187                  }
00188                  desc_ptr    += desc_ptr[0];                      /* Move to next descriptor start      */
00189                  break;
00190 
00191             case USB_DESCRIPTOR_TYPE_ENDPOINT:                        /* If it is an endpoint descriptor    */
00192                  PRINT_Log("\r\nEp %02x of size %d.\r\n", desc_ptr[2], (ReadLE16U(&desc_ptr[4]) ));
00193                  if ( SerialHasToSwitch() )
00194                  {
00195                    if( (dongleState == DONGLE_STATE_CDFS) && (pEpOut == NULL) /*desc_ptr[2] == 1*/) //EP 1
00196                    {
00197                      pEpOut = new UsbEndpoint((desc_ptr[2] & 0x7F), false, ReadLE16U(&desc_ptr[4]));
00198                    }
00199                                       /* Move to next descriptor start      */
00200                  }
00201                  desc_ptr += desc_ptr[0];  
00202                  break;
00203 
00204             default:                                 /* If the descriptor is neither interface nor endpoint */
00205                  desc_ptr += desc_ptr[0];                             /* Move to next descriptor start      */
00206                  break;
00207         }
00208     }
00209     if (dongleState == DONGLE_STATE_SERIAL) {
00210         PRINT_Log("Virtual Serial Port device %04x:%04x connected, vid=%d, pid=%d\n", m_vid, m_pid);
00211       if(m_vid==0x0af0) //Voda
00212       {
00213         pEpOut = new UsbEndpoint((0x0a & 0x7F), false, 64);
00214         pEpIn = new UsbEndpoint((0x8b & 0x7F), true, 64);
00215         PRINT_Log("Voda K3760\r\n");
00216       }
00217       else //if ( ( m_vid  == 0x12d1 ) && ( m_pid == 0x1003 ) )
00218       /*{*/
00219       if ( ( m_vid  == 0x12d1 ) && ( m_pid == 0x1003 ) )
00220       {
00221         pEpOut = new UsbEndpoint((0x02 & 0x7F), false, 64);
00222         pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64);
00223         PRINT_Log("Huawei E220\r\n");
00224       }
00225       else /*if (  m_vid  == 0x12d1 &&
00226             m_pid == 0x1001 )*/
00227       {
00228         pEpOut = new UsbEndpoint((0x01 & 0x7F), false, 64);
00229         pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64); 
00230         PRINT_Log("Huawei E1550\r\n");
00231       }   
00232         
00233         PRINT_Log("Virtual Serial Port device %04x:%04x connected\n", m_vid, m_pid);
00234         return (OK);
00235     }
00236     else if (dongleState == DONGLE_STATE_CDFS) {
00237         PRINT_Log("CDFS dongle connected, reset\n");
00238         return (OK);
00239     } else {
00240         PRINT_Log("Not a Virtual Serial Port device\n");
00241         return (ERR_NO_MS_INTERFACE);
00242     }
00243 }
00244 
00245 
00246 USB_INT32S SerialRx( volatile USB_INT08U* buf, USB_INT32U len )
00247 {
00248     USB_INT32S rc;
00249     rc = pEpIn->transfer(buf, len);
00250     return rc;
00251 }
00252 
00253 USB_INT32S SerialReceived()
00254 {
00255   return pEpIn->status();
00256 }
00257 
00258 USB_INT32S SerialTx( volatile USB_INT08U* buf, USB_INT32U len )
00259 {
00260     USB_INT32S rc;
00261     rc = pEpOut->transfer(buf, len);
00262   //  PRINT_Log("\r\nOut rc = %d\r\n",len);
00263     return rc;
00264 }
00265 
00266 USB_INT32S SerialTransmitted()
00267 {
00268   USB_INT32S rc = pEpOut->status();
00269 /*  if(rc>=0)
00270   {
00271       PRINT_Log("\r\nTransmitted %d\r\n",rc);
00272   }*/
00273   return rc;
00274 }
00275 
00276 USB_INT32S SerialReg(USB_INT16U vid, USB_INT16U pid) {return 0;}
00277 
00278 #endif