diff -r 000000000000 -r c9bc50fca66e usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/src/Stub3CC.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbmgmt/usbmgrtest/t_usbmanager_suite/Stub3CC/src/Stub3CC.cpp Tue Feb 02 02:02:59 2010 +0200 @@ -0,0 +1,403 @@ +/* +* 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: +* Adheres to the UsbMan USB Class Controller API and talks to C32 +* to manage the stub3.CSY that is used to provide a virtual +* serial port service to clients +* +*/ + +/** + @file +*/ + +#include "Stub3CC.h" +#include +#include +#include +#include + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, "STUB3CC"); +#endif + + +#include "usbmaninternalconstants.h" + + +// Panic category +_LIT( Kstub3CcPanicCategory, "Usbstub3Cc" ); + + +/** + * Panic codes for the USB stub3 Class Controller. + */ +enum Tstub3CcPanic + { + /** Class called while in an illegal state */ + EBadApiCall = 0, + /** Asynchronous function called (not needed, as all requests complete synchronously) */ + EUnusedFunction = 1, + /** Error reading ini file. */ + EPanicBadIniFile = 2, + /** Bad value for the iNumberOfstub3Functions member.*/ + EPanicBadNumberOfstub3Functions = 3, + + EPanicUnexpectedStatus, + EPanicUnexpectedState + + }; + +_LIT16(KIfcName, "SubCC 1 Interface"); +const TInt KMaxPacketTypeInterrupt = 64; +const TInt KPollInterval = 128; + + + + +/** + * Constructs a CUsbstub3ClassController object + * + * @param aOwner USB Device that owns and manages the class + * + * @return A new CUsbstub3ClassController object + */ +CUsbstub3ClassController* CUsbstub3ClassController::NewL( + MUsbClassControllerNotify& aOwner) + { + CUsbstub3ClassController* r = new (ELeave) CUsbstub3ClassController(aOwner); + CleanupStack::PushL(r); + r->ConstructL(); + CleanupStack::Pop(); + return r; + } + +/** + * Destructor + */ +CUsbstub3ClassController::~CUsbstub3ClassController() + { + Cancel(); + + iTimer.Close(); + +#ifndef __WINS__ + iLdd.Close(); +#endif + + } + + + +/** + * Constructor. + * + * @param aOwner USB Device that owns and manages the class + */ +CUsbstub3ClassController::CUsbstub3ClassController( + MUsbClassControllerNotify& aOwner) + : CUsbClassControllerPlugIn(aOwner, Kstub3StartupPriority), + iStartDelay(Kstub3CCDefaultDelay), + iStopDelay(Kstub3CCDefaultDelay), + iFailToStart(EFalse), + iFailToStop(EFalse) + + { + iTimer.CreateLocal(); + } + + + +/** + * 2nd Phase Construction. + */ +void CUsbstub3ClassController::ConstructL() + { + //read INI file + TInt ret; + CESockIniData* ini = 0; + _LIT(KIniFile, "c:\\testdata\\config\\stub3cc.ini"); + TRAP(ret, ini=CESockIniData::NewL(KIniFile)); + if(ret!=KErrNone) + return; + + CleanupStack::PushL(ini); + + TInt val; + if ((ini->FindVar(_L("0x10203289"),_L("StartDelay"), val))) + { + iStartDelay = val; + } + if ((ini->FindVar(_L("0x10203289"),_L("StopDelay"), val))) + { + iStopDelay = val; + } + if ((ini->FindVar(_L("0x10203289"),_L("FailToStart"), val)) && val!=0) + { + iFailToStart = ETrue; + } + if ((ini->FindVar(_L("0x10203289"),_L("FailToStop"), val)) && val!=0 ) + { + iFailToStop = ETrue; + } + CleanupStack::PopAndDestroy(ini); + } + +/** + * Called by UsbMan when it wants to start the USB stub3 class. This always + * completes immediately. + * + * @param aStatus The caller's request status, filled in with an error code + */ +void CUsbstub3ClassController::Start(TRequestStatus& aStatus) + { + LOG_FUNC + + aStatus = KRequestPending; + iReportStatus = &aStatus; + //If we are already started then just complete the request. + if (iState == EUsbServiceStarted) + { + User::RequestComplete(iReportStatus, KErrNone); + return; + } + + if (iFailToStart) + { + User::RequestComplete(iReportStatus, KErrGeneral); + return; + } + + iState = EUsbServiceStarting; + +#ifndef __WINS__ + TInt ret = iLdd.Open(0); + LOGTEXT2(_L8("Open LDD, ret=%d"), ret); + ret = SetUpInterface(); + LOGTEXT2(_L8("SetUpInterface(), ret=%d"), ret); +#endif + + + iTimer.After(iStatus, iStartDelay*1000); //convert from usec to msec + SetActive(); + } + +/** + * Called by UsbMan when it wants to stop the USB stub3 class. + * + * @param aStatus The caller's request status: always set to KErrNone + */ +void CUsbstub3ClassController::Stop(TRequestStatus& aStatus) + { + LOG_FUNC + + aStatus = KRequestPending; + iReportStatus = &aStatus; + //If we are already idle then just complete the request. + if (iState == EUsbServiceIdle) + { + User::RequestComplete(iReportStatus, KErrNone); + return; + } + + if (iFailToStop) + { + User::RequestComplete(iReportStatus, KErrGeneral); + return; + } + + iState = EUsbServiceStopping; + +#ifndef __WINS__ + iLdd.Close(); +#endif + + + iTimer.After(iStatus, iStopDelay*1000); //convert from usec to msec + SetActive(); + } + +/** + * Gets information about the descriptor which this class provides. + * + * @param aDescriptorInfo Descriptor info structure filled in by this function + */ +void CUsbstub3ClassController::GetDescriptorInfo(TUsbDescriptor& aDescriptorInfo) const + { + LOG_FUNC + + aDescriptorInfo.iLength = Kstub3DescriptorLength; + aDescriptorInfo.iNumInterfaces = Kstub3NumberOfInterfacesPerstub3Function; + } + + +/** + * Standard active object RunL. + */ +void CUsbstub3ClassController::RunL() + { + LOG_FUNC + + __ASSERT_DEBUG( iStatus == KErrNone, _USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedStatus) ); + switch (iState) + { + case EUsbServiceStarting: + iState = EUsbServiceStarted; + break; + case EUsbServiceStopping: + iState = EUsbServiceIdle; + break; + default: + _USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedState); + } + *iReportStatus = KErrNone; + User::RequestComplete(iReportStatus, iStatus.Int()); + } + +/** + * Standard active object cancellation function. Never called because this + * class has no asynchronous requests. + */ +void CUsbstub3ClassController::DoCancel() + { + + if (IsActive()) + { + iTimer.Cancel(); + } + switch (iState) + { + case EUsbServiceStarting: + iState = EUsbServiceIdle; + break; + case EUsbServiceStopping: + iState = EUsbServiceStarted; + break; + default: + _USB_PANIC(Kstub3CcPanicCategory, EPanicUnexpectedState); + } + *iReportStatus = KErrNone; + User::RequestComplete(iReportStatus, KErrCancel); + } + +/** + * Standard active object error function. Never called because this class has + * no asynchronous requests, and hence its RunL is never called. + * + * @param aError The error code (unused) + * @return Always KErrNone to avoid an active scheduler panic + */ +TInt CUsbstub3ClassController::RunError(TInt /*aError*/) + { + __ASSERT_DEBUG( EFalse, _USB_PANIC(Kstub3CcPanicCategory, EUnusedFunction) ); + return KErrNone; + } + +TInt CUsbstub3ClassController::SetUpInterface() +/** + * Set up the interface for use. This involves finding a "Interrupt IN" + * endpoint and, if found, configuring the interface. + */ + { + LOG_FUNC + + TUsbDeviceCaps dCaps; + TInt ret = iLdd.DeviceCaps(dCaps); + LOGTEXT(_L8("\tchecking result of DeviceCaps")); + if ( ret ) + { + LOGTEXT2(_L8("<(dCaps().iTotalEndpoints); + LOGTEXT2(_L8("\tiTotalEndpoints = %d"), totalEndpoints); + if ( totalEndpoints < KRequiredNumberOfEndpoints ) + { + LOGTEXT2(_L8("<(data), sizeof(data), sizeof(data)); + ret = iLdd.EndpointCaps(dataptr); + LOGTEXT(_L8("\tchecking result of EndpointCaps")); + if ( ret ) + { + LOGTEXT2(_L8("<iTypesAndDir & (KUsbEpTypeInterrupt | KUsbEpDirIn)) == + (KUsbEpTypeInterrupt | KUsbEpDirIn)) + { + // EEndpoint1 is interrupt endpoint + ifc().iEndpointData[0].iType = KUsbEpTypeInterrupt; + ifc().iEndpointData[0].iDir = KUsbEpDirIn; + + //get the max packet size it can potentially support + //it's possible that it can support Isoch (1023) which is greater + //than max for Int at 64 + TInt maxSize = Min(caps->MaxPacketSize(), KMaxPacketTypeInterrupt); + + ifc().iEndpointData[0].iSize = maxSize; + + ifc().iEndpointData[0].iInterval = KPollInterval; + epFound = ETrue; + break; + } + } + LOGTEXT(_L8("\tchecking epFound")); + if ( !epFound ) + { + LOGTEXT2(_L8("<