diff -r 000000000000 -r c9bc50fca66e usbmgmt/usbmgr/usbman/server/SRC/CUsbOtg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbmgmt/usbmgr/usbman/server/SRC/CUsbOtg.cpp Tue Feb 02 02:02:59 2010 +0200 @@ -0,0 +1,374 @@ +/* +* 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: +* Implements the object of Usbman that manages all the USB OTG +* activity (via CUsbOtgWatcher). +* +*/ + +/** + @file +*/ + +#include "CUsbOtg.h" +#include "cusbotgwatcher.h" +#include "CUsbDevice.h" +#include "musbotghostnotifyobserver.h" +#include "CUsbServer.h" +#include //Publish & Subscribe header +#include "usberrors.h" + +//Name used in call to User::LoadLogicalDevice/User::FreeLogicalDevice +_LIT(KUsbOtgLDDName,"otgdi"); + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, "USBSVR-OTG"); +#endif + + +CUsbOtg* CUsbOtg::NewL() +/** + * Constructs a CUsbOtg object. + * + * @return A new CUsbOtg object + */ + { + LOG_STATIC_FUNC_ENTRY + + CUsbOtg* self = new (ELeave) CUsbOtg(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +CUsbOtg::~CUsbOtg() +/** + * Destructor. + */ + { + LOG_FUNC + + // Cancel any outstanding asynchronous operation. + Stop(); + + // Free any memory allocated to the list of observers. Note that + // we don't want to call ResetAndDestroy, because we don't own + // the observers themselves. + iObservers.Reset(); + + LOGTEXT2(_L8("about to stop Id-Pin watcher @ %08x"), (TUint32) iIdPinWatcher); + if (iIdPinWatcher) + { + iIdPinWatcher->Cancel(); + delete iIdPinWatcher; + iIdPinWatcher = NULL; + LOGTEXT(_L8("deleted Id-Pin watcher")); + } + LOGTEXT2(_L8("about to stop Vbus watcher @ %08x"), (TUint32) iVbusWatcher); + if (iVbusWatcher) + { + iVbusWatcher->Cancel(); + delete iVbusWatcher; + iVbusWatcher = NULL; + LOGTEXT(_L8("deleted Vbus watcher")); + } + LOGTEXT2(_L8("about to stop OTG State watcher @ %08x"), (TUint32) iVbusWatcher); + if (iOtgStateWatcher) + { + iOtgStateWatcher->Cancel(); + delete iOtgStateWatcher; + iOtgStateWatcher = NULL; + LOGTEXT(_L8("deleted OTG State watcher")); + } + LOGTEXT2(_L8("about to stop OTG Event watcher @ %08x"), (TUint32) iVbusWatcher); + if (iOtgEventWatcher) + { + iOtgEventWatcher->Cancel(); + delete iOtgEventWatcher; + iOtgEventWatcher = NULL; + LOGTEXT(_L8("deleted OTG Event watcher")); + } + + if (iRequestSessionWatcher) + { + delete iRequestSessionWatcher; + LOGTEXT(_L8("deleted Session Request watcher")); + } + + LOGTEXT2(_L8("about to stop Connection Idle watcher @ %08x"), (TUint32)iOtgConnectionIdleWatcher); + if (iOtgConnectionIdleWatcher) + { + iOtgConnectionIdleWatcher->Cancel(); + delete iOtgConnectionIdleWatcher; + iOtgConnectionIdleWatcher= NULL; + LOGTEXT(_L8("deleted Connection Idle watcher")); + } + + // Unload OTGDI components if it was ever started + if ( iOtgDriver.Handle() ) + { + LOGTEXT(_L8("Stopping stacks")); + iOtgDriver.StopStacks(); + iOtgDriver.Close(); + } + else + { + LOGTEXT(_L8("No OTG Driver session was opened, nothing to do")); + } + + LOGTEXT(_L8("Freeing logical device")); + TInt err = User::FreeLogicalDevice(KUsbOtgLDDName); + //Putting the LOGTEXT2 inside the if statement prevents a compiler + //warning about err being unused in UREL builds. + if(err) + { + LOGTEXT2(_L8(" User::FreeLogicalDevice returned %d"),err); + } + + iCriticalSection.Close(); + } + + +CUsbOtg::CUsbOtg() +/** + * Constructor. + */ + { + LOG_FUNC + } + + +void CUsbOtg::ConstructL() +/** + * Performs 2nd phase construction of the OTG object. + */ + { + LOG_FUNC + + LOGTEXT(_L8("About to open LDD")); + iLastError = User::LoadLogicalDevice(KUsbOtgLDDName); + if ( (iLastError != KErrNone) && (iLastError != KErrAlreadyExists) ) + { + LOGTEXT3(_L8("Error %d: Unable to load driver: %S"), iLastError, &KUsbOtgLDDName); + LEAVEIFERRORL(iLastError); + } + + LOGTEXT(_L8("About to open RUsbOtgDriver")); + iLastError = iOtgDriver.Open(); + if ( (iLastError != KErrNone) && (iLastError != KErrAlreadyExists) ) + { + LOGTEXT2(_L8("Error %d: Unable to open RUsbOtgDriver session"), iLastError); + LEAVEIFERRORL(iLastError); + } + + + LOGTEXT(_L8("About to start OTG stacks")); + iLastError = iOtgDriver.StartStacks(); + if (iLastError != KErrNone) + { + LOGTEXT2(_L8("Error %d: Unable to open start OTG stacks"), iLastError); + LEAVEIFERRORL(iLastError); + } + + // Request Otg notifications + iIdPinWatcher = CUsbOtgIdPinWatcher::NewL(iOtgDriver); + iIdPinWatcher->Start(); + + iVbusWatcher = CUsbOtgVbusWatcher::NewL(iOtgDriver); + iVbusWatcher->Start(); + + iOtgStateWatcher = CUsbOtgStateWatcher::NewL(iOtgDriver); + iOtgStateWatcher->Start(); + + iOtgEventWatcher = CUsbOtgEventWatcher::NewL(*this, iOtgDriver, iOtgEvent); + iOtgEventWatcher->Start(); + + iOtgConnectionIdleWatcher = CUsbOtgConnectionIdleWatcher::NewL(iOtgDriver); + iOtgConnectionIdleWatcher->Start(); + + iRequestSessionWatcher = CRequestSessionWatcher::NewL(*this); + + iCriticalSection.CreateLocal(EOwnerProcess); + + LOGTEXT(_L8("UsbOtg::ConstructL() finished")); + } + +void CUsbOtg::NotifyMessage(TInt aMessage) +/** + * The CUsbOtg::NotifyMessage method + * + * Reports the OTG message to the observers + * + * @internalComponent + */ + { + iCriticalSection.Wait(); + + TInt msg = aMessage == 0 ? iOtgMessage : aMessage; + TUint length = iObservers.Count(); + for (TUint i = 0; i < length; i++) + { + iObservers[i]->UsbOtgHostMessage(msg); + } + + iCriticalSection.Signal(); + } + +TInt CUsbOtg::TranslateOtgEvent() +/** + * The CUsbOtg::TranslateOtgEvent method + * + * Attempts to translate the OTG event into OTG message + * + * @internalComponent + */ + { + TInt otgEvent = KErrBadName; + switch (iOtgEvent) + { + case RUsbOtgDriver::EEventHnpDisabled: + otgEvent = KUsbMessageHnpDisabled; + break; + case RUsbOtgDriver::EEventHnpEnabled: + otgEvent = KUsbMessageHnpEnabled; + break; + case RUsbOtgDriver::EEventSrpReceived: + otgEvent = KUsbMessageSrpReceived; + break; + case RUsbOtgDriver::EEventSrpInitiated: + otgEvent = KUsbMessageSrpInitiated; + break; + case RUsbOtgDriver::EEventVbusRaised: + otgEvent = KUsbMessageVbusRaised; + break; + case RUsbOtgDriver::EEventVbusDropped: + otgEvent = KUsbMessageVbusDropped; + break; + } + + return otgEvent; + } + +void CUsbOtg::NotifyOtgEvent() +/** + * The CUsbOtg::NotifyOtgEvent method + * + * Reports the OTG message translated from OTG Event to the observers + * + * @internalComponent + */ + { + TUint length = iObservers.Count(); + TInt otgEvent = TranslateOtgEvent(); + if ( otgEvent == KErrBadName ) + { + LOGTEXT2(_L8("CUsbOtg::NotifyOtgEvent(): OTG event %d was reported, but not propagated"), (TInt) iOtgEvent); + return; + } + + for (TUint i = 0; i < length; i++) + { + iObservers[i]->UsbOtgHostMessage(otgEvent); + } + } + +void CUsbOtg::RegisterObserverL(MUsbOtgHostNotifyObserver& aObserver) +/** + * Register an observer of the OTG events. + * Presently, the device supports watching state. + * + * @param aObserver New Observer of the OTG events + */ + { + LOG_FUNC + + LEAVEIFERRORL(iObservers.Append(&aObserver)); + } + + +void CUsbOtg::DeRegisterObserver(MUsbOtgHostNotifyObserver& aObserver) +/** + * De-registers an existing OTG events observer. + * + * @param aObserver The existing OTG events observer to be de-registered + */ + { + LOG_FUNC + + TInt index = iObservers.Find(&aObserver); + + if (index >= 0 && index < iObservers.Count()) + { + iObservers.Remove(index); + } + } + + +void CUsbOtg::StartL() +/** + * Start the USB OTG events watcher + * Reports errors and OTG events via observer interface. + */ + { + LOG_FUNC + + iOtgWatcher = CUsbOtgWatcher::NewL(*this, iOtgDriver, iOtgMessage); + iOtgWatcher->Start(); + } + +void CUsbOtg::Stop() +/** + * Stop the USB OTG events watcher + */ + { + LOG_FUNC + + LOGTEXT2(_L8("about to stop OTG watcher @ %08x"), (TUint32) iOtgWatcher); + + if (iOtgWatcher) + { + iOtgWatcher->Cancel(); + delete iOtgWatcher; + iOtgWatcher = NULL; + LOGTEXT(_L8("deleted OTG watcher")); + } + + iLastError = KErrNone; + } + +TInt CUsbOtg::BusRequest() + { + LOG_FUNC + return iOtgDriver.BusRequest(); + } + +TInt CUsbOtg::BusRespondSrp() + { + LOG_FUNC + return iOtgDriver.BusRespondSrp(); + } + +TInt CUsbOtg::BusClearError() + { + LOG_FUNC + return iOtgDriver.BusClearError(); + } + +TInt CUsbOtg::BusDrop() + { + LOG_FUNC + return iOtgDriver.BusDrop(); + }