Webcam Server.
Dependencies: uvchost FatFileSystem mbed HTTPServer NetServicesMin
Diff: usb/UsbDevice.cpp
- Revision:
- 1:7a4f2c038803
- Parent:
- 0:2b4ea8a138e5
diff -r 2b4ea8a138e5 -r 7a4f2c038803 usb/UsbDevice.cpp --- a/usb/UsbDevice.cpp Wed Jun 06 11:47:06 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,400 +0,0 @@ - -/* -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. -*/ - -#include "UsbDevice.h" -//#define __DEBUG -#include "mydbg.h" - -UsbDevice::UsbDevice( UsbHostMgr* pMgr, int hub, int port, int addr ) : m_pControlEp(NULL), /*m_controlEp( this, 0x00, false, USB_CONTROL, 8 ),*/ -m_pMgr(pMgr), m_connected(false), m_enumerated(false), m_hub(hub), m_port(port), m_addr(addr), m_refs(0), -m_vid(0), m_pid(0) -{ - m_DeviceClass = 0x00; - m_InterfaceClass = 0x00; -} - -UsbDevice::~UsbDevice() -{ - DBG_ASSERT(0); - - if(m_pControlEp) - delete m_pControlEp; -} - -UsbErr UsbDevice::enumerate() -{ - VERBOSE("Hub: %d Port: %d\n", m_hub, m_port); - UsbErr rc; - DBG("%p m_hub=%d m_port=%d\n", this, m_hub, m_port); - DBG_ASSERT(m_pMgr); - m_pMgr->resetPort(m_hub, m_port); - - wait_ms(400); - - uint8_t temp[8]; - DBG_ASSERT(m_pControlEp == NULL); - m_pControlEp = new UsbEndpoint( this, 0x00, false, USB_CONTROL, sizeof(temp), 0 ); - DBG_ASSERT(m_pControlEp); - //EDCtrl->Control = 8 << 16;/* Put max pkt size = 8 */ - /* Read first 8 bytes of device desc */ - DBG_ASSERT(sizeof(temp) >= 8); - //rc = controlReceive( - // USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, - // (USB_DESCRIPTOR_TYPE_DEVICE << 8) |(0), 0, temp, sizeof(temp)); - //DBG_ASSERT(rc == USBERR_OK); - rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, temp, sizeof(temp)); - if (rc != USBERR_OK) { - DBG("rc=%d\n", rc); - DBG_ASSERT(rc == USBERR_OK); - return rc; - } - DBG_ASSERT(rc == USBERR_OK); - DBG_BYTES("DeviceDescriptor first 8 bytes", temp, sizeof(temp)); - DBG_ASSERT(temp[0] == 18); // bLength - DBG_ASSERT(temp[1] == 0x01); // bDescriptType - if (rc) - { - DBG("RC=%d",rc); - return (rc); - } - uint8_t bMaxPacketSize = temp[7]; - DBG_ASSERT(bMaxPacketSize >= 8); - DBG("Got descriptor, max ep size is %d\n", bMaxPacketSize); - - m_pControlEp->updateSize(bMaxPacketSize); /* Get max pkt size of endpoint 0 */ - rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS, m_addr, 0, NULL, 0); /* Set the device address to m_addr */ - DBG_ASSERT(rc == USBERR_OK); - if (rc) - { - // PRINT_Err(rc); - return (rc); - } - wait_ms(2); - //EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */ - - //Update address - m_pControlEp->updateAddr(m_addr); - DBG("Ep addr is now %d", m_addr); - /**/ - - //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 17); //Read full device descriptor - //rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, - // (USB_DESCRIPTOR_TYPE_DEVICE << 8)|(0), 0, - // m_controlDataBuf, 17); - uint8_t DeviceDesc[18]; - rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, DeviceDesc, sizeof(DeviceDesc)); - DBG_ASSERT(rc == USBERR_OK); - DBG_BYTES("DeviceDescriptor", DeviceDesc, sizeof(DeviceDesc)); - DBG_ASSERT(DeviceDesc[0] == 18); - DBG_ASSERT(DeviceDesc[1] == 0x01); - DBG_ASSERT(DeviceDesc[17] == 1); // bNumConfiguration - if (rc) - { - //PRINT_Err(rc); - return (rc); - } - - /* - rc = SerialCheckVidPid(); - if (rc != OK) { - PRINT_Err(rc); - return (rc); - } - */ - /**/ - m_DeviceClass = DeviceDesc[4]; - VERBOSE("DeviceClass: %02X\n", m_DeviceClass); - - m_vid = *((uint16_t*)&DeviceDesc[8]); - m_pid = *((uint16_t*)&DeviceDesc[10]); - VERBOSE("Vender: %04X\n", m_vid); - VERBOSE("Product: %04X\n", m_pid); - int iManufacture = DeviceDesc[14]; - if (iManufacture) { - char str[64]; - rc = GetString(iManufacture, str, sizeof(str)); - DBG_ASSERT(rc == USBERR_OK); - VERBOSE("Manufacture: %s\n", str); - } - int iProduct = DeviceDesc[15]; - if (iProduct) { - char str[64]; - rc = GetString(iProduct, str, sizeof(str)); - DBG_ASSERT(rc == USBERR_OK); - VERBOSE("Product: %s\n", str); - } - if (DeviceDesc[4] == 0x09) { // Hub - return hub_init(); - } - - uint8_t ConfigDesc[9]; - int index = 0; - rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc)); - DBG_ASSERT(rc == USBERR_OK); - DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc)); - DBG_ASSERT(ConfigDesc[0] == 9); - DBG_ASSERT(ConfigDesc[1] == 0x02); - int wTotalLength = *((uint16_t*)&ConfigDesc[2]); - DBG("TotalLength: %d\n", wTotalLength); - int bConfigValue = ConfigDesc[5]; - DBG_ASSERT(bConfigValue == 1); - DBG("ConfigValue: %d\n", bConfigValue); - DBG("MaxPower: %d mA\n", ConfigDesc[8]*2); - - uint8_t* buf = new uint8_t[wTotalLength]; - rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength); - DBG_ASSERT(rc == USBERR_OK); - DBG_ASSERT(ConfigDesc[1] == 0x02); - int pos = 0; - while(pos < wTotalLength) { - DBG_BYTES("", buf+pos, buf[pos]); - if (buf[pos+1] == 4) { // interface ? - m_InterfaceClass = buf[pos+5]; - VERBOSE("InterfaceClass: %02X\n", m_InterfaceClass); - break; - } - pos += buf[pos]; - } - delete[] buf; - - rc = setConfiguration(1); - DBG_ASSERT(rc == USBERR_OK); - if (rc) - { - // PRINT_Err(rc); - return rc; - } - wait_ms(100);/* Some devices may require this delay */ - - m_enumerated = true; - return USBERR_OK; -} - -bool UsbDevice::connected() -{ - return m_connected; -} - -bool UsbDevice::enumerated() -{ - return m_enumerated; -} - -int UsbDevice::getPid() -{ - return m_pid; -} - -int UsbDevice::getVid() -{ - return m_vid; -} -#if 0 -UsbErr UsbDevice::getConfigurationDescriptor(int config, uint8_t** pBuf) -{ - DBG_ASSERT(m_controlDataBuf); - //For now olny one config - *pBuf = m_controlDataBuf; - return USBERR_OK; -} - -UsbErr UsbDevice::getInterfaceDescriptor(int config, int item, uint8_t** pBuf) -{ - DBG_ASSERT(m_controlDataBuf); - byte* desc_ptr = m_controlDataBuf; - -/* if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) - { - return USBERR_BADCONFIG; - }*/ - DBG_ASSERT(m_controlDataBuf); - if(item>=m_controlDataBuf[4])//Interfaces count - return USBERR_NOTFOUND; - - desc_ptr += desc_ptr[0]; - - *pBuf = NULL; - - while (desc_ptr < m_controlDataBuf + *((uint16_t*)&m_controlDataBuf[2])) - { - - switch (desc_ptr[1]) { - case USB_DESCRIPTOR_TYPE_INTERFACE: - if(desc_ptr[2] == item) - { - *pBuf = desc_ptr; - return USBERR_OK; - } - desc_ptr += desc_ptr[0]; // Move to next descriptor start - break; - } - - } - - if(*pBuf == NULL) - return USBERR_NOTFOUND; - - return USBERR_OK; -} -#endif - -UsbErr UsbDevice::setConfiguration(int config) -{ - DBG("config=%d\n", config); - DBG_ASSERT(config == 1); - UsbErr rc = controlSend( - USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, // 0x00 - SET_CONFIGURATION, config, 0, 0, 0); - return rc; -} - -UsbErr UsbDevice::controlSend(byte requestType, byte request, word value, word index, const byte* buf, int len) -{ - UsbErr rc; - fillControlBuf(requestType, request, value, index, len); - DBG_ASSERT(m_pControlEp); - m_pControlEp->setNextToken(TD_SETUP); - rc = m_pControlEp->transfer(m_controlBuf, 8); - while(m_pControlEp->status() == USBERR_PROCESSING); - rc = (UsbErr) MIN(0, m_pControlEp->status()); - if(rc) - return rc; - if(len) - { - m_pControlEp->setNextToken(TD_OUT); - rc = m_pControlEp->transfer((byte*)buf, len); - while(m_pControlEp->status() == USBERR_PROCESSING); - rc = (UsbErr) MIN(0, m_pControlEp->status()); - if(rc) - return rc; - } - m_pControlEp->setNextToken(TD_IN); - rc = m_pControlEp->transfer(NULL, 0); - while(m_pControlEp->status() == USBERR_PROCESSING); - rc = (UsbErr) MIN(0, m_pControlEp->status()); - if(rc) - return rc; - return USBERR_OK; -} - -UsbErr UsbDevice::controlReceive(byte requestType, byte request, word value, word index, const byte* buf, int len) -{ - DBG("buf=%p len=%d\n", buf, len); - UsbErr rc; - fillControlBuf(requestType, request, value, index, len); - DBG_ASSERT(m_pControlEp); - m_pControlEp->setNextToken(TD_SETUP); - rc = m_pControlEp->transfer(m_controlBuf, 8); - while(m_pControlEp->status() == USBERR_PROCESSING); - rc = (UsbErr) MIN(0, m_pControlEp->status()); - if(rc) - return rc; - if(len) - { - m_pControlEp->setNextToken(TD_IN); - rc = m_pControlEp->transfer( (byte*) buf, len); - while(m_pControlEp->status() == USBERR_PROCESSING); - rc = (UsbErr) MIN(0, m_pControlEp->status()); - if(rc) - return rc; - } - m_pControlEp->setNextToken(TD_OUT); - rc = m_pControlEp->transfer(NULL, 0); - while(m_pControlEp->status() == USBERR_PROCESSING); - rc = (UsbErr) MIN(0, m_pControlEp->status()); - if(rc) - return rc; - return USBERR_OK; -} - -UsbErr UsbDevice::GetDescriptor(int type, int index, const byte* buf, int len) -{ - DBG("type=%02X\n", type); - return controlReceive( - USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, - (type << 8) |(index), 0, buf, len); - -} - -UsbErr UsbDevice::GetString(int index, char* buf, int len) -{ - DBG("index=%d buf=%p len=%d\n", index, buf, len); - DBG_ASSERT(index >= 1); - uint8_t temp[4]; - UsbErr rc; - rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, 0, temp, sizeof(temp)); - DBG_ASSERT(rc == USBERR_OK); - DBG_BYTES("LANG_ID", temp, sizeof(temp)); - DBG_ASSERT(temp[0] == 4); - DBG_ASSERT(temp[1] == 0x03); - - rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp, 2); - DBG_ASSERT(rc == USBERR_OK); - DBG_BYTES("length check", temp, 2); - if (temp[0] == 0x00 && temp[1] == 0x00) { // for pl2303 - if (len > 0) { - strcpy(buf, ""); - } - return rc; - } - DBG_ASSERT(temp[1] == 0x03); - int temp_len = temp[0]; - - uint8_t* temp_buf = new uint8_t[temp_len]; - DBG_ASSERT(temp_buf); - rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp_buf, temp_len); - DBG_ASSERT(rc == USBERR_OK); - temp_len = temp_buf[0]; - DBG_HEX(temp_buf, temp_len); - int i = 0; - for(int pos = 2; pos < temp_len; pos+= 2) { - buf[i++] = temp_buf[pos]; - DBG_ASSERT(i < len-1); - } - buf[i] = '\0'; - delete[] temp_buf; - return rc; -} - -UsbErr UsbDevice::SetInterfaceAlternate(int interface, int alternate) -{ - UsbErr rc = controlSend( - USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE, - SET_INTERFACE, alternate, interface, NULL, 0); - return rc; -} - -void UsbDevice::fillControlBuf(byte requestType, byte request, word value, word index, int len) -{ -#ifdef __BIG_ENDIAN - #error "Must implement BE to LE conv here" -#endif - m_controlBuf[0] = requestType; - m_controlBuf[1] = request; - //We are in LE so it's fine - *((word*)&m_controlBuf[2]) = value; - *((word*)&m_controlBuf[4]) = index; - *((word*)&m_controlBuf[6]) = (word) len; -} - -