////////////////////////////////////////////////////////////////////////////// // // Application entry point // ////////////////////////////////////////////////////////////////////////////// static void RunAppL() { TInt error = KErrUnknown; //RDebug::Print(_L("USBMSAPP: Creating console\n")); console = Console::NewL(KTxtApp,TSize(KConsFullScreen,KConsFullScreen)); CleanupStack::PushL(console); console->SetPos(0,2); console->Printf(_L("========================================")); // Command line: list of drive letters to auto-mount (all if not specified) User::CommandLine(mountList); mountList.UpperCase(); CActiveScheduler* sched = new(ELeave) CActiveScheduler; CleanupStack::PushL(sched); CActiveScheduler::Install(sched); fs.Connect(); CleanupClosePushL(fs); _LIT(KMountAllDefault,"(all)"); console->SetPos(0,3); LogPrint(_L("Drives to auto-mount: %S"), (mountList.Length() ? &mountList : &KMountAllDefault)); // Add MS file system error = fs.AddFileSystem(KMsFsy); if(error != KErrNone && error != KErrAlreadyExists) { //RDebug::Print(_L("AddFileSystem failed, err=%d\n"), error); User::Leave(error); } console->SetPos(0,4); LogPrint(_L("MSFS file system:\tAdded OK\n")); RUsb usb; // Load the logical device _LIT(KDriverFileName,"EUSBC.LDD"); error = User::LoadLogicalDevice(KDriverFileName); if (error != KErrAlreadyExists) User::LeaveIfError(error); error = usb.Open(0); User::LeaveIfError(error); _LIT(KOtgdiLddFilename, "otgdi"); // Check for OTG support TBuf8<KUsbDescSize_Otg> otg_desc; error = usb.GetOtgDescriptor(otg_desc); if (!(error == KErrNotSupported || error == KErrNone)) { LogPrint(_L("Error %d while fetching OTG descriptor"), error); User::Leave(-1); return; } // On an OTG device we have to start the OTG driver, otherwise the Client // stack will remain disabled forever. if (error == KErrNotSupported) { CleanupClosePushL(usb); User::Leave(-1); } error = User::LoadLogicalDevice(KOtgdiLddFilename); if (error != KErrNone) { LogPrint(_L("Error %d on loading OTG LDD"), error); User::Leave(-1); return; } RUsbOtgDriver iOtgPort; error = iOtgPort.Open(); if (error != KErrNone) { LogPrint(_L("Error %d on opening OTG port"), error); User::Leave(-1); return; } error = iOtgPort.StartStacks(); if (error != KErrNone) { LogPrint(_L("Error %d on starting USB stack"), error); User::Leave(-1); return; } CleanupClosePushL(usb); // RDebug::Print(_L("USBMSAPP: Create active objects\n")); CMessageKeyProcessor::NewLC(console); CPropertyWatch::NewLC(EUsbMsDriveState_KBytesRead, PropertyHandlers::Read); CPropertyWatch::NewLC(EUsbMsDriveState_KBytesWritten, PropertyHandlers::Written); CPropertyWatch::NewLC(EUsbMsDriveState_DriveStatus, PropertyHandlers::DriveStatus); CPropertyWatch::NewLC(EUsbMsDriveState_MediaError, PropertyHandlers::MediaError); CUsbWatch::NewLC(usb); CPeriodUpdate::NewLC(); RUsbMassStorage UsbMs; TBuf<8> t_vendorId(_L("vendor")); TBuf<16> t_productId(_L("product")); TBuf<4> t_productRev(_L("1.00")); TMassStorageConfig msConfig; msConfig.iVendorId.Copy(t_vendorId); msConfig.iProductId.Copy(t_productId); msConfig.iProductRev.Copy(t_productRev); // console->Printf(_L("Connect to Mass Storage")); error = UsbMs.Connect(); User::LeaveIfError(error); // console->Printf(_L("Start Mass Storage")); error = UsbMs.Start(msConfig); User::LeaveIfError(error); TBuf8<KUsbDescSize_Device> deviceDescriptor; error = usb.GetDeviceDescriptor(deviceDescriptor); User::LeaveIfError(error); const TInt KUsbSpecOffset = 2; const TInt KUsbDeviceClassOffset = 4; const TInt KUsbVendorIdOffset = 8; const TInt KUsbProductIdOffset = 10; const TInt KUsbDevReleaseOffset = 12; //Change the USB spec number to 2.00 deviceDescriptor[KUsbSpecOffset] = 0x00; deviceDescriptor[KUsbSpecOffset+1] = 0x02; //Change the Device Class, Device SubClass and Device Protocol deviceDescriptor[KUsbDeviceClassOffset] = 0x00; deviceDescriptor[KUsbDeviceClassOffset+1] = 0x00; deviceDescriptor[KUsbDeviceClassOffset+2] = 0x00; //Change the device vendor ID (VID) to 0x0E22 (Symbian) deviceDescriptor[KUsbVendorIdOffset] = 0x22; // little endian deviceDescriptor[KUsbVendorIdOffset+1] = 0x0E; //Change the device product ID (PID) to 0x1111 deviceDescriptor[KUsbProductIdOffset] = 0x12; deviceDescriptor[KUsbProductIdOffset+1] = 0x11; //Change the device release number to 3.05 deviceDescriptor[KUsbDevReleaseOffset] = 0x05; deviceDescriptor[KUsbDevReleaseOffset+1] = 0x03; error = usb.SetDeviceDescriptor(deviceDescriptor); User::LeaveIfError(error); // Remove possible Remote-Wakup support in Configuration descriptor, // so that we can use the MSC device also easily for Chapter9 testing. TBuf8<KUsbDescSize_Config> configDescriptor; error = usb.GetConfigurationDescriptor(configDescriptor); User::LeaveIfError(error); const TInt KConfDesc_AttribOffset = 7; configDescriptor[KConfDesc_AttribOffset] &= ~KUsbDevAttr_RemoteWakeup; error = usb.SetConfigurationDescriptor(configDescriptor); User::LeaveIfError(error); _LIT16(productID_L, "Symbian USB Mass Storage Device (Base)"); TBuf16<KUsbStringDescStringMaxSize / 2> productID(productID_L); error = usb.SetProductStringDescriptor(productID); User::LeaveIfError(error); TRequestStatus enum_status; console->SetPos(0,5); LogPrint(_L("Re-enumerating...\n")); usb.ReEnumerate(enum_status); User::LeaveIfError(error); console->SetPos(0,5); User::WaitForRequest(enum_status); if(enum_status.Int() == KErrNone) LogPrint(_L("Re-enumeration Done\n")); else LogPrint(_L("Re-enumeration not successfully done\n")); console->SetPos(0,14); TBuf<3>password(KDefPwd); LogPrint(_L("Password: %S"), &password); ShowDriveSelection(); console->SetPos(0,17); _LIT(KMsgTitleB,"Menu: q=quit d=chg drv\n m=mount u=unmount\n l=lock i=lock n=unlock\n c=clr pwd"); //RDebug::Print(_L("USBMSAPP: Start CActiveScheduler\n")); console->Printf(KMsgTitleB); CActiveScheduler::Start(); error = UsbMs.Stop(); User::LeaveIfError(error); UsbMs.Close(); error = fs.RemoveFileSystem(KMsFs); User::LeaveIfError(error); CleanupStack::PopAndDestroy(11); iOtgPort.StopStacks(); iOtgPort.Close(); error = User::FreeLogicalDevice(RUsbOtgDriver::Name()); User::LeaveIfError(error); error = User::FreeLogicalDevice(_L("USBC")); User::LeaveIfError(error); }
QList<DMXInterface *> LibFTDIInterface::interfaces(QList<DMXInterface *> discoveredList) { QList <DMXInterface*> interfacesList; int id = 0; struct ftdi_context ftdi; ftdi_init(&ftdi); #ifdef LIBFTDI1 libusb_device *dev; libusb_device **devs; struct libusb_device_descriptor dev_descriptor; int i = 0; if (libusb_get_device_list(ftdi.usb_ctx, &devs) < 0) { qDebug() << "usb_find_devices() failed"; return interfacesList; } while ((dev = devs[i++]) != NULL) { libusb_get_device_descriptor(dev, &dev_descriptor); #else struct usb_bus *bus; struct usb_device *dev; struct usb_device_descriptor dev_descriptor; usb_init(); if (usb_find_busses() < 0) { qDebug() << "usb_find_busses() failed"; return interfacesList; } if (usb_find_devices() < 0) { qDebug() << "usb_find_devices() failed"; return interfacesList; } for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { dev_descriptor = dev->descriptor; #endif Q_ASSERT(dev != NULL); // Skip non wanted devices if (validInterface(dev_descriptor.idVendor, dev_descriptor.idProduct) == false) continue; char ser[256]; memset(ser, 0, 256); char nme[256]; char vend[256]; ftdi_usb_get_strings(&ftdi, dev, vend, 256, nme, 256, ser, 256); QString serial(ser); QString name(nme); QString vendor(vend); qDebug() << Q_FUNC_INFO << "DMX USB VID:" << QString::number(dev_descriptor.idVendor, 16) << "PID:" << QString::number(dev_descriptor.idProduct, 16); qDebug() << Q_FUNC_INFO << "DMX USB serial: " << serial << "name:" << name << "vendor:" << vendor; bool found = false; for (int c = 0; c < discoveredList.count(); c++) { if (discoveredList.at(c)->checkInfo(serial, name, vendor) == true) { found = true; break; } } if (found == false) { LibFTDIInterface *iface = new LibFTDIInterface(serial, name, vendor, dev_descriptor.idVendor, dev_descriptor.idProduct, id++); #ifdef LIBFTDI1 iface->setBusLocation(libusb_get_port_number(dev)); #else iface->setBusLocation(dev->bus->location); #endif interfacesList << iface; } #ifndef LIBFTDI1 } #endif } #ifdef LIBFTDI1 libusb_free_device_list(devs, 1); #endif ftdi_deinit(&ftdi); return interfacesList; } bool LibFTDIInterface::open() { if (isOpen() == true) return true; QByteArray sba = serial().toLatin1(); const char *ser = NULL; if (serial().isEmpty() == false) ser = (const char *)sba.data(); if (ftdi_usb_open_desc(&m_handle, vendorID(), productID(), name().toLatin1(), ser) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::openByPID(const int PID) { if (isOpen() == true) return true; if (ftdi_usb_open(&m_handle, DMXInterface::FTDIVID, PID) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::close() { if (ftdi_usb_close(&m_handle) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::isOpen() const { return (m_handle.usb_dev != NULL) ? true : false; } bool LibFTDIInterface::reset() { if (ftdi_usb_reset(&m_handle) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::setLineProperties() { if (ftdi_set_line_property(&m_handle, BITS_8, STOP_BIT_2, NONE) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::setBaudRate() { if (ftdi_set_baudrate(&m_handle, 250000) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::setFlowControl() { if (ftdi_setflowctrl(&m_handle, SIO_DISABLE_FLOW_CTRL) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::clearRts() { if (ftdi_setrts(&m_handle, 0) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::purgeBuffers() { if (ftdi_usb_purge_buffers(&m_handle) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } } bool LibFTDIInterface::setBreak(bool on) { ftdi_break_type type; if (on == true) type = BREAK_ON; else type = BREAK_OFF; if (ftdi_set_line_property2(&m_handle, BITS_8, STOP_BIT_2, NONE, type) < 0) { qWarning() << Q_FUNC_INFO << name() << ftdi_get_error_string(&m_handle); return false; } else { return true; } }