diff -r 000000000000 -r 1e05558e2206 usbengines/usbdevcon/src/cusbdevcon.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbengines/usbdevcon/src/cusbdevcon.cpp Thu Dec 17 09:14:30 2009 +0200 @@ -0,0 +1,419 @@ +/* +* Copyright (c) 2007 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: Takes control of device&vendor-specific control messages over EP0 +* +*/ + + +#include + +#include "cusbdevcon.h" +#include "cusbstatewatcher.h" +#include "crequestshandler.h" +#include "cstatemachine.h" +#include "debug.h" + +// LITERALS +_LIT( KUsbDevConName, "UsbDevCon" ); + +// --------------------------------------------------------------------------- +// Two-phase construction +// --------------------------------------------------------------------------- +// +CUsbDevCon* CUsbDevCon::NewLC() + { + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::NewLC" ) ); + + CUsbDevCon* self = new (ELeave) CUsbDevCon(); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// Two-phase construction +// --------------------------------------------------------------------------- +// +CUsbDevCon* CUsbDevCon::NewL() + { + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::NewL" ) ); + + CUsbDevCon* self = CUsbDevCon::NewLC(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Two-phase construction +// --------------------------------------------------------------------------- +// +void CUsbDevCon::ConstructL() + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ConstructL" ) ); + + // usbc + User::LeaveIfError(iLdd.Open(0)); + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ConstructL RDevUsbcClient opened OK" ) ); + + // usb manager + User::LeaveIfError(iUsbManager.Connect()); + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ConstructL RUsb connected OK" ) ); + + // usb watcher + User::LeaveIfError(iUsbWatcher.Connect()); + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ConstructL RUsbWatcher connected OK" ) ); + + // device state watcher + iUsbStateWatcher = CUsbStateWatcher::NewL(*this, iLdd); + + // Requests handler + iRequestsHandler = CRequestsHandler::NewL(iLdd, iUsbWatcher, iUsbManager); + + // state machine + iStateMachine = CStateMachine::NewL(*iRequestsHandler, iLdd); + + User::LeaveIfError(iShutdownTimer.CreateLocal()); + + // get usb state, and act accordingly to it + TUsbcDeviceState usbcstate(EUsbcDeviceStateUndefined); + iLdd.DeviceStatus(usbcstate); + + FTRACE(FPrint( + _L("[USBDEVCON]\tCUsbDevCon::ConstructL: Usbc state = %d" ),usbcstate)); + + ActAccordinglyToUsbStateL(usbcstate); + + } + +// --------------------------------------------------------------------------- +// Default construction +// --------------------------------------------------------------------------- +// +CUsbDevCon::CUsbDevCon() : CActive(EPriorityStandard), + iUsbStateWatcher(0), + iStateMachine (0), + iRequestsHandler(0), + iPrevUsbState(EUsbcDeviceStateUndefined) + { + CActiveScheduler::Add(this); + } + +// --------------------------------------------------------------------------- +// Destruction +// --------------------------------------------------------------------------- +// +CUsbDevCon::~CUsbDevCon() + { + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::~CUsbDevCon" ) ); + + Cancel(); + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::~CUsbDevCon Cancel" ) ); + + delete iStateMachine; + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::~CUsbDevCon StateMachine" ) ); + + delete iRequestsHandler; + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::~CUsbDevCon RequestsHandler" ) ); + + delete iUsbStateWatcher; + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::~CUsbDevCon UsbStateWatcher" ) ); + + iUsbWatcher.Close(); + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::~CUsbDevCon UsbWatcher" ) ); + + iUsbManager.Close(); + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::~CUsbDevCon UsbManager" ) ); + + iLdd.Close(); + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::~CUsbDevCon LDD" ) ); + + iShutdownTimer.Close(); + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::~CUsbDevCon Timer" ) ); + + } + +// --------------------------------------------------------------------------- +// Acts accordingly to USB state +// --------------------------------------------------------------------------- +// +void CUsbDevCon::ActAccordinglyToUsbStateL(TUsbcDeviceState aUsbcState) + { + + switch (aUsbcState) + { + case EUsbcDeviceStateUndefined: + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ActAccordinglyToUsbStateL State: Undefined" ) ); + + StopL(); + break; + } + + case EUsbcDeviceStateAttached: + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ActAccordinglyToUsbStateL State: Attached" ) ); + + StartL(); + break; + } + + case EUsbcDeviceStatePowered: + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ActAccordinglyToUsbStateL State: Powered" ) ); + + StartL(); + break; + } + + case EUsbcDeviceStateDefault: + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ActAccordinglyToUsbStateL State: Default" ) ); + + StartL(); + break; + } + + case EUsbcDeviceStateAddress: + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ActAccordinglyToUsbStateL State: Addressed" ) ); + + StartL(); + break; + } + + case EUsbcDeviceStateConfigured: + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ActAccordinglyToUsbStateL State: Configured" ) ); + + if(iPrevUsbState == EUsbcDeviceStateSuspended) + { + ResumeL(); + } + else + { + StartL(); + } + + break; + } + case EUsbcDeviceStateSuspended: + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ActAccordinglyToUsbStateL State: Suspended" ) ); + + break; + } + + default: + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ActAccordinglyToUsbStateL State: ***Undefined***" ) ); + + StopL(); + break; + } + } + + iPrevUsbState = aUsbcState; + + // listen to USB states change + iUsbStateWatcher->Activate(); + + } + + // --------------------------------------------------------------------------- +// Timer is completed +// --------------------------------------------------------------------------- +// +void CUsbDevCon::RunL() + { + FTRACE(FPrint( + _L("[USBDEVCON]\tCUsbDevCon::RunL: iStatus = %d" ),iStatus.Int())); + + if(KErrNone == iStatus.Int()) + { + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::RunL Exiting usbdevcon" ) ); + + // Shutdown timer is finished, exit program + CUsbDevCon:: ~CUsbDevCon(); // destruct resources + User::Exit(KErrNone); + } + } + +// --------------------------------------------------------------------------- +// Cancellation +// --------------------------------------------------------------------------- +// +void CUsbDevCon::DoCancel() + { + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::DoCancel" ) ) + iShutdownTimer.Cancel(); + } + +// ---------------------------------------------------------------------------- +// Standard active object error function. +// ---------------------------------------------------------------------------- +// +TInt CUsbDevCon::RunError( TInt /*aError*/ ) + { + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Starts UsbDevCon services +// --------------------------------------------------------------------------- +// +void CUsbDevCon::StartL() + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::StartL" ) ); + + if(!iStateMachine->IsStarted()) + { + // set device control + User::LeaveIfError(iLdd.SetDeviceControl()); + + // start state machine + iStateMachine->Start(); + + } + + // Cancel shutdown timer, if it is started + iShutdownTimer.Cancel(); + } + +// --------------------------------------------------------------------------- +// Stops UsbDevCon services +// --------------------------------------------------------------------------- +// +void CUsbDevCon::StopL() + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::StopL" ) ); + + if(iStateMachine->IsStarted()) + { + + // stop state machine + iStateMachine->Stop(); + + // release device control + User::LeaveIfError(iLdd.ReleaseDeviceControl()); + + } + + if(!IsActive()) // not waiting for timer + { + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::StopL Starting timer" ) ); + // run timer + iShutdownTimer.Cancel(); + + // RunL will be called after KInactiveTimeForShutDown milliseconds + iShutdownTimer.After(iStatus, TTimeIntervalMicroSeconds32(KInactiveTimeForShutDown)); + SetActive(); + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::StopL Timer is started" ) ); + } + } + +// --------------------------------------------------------------------------- +// Resumes UsbDevCon services +// --------------------------------------------------------------------------- +// +void CUsbDevCon::ResumeL() + { + + FLOG( _L( "[USBDEVCON]\tCUsbDevCon::ResumeL" ) ); + + // Resume state machine + StartL(); + + } + +// ---------------------------------------------------------------------------- +// Constructs and installs the active scheduler, constructs UsbDevCon object. +// ---------------------------------------------------------------------------- +// +static void StartUsbDevConL() + { + + FLOG( _L( "[USBDEVCON]\tStartUsbDevConL" ) ); + + // Construct and install the active scheduler + CActiveScheduler *myScheduler = new ( ELeave ) CActiveScheduler(); + + // Push onto the cleanup stack + CleanupStack::PushL( myScheduler ); + + // Install as the active scheduler + CActiveScheduler::Install( myScheduler ); + + CUsbDevCon* instance = CUsbDevCon::NewLC(); + + RProcess::Rendezvous(KErrNone); // signal to starter process, that usbdevcon started OK or failed to start + + FLOG( _L( "[USBDEVCON]\tStartUsbDevConL Usbdevcon is started successfully" ) ); + + // returns only when UsbDevCon closing + CActiveScheduler::Start(); + + CleanupStack::PopAndDestroy( instance ); + CleanupStack::PopAndDestroy( myScheduler ); + } + +// --------------------------------------------------------------------------- +// Main function of the application executable. +// --------------------------------------------------------------------------- +// +GLDEF_C TInt E32Main() + { + TInt err; + + // rename the thread so it is easy to find the panic application + err = User::RenameThread(KUsbDevConName); + + if(KErrNone != err) + { + return err; + } + + __UHEAP_MARK; + + // create clean-up stack + CTrapCleanup* cleanup = CTrapCleanup::New(); + + TRAP( err, StartUsbDevConL() ); + + delete cleanup; // destroy clean-up stack + __UHEAP_MARKEND; + + return err; + } + + +