usbmgmt/usbmgr/usbman/server/SRC/CUsbOtg.cpp
changeset 0 c9bc50fca66e
child 29 59aa7d6e3e0f
--- /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 <e32property.h> //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();
+	}