Changes to support Vodafone K4606
Fork of USBHostWANDongle by
Diff: USB3GModule/WANDongle.cpp
- Revision:
- 2:a8b2d0cd9bbd
- Parent:
- 1:49df46e3295c
- Child:
- 3:4394986752db
diff -r 49df46e3295c -r a8b2d0cd9bbd USB3GModule/WANDongle.cpp --- a/USB3GModule/WANDongle.cpp Fri May 25 09:31:41 2012 +0000 +++ b/USB3GModule/WANDongle.cpp Tue Jun 26 13:43:54 2012 +0000 @@ -26,15 +26,9 @@ #include "rtos.h" #include "WANDongle.h" - -//TODO refactor +#include "WANDongleInitializer.h" -//Huawei K3770 (Vodafone) -uint8_t vodafone_k3770_switch_packet[] = { - 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0, 0x11, 0x06, 0x20, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -WANDongle::WANDongle() : cb_tx_en(false), cb_rx_en(false), listener(NULL) +WANDongle::WANDongle() : cb_tx_en(false), cb_rx_en(false), listener(NULL), m_serialCount(0) { host = USBHost::getHostInst(); init(); @@ -59,385 +53,69 @@ host->lock(); - for (int i = 0; i < MAX_DEVICE_NB; i++) { - if ((dev = host->getDevice(i)) != NULL) { - + for (int i = 0; i < MAX_DEVICE_NB; i++) + { + if ((dev = host->getDevice(i)) != NULL) + { DBG("Found one device, reset it"); host->resetDevice(dev); DBG("Enumerate"); host->enumerate(dev); - - //Vodafone K3770 - if ((dev->getVid() == 0x12D1) && (dev->getPid() == 0x14D1)) { + + WANDongleInitializer* initializer = getInitializers(); + + while(initializer++) + { + if ((dev->getVid() == initializer->getSerialVid()) && (dev->getPid() == initializer->getSerialPid())) + { + host->registerDriver(dev, 0, this, &WANDongle::init); + m_serialCount = initializer->getSerialPortCount(); + for(int j = 0; j < m_serialCount; j++) + { + m_serial[j].connect( initializer->getEp(dev, j, false), initializer->getEp(dev, j, true) ); + } + dev_connected = true; + host->unlock(); + return true; + } + else if ((dev->getVid() == initializer->getMSDVid()) && (dev->getPid() == initializer->getMSDPid())) + { DBG("Vodafone K3370 dongle detected in MSD mode"); - - for (int j = 0; j < dev->getNbInterface(); j++) { - - if (dev->getInterface(j)->intf_class == MSD_CLASS) { - - if ( (bulk_out = dev->getEndpoint(j, BULK_ENDPOINT, OUT)) != NULL ) { - - DBG("MSD descriptor found on device %p, intf %d, will now try to switch into serial mode", (void *)dev, j); - - host->bulkWrite(dev, (Endpoint *)bulk_out, vodafone_k3770_switch_packet, 31); - - DBG("Switch packet sent"); - host->unlock(); - - - Thread::wait(500); //Not in a thread - - //Not wait for the dongle to reconnect - while (1) { - - if (found) { - break; - } - - Thread::wait(100); - - host->lock(); - - - for (int i = 0; i < MAX_DEVICE_NB; i++) { - if ((dev = host->getDevice(i)) != NULL) { - host->resetDevice(dev); - host->enumerate(dev); - - DBG("Found one device with vid: %04x pid: %04x", dev->getVid(), dev->getPid()); - - //Vodafone K3770 - if ((dev->getVid() == 0x12D1) && (dev->getPid() == 0x14C9)) { - DBG("Switched successfully"); - found = true; - break; - } - } - } - - host->unlock(); - - } - host->lock(); - - if (fetchEndpoints()) { - DBG("ep: %p, %p\r\n", bulk_in, bulk_out); - max_out_size = bulk_out->getSize(); - if( max_out_size > WANDONGLE_MAX_OUTEP_SIZE ) - { - max_out_size = WANDONGLE_MAX_OUTEP_SIZE; - } - host->unlock(); - return true; - } - host->unlock(); - } - } + //Try to switch + if( initializer->switchMode() ) + { + DBG("Switched OK"); + host->unlock(); + return false; //Will be connected on a next iteration } - } else if ((dev->getVid() == 0x12D1) && (dev->getPid() == 0x14C9)) { - if (fetchEndpoints()) { - DBG("ep: %p, %p\r\n", bulk_in, bulk_out); - max_out_size = bulk_out->getSize(); - if( max_out_size > WANDONGLE_MAX_OUTEP_SIZE ) - { - max_out_size = WANDONGLE_MAX_OUTEP_SIZE; - } + else + { + ERR("Could not switch mode"); host->unlock(); - return true; + return false; } - } - } - } + } + } //while() + } //if() + } //for() host->unlock(); - bulk_in = NULL; - bulk_out = NULL; - dev_connected = false; return false; } -int WANDongle::readPacket() -{ - rx_mtx.lock(); - if(lock_rx) - { - ERR("Fail"); - rx_mtx.unlock(); - return -1; - } - - lock_rx = true; //Receiving - rx_mtx.unlock(); -// DBG("readPacket"); - //lock_rx.lock(); - host->lock(); - USB_TYPE res = host->bulkRead(dev, (Endpoint *)bulk_in, buf_in, ((Endpoint *)bulk_in)->getSize(), false); //Queue transfer - if(res != USB_TYPE_PROCESSING) - { - host->unlock(); - //lock_rx.unlock(); - ERR("host->bulkRead() returned %d", res); - Thread::wait(100); - return -1; - } - host->unlock(); - return 0; -} - -int WANDongle::writePacket() +IUSBHostSerial* WANDongle::getSerial(int index) { - tx_mtx.lock(); - if(lock_tx) - { - ERR("Fail"); - tx_mtx.unlock(); - return -1; - } - - lock_tx = true; //Transmitting - tx_mtx.unlock(); -// DBG("writePacket"); - - //lock_tx.lock(); - host->lock(); - USB_TYPE res = host->bulkWrite(dev, (Endpoint *)bulk_out, buf_out, buf_out_len, false); //Queue transfer - if(res != USB_TYPE_PROCESSING) - { - host->unlock(); - //lock_tx.unlock(); - ERR("host->bulkWrite() returned %d", res); - Thread::wait(100); - return -1; - } - host->unlock(); - return 0; -} - -int WANDongle::putc(int c) -{ - tx_mtx.lock(); - if(!lock_tx) - { - if(buf_out_len < max_out_size) - { - buf_out[buf_out_len] = (uint8_t)c; - buf_out_len++; - } - } - else - { - ERR("CAN'T WRITE!"); - } - tx_mtx.unlock(); - return c; + return m_serial[index]; } -int WANDongle::getc() -{ - rx_mtx.lock(); - int c = 0; - if(!lock_rx) - { - if(buf_in_read_pos < buf_in_len) - { - c = (int)buf_in[buf_in_read_pos]; - buf_in_read_pos++; - } - } - else - { - ERR("CAN'T READ!"); - } - rx_mtx.unlock(); - return c; -} - -int WANDongle::readable() -{ - rx_mtx.lock(); - if (lock_rx) - { - rx_mtx.unlock(); - return 0; - } - - /* if( !lock_rx.trylock() ) - { - return 0; - }*/ - int res = buf_in_len - buf_in_read_pos; - //lock_rx.unlock(); - rx_mtx.unlock(); - return res; -} - -int WANDongle::writeable() +int WANDongle::getSerialCount() { - tx_mtx.lock(); - if (lock_tx) - { - tx_mtx.unlock(); - return 0; - } - - /*if( !lock_tx.trylock() ) - { - return 0; - }*/ - int res = max_out_size - buf_out_len; - tx_mtx.unlock(); - //lock_tx.unlock(); - return res; -} - -void WANDongle::attach(IUSBHostSerialListener* pListener) -{ - if(pListener == NULL) - { - setupIrq(false, RxIrq); - setupIrq(false, TxIrq); - } - listener = pListener; - if(pListener != NULL) - { - setupIrq(true, RxIrq); - setupIrq(true, TxIrq); - } -} - -void WANDongle::setupIrq(bool en, IrqType irq /*= RxIrq*/) -{ - switch(irq) - { - case RxIrq: - rx_mtx.lock(); - cb_rx_en = en; - if(en && cb_rx_pending) - { - cb_rx_pending = false; - rx_mtx.unlock(); - listener->readable(); //Process the interrupt that was raised - } - else - { - rx_mtx.unlock(); - } - break; - case TxIrq: - tx_mtx.lock(); - cb_tx_en = en; - if(en && cb_tx_pending) - { - cb_tx_pending = false; - tx_mtx.unlock(); - listener->writeable(); //Process the interrupt that was raised - } - else - { - tx_mtx.unlock(); - } - break; - } + return m_serialCount; } //Private methods - void WANDongle::init() { dev_connected = false; - - bulk_in = NULL; - bulk_out = NULL; - - buf_out_len = 0; - lock_tx = false; - cb_tx_en = false; - cb_tx_pending = false; - - buf_in_len = 0; - buf_in_read_pos = 0; - lock_rx = false; - cb_rx_en = false; - cb_rx_pending = false; - -} - -bool WANDongle::fetchEndpoints() -{ - bulk_in = dev->getEndpoint(0, BULK_ENDPOINT, IN); - bulk_out = dev->getEndpoint(0, BULK_ENDPOINT, OUT); - if ((bulk_in != NULL) && (bulk_out != NULL)) - { - - DBG("SERIAL FOUND on device %p, intf %d, bulk_in: %p, bulk_out: %p\r\n", - (void *)dev, 0, (void *)bulk_in, (void *)bulk_out); - - bulk_in->attach(this, &WANDongle::rxHandler); - bulk_out->attach(this, &WANDongle::txHandler); - host->lock(); - host->registerDriver(dev, 0, this, &WANDongle::init); - host->unlock(); - dev_connected = true; - - readPacket(); //Start receiving data - - return true; - } - return false; } -void WANDongle::rxHandler() -{ - if (((Endpoint *) bulk_in)->getState() == USB_TYPE_IDLE) //Success - { - buf_in_read_pos = 0; - buf_in_len = ((Endpoint *) bulk_in)->getLengthTransferred(); //Update length - //lock_rx.unlock(); - rx_mtx.lock(); - lock_rx = false; //Transmission complete - if(cb_rx_en) - { - rx_mtx.unlock(); - listener->readable(); //Call handler from the IRQ context - //readPacket() should be called by the handler subsequently once the buffer has been emptied - } - else - { - cb_rx_pending = true; //Queue the callback - rx_mtx.unlock(); - } - - } - else //Error, try reading again - { - //lock_rx.unlock(); - readPacket(); - } -} - -void WANDongle::txHandler() -{ - if (((Endpoint *) bulk_out)->getState() == USB_TYPE_IDLE) //Success - { - tx_mtx.lock(); - buf_out_len = 0; //Reset length - lock_tx = false; //Transmission complete - //lock_tx.unlock(); - if(cb_tx_en) - { - tx_mtx.unlock(); - listener->writeable(); //Call handler from the IRQ context - //writePacket() should be called by the handler subsequently once the buffer has been filled - } - else - { - cb_tx_pending = true; //Queue the callback - tx_mtx.unlock(); - } - } - else //Error, try reading again - { - //lock_tx.unlock(); - writePacket(); - } -}