--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usbengines/usbotgwatcher/src/cusbotgwatcher.cpp Fri Jun 04 10:27:39 2010 +0100
@@ -0,0 +1,1126 @@
+/*
+ * 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 <usbpersonalityids.h>
+#include <usbuinotif.h>
+#include <UsbWatcherInternalPSKeys.h>
+#include "cusbotgwatcher.h"
+#include "cusbstate.h"
+#include "cusbstatehostainitiate.h"
+#include "cusbstatehostahost.h"
+#include "cusbstatehostaperipheral.h"
+#include "cusbstatehosthandle.h"
+#include "cusbstatehostdelayhandle.h"
+#include "cusbstatehostdelayattachedhandle.h"
+#include "cusbstatehostdelaynotattachedhandle.h"
+#include "cusbstatehosthandledropping.h"
+#include "cusbstatehostundefined.h"
+#include "cusbwarningnotifier.h"
+#ifndef STIF
+#include "cusbnotifmanager.h"
+#else
+#include "mockcusbnotifmanager.h"
+#endif
+#include "errors.h"
+#include "debug.h"
+#include "panic.h"
+_LIT_SECURITY_POLICY_PASS( KAlwaysPassPolicy );
+_LIT_SECURITY_POLICY_C1( KLocalServicesPolicy, ECapabilityLocalServices );
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbOtgWatcher::CUsbOtgWatcher(RUsb& aUsbMan) :
+ iUsb(aUsbMan), iPersonalityId(KUsbPersonalityIdMTP), iUsbServiceRequest(
+ CUsbServiceControl::ERequestUndefined)
+ {
+ LOG_FUNC
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::ConstructL()
+ {
+ LOG_FUNC
+
+#ifdef _DEBUG
+ SelfTestL();
+#endif
+
+#ifndef STIF
+ LEAVEIFERROR(RProperty::Define(KPSUidUsbWatcher,
+ KUsbWatcherIsPeripheralConnected, RProperty::EInt,
+ KAlwaysPassPolicy, KLocalServicesPolicy));
+
+ LEAVEIFERROR(RProperty::Set(KPSUidUsbWatcher,
+ KUsbWatcherIsPeripheralConnected,
+ KUsbWatcherPeripheralIsNotConnected));
+#endif
+
+ iUsbServiceControl = CUsbServiceControl::NewL(*this, iUsb);
+
+ LEAVEIFERROR(iStates.Append(CUsbStateHostUndefined::NewL(*this)));
+ LEAVEIFERROR(iStates.Append(CUsbStateHostAInitiate::NewL(*this)));
+ LEAVEIFERROR(iStates.Append(CUsbStateHostAHost::NewL(*this)));
+ LEAVEIFERROR(iStates.Append(CUsbStateHostAPeripheral::NewL(*this)));
+
+ LEAVEIFERROR(iStates.Append(CUsbStateHostDelayAttachedHandle::NewL(
+ *this)));
+ LEAVEIFERROR(iStates.Append(
+ CUsbStateHostDelayNotAttachedHandle::NewL(*this)));
+ LEAVEIFERROR(iStates.Append(
+ CUsbStateHostHandleDropping::NewL(*this)));
+
+ iIdPinObserver = CUsbIdPinObserver::NewL();
+ iVBusObserver = CUsbVBusObserver::NewL();
+ iOtgStateObserver = CUsbOtgStateObserver::NewL();
+ iBusActivityObserver = CUsbBusActivityObserver::NewL();
+ iHostEventNotificationObserver = CUsbHostEventNotificationObserver::NewL(
+ &iUsb);
+ iMessageNotificationObserver = CUsbMessageNotificationObserver::NewL(
+ &iUsb);
+
+ iHostState = iStates[EUsbStateHostUndefined];
+
+ // Notif manager must be created at least after VBus observer and iHostState initialization
+ // to allow USb indicator subscribe to its notifications at construction and check their's current states
+ iNotifManager = CUsbNotifManager::NewL(*this);
+
+ iVBusObserver->SubscribeL(*this);
+ iOtgStateObserver->SubscribeL(*this);
+ iBusActivityObserver->SubscribeL(*this);
+ iHostEventNotificationObserver->SubscribeL(*this);
+ iMessageNotificationObserver->SubscribeL(*this);
+ iIdPinObserver->SubscribeL(*this);
+
+ if (CUsbIdPinObserver::EIdPinOn == iIdPinObserver->IdPin())
+ {
+ StartSessionL();
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CUsbOtgWatcher::IsDeviceA()
+ {
+ ASSERT_PANIC(iIdPinObserver != NULL, EIdPinObserverNULLPointer);
+ return (iIdPinObserver->IdPin() == CUsbIdPinObserver::EIdPinOn
+ ? ETrue
+ : EFalse);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CUsbOtgWatcher* CUsbOtgWatcher::NewL(RUsb& aUsbMan)
+ {
+ LOG_FUNC
+
+ CUsbOtgWatcher* self = new (ELeave) CUsbOtgWatcher(aUsbMan);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbOtgWatcher::~CUsbOtgWatcher()
+ {
+ LOG_FUNC
+
+#ifndef STIF
+ RProperty::Delete(KPSUidUsbWatcher, KUsbWatcherIsPeripheralConnected);
+#endif
+
+ // delete Notif manager before VBus observer, due to USB indicator observes VBus
+ delete iNotifManager;
+
+ if (iIdPinObserver)
+ {
+ TRAP_IGNORE(iIdPinObserver->UnsubscribeL(*this));
+ }
+
+ if (iVBusObserver)
+ {
+ TRAP_IGNORE(iVBusObserver->UnsubscribeL(*this));
+ }
+ if (iOtgStateObserver)
+ {
+ TRAP_IGNORE(iOtgStateObserver->UnsubscribeL(*this));
+ }
+ if (iBusActivityObserver)
+ {
+ TRAP_IGNORE(iBusActivityObserver->UnsubscribeL(*this));
+ }
+ if (iHostEventNotificationObserver)
+ {
+ TRAP_IGNORE(iHostEventNotificationObserver->UnsubscribeL(*this));
+ }
+ if (iMessageNotificationObserver)
+ {
+ TRAP_IGNORE(iMessageNotificationObserver->UnsubscribeL(*this));
+ }
+
+ delete iIdPinObserver;
+ delete iVBusObserver;
+ delete iOtgStateObserver;
+ delete iBusActivityObserver;
+ delete iHostEventNotificationObserver;
+ delete iMessageNotificationObserver;
+
+ iOtgStateObservers.Close();
+
+ // Destroy states
+ iStates.ResetAndDestroy();
+ iStates.Close();
+
+ delete iUsbServiceControl;
+
+ iUsb.Close();
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::SetPersonalityL(TRequestStatus& /*aStatus*/,
+ TInt aPersonality)
+ {
+ LOG_FUNC
+
+ LOG1( "aPersonality = %d" , aPersonality);
+
+ // watcher keeps this value, no need to pass it to request object
+ // state can read it from watcher when needed
+ iPersonalityId = aPersonality;
+
+ // more complex processing has to be here, remember aStatus, etc.
+ // pass the request to device state machine
+ iState->SetPersonalityL();
+
+ // the request is not passed to host state machine due to host ignores SetPersonality
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::CancelSetPersonalityL()
+ {
+ LOG_FUNC
+
+ iState->CancelSetPersonalityL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::SetPreviousPersonalityL(TRequestStatus& /*aStatus*/)
+ {
+ LOG_FUNC
+
+ // maybe more complex processing needed here
+ iState->SetPreviousPersonalityL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::SetPreviousPersonalityL()
+ {
+ LOG_FUNC
+
+ iState->SetPreviousPersonalityL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::CancelSetPreviousPersonalityL()
+ {
+ LOG_FUNC
+
+ iState->CancelSetPreviousPersonalityL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::SetPreviousPreviousPersonalityOnDisconnectL()
+ {
+ LOG_FUNC
+
+ }
+
+// From IdPin observer
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::StartSessionL()
+ {
+ LOG_FUNC
+
+ if (!CanStartSessionL())
+ {
+ HandleHostProblemL(EUsbWatcherCanNotStartSession,
+ EUsbStateHostHandleDropping);
+ return;
+ }
+
+ iUsbServiceRequest = CUsbServiceControl::EStartUsbService;
+ TInt err = iUsbServiceControl->StartL(iPersonalityId);
+ if (KErrNone != err)
+ {
+ LOG1( "Can not start usb services. err = %d" , err);
+ HandleHostProblemL(EUsbWatcherCanNotStartUsbServices,
+ EUsbStateHostHandleDropping);
+ return;
+ }
+
+ // call back from iUsbServiceControl->Start(iPersonalityId) call is UsbServiceControlReqCompletedL(TInt aError)
+ // so, continue there if everything is OK
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::HandleHostProblemL(TInt aWhatKindOf,
+ TUsbStateIds aInState)
+ {
+ LOG_FUNC
+ HostHandle(aInState)->SetWhat(aWhatKindOf);
+ ChangeHostStateL(aInState);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::IdPinOnL()
+ {
+ LOG_FUNC
+ StartSessionL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::IdPinOffL()
+ {
+ LOG_FUNC
+
+ ChangeHostStateL(EUsbStateHostUndefined);
+
+ iNotifManager->CloseAllNotifiers();
+
+ Usb().DisableFunctionDriverLoading();
+
+ iUsbServiceRequest = CUsbServiceControl::EStopUsbService;
+ TInt err = iUsbServiceControl->StopL();
+
+ LOG1( "iUsbServiceControl->Stop() err = %d", err );
+
+ if (KErrNone != err)
+ {
+ LOG( "ErrorStoppingUsbServices" );
+ PANIC(ECanNotStopUsbServices);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::IdPinErrorL(TInt aError)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ HandleHostProblemL(EUsbWatcherIdPinError, EUsbStateHostHandleDropping);
+
+ }
+
+// From VBus observer
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::VBusDownL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->VBusDownL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::VBusUpL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->VBusUpL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::VBusObserverErrorL(TInt aError)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ HandleHostProblemL(EUsbWatcherVBusObserverError,
+ EUsbStateHostHandleDropping);
+ }
+
+// From OTG state observer
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::AIdleL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->AIdleL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::AHostL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->AHostL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::APeripheralL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->APeripheralL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::AVBusErrorL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->AVBusErrorL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::BIdleL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->BIdleL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::BPeripheralL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->BPeripheralL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::BHostL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->BHostL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::OtgStateErrorL(TInt aError)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ HandleHostProblemL(EUsbWatcherOtgStateError, EUsbStateHostHandleDropping);
+ }
+
+// From bus activity observer
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::BusIdleL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->BusIdleL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::BusActiveL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->BusActiveL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::BusActivityErrorL(TInt aError)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ // no action, continue
+ }
+
+// From Host Event notification observer
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::DeviceAttachedL(TDeviceEventInformation aTdi)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->DeviceAttachedL(aTdi);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::DeviceDetachedL(TDeviceEventInformation aTdi)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->DeviceDetachedL(aTdi);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::DriverLoadSuccessL(TDeviceEventInformation aTdi)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->DriverLoadSuccessL(aTdi);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::DriverLoadPartialSuccessL(TDeviceEventInformation aTdi)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->DriverLoadPartialSuccessL(aTdi);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::DriverLoadFailureL(TDeviceEventInformation aTdi)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->DriverLoadFailureL(aTdi);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::HostEventNotificationErrorL(TInt aError)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ HandleHostProblemL(EUsbWatcherHostEventNotificationError,
+ EUsbStateHostHandleDropping);
+ }
+
+// From message notification observer
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::MessageNotificationReceivedL(TInt aMessage)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->MessageNotificationReceivedL(aMessage);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::BadHubPositionL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->BadHubPositionL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::VBusErrorL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->VBusErrorL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::SrpReceivedL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->SrpReceivedL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::SessionRequestedL()
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ iHostState->SessionRequestedL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::MessageNotificationErrorL(TInt aError)
+ {
+ ASSERT_PANIC(iHostState != NULL, EBadHostState);
+ HandleHostProblemL(EUsbWatcherMessageNotificationError,
+ EUsbStateHostHandleDropping);
+ }
+
+// ---------------------------------------------------------------------------
+// getters
+// ---------------------------------------------------------------------------
+//
+CUsbIdPinObserver* CUsbOtgWatcher::IdPinObserver() const
+ {
+ return iIdPinObserver;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbVBusObserver* CUsbOtgWatcher::VBusObserver() const
+ {
+ return iVBusObserver;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbOtgStateObserver* CUsbOtgWatcher::OtgStateObserver() const
+ {
+ return iOtgStateObserver;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbBusActivityObserver* CUsbOtgWatcher::BusActivityObserver() const
+ {
+ return iBusActivityObserver;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbHostEventNotificationObserver* CUsbOtgWatcher::HostEventNotificationObserver() const
+ {
+ return iHostEventNotificationObserver;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbMessageNotificationObserver* CUsbOtgWatcher::MessageNotificationObserver() const
+ {
+
+ return iMessageNotificationObserver;
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+RUsb& CUsbOtgWatcher::Usb()
+ {
+ return iUsb;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbState* CUsbOtgWatcher::CurrentState() const
+ {
+ return iState;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbState* CUsbOtgWatcher::CurrentHostState() const
+ {
+ return iHostState;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbState* CUsbOtgWatcher::State(TUsbStateIds aStateId) const
+ {
+ return iStates[aStateId];
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbStateHostHandle* CUsbOtgWatcher::HostHandle(TUsbStateIds aInState) const
+ {
+ ASSERT_PANIC(iStates[aInState] != NULL, EBadState);
+
+ return (CUsbStateHostHandle*) iStates[aInState];
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::ChangeStateL(TUsbStateIds aNewStateId)
+ {
+ LOG_FUNC
+
+ LOG1( "aNewState = %d" , aNewStateId);
+
+ if (NULL != iState)
+ {
+ iState->JustBeforeLeavingThisStateL();
+ }
+
+ // sets new state
+
+ // be careful to add states into States in exactly the same order as they enumerated
+ // this method will work right as long as states, which in the enumeration, is added
+ // to the list iStates in the same order as they enumerated and no one state is added,
+ // if all previous states are not added. no need to add all states, but if added -
+ // previous all must be added.
+ // For the general case, when some states added, some not, this method has to implement search by state ID. for this CUsbOtgWatcher::Id() is maintained.
+
+ iState = iStates[aNewStateId];
+
+ ASSERT_PANIC(iState != NULL, EBadState);
+
+ iState->JustAdvancedToThisStateL(); // do any initial activity, once advanced to the state
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::ChangeHostStateL(TUsbStateIds aNewStateId)
+ {
+ LOG_FUNC
+
+ LOG1( "aNewState = %d", aNewStateId);
+
+ if (NULL != iHostState)
+ {
+ iHostState->JustBeforeLeavingThisStateL();
+ }
+
+ // set new state
+
+ // be careful to add states into States in exactly the same order as they enumerated
+ // this method will work right as long as states, which in the enumeration, is added
+ // to the list iStates in the same order as they enumerated and no one state is added,
+ // if all previous states are not added. no need to add all states, but if added -
+ // previous all must be added.
+ // For the general case, when some states added, some not, this method has to implement search by state ID. for this CUsbOtgWatcher::Id() is maintained.
+
+ iHostState = iStates[aNewStateId];
+
+ ASSERT_PANIC(iHostState != NULL, EBadState)
+
+ iHostState->JustAdvancedToThisStateL(); // checks if there are conditions for advancing to another state(s)
+
+ // notify state change to observers
+ for (TInt i(0); i < iOtgStateObservers.Count(); ++i)
+ {
+ iOtgStateObservers[i]->OtgWatcherStateChangedL(iHostState->Id());
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool CUsbOtgWatcher::CanStartSessionL()
+ {
+ // define policy here
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::PrintStateToLog()
+ {
+ LOG1( "Current state id = %d" , iHostState->Id());
+ LOG1( "IdPin = %d" , iIdPinObserver->IdPin());
+ LOG1( "VBus = %d" , iVBusObserver->VBus());
+ LOG1( "OtgState = %d" , iOtgStateObserver->OtgState());
+ LOG1( "BusActivity = %d" , iBusActivityObserver->BusActivity());
+
+ TInt isPeripheralConnected(KUsbWatcherPeripheralIsNotConnected);
+
+ RProperty::Get(KPSUidUsbWatcher, KUsbWatcherIsPeripheralConnected,
+ isPeripheralConnected);
+
+ LOG1( "IsPeripheralConnected = %d" , isPeripheralConnected);
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+CUsbNotifManager* CUsbOtgWatcher::NotifManager()
+ {
+ return iNotifManager;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::UsbServiceControlReqCompletedL(TInt aError)
+ {
+ LOG_FUNC
+
+ LOG1( "aError = %d" , aError);
+
+ iUsbServiceRequest = CUsbServiceControl::ERequestUndefined;
+
+ switch (aError)
+ {
+ case KErrInUse:
+ // usb services already started (this might happen if more than one idpin on event come)
+ {
+ return;
+ }
+
+ case KErrNone:
+ {
+ break; // do normal routine
+ }
+ case KErrNoMemory:
+ {
+ HandleHostProblemL(EUsbWatcherNoMemory,
+ EUsbStateHostHandleDropping);
+ return;
+ }
+
+ default:
+ // handle the issue
+ {
+ if (iUsbServiceRequest == CUsbServiceControl::EStartUsbService) // Handle only start issues
+ {
+ HandleHostProblemL(EUsbWatcherNoMemory,
+ EUsbStateHostHandleDropping);
+ }
+
+ iUsbServiceRequest = CUsbServiceControl::ERequestUndefined;
+ return;
+ }
+ }
+
+ iUsbServiceRequest = CUsbServiceControl::ERequestUndefined;
+
+ TUsbServiceState serviceState;
+ TInt err = iUsb.GetServiceState(serviceState);
+
+ if (KErrNone != err)
+ {
+ LOG1( "Error when requesting GetServiceState = %d" , err);
+ HandleHostProblemL(EUsbWatcherCanNotStartUsbServices,
+ EUsbStateHostHandleDropping);
+ return;
+ }
+
+ switch (serviceState)
+ {
+ case EUsbServiceIdle: // just stopped usb service
+
+ {
+ LOG("UsbServiceState == EUsbServiceIdle" );
+ // do nothing
+ break;
+ }
+
+ case EUsbServiceStarted: // just started usb service
+
+ {
+ LOG( "UsbServiceState == EUsbServiceStarted" );
+
+ ChangeHostStateL(EUsbStateHostAInitiate);
+
+ break;
+ }
+ case EUsbServiceStarting:
+ {
+ LOG("UsbServiceState == EUsbServiceStarting" );
+ // should not receive that, due to call back is called when service stopped or started
+ // therefore scream
+ PANIC(EUnexpectedUsbServiceState);
+ break;
+ }
+ case EUsbServiceStopping:
+ {
+ LOG("UsbServiceState == EUsbServiceStopping" );
+ // should not receive that, due to call back is called when service stopped or started
+ // therefore scream
+ PANIC(EUnexpectedUsbServiceState);
+ break;
+ }
+ case EUsbServiceFatalError:
+ {
+ LOG( "UsbServiceState == EUsbServiceFatalError" );
+ PANIC(EUnexpectedUsbServiceState);
+ break;
+ }
+
+ default:
+ {
+ PANIC(EUnknownUsbServiceState);
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt CUsbOtgWatcher::SelfTestL()
+ {
+#ifdef _DEBUG
+ LOG_FUNC
+
+ // create all the observers
+ iIdPinObserver = CUsbIdPinObserver::NewL();
+ iVBusObserver = CUsbVBusObserver::NewL();
+ iOtgStateObserver = CUsbOtgStateObserver::NewL();
+ iBusActivityObserver = CUsbBusActivityObserver::NewL();
+ iHostEventNotificationObserver = CUsbHostEventNotificationObserver::NewL(
+ &iUsb);
+ iMessageNotificationObserver = CUsbMessageNotificationObserver::NewL(
+ &iUsb);
+
+ LOG( "Observers getters" );
+
+ if (iIdPinObserver != IdPinObserver())
+ {
+ LEAVE(KErrGeneral);
+ }
+
+ if (iOtgStateObserver != OtgStateObserver())
+ {
+ LEAVE(KErrGeneral);
+ }
+
+ if (iBusActivityObserver != BusActivityObserver())
+ {
+ LEAVE(KErrGeneral);
+ }
+
+ if (iHostEventNotificationObserver != HostEventNotificationObserver())
+ {
+ LEAVE(KErrGeneral);
+ }
+
+ if (iMessageNotificationObserver != MessageNotificationObserver())
+ {
+ LEAVE(KErrGeneral);
+ }
+
+ LOG( "Observers destructors" );
+
+ // idpinobserver is deleted later
+ // Vbus observer is deleted later
+
+ delete iOtgStateObserver;
+ iOtgStateObserver = 0;
+ delete iBusActivityObserver;
+ iBusActivityObserver = 0;
+ delete iHostEventNotificationObserver;
+ iHostEventNotificationObserver = 0;
+ delete iMessageNotificationObserver;
+ iMessageNotificationObserver = 0;
+
+ LOG("Creating states");
+
+ LEAVEIFERROR(iStates.Append(CUsbStateHostUndefined::NewL(*this)));
+ LEAVEIFERROR(iStates.Append(CUsbStateHostAInitiate::NewL(*this)));
+ LEAVEIFERROR(iStates.Append(CUsbStateHostAHost::NewL(*this)));
+ LEAVEIFERROR(iStates.Append(CUsbStateHostAPeripheral::NewL(*this)));
+ LEAVEIFERROR(iStates.Append(CUsbStateHostDelayAttachedHandle::NewL(
+ *this)));
+ LEAVEIFERROR(iStates.Append(
+ CUsbStateHostDelayNotAttachedHandle::NewL(*this)));
+ LEAVEIFERROR(iStates.Append(
+ CUsbStateHostHandleDropping::NewL(*this)));
+
+ LOG("Check State()" );
+
+ if (iStates[EUsbStateHostAInitiate] != State(EUsbStateHostAInitiate))
+ {
+ LEAVE(KErrGeneral);
+ }
+
+ LOG("Check CurrentHostState()" );
+
+ iHostState = iStates[EUsbStateHostAInitiate];
+
+ if (iStates[EUsbStateHostAInitiate] != CurrentHostState())
+ {
+ LEAVE(KErrGeneral);
+ }
+
+ LOG("NotifManager and WarningNotifier." );
+
+ CUsbNotifManager* usbnotifmanager = CUsbNotifManager::NewL(*this);
+ RNotifier rnotifier;
+ LEAVEIFERROR(rnotifier.Connect());
+ CUsbWarningNotifier* usbnotifier = CUsbWarningNotifier::NewL(rnotifier,
+ *usbnotifmanager, EUsbOtgPartiallySupportedDevice);
+ usbnotifier->IsFeedbackNeeded();
+
+ LOG( "NotifManager and WarningNotifier destruction." );
+
+ delete usbnotifier;
+ rnotifier.Close();
+ delete usbnotifmanager;
+
+ // VBus observer is deleted here, due to it is used by usbnotifmanager.usbindicatornotifier
+ delete iVBusObserver;
+ iVBusObserver = 0;
+
+ // id pin observer is deleted here due to it is used by usbnotifmanager.usbindicatornotifier
+ delete iIdPinObserver;
+ iIdPinObserver = 0;
+
+ LOG("Destructing states");
+
+ iStates.ResetAndDestroy();
+
+ LOG( "Check UsbServiceControl" );
+
+ CUsbServiceControl* usbServiceControl = CUsbServiceControl::NewL(*this,
+ iUsb);
+ usbServiceControl->RunError(KErrNone);
+ delete usbServiceControl;
+
+ LOG("All completed OK" );
+#endif
+ return KErrNone;
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::SubscribeL(MUsbOtgWatcherStateObserver& aObserver)
+ {
+ LOG_FUNC
+
+ // check if the same observer already exist in a list
+ if (KErrNotFound != iOtgStateObservers.Find(&aObserver))
+ {
+ LOG( "Observer already exists" );
+ PANIC(EObserverAlreadyExists);
+ return;
+ }
+ iOtgStateObservers.AppendL(&aObserver);
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void CUsbOtgWatcher::UnsubscribeL(MUsbOtgWatcherStateObserver& aObserver)
+ {
+ LOG_FUNC
+
+ TInt i(iOtgStateObservers.Find(&aObserver));
+ if (KErrNotFound == i)
+ {
+ LOG( "Observer not found" );
+ PANIC(ECanNotFindUsbOtgWatcherStateObserver);
+ return;
+ }
+
+ iOtgStateObservers.Remove(i);
+ }