usbengines/usbotgwatcher/src/cusbotgwatcher.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 09:14:30 +0200
changeset 0 1e05558e2206
child 1 705ec7b86991
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2008-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:  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 "cusbstatehostaidle.h"
#include "cusbstatehosthandle.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)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::CUsbOtgWatcher" ) );
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::ConstructL()
    {

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::ConstructL" ) );

#ifdef _DEBUG
    SelfTestL();
#endif

#ifndef STIF
    User::LeaveIfError(RProperty::Define( KPSUidUsbWatcher,
            KUsbWatcherIsPeripheralConnected, RProperty::EInt, KAlwaysPassPolicy,
                KLocalServicesPolicy ) );

    User::LeaveIfError( RProperty::Set( KPSUidUsbWatcher,
            KUsbWatcherIsPeripheralConnected,
            KUsbWatcherPeripheralIsNotConnected ) );
#endif
    
    iNotifManager = CUsbNotifManager::NewL();
    iUsbServiceControl = CUsbServiceControl::NewL(this, iUsb);

    User::LeaveIfError(iStates.Append(CUsbStateHostAInitiate::NewL(this)));
    User::LeaveIfError(iStates.Append(CUsbStateHostAHost::NewL(this)));
    User::LeaveIfError(iStates.Append(CUsbStateHostAPeripheral::NewL(this)));
    User::LeaveIfError(iStates.Append(CUsbStateHostAIdle::NewL(this)));
    User::LeaveIfError(iStates.Append(CUsbStateHostHandle::NewL(this)));

    iIdPinObserver = CUsbIdPinObserver::NewL();
    iVBusObserver = CUsbVBusObserver::NewL();
    iOtgStateObserver = CUsbOtgStateObserver::NewL();
    iBusActivityObserver = CUsbBusActivityObserver::NewL();
    iHostEventNotificationObserver = CUsbHostEventNotificationObserver::NewL(
            &iUsb);
    iMessageNotificationObserver = CUsbMessageNotificationObserver::NewL(
            &iUsb);

    iIdPinObserver->SubscribeL(this);

    if (CUsbIdPinObserver::EIdPinOn == iIdPinObserver->IdPin())
        {
        StartSessionL();
        }

    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
EXPORT_C TBool CUsbOtgWatcher::IsDeviceA()
    {
    __ASSERT_DEBUG(iIdPinObserver != NULL, Panic(EIdPinObserverNULLPointer));
    return (iIdPinObserver->IdPin() == CUsbIdPinObserver::EIdPinOn
                                                                   ? ETrue
                                                                      : EFalse);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
EXPORT_C CUsbOtgWatcher* CUsbOtgWatcher::NewL(RUsb& aUsbMan)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::NewL" ) );

    CUsbOtgWatcher* self = new (ELeave) CUsbOtgWatcher(aUsbMan);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
CUsbOtgWatcher::~CUsbOtgWatcher()
    {
		FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::~CUsbOtgWatcher" ) );
        
#ifndef STIF
    RProperty::Delete( KPSUidUsbWatcher, KUsbWatcherIsPeripheralConnected );
#endif
    
    delete iIdPinObserver;
    delete iVBusObserver;
    delete iOtgStateObserver;
    delete iBusActivityObserver;
    delete iHostEventNotificationObserver;
    delete iMessageNotificationObserver;

    // Destroy states
    iStates.ResetAndDestroy();
    iStates.Close();

    delete iNotifManager;
    delete iUsbServiceControl;

    iUsb.Close();

    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::SetPersonalityL(TRequestStatus& /*aStatus*/,
        TInt aPersonality)
    {

        FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SetPersonalityL 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()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::CancelSetPersonalityL" ) );

    iState->CancelSetPersonalityL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::SetPreviousPersonalityL(TRequestStatus& /*aStatus*/)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SetPreviousPersonalityL" ) );

    // maybe more complex processing needed here
    iState->SetPreviousPersonalityL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::SetPreviousPersonalityL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SetPreviousPersonalityL" ) );

    iState->SetPreviousPersonalityL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::CancelSetPreviousPersonalityL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::CancelSetPreviousPersonalityL" ) );

    iState->CancelSetPreviousPersonalityL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::SetPreviousPreviousPersonalityOnDisconnectL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SetPreviousPreviousPersonalityOnDisconnectL" ) );

    }

// From IdPin observer
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::StartSessionL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::StartSessionL" ) );

    if (!CanStartSessionL())
        {
        HandleHostProblemL(EUsbWatcherErrorInConnection);
        return;
        }

    TInt err = iUsbServiceControl->Start(iPersonalityId);
    if (KErrNone != err)
        {
            FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::StartSessionL Can not start usb services. reason = %d" ), err));
        HandleHostProblemL(EUsbWatcherCanNotStartUsbServices);
        return;
        }

    // call back from iUsbServiceControl->Start(iPersonalityId) call is UsbServiceControlReqCompletedL(TInt aError)
    // so, continue there if everything is OK

    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::HandleHostProblemL(TInt aWhatKindOf)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::HandleProblemL" ) );
    HostHandle()->SetWhat(aWhatKindOf);
    ChangeHostStateL(EUsbStateHostHandle);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::IdPinOnL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::IdPinOnL" ) );
    StartSessionL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::IdPinOffL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::IdPinOffL" ) );

    // for example, USB failed to start    
    if(NULL == iHostState) return;

    iVBusObserver->UnsubscribeL(this);
    iOtgStateObserver->UnsubscribeL(this);
    iBusActivityObserver->UnsubscribeL(this);
    iHostEventNotificationObserver->UnsubscribeL(this);
    iMessageNotificationObserver->UnsubscribeL(this);

    iHostState->JustBeforeLeavingThisStateL();

    iHostState = NULL;

    iNotifManager->CloseAllNotifiers();

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::IdPinOffL Before DisableFunctionDriverLoad " ) );
    Usb().DisableFunctionDriverLoading();

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::IdPinOffL Before TryStop" ) );

    TInt err = iUsbServiceControl->Stop();

    if (KErrNone != err)
        {
            FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::IdPinOnL ErrorStoppingUsbServices" ) );
        Panic(ECanNotStopUsbServices);
        }

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::IdPinOffL iUsbServiceControl->Stop() OK" ) );
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::IdPinErrorL(TInt aError)
    {
    FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::IdPinErrorL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));  
    HandleHostProblemL(EUsbWatcherIdPinError);

    }

// From VBus observer
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::VBusDownL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::VBusDownL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->VBusDownL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::VBusUpL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::VBusUpL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->VBusUpL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::VBusObserverErrorL(TInt aError)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::VBusObserverErrorL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    HandleHostProblemL(EUsbWatcherVBusObserverError);
    }

// From OTG state observer
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::AIdleL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::AIdleL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->AIdleL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::AHostL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::AHostL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->AHostL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::APeripheralL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::APeripheralL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->APeripheralL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::AVBusErrorL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::AVBusErrorL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->AVBusErrorL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::BIdleL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::BIdleL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->BIdleL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::BPeripheralL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::BPeripheralL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->BPeripheralL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::BHostL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::BHostL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->BHostL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::OtgStateErrorL(TInt aError)
    {
    FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::OtgStateErrorL" ) );
__ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));  
HandleHostProblemL(EUsbWatcherOtgStateError);
    }

// From bus activity observer
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::BusIdleL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::BusIdleL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->BusIdleL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::BusActiveL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::BusActiveL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->BusActiveL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::BusActivityErrorL(TInt aError)
    {
    FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::BusActivityErrorL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    // no action, continue
    }

// From Host Event notification observer
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::DeviceAttachedL(TDeviceEventInformation aTdi)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::DeviceAttachedL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->DeviceAttachedL(aTdi);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::DeviceDetachedL(TDeviceEventInformation aTdi)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::DeviceDetachedL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->DeviceDetachedL(aTdi);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::DriverLoadSuccessL(TDeviceEventInformation aTdi)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::DriverLoadSuccessL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->DriverLoadSuccessL(aTdi);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::DriverLoadPartialSuccessL(TDeviceEventInformation aTdi)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::DriverLoadPartialSuccessL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->DriverLoadPartialSuccessL(aTdi);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::DriverLoadFailureL(TDeviceEventInformation aTdi)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::DriverLoadFailureL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->DriverLoadFailureL(aTdi);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::HostEventNotificationErrorL(TInt aError)
    {
    FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::HostEventNotificationErrorL" ) );
__ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));  
HandleHostProblemL(EUsbWatcherHostEventNotificationError);
    }

// From message notification observer
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::MessageNotificationReceivedL(TInt aMessage)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::MessageNotificationReceivedL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->MessageNotificationReceivedL(aMessage);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::BadHubPositionL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::BadHubPositionL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->BadHubPositionL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::VBusErrorL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::VBusErrorL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->VBusErrorL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::SrpReceivedL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SrpReceivedL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->SrpReceivedL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::SessionRequestedL()
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SessionRequestedL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));
    iHostState->SessionRequestedL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::MessageNotificationErrorL(TInt aError)
    {
    FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::MessageNotificationErrorL" ) );
    __ASSERT_DEBUG(iHostState != NULL, Panic(EBadHostState));    
    HandleHostProblemL(EUsbWatcherMessageNotificationError);
    }

// ---------------------------------------------------------------------------
// 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() const
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::HostHandle" ) );
    __ASSERT_DEBUG(iStates[EUsbStateHostHandle] != NULL, Panic(EBadState));
    return (CUsbStateHostHandle*) iStates[EUsbStateHostHandle];
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::ChangeStateL(TUsbStateIds aNewStateId)
    {

        FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::ChangeStateL aNewState = %d" ), aNewStateId));

    if (NULL != iState)
        {
        if (aNewStateId == iState->Id())
            {
            return; // we already in the target state
            }
        else
            {

            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_DEBUG(iState != NULL, Panic(EBadState));

    iState->JustAdvancedToThisStateL(); // do any initial activity, once advanced to the state

    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::ChangeHostStateL(TUsbStateIds aNewStateId)
    {

        FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::ChangeHostStateL aNewState = %d" ), aNewStateId));

    if (NULL != iHostState)
        {
        if (aNewStateId == iHostState->Id())
            {
            return; // we already in the target state
            }
        else
            {

            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_DEBUG(iHostState != NULL, Panic(EBadState));

    iHostState->JustAdvancedToThisStateL(); // checks if there are conditions for advancing to another state(s)

    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TBool CUsbOtgWatcher::CanStartSessionL()
    {
    // define policy here
    return ETrue;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::PrintStateToLog()
    {
        FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::PrintStateToLog IdPin       = %d" ), iIdPinObserver->IdPin()));
        FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::PrintStateToLog VBus        = %d" ), iVBusObserver->VBus()));
        FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::PrintStateToLog OtgState    = %d" ), iOtgStateObserver->OtgState()));
        FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::PrintStateToLog BusActivity = %d" ), iBusActivityObserver->BusActivity()));
        
        TInt isPeripheralConnected(KUsbWatcherPeripheralIsNotConnected);
        
        RProperty::Get( KPSUidUsbWatcher, KUsbWatcherIsPeripheralConnected,
                isPeripheralConnected  );
        
        FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::PrintStateToLog IsPeripheralConnected = %d" ), isPeripheralConnected));
        
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
CUsbNotifManager* CUsbOtgWatcher::NotifManager()
    {
    return iNotifManager;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CUsbOtgWatcher::UsbServiceControlReqCompletedL(TInt aError)
    {
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::UsbServiceControlReqCompleted" ) );

    if (KErrNone != aError)
        {
            FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::UsbServiceControlReqCompleted Error returned by UsbServiceControl = %d" ), aError));
        HandleHostProblemL(EUsbWatcherCanNotStartUsbServices);
        return;
        }

    TUsbServiceState serviceState;
    TInt err = iUsb.GetServiceState(serviceState);

    if (KErrNone != err)
        {
            FTRACE( FPrint(_L( "[USBOTGWATCHER]\tCUsbOtgWatcher::UsbServiceControlReqCompleted Error when requesting GetServiceState = %d" ), err));
        HandleHostProblemL(EUsbWatcherCanNotStartUsbServices);
        return;
        }

    switch (serviceState)
        {
        case EUsbServiceIdle: // just stopped usb service
            {
                FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::UsbServiceControlReqCompletedL UsbServiceState == EUsbServiceIdle" ) );
            // do nothing
            break;
            }

        case EUsbServiceStarted: // just started usb service
            {
                FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::UsbServiceControlReqCompletedL UsbServiceState == EUsbServiceStarted" ) );

            iHostState = iStates[EUsbStateHostAInitiate];

            iHostState->JustAdvancedToThisStateL(); // do any initial activity, once advanced to the state 

            iVBusObserver->SubscribeL(this);
            iOtgStateObserver->SubscribeL(this);
            iBusActivityObserver->SubscribeL(this);
            iHostEventNotificationObserver->SubscribeL(this);
            iMessageNotificationObserver->SubscribeL(this);

            break;
            }
        case EUsbServiceStarting:
            {
                FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::UsbServiceControlReqCompletedL UsbServiceState == EUsbServiceStarting" ) );
            // should not receive that, due to call back is called when service stopped or started
            // therefore scream
            }
        case EUsbServiceStopping:
            {
                FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::UsbServiceControlReqCompletedL UsbServiceState == EUsbServiceStopping" ) );
            // should not receive that, due to call back is called when service stopped or started
            // therefore scream
            }
        case EUsbServiceFatalError:
            {
                FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::UsbServiceControlReqCompletedL UsbServiceState == EUsbServiceFatalError" ) );
            Panic(EUnexpectedUsbServiceState);
            break;
            }

        default:
            {
            Panic(EUnknownUsbServiceState);
            }
        }

    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//


TInt CUsbOtgWatcher::SelfTestL()
    {
#ifdef _DEBUG

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL Creating observers." ) );

    // create all the observers
    iIdPinObserver = CUsbIdPinObserver::NewL();
    iVBusObserver = CUsbVBusObserver::NewL();
    iOtgStateObserver = CUsbOtgStateObserver::NewL();
    iBusActivityObserver =
            CUsbBusActivityObserver::NewL();
    iHostEventNotificationObserver =
            CUsbHostEventNotificationObserver::NewL(&iUsb);
    iMessageNotificationObserver =
            CUsbMessageNotificationObserver::NewL(&iUsb);

  /*      FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL idPinObserver->Subscribe" ) );

    iIdPinObserver->SubscribeL(this);

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL idPinObserver->Unsubscribe" ) );

    iIdPinObserver->UnsubscribeL(this); */

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL Observers getters." ) );

    if (iIdPinObserver != IdPinObserver())
        {
        User::Leave(KErrGeneral);
        }

    if (iOtgStateObserver != OtgStateObserver())
        {
        User::Leave(KErrGeneral);
        }

    if (iBusActivityObserver != BusActivityObserver())
        {
        User::Leave(KErrGeneral);
        }

    if (iHostEventNotificationObserver != HostEventNotificationObserver())
        {
        User::Leave(KErrGeneral);
        }

    if (iMessageNotificationObserver != MessageNotificationObserver())
        {
        User::Leave(KErrGeneral);
        }

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL Observers destructors." ) );

    delete iIdPinObserver;
    iIdPinObserver = 0;
    delete iVBusObserver;
    iVBusObserver = 0;
    delete iOtgStateObserver;
    iOtgStateObserver = 0;
    delete iBusActivityObserver;
    iBusActivityObserver = 0;
    delete iHostEventNotificationObserver;
    iHostEventNotificationObserver = 0;
    delete iMessageNotificationObserver;
    iMessageNotificationObserver = 0;

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL NotifManager and WarningNotifier." ) );

    CUsbNotifManager* usbnotifmanager = CUsbNotifManager::NewL();
    RNotifier rnotifier;
    User::LeaveIfError(rnotifier.Connect());
    CUsbWarningNotifier* usbnotifier = CUsbWarningNotifier::NewL(rnotifier,
            usbnotifmanager, EUsbOtgPartiallySupportedDevice);
    usbnotifier->IsFeedbackNeeded();

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL NotifManager and WarningNotifier destruction." ) );

    delete usbnotifier;
    rnotifier.Close();
    delete usbnotifmanager;

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL Creating states." ) );

    User::LeaveIfError(iStates.Append(CUsbStateHostAInitiate::NewL(this)));
    User::LeaveIfError(iStates.Append(CUsbStateHostAHost::NewL(this)));
    User::LeaveIfError(iStates.Append(CUsbStateHostAPeripheral::NewL(this)));
    User::LeaveIfError(iStates.Append(CUsbStateHostAIdle::NewL(this)));
    User::LeaveIfError(iStates.Append(CUsbStateHostHandle::NewL(this)));

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL Check State()" ) );

    if (iStates[EUsbStateHostAInitiate] != State(EUsbStateHostAInitiate))
        {
        User::Leave(KErrGeneral);
        }
        
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL Check CurrentHostState()" ) );    
        
    iHostState = iStates[EUsbStateHostAInitiate];
		
		if (iStates[EUsbStateHostAInitiate] != CurrentHostState())
        {
        User::Leave(KErrGeneral);
        }
        
        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL Destructing states." ) );
        
    iStates.ResetAndDestroy();

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL Check UsbServiceControl" ) );

    CUsbServiceControl* usbServiceControl = CUsbServiceControl::NewL(this,
            iUsb);
    usbServiceControl->RunError(KErrNone);
    delete usbServiceControl;

        FLOG( _L( "[USBOTGWATCHER]\tCUsbOtgWatcher::SelfTestL All completed OK." ) );
#endif
        return KErrNone;

    }