diff -r 7858bc6ead78 -r 9d8b04ca6939 usbengines/usbotgwatcher/src/cusbservicecontrol.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbengines/usbotgwatcher/src/cusbservicecontrol.cpp Fri Jun 04 10:27:39 2010 +0100 @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2008 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: Implementation + * + */ + +#include + +#include "cusbservicecontrol.h" +#include "debug.h" +#include "panic.h" + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CUsbServiceControl::CUsbServiceControl(MUsbServiceControlObserver& aObserver, + RUsb& aUsb) : + CActive(CActive::EPriorityStandard), iObserver(aObserver), iUsb(aUsb), + iPersonalityId(0) + { + CActiveScheduler::Add(this); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CUsbServiceControl::~CUsbServiceControl() + { + LOG_FUNC + + Cancel(); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CUsbServiceControl::ConstructL() + { + LOG_FUNC + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CUsbServiceControl* CUsbServiceControl::NewL( + MUsbServiceControlObserver& aObserver, RUsb& aUsb) + { + LOG_FUNC + + CUsbServiceControl* self = new (ELeave) CUsbServiceControl(aObserver, + aUsb); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); // pop self + return self; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CUsbServiceControl::StartL(TInt aPersonalityId) + { + LOG_FUNC + + LOG1( "aPersonalityId = %d" , aPersonalityId); + + TUsbServiceState serviceState; + TInt err = iUsb.GetServiceState(serviceState); + + if (KErrNone != err) + { + return err; + } + + switch (serviceState) + { + case EUsbServiceIdle: + { + LOG( "UsbServiceState == EUsbServiceIdle" ); + + iPersonalityId = aPersonalityId; // when request completed, this will indicate that we started what we wanted + if (IsActive()) + { + LOG("Request is outstanding, cancelling first" ); + Cancel(); + } + iUsb.TryStart(aPersonalityId, iStatus); + SetActive(); + break; + } + + case EUsbServiceStarted: + { + LOG("UsbServiceState == EUsbServiceStarted"); + + TInt currentPersonality(0); + err = iUsb.GetCurrentPersonalityId(currentPersonality); + if (KErrNone != err) + { + LOG1( "Error getting current personality err = %d" , err); + return err; + } + + if (aPersonalityId == currentPersonality) // already started + { + LOG("Personality already started" ); + iObserver.UsbServiceControlReqCompletedL(KErrInUse); + return KErrNone; + } + + // we need to stop current personality and start service with new personailty id + iPersonalityId = aPersonalityId; // this will indicate that we want to start this personality after + + StopL(); + + // start new personality in RunL() when state is Idle + + break; + } + case EUsbServiceStarting: + { + LOG("UsbServiceState == EUsbServiceStarting" ); + // do exactly the same as in case of EUsbServiceStopping; + // break statement is not required here + } + case EUsbServiceStopping: + { + LOG( "UsbServiceState == EUsbServiceStopping" ); + + // subscribe for usb service state change, and start new usb service once current one started/stopped + iPersonalityId = aPersonalityId; // this will indicate that we want to start this personality + + // this check is needed due to usb service might be stopping by other client + if (IsActive()) + { + LOG( "Request outstanding. Waiting for completion" ); + return KErrNone; // when the outstanding request get completed, we start usb services with iPersonalityId + } + + // otherwise, monitor usb service state + iUsb.ServiceStateNotification(iServiceState, iStatus); + SetActive(); + + break; + } + case EUsbServiceFatalError: + { + LOG( "UsbServiceState == EUsbServiceFatalError" ); + return KErrGeneral; + } + default: + { + PANIC( EUnknownUsbServiceState); + } + } + + return KErrNone; + + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CUsbServiceControl::StopL() + { + LOG_FUNC + + TUsbServiceState serviceState; + TInt err = iUsb.GetServiceState(serviceState); + + LOG2("err = %d; serviceState = %d" , err, serviceState); + + if (KErrNone != err) + { + return err; + } + + switch (serviceState) + { + case EUsbServiceIdle: + { + LOG("UsbServiceState == EUsbServiceIdle" ); + + return KErrNone; + } + + case EUsbServiceStarted: + { + LOG("UsbServiceState == EUsbServiceStarted" ); + + if (IsActive()) + { + LOG("Request is outstanding, cancelling it" ); + Cancel(); + } + iUsb.TryStop(iStatus); + SetActive(); + + break; + } + case EUsbServiceStopping: + { + LOG( "UsbServiceState == EUsbServiceStopping" ); + // do exactly the same as in case of EUsbServiceStarting; + // break statement is not required here + } + case EUsbServiceStarting: + { + LOG("UsbServiceState == EUsbServiceStarting" ); + + // subscribe for usb service state change, and stop usb service once current one started + iPersonalityId = 0; // this will indicate that we do not want to start this personality + + // this check is needed due to usb service might be starting by other client + if (IsActive()) + { + LOG("Request is outstanding, waiting for completion" ); + return KErrNone; // when this request get completed, we request to stop usb services + } + + // otherwise, monitor usb service state + iUsb.ServiceStateNotification(iServiceState, iStatus); + SetActive(); + + break; + } + case EUsbServiceFatalError: + { + LOG("UsbServiceState == EUsbServiceFatalError" ); + return KErrGeneral; + } + default: + { + PANIC( EUnknownUsbServiceState); + } + } + return KErrNone; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CUsbServiceControl::RunL() + { + LOG_FUNC + + LOG1("iStatus = %d" , iStatus.Int()); + + if (KErrNone != iStatus.Int()) + { + iObserver.UsbServiceControlReqCompletedL(iStatus.Int()); + return; + } + + TUsbServiceState serviceState; + TInt err = iUsb.GetServiceState(serviceState); + + if (KErrNone != err) + { + LOG1("Error while getting service state %d" , err); + iObserver.UsbServiceControlReqCompletedL(err); + return; + } + + switch (serviceState) + { + case EUsbServiceIdle: // usb service stopped + { + LOG("UsbServiceState == EUsbServiceIdle" ); + + if (iPersonalityId != 0) // during service stopping, requested to start it + { + LOG1("Requested to start personality %d. Starting it." , iPersonalityId); + TInt personalityId = iPersonalityId; + iPersonalityId = 0; // reset + err = StartL(personalityId); + if (KErrNone != err) + { + iObserver.UsbServiceControlReqCompletedL(err); + } + return; + } + + // otherwise, we've done, notify + iObserver.UsbServiceControlReqCompletedL(KErrNone); + break; + } + + case EUsbServiceStarted: + { + LOG("UsbServiceState == EUsbServiceStarted" ); + + TInt currentPersonality(0); + err = iUsb.GetCurrentPersonalityId(currentPersonality); + if (KErrNone != err) + { + LOG1("Error while getting PersonalityId err = %d" , err); + iObserver.UsbServiceControlReqCompletedL(err); + return; + } + + if (iPersonalityId == currentPersonality) // already done + { + LOG("Personality already started" ); + iPersonalityId = 0; + iObserver.UsbServiceControlReqCompletedL(KErrNone); + return; + } + + if (iPersonalityId == 0) // during service start requested to stop it + { + LOG("Requested to stop personality. Stopping." ); + err = StopL(); + if (KErrNone != err) + { + LOG1("Error while stopping personality err = %d" , err); + iObserver.UsbServiceControlReqCompletedL(err); + } + return; + } + + // otherwise, during service start, requested to start it with another personality + LOG1( "Requested to start personality %d. Starting it.", iPersonalityId); + TInt personalityId = iPersonalityId; + iPersonalityId = 0; // reset + err = StartL(personalityId); + if (KErrNone != err) + { + LOG1("Error while starting personality err = %d" , err); + iObserver.UsbServiceControlReqCompletedL(err); + } + break; + } + + case EUsbServiceStarting: + { + // do exactly same as in EUsbServiceStopping + // break statement is not required here + LOG("State == EUsbServiceStarting. Continue." ); + } + case EUsbServiceStopping: + { + // we are not interested in these states, just continue monitoring + LOG("State == EUsbServiceStopping. Continue." ); + iUsb.ServiceStateNotification(iServiceState, iStatus); + SetActive(); + break; + } + case EUsbServiceFatalError: + { + LOG("UsbServiceState == EUsbServiceFatalError" ); + iObserver.UsbServiceControlReqCompletedL(KErrGeneral); + break; + } + default: + { + PANIC( EUnknownUsbServiceState); + } + } + + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CUsbServiceControl::RunError(TInt aError) + { + LOG_FUNC + LOG1("aError = %d", aError ); + TRAP_IGNORE(iObserver.UsbServiceControlReqCompletedL(aError)); + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CUsbServiceControl::DoCancel() + { + LOG( "Cancelling interest to Usb TryStart.") + iUsb.CancelInterest(RUsb::ETryStart); + LOG( "Cancelling interest to Usb TrySop.") + iUsb.CancelInterest(RUsb::ETryStop); + LOG("Cancelling interest to usb states notifications.") + iUsb.ServiceStateNotificationCancel(); + }