diff -r 000000000000 -r c9bc50fca66e usbmgmt/usbmgr/usbman/server/SRC/CUsbDummyClassController.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbmgmt/usbmgr/usbman/server/SRC/CUsbDummyClassController.cpp Tue Feb 02 02:02:59 2010 +0200 @@ -0,0 +1,502 @@ +/* +* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Implements part of UsbMan USB Class Framework. +* +*/ + +/** + @file +*/ + +#include "CUsbDummyClassController.h" +#include +#include "inifile.h" +#include + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, "USBSVR"); +#endif + +_LIT(KDummyControllerPanic, "UsbDummyCC"); // must be <=16 chars +// Panic codes +enum + { + // Bad value for the iSynchronicity member. + EDummyPanicBadSynchronicity = 0, + + // Used for environment errors we do not handle. + EDummyPanicUnhandledError = 1, + + // Used for bad iStatus and other state errors. + EDummyPanicBadState = 2, + + // Error reading ini file. + EDummyPanicBadIniFile = 3, + + // We already have our async request active. + EDummyPanicAlreadyActive = 4, + + // We already have a request outstanding from the device class. + EDummyPanicOutstandingRequestFromDevice = 5, + + // Attempt to call Start() when in illegal state + EDummyPanicBadApiCallStart = 6, + + // Attempt to call Stop() when in illegal state + EDummyPanicBadApiCallStop = 7, + }; + +const TInt KDummyClassPriority = 1; + +// Keys for reading the ini file. +_LIT(KStartup, "Startup"); +_LIT(KShutdown, "Shutdown"); +_LIT(KType, "Type"); +_LIT(KTime, "Time"); +_LIT(KError, "Error"); +_LIT(KSync, "sync"); +_LIT(KAsync, "async"); +_LIT(KNever, "never"); + +CUsbDummyClassController* CUsbDummyClassController::NewL( + MUsbClassControllerNotify& aOwner, + TUint aIndex) +/** + * Constructs a CUsbDummyClassController object. + * + * @param aOwner USB Device that owns and manages the class + * @param aIndex The index number of the instance + * @return Ownership of a new CUsbDummyClassController object + */ + { + LOG_STATIC_FUNC_ENTRY + + CUsbDummyClassController* self = new(ELeave) CUsbDummyClassController(aOwner, aIndex); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +CUsbDummyClassController* CUsbDummyClassController::NewL( + MUsbClassControllerNotify& aOwner, + TUint aIndex, TInt aPriority) +/** + * Constructs a CUsbDummyClassController object. + * + * @param aOwner USB Device that owns and manages the class + * @param aIndex The index number of the instance + * @param aPriority The startup priority of the instance + * @return Ownership of a new CUsbDummyClassController object + */ + { + LOG_STATIC_FUNC_ENTRY + + CUsbDummyClassController* self = new(ELeave) CUsbDummyClassController(aOwner, aIndex, aPriority); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CUsbDummyClassController::CUsbDummyClassController( + MUsbClassControllerNotify& aOwner, + TUint aIndex) +/** + * Constructor. + * + * @param aOwner USB Device that owns and manages the class + * @param aIndex The index number of the instance + */ + : CUsbClassControllerBase(aOwner, KDummyClassPriority), + iIndex(aIndex) + { + iState = EUsbServiceIdle; // needs explicit initialisation as non-zero + } + +CUsbDummyClassController::CUsbDummyClassController( + MUsbClassControllerNotify& aOwner, + TUint aIndex, TInt aPriority) + +/** + * Constructor. + * + * @param aOwner USB Device that owns and manages the class + * @param aIndex The index number of the instance + * @param aPriority a startup priority for the class controller + */ + : CUsbClassControllerBase(aOwner, aPriority), + iIndex(aIndex) + { + iState = EUsbServiceIdle; // needs explicit initialisation as non-zero + } + +void CUsbDummyClassController::ConstructL() +/** + * Method to perform second phase construction. + */ + { + LEAVEIFERRORL(iTimer.CreateLocal()); + } + +CUsbDummyClassController::~CUsbDummyClassController() +/** + * Destructor. + */ + { + Cancel(); + + iTimer.Close(); + } + +void CUsbDummyClassController::GetBehaviour(CIniFile& aIniFile, + const TDesC& aSection, + TBehaviour& aBehaviour) +/** + * Reads information from the ini file, from a given section, to the given + * behaviour structure. + * + * @param aIniFile The ini file to read from. + * @param aSection The section to reads from. + * @param aBehaviour The behaviour struct to read to. + */ + { + LOG_FUNC +#ifdef __FLOG_ACTIVE + TBuf8 buf; + buf.Copy(aSection); + LOGTEXT2(_L8("\taSection = %S"), &buf); +#endif // __FLOG_ACTIVE + + TPtrC temp; + if ( !aIniFile.FindVar(aSection, KType(), temp) ) + { + LOGTEXT2(_L8("\tPANICKING: can't find Type item in section %S"), &aSection); + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadIniFile); + } + if ( temp == KSync ) + { + aBehaviour.iSynchronicity = ESynchronous; + } + else if ( temp == KAsync ) + { + aBehaviour.iSynchronicity = EAsynchronous; + } + else if ( temp == KNever ) + { + aBehaviour.iSynchronicity = ENever; + } + else + { + LOGTEXT3(_L8("\tPANICKING: bad Type value (%S) in section %S"), &temp, &aSection); + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadIniFile); + } + TInt delay; + if ( !aIniFile.FindVar(aSection, KTime(), delay) ) + { + LOGTEXT2(_L8("\tPANICKING: can't find Time item in section %S"), &aSection); + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadIniFile); + } + aBehaviour.iDelay = delay; + if ( !aIniFile.FindVar(aSection, KError(), aBehaviour.iErrorCode) ) + { + LOGTEXT2(_L8("\tPANICKING: can't find Error item in section %S"), &aSection); + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadIniFile); + } + } + +void CUsbDummyClassController::DoGetConfigL() +/** + * Reads the config from the ini file. + */ + { + LOG_FUNC + + CIniFile* iniFile = CIniFile::NewL(_L("dummy.ini")); + CleanupStack::PushL(iniFile); + TName section; + + // Read startup behaviour + section.Format(_L("%S.%d"), &KStartup(), iIndex); + GetBehaviour(*iniFile, section, iStartupBehaviour); + // Read shutdown behaviour + section.Format(_L("%S.%d"), &KShutdown(), iIndex); + GetBehaviour(*iniFile, section, iShutdownBehaviour); + + CleanupStack::PopAndDestroy(iniFile); + } + +void CUsbDummyClassController::GetConfig() +/** + * Reads the config from the ini file. + * Note that this is assumed to succeed. Any failure will break the test and + * it's much cleaner to panic out of the test entirely rather than leave it to + * the user to figure out what's gone wrong. + */ + { + LOG_FUNC + + // Always use dummy.ini. The entity setting up the test is responsible for + // copying the correct file to c:\\dummy.ini. The first found + // by FindByDir will be used. TODO: enforce c:\\. + TRAPD(err, DoGetConfigL()); + if ( err != KErrNone ) + { + _USB_PANIC(KDummyControllerPanic, EDummyPanicUnhandledError); + } + + LOGTEXT2(_L8("\tLogging dummy class controller behaviour for instance %d"), iIndex); + LOGTEXT2(_L8("\tiStartupBehaviour.iSynchronicity = %d"), iStartupBehaviour.iSynchronicity); + LOGTEXT2(_L8("\tiStartupBehaviour.iDelay = %d"), iStartupBehaviour.iDelay.Int()); + LOGTEXT2(_L8("\tiStartupBehaviour.iErrorCode = %d"), iStartupBehaviour.iErrorCode); + LOGTEXT2(_L8("\tiShutdownBehaviour.iSynchronicity = %d"), iShutdownBehaviour.iSynchronicity); + LOGTEXT2(_L8("\tiShutdownBehaviour.iDelay = %d"), iShutdownBehaviour.iDelay.Int()); + LOGTEXT2(_L8("\tiShutdownBehaviour.iErrorCode = %d"), iShutdownBehaviour.iErrorCode); + } + +void CUsbDummyClassController::Start(TRequestStatus& aStatus) +/** + * Called by UsbMan to start this class. + * + * @param aStatus Will be completed with success or failure. + */ + { + LOG_FUNC + + //Start() should only be called if the CC is idle or started + __ASSERT_DEBUG((iState == EUsbServiceIdle || iState == EUsbServiceStarted), + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadApiCallStart) ); + + // Get config from ini file. Note that can't be done once in ConstructL + // because then, in the case of a CC which doesn't Stop, we'd never be + // able to shut down USBMAN! + GetConfig(); + + // NB We enforce that the device doesn't re-post requests on us. + __ASSERT_DEBUG(!iReportStatus, + _USB_PANIC(KDummyControllerPanic, EDummyPanicOutstandingRequestFromDevice)); + aStatus = KRequestPending; + iReportStatus = &aStatus; + + iState = EUsbServiceStarting; + + switch ( iStartupBehaviour.iSynchronicity ) + { + case ESynchronous: + User::After(iStartupBehaviour.iDelay); + iState = EUsbServiceStarted; + User::RequestComplete(iReportStatus, iStartupBehaviour.iErrorCode); + iReportStatus = NULL; + break; + + case EAsynchronous: + iTimer.After(iStatus, iStartupBehaviour.iDelay); + __ASSERT_DEBUG(!IsActive(), _USB_PANIC(KDummyControllerPanic, EDummyPanicAlreadyActive)); + SetActive(); + break; + + case ENever: + // Don't do anything and never complete + break; + + default: + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity); + break; + } + } + +void CUsbDummyClassController::Stop(TRequestStatus& aStatus) +/** + * Called by UsbMan to stop this class. + * + * @param aStatus Will be completed with success or failure. + */ + { + LOG_FUNC + + //Stop() should only be called if the CC is Started or Idle + __ASSERT_DEBUG((iState == EUsbServiceStarted || iState == EUsbServiceIdle), + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadApiCallStop)); + + // Get config from ini file. Note that can't be done once in ConstructL + // because then, in the case of a CC which doesn't Stop, we'd never be + // able to shutdown USBMAN! + GetConfig(); + + // NB We enforce that the device doesn't re-post requests on us. + __ASSERT_DEBUG(!iReportStatus, + _USB_PANIC(KDummyControllerPanic, EDummyPanicOutstandingRequestFromDevice)); + aStatus = KRequestPending; + iReportStatus = &aStatus; + + iState = EUsbServiceStopping; + + switch ( iShutdownBehaviour.iSynchronicity ) + { + case ESynchronous: + User::After(iShutdownBehaviour.iDelay); + iState = EUsbServiceIdle; + User::RequestComplete(iReportStatus, iShutdownBehaviour.iErrorCode); + iReportStatus = NULL; + break; + + case EAsynchronous: + iTimer.After(iStatus, iShutdownBehaviour.iDelay); + __ASSERT_DEBUG(!IsActive(), _USB_PANIC(KDummyControllerPanic, EDummyPanicAlreadyActive)); + SetActive(); + break; + + case ENever: + // Don't do anything and never complete + break; + + default: + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity); + break; + } + } + +void CUsbDummyClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const +/** + * Returns information about the interfaces supported by this class. + * + * @param aDescriptorInfo Will be filled in with interface information. + */ + { + aDescriptorInfo.iNumInterfaces = 0; + aDescriptorInfo.iLength = 0; + } + +void CUsbDummyClassController::RunL() +/** + * Standard active object RunL. + */ + { + LOGTEXT3(_L8(">>CUsbDummyClassController::RunL [iStatus=%d,iState=%d]"), + iStatus.Int(), iState); + + if ( iStatus != KErrNone ) + { + // Panic runtime errors from the timer. We can't ignore them, and + // there's no point trying to code round them. This is part of the + // test framework and if it's failing we want to alert the user + // without faffing around. (It invalidates the test.) + _USB_PANIC(KDummyControllerPanic, EDummyPanicUnhandledError); + } + + __ASSERT_DEBUG(iReportStatus, + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadState)); + + switch ( iState ) + { + case EUsbServiceStarting: + // Completion of asynchronous startup... + __ASSERT_DEBUG(iStartupBehaviour.iSynchronicity == EAsynchronous, + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity)); + iState = EUsbServiceStarted; + User::RequestComplete(iReportStatus, iStartupBehaviour.iErrorCode); + iReportStatus = NULL; + break; + + case EUsbServiceStopping: + // Completion of asynchronous shutdown... + __ASSERT_DEBUG(iShutdownBehaviour.iSynchronicity == EAsynchronous, + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadSynchronicity)); + iState = EUsbServiceIdle; + User::RequestComplete(iReportStatus, iShutdownBehaviour.iErrorCode); + iReportStatus = NULL; + break; + + case EUsbServiceIdle: + case EUsbServiceStarted: + default: + _USB_PANIC(KDummyControllerPanic, EDummyPanicBadState); + break; + } + + LOGTEXT(_L8("<