diff -r 4349d4d62266 -r 60f47003f4b1 plugins/consoles/vt100cons/src/usb/vtc_usb.cpp --- a/plugins/consoles/vt100cons/src/usb/vtc_usb.cpp Thu Sep 16 15:06:08 2010 +0100 +++ b/plugins/consoles/vt100cons/src/usb/vtc_usb.cpp Mon Sep 20 15:37:51 2010 +0100 @@ -20,6 +20,14 @@ return new CUsbConsole; } +TUsbPortConfig::TUsbPortConfig() + :iPort(KNullDesC), iPersonality(-1) + { + } + +#define ErrOrDebug(err) (((err) < 0 && (err) != KErrAlreadyExists) ? EError : EDebug) + + //______________________________________________________________________________ // CUsbConsole CUsbConsole::CUsbConsole() @@ -33,18 +41,18 @@ void CUsbConsole::ConstructL(const TDesC& aTitle) { + TUsbPortConfig portConfig; + User::LeaveIfError(ReadConfig(aTitle, portConfig)); + User::LeaveIfError(iUsb.Connect()); TRequestStatus stat; - // assume USB device already started - /*iUsb.Start(stat); - User::WaitForRequest(stat); - // KErrAccessDenied returned if already started; - if (stat.Int()!=KErrAccessDenied) + if (portConfig.iPersonality >= 0) { - Message(EError, KUsbError, stat.Int(), 1); - User::LeaveIfError(stat.Int()); - }*/ + iUsb.TryStart(portConfig.iPersonality, stat); + User::WaitForRequest(stat); + Message(ErrOrDebug(stat.Int()), _L("Starting USB personality %d returned %d"), portConfig.iPersonality, stat.Int()); + } // Wait for an enumeration that supports ACM (this is so that if the device defaulted to say mass storage and was then reconfigured to a personality with ACM, we wait for the ACM reconfiguration TBool gotAcm = EFalse; @@ -52,12 +60,15 @@ { TUsbDeviceState usbState; User::LeaveIfError(iUsb.GetDeviceState(usbState)); - if (usbState & EUsbDeviceStateConfigured) + if (usbState & (EUsbDeviceStateConfigured|EUsbDeviceStatePowered)) // We should only need to check for EUsbDeviceStateConfigured, but some HW doesn't go to configured state if the cable is inserted before USB is started { // Check if we have ACM TInt currentPersonality; - User::LeaveIfError(iUsb.GetCurrentPersonalityId(currentPersonality)); - User::LeaveIfError(iUsb.ClassSupported(currentPersonality, KECACMUid, gotAcm)); + TInt err = iUsb.GetCurrentPersonalityId(currentPersonality); + if (!err) + { + err = iUsb.ClassSupported(currentPersonality, KECACMUid, gotAcm); + } _LIT(KGotIt, "Current USB personality has ACM, proceeding"); _LIT(KNotGotIt, "Current USB personality doesn't have ACM, waiting for re-enumeration"); if (gotAcm) Message(EInformation, KGotIt); @@ -69,7 +80,7 @@ // We're not enumerated, or we are but don't have ACM. So wait for a (re-)enumeration _LIT(KWaitingForEnumeration, "Waiting for USB enumeration (please connect USB cable)"); Message(EInformation, KWaitingForEnumeration); - iUsb.DeviceStateNotification(EUsbDeviceStateConfigured, usbState, stat); + iUsb.DeviceStateNotification(EUsbDeviceStateConfigured|EUsbDeviceStatePowered, usbState, stat); User::WaitForRequest(stat); if (stat.Int() != KErrNone) { @@ -77,8 +88,8 @@ Message(EError, KUsbError, stat.Int()); User::Leave(stat.Int()); } - _LIT(KUsbEnumerated, "USB cable connected."); - Message(EInformation, KUsbEnumerated); + _LIT(KUsbEnumerated, "USB state changed to %d."); + Message(EInformation, KUsbEnumerated, usbState); } } @@ -107,7 +118,46 @@ Message(EInformation, _L("Preamble script failed with %d"), err); } - //TODO should we ensure that the port passed in here is an ACM::%s port? - Message(EInformation, _L("Opening %S"), &aTitle); - CVtcSerialConsole::ConstructL(aTitle); + Message(EInformation, _L("Opening %S"), &portConfig.iPort); + CVtcSerialConsole::ConstructL(portConfig.iPort); } + +TInt CUsbConsole::ReadConfig(const TDesC& aConfigDes, TUsbPortConfig& aConfig) + { + _LIT(KKeywordPort, "port"); + _LIT(KKeywordPersonality, "personality"); + + TBool keywordFound(EFalse); + TLex lex(aConfigDes); + while (!lex.Eos()) + { + TPtrC keyword; + TPtrC value; + TInt err = ReadKeywordValuePair(lex, keyword, value); + if (err != KErrNone) + { + break; + } + + if (keyword == KKeywordPort) + { + aConfig.iPort.Set(value); + keywordFound = ETrue; + } + else if (keyword == KKeywordPersonality) + { + TLex lex(value); + TInt err = lex.Val(aConfig.iPersonality); + if (err) return err; + keywordFound = ETrue; + } + } + + if (!keywordFound) + { + // Treat unrecognised string as a port (to preserve backwards compatibility with earlier releases). + aConfig.iPort.Set(aConfigDes); + } + + return KErrNone; + }