modded version Dirk-Willem van Gulik's Bonjour/Zerconf library http://mbed.org/users/dirkx/code/Bonjour/
Fork of Bonjour by
Diff: drv/serial/usb/usbserialif.cpp
- Revision:
- 0:355018f44c9f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/serial/usb/usbserialif.cpp Wed Jul 21 19:25:56 2010 +0000 @@ -0,0 +1,278 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* + USB-Serial device driver + Donatien Garnier 2010 +*/ + +#include "usbserialif.h" +#include "drv/usb/UsbEndpoint.h" + +#include "netCfg.h" +#if NET_USB_SERIAL + +UsbEndpoint* pEpIn; +UsbEndpoint* pEpOut; + +#define DONGLE_STATE_UNKNOWN 0 +#define DONGLE_STATE_CDFS 1 +#define DONGLE_STATE_SERIAL 2 + +USB_INT08U dongleState; + +USB_INT32S SerialInit() +{ + dongleState = DONGLE_STATE_UNKNOWN; + Host_Init(); // Initialize the host controller + USB_INT32S rc = Host_EnumDev(); // Enumerate the device connected + if (rc != OK) + { + fprintf(stderr, "Could not enumerate device: %d\n", rc); + return rc; + } + return OK; +} + +bool SerialHasToSwitch() +{ + return (dongleState == DONGLE_STATE_CDFS); +} + +uint16_t m_vid; +uint16_t m_pid; + +USB_INT32S SerialSendMagic() +{ + bool scsi = false; + //Size 31 + 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 }; + 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 }; + char* magic; + USB_INT32S rc; + if((m_vid == 0x12d1) && (m_pid == 0x1446)) + { + PRINT_Log("\r\nHuawei magic packet sent.\r\n"); + magic = (char*) magicHuawei; + scsi = true; + } + else if((m_vid == 0x12d1) && (m_pid == 0x1003)) + { + PRINT_Log("\r\nHuawei magic control packet sent.\r\n"); + rc = Host_CtrlSend( 0 /*USB_TYPE_STANDARD | USB_RECIP_DEVICE*/, 0x03 /*USB_REQ_SET_FEATURE*/, 00000001, 0, 0, NULL); + } + else if(m_vid == 0x0af0) + { + PRINT_Log("\r\nVoda magic packet sent.\r\n"); + magic = (char*) magicVoda; + scsi = true; + } + else + { + return -1; + } + + if(scsi) + { + rc = pEpOut->transfer((volatile USB_INT08U*)magic, 31); + while(rc == PROCESSING) + { + rc = pEpOut->status(); + } + } + + delete pEpOut; + pEpOut = NULL; + return rc; +} + +USB_INT32S SerialCheckVidPid() +{ + volatile USB_INT08U *desc_ptr; + desc_ptr = TDBuffer; + + ser_int_found = 0; + + m_vid = *((USB_INT16U*)&desc_ptr[8]); + m_pid = *((USB_INT16U*)&desc_ptr[10]); + + if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_DEVICE) { + PRINT_Log("\r\nLen = %02x\r\n",desc_ptr[0]); + PRINT_Log("\r\nDesc code %02x\r\n",desc_ptr[1]); + return (ERR_BAD_CONFIGURATION); + } + + if( m_vid == 0x12d1 &&//Huawei : Change + m_pid == 0x1446 ) + { + PRINT_Log("\r\nHuawei device found in CDFS mode\r\n"); + dongleState = DONGLE_STATE_CDFS; + } + else if( m_vid == 0x12d1 &&//Huawei : Change + m_pid == 0x1001 ) + { + PRINT_Log("\r\nHuawei device found in Serial mode\r\n"); + dongleState = DONGLE_STATE_SERIAL; + } + else if( m_vid == 0x0af0 &&//Voda?Qualcomm? : Change + m_pid == 0x7501 ) + { + PRINT_Log("\r\nVodafone K3760 found, checking mode...\r\n"); + dongleState = DONGLE_STATE_UNKNOWN; + } + else if( m_vid == 0x12d1 &&//Voda?Qualcomm? : Change + m_pid == 0x1003 ) + { + PRINT_Log("\r\nHuawei device found, checking mode...\r\n"); + dongleState = DONGLE_STATE_UNKNOWN; + } + else + { + PRINT_Log("\r\nDevice %04x : %04x found.\r\n",m_vid,m_pid); + } + return OK; +} + +USB_INT32S SerialParseConfig() +{ + volatile USB_INT08U *desc_ptr; + + desc_ptr = TDBuffer; + + if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) { + return (ERR_BAD_CONFIGURATION); + } + desc_ptr += desc_ptr[0]; + + int epOut = 0; + int epIn = 0; + + pEpOut = NULL; + pEpIn = NULL; + while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) { + + switch (desc_ptr[1]) { + case USB_DESCRIPTOR_TYPE_INTERFACE: + PRINT_Log("\r\nIf %02x:%02x:%02x.\r\n",desc_ptr[5],desc_ptr[6],desc_ptr[7]); + if (desc_ptr[5] == 0xFF && + desc_ptr[6] == 0xFF && + desc_ptr[7] == 0xFF ) { + dongleState = DONGLE_STATE_SERIAL; + } + else + if (desc_ptr[5] == 0xFF && + desc_ptr[6] == 0xFF && + desc_ptr[7] == 0xFF ) { + dongleState = DONGLE_STATE_CDFS; + } + desc_ptr += desc_ptr[0]; /* Move to next descriptor start */ + break; + + case USB_DESCRIPTOR_TYPE_ENDPOINT: /* If it is an endpoint descriptor */ + PRINT_Log("\r\nEp %02x of size %d.\r\n", desc_ptr[2], (ReadLE16U(&desc_ptr[4]) )); + if ( SerialHasToSwitch() ) + { + if( (dongleState == DONGLE_STATE_CDFS) && (pEpOut == NULL) /*desc_ptr[2] == 1*/) //EP 1 + { + pEpOut = new UsbEndpoint((desc_ptr[2] & 0x7F), false, ReadLE16U(&desc_ptr[4])); + } + /* Move to next descriptor start */ + } + desc_ptr += desc_ptr[0]; + break; + + default: /* If the descriptor is neither interface nor endpoint */ + desc_ptr += desc_ptr[0]; /* Move to next descriptor start */ + break; + } + } + if (dongleState == DONGLE_STATE_SERIAL) { + PRINT_Log("Virtual Serial Port device %04x:%04x connected, vid=%d, pid=%d\n", m_vid, m_pid); + if(m_vid==0x0af0) //Voda + { + pEpOut = new UsbEndpoint((0x0a & 0x7F), false, 64); + pEpIn = new UsbEndpoint((0x8b & 0x7F), true, 64); + PRINT_Log("Voda K3760\r\n"); + } + else //if ( ( m_vid == 0x12d1 ) && ( m_pid == 0x1003 ) ) + /*{*/ + if ( ( m_vid == 0x12d1 ) && ( m_pid == 0x1003 ) ) + { + pEpOut = new UsbEndpoint((0x02 & 0x7F), false, 64); + pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64); + PRINT_Log("Huawei E220\r\n"); + } + else /*if ( m_vid == 0x12d1 && + m_pid == 0x1001 )*/ + { + pEpOut = new UsbEndpoint((0x01 & 0x7F), false, 64); + pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64); + PRINT_Log("Huawei E1550\r\n"); + } + + PRINT_Log("Virtual Serial Port device %04x:%04x connected\n", m_vid, m_pid); + return (OK); + } + else if (dongleState == DONGLE_STATE_CDFS) { + PRINT_Log("CDFS dongle connected, reset\n"); + return (OK); + } else { + PRINT_Log("Not a Virtual Serial Port device\n"); + return (ERR_NO_MS_INTERFACE); + } +} + + +USB_INT32S SerialRx( volatile USB_INT08U* buf, USB_INT32U len ) +{ + USB_INT32S rc; + rc = pEpIn->transfer(buf, len); + return rc; +} + +USB_INT32S SerialReceived() +{ + return pEpIn->status(); +} + +USB_INT32S SerialTx( volatile USB_INT08U* buf, USB_INT32U len ) +{ + USB_INT32S rc; + rc = pEpOut->transfer(buf, len); + // PRINT_Log("\r\nOut rc = %d\r\n",len); + return rc; +} + +USB_INT32S SerialTransmitted() +{ + USB_INT32S rc = pEpOut->status(); +/* if(rc>=0) + { + PRINT_Log("\r\nTransmitted %d\r\n",rc); + }*/ + return rc; +} + +USB_INT32S SerialReg(USB_INT16U vid, USB_INT16U pid) {return 0;} + +#endif