usbmgmt/usbmgr/usbman/server/SRC/CUsbOtg.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
equal deleted inserted replaced
-1:000000000000 0:c9bc50fca66e
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 * Implements the object of Usbman that manages all the USB OTG
       
    16 * activity (via CUsbOtgWatcher).
       
    17 *
       
    18 */
       
    19 
       
    20 /**
       
    21  @file
       
    22 */
       
    23 
       
    24 #include "CUsbOtg.h"
       
    25 #include "cusbotgwatcher.h"
       
    26 #include "CUsbDevice.h"
       
    27 #include "musbotghostnotifyobserver.h"
       
    28 #include "CUsbServer.h"
       
    29 #include <e32property.h> //Publish & Subscribe header
       
    30 #include "usberrors.h"
       
    31 
       
    32 //Name used in call to User::LoadLogicalDevice/User::FreeLogicalDevice
       
    33 _LIT(KUsbOtgLDDName,"otgdi");
       
    34 
       
    35 #ifdef __FLOG_ACTIVE
       
    36 _LIT8(KLogComponent, "USBSVR-OTG");
       
    37 #endif
       
    38 
       
    39 
       
    40 CUsbOtg* CUsbOtg::NewL()
       
    41 /**
       
    42  * Constructs a CUsbOtg object.
       
    43  *
       
    44  * @return	A new CUsbOtg object
       
    45  */
       
    46 	{
       
    47 	LOG_STATIC_FUNC_ENTRY
       
    48 
       
    49 	CUsbOtg* self = new (ELeave) CUsbOtg();
       
    50 	CleanupStack::PushL(self);
       
    51 	self->ConstructL();
       
    52 	CleanupStack::Pop(self);
       
    53 	return self;
       
    54 	}
       
    55 
       
    56 
       
    57 CUsbOtg::~CUsbOtg()
       
    58 /**
       
    59  * Destructor.
       
    60  */
       
    61 	{
       
    62 	LOG_FUNC
       
    63 
       
    64 	// Cancel any outstanding asynchronous operation.
       
    65 	Stop();
       
    66 	
       
    67 	// Free any memory allocated to the list of observers. Note that
       
    68 	// we don't want to call ResetAndDestroy, because we don't own
       
    69 	// the observers themselves.
       
    70 	iObservers.Reset();
       
    71 	
       
    72 	LOGTEXT2(_L8("about to stop Id-Pin watcher @ %08x"), (TUint32) iIdPinWatcher);
       
    73 	if (iIdPinWatcher)
       
    74 		{
       
    75 		iIdPinWatcher->Cancel();
       
    76 		delete iIdPinWatcher;
       
    77 		iIdPinWatcher = NULL;
       
    78 		LOGTEXT(_L8("deleted Id-Pin watcher"));
       
    79 		}
       
    80 	LOGTEXT2(_L8("about to stop Vbus watcher @ %08x"), (TUint32) iVbusWatcher);
       
    81 	if (iVbusWatcher)
       
    82 		{
       
    83 		iVbusWatcher->Cancel();
       
    84 		delete iVbusWatcher;
       
    85 		iVbusWatcher = NULL;
       
    86 		LOGTEXT(_L8("deleted Vbus watcher"));
       
    87 		}
       
    88 	LOGTEXT2(_L8("about to stop OTG State watcher @ %08x"), (TUint32) iVbusWatcher);
       
    89 	if (iOtgStateWatcher)
       
    90 		{
       
    91 		iOtgStateWatcher->Cancel();
       
    92 		delete iOtgStateWatcher;
       
    93 		iOtgStateWatcher = NULL;
       
    94 		LOGTEXT(_L8("deleted OTG State watcher"));
       
    95 		}
       
    96 	LOGTEXT2(_L8("about to stop OTG Event watcher @ %08x"), (TUint32) iVbusWatcher);
       
    97 	if (iOtgEventWatcher)
       
    98 		{
       
    99 		iOtgEventWatcher->Cancel();
       
   100 		delete iOtgEventWatcher;
       
   101 		iOtgEventWatcher = NULL;
       
   102 		LOGTEXT(_L8("deleted OTG Event watcher"));
       
   103 		}
       
   104 	
       
   105 	if (iRequestSessionWatcher)
       
   106 		{
       
   107 		delete iRequestSessionWatcher;
       
   108 		LOGTEXT(_L8("deleted Session Request watcher"));
       
   109 		}
       
   110 
       
   111 	LOGTEXT2(_L8("about to stop Connection Idle watcher @ %08x"), (TUint32)iOtgConnectionIdleWatcher);
       
   112 	if (iOtgConnectionIdleWatcher)
       
   113 		{
       
   114 		iOtgConnectionIdleWatcher->Cancel();
       
   115 		delete iOtgConnectionIdleWatcher;
       
   116 		iOtgConnectionIdleWatcher= NULL;
       
   117 		LOGTEXT(_L8("deleted Connection Idle watcher"));
       
   118 		}
       
   119 
       
   120 	// Unload OTGDI components if it was ever started
       
   121 	if ( iOtgDriver.Handle() )
       
   122 		{
       
   123 		LOGTEXT(_L8("Stopping stacks"));
       
   124 		iOtgDriver.StopStacks();
       
   125 		iOtgDriver.Close();
       
   126 		}
       
   127 	else
       
   128 		{
       
   129 		LOGTEXT(_L8("No OTG Driver session was opened, nothing to do"));
       
   130 		}
       
   131 
       
   132 	LOGTEXT(_L8("Freeing logical device"));
       
   133 	TInt err = User::FreeLogicalDevice(KUsbOtgLDDName);
       
   134 	//Putting the LOGTEXT2 inside the if statement prevents a compiler
       
   135 	//warning about err being unused in UREL builds.
       
   136 	if(err)
       
   137 		{
       
   138 		LOGTEXT2(_L8("     User::FreeLogicalDevice returned %d"),err);
       
   139 		}
       
   140 	
       
   141 	iCriticalSection.Close();
       
   142 	}
       
   143 
       
   144 
       
   145 CUsbOtg::CUsbOtg()
       
   146 /**
       
   147  * Constructor.
       
   148  */
       
   149 	{
       
   150 	LOG_FUNC
       
   151 	}
       
   152 
       
   153 
       
   154 void CUsbOtg::ConstructL()
       
   155 /**
       
   156  * Performs 2nd phase construction of the OTG object.
       
   157  */
       
   158 	{
       
   159 	LOG_FUNC
       
   160 	
       
   161 	LOGTEXT(_L8("About to open LDD"));
       
   162 	iLastError = User::LoadLogicalDevice(KUsbOtgLDDName);
       
   163 	if ( (iLastError != KErrNone) && (iLastError != KErrAlreadyExists) )
       
   164 		{
       
   165 		LOGTEXT3(_L8("Error %d: Unable to load driver: %S"), iLastError, &KUsbOtgLDDName);
       
   166 		LEAVEIFERRORL(iLastError);
       
   167 		}
       
   168 
       
   169 	LOGTEXT(_L8("About to open RUsbOtgDriver"));
       
   170 	iLastError = iOtgDriver.Open();
       
   171 	if ( (iLastError != KErrNone) && (iLastError != KErrAlreadyExists) )
       
   172 		{
       
   173 		LOGTEXT2(_L8("Error %d: Unable to open RUsbOtgDriver session"), iLastError);
       
   174 		LEAVEIFERRORL(iLastError);
       
   175 		}
       
   176 
       
   177 
       
   178 	LOGTEXT(_L8("About to start OTG stacks"));
       
   179 	iLastError = iOtgDriver.StartStacks();
       
   180 	if (iLastError != KErrNone)
       
   181 		{
       
   182 		LOGTEXT2(_L8("Error %d: Unable to open start OTG stacks"), iLastError);
       
   183 		LEAVEIFERRORL(iLastError);
       
   184 		}
       
   185 
       
   186 	// Request Otg notifications
       
   187 	iIdPinWatcher = CUsbOtgIdPinWatcher::NewL(iOtgDriver);
       
   188 	iIdPinWatcher->Start();
       
   189 
       
   190 	iVbusWatcher = CUsbOtgVbusWatcher::NewL(iOtgDriver);
       
   191 	iVbusWatcher->Start();
       
   192 
       
   193 	iOtgStateWatcher = CUsbOtgStateWatcher::NewL(iOtgDriver);
       
   194 	iOtgStateWatcher->Start();
       
   195 	
       
   196 	iOtgEventWatcher = CUsbOtgEventWatcher::NewL(*this, iOtgDriver, iOtgEvent);
       
   197 	iOtgEventWatcher->Start();
       
   198 	
       
   199     iOtgConnectionIdleWatcher = CUsbOtgConnectionIdleWatcher::NewL(iOtgDriver);
       
   200     iOtgConnectionIdleWatcher->Start();
       
   201 
       
   202 	iRequestSessionWatcher = CRequestSessionWatcher::NewL(*this);
       
   203 	
       
   204 	iCriticalSection.CreateLocal(EOwnerProcess);
       
   205 	
       
   206 	LOGTEXT(_L8("UsbOtg::ConstructL() finished"));
       
   207 	}
       
   208 	
       
   209 void CUsbOtg::NotifyMessage(TInt aMessage)
       
   210 /**
       
   211  * The CUsbOtg::NotifyMessage method
       
   212  *
       
   213  * Reports the OTG message to the observers
       
   214  *
       
   215  * @internalComponent
       
   216  */
       
   217 	{
       
   218 	iCriticalSection.Wait();
       
   219 
       
   220 	TInt msg = aMessage == 0 ? iOtgMessage : aMessage;
       
   221 	TUint length = iObservers.Count();
       
   222 	for (TUint i = 0; i < length; i++)
       
   223 		{
       
   224 		iObservers[i]->UsbOtgHostMessage(msg);
       
   225 		}
       
   226 
       
   227 	iCriticalSection.Signal();
       
   228 	}
       
   229 
       
   230 TInt CUsbOtg::TranslateOtgEvent()
       
   231 /**
       
   232  * The CUsbOtg::TranslateOtgEvent method
       
   233  *
       
   234  * Attempts to translate the OTG event into OTG message
       
   235  *
       
   236  * @internalComponent
       
   237  */
       
   238 	{
       
   239 	TInt otgEvent = KErrBadName;
       
   240 	switch (iOtgEvent)
       
   241 	{
       
   242 	case RUsbOtgDriver::EEventHnpDisabled:
       
   243 		otgEvent = KUsbMessageHnpDisabled;
       
   244 		break;
       
   245 	case RUsbOtgDriver::EEventHnpEnabled:
       
   246 		otgEvent = KUsbMessageHnpEnabled;
       
   247 		break;
       
   248 	case RUsbOtgDriver::EEventSrpReceived:
       
   249 		otgEvent = KUsbMessageSrpReceived;
       
   250 		break;
       
   251 	case RUsbOtgDriver::EEventSrpInitiated:
       
   252 		otgEvent = KUsbMessageSrpInitiated;
       
   253 		break;
       
   254 	case RUsbOtgDriver::EEventVbusRaised:
       
   255 		otgEvent = KUsbMessageVbusRaised;
       
   256 		break;
       
   257 	case RUsbOtgDriver::EEventVbusDropped:
       
   258 		otgEvent = KUsbMessageVbusDropped;
       
   259 		break;
       
   260 	}
       
   261 
       
   262 	return otgEvent;
       
   263 	}
       
   264 
       
   265 void CUsbOtg::NotifyOtgEvent()
       
   266 /**
       
   267  * The CUsbOtg::NotifyOtgEvent method
       
   268  *
       
   269  * Reports the OTG message translated from OTG Event to the observers
       
   270  *
       
   271  * @internalComponent
       
   272  */
       
   273 	{
       
   274 	TUint length = iObservers.Count();
       
   275 	TInt otgEvent = TranslateOtgEvent();
       
   276 	if ( otgEvent == KErrBadName )
       
   277 		{
       
   278 		LOGTEXT2(_L8("CUsbOtg::NotifyOtgEvent(): OTG event %d was reported, but not propagated"), (TInt) iOtgEvent);
       
   279 		return;
       
   280 		}
       
   281 
       
   282 	for (TUint i = 0; i < length; i++)
       
   283 		{
       
   284 		iObservers[i]->UsbOtgHostMessage(otgEvent);
       
   285 		}
       
   286 	}
       
   287 
       
   288 void CUsbOtg::RegisterObserverL(MUsbOtgHostNotifyObserver& aObserver)
       
   289 /**
       
   290  * Register an observer of the OTG events.
       
   291  * Presently, the device supports watching state.
       
   292  *
       
   293  * @param	aObserver	New Observer of the OTG events
       
   294  */
       
   295 	{
       
   296 	LOG_FUNC
       
   297 
       
   298 	LEAVEIFERRORL(iObservers.Append(&aObserver));
       
   299 	}
       
   300 
       
   301 
       
   302 void CUsbOtg::DeRegisterObserver(MUsbOtgHostNotifyObserver& aObserver)
       
   303 /**
       
   304  * De-registers an existing OTG events observer.
       
   305  *
       
   306  * @param	aObserver	The existing OTG events observer to be de-registered
       
   307  */
       
   308 	{
       
   309 	LOG_FUNC
       
   310 
       
   311 	TInt index = iObservers.Find(&aObserver);
       
   312 
       
   313 	if (index >= 0 && index < iObservers.Count())
       
   314 		{
       
   315 		iObservers.Remove(index);
       
   316 		}
       
   317 	}
       
   318 
       
   319 
       
   320 void CUsbOtg::StartL()
       
   321 /**
       
   322  * Start the USB OTG events watcher
       
   323  * Reports errors and OTG events via observer interface.
       
   324  */
       
   325 	{
       
   326 	LOG_FUNC
       
   327 
       
   328 	iOtgWatcher = CUsbOtgWatcher::NewL(*this, iOtgDriver, iOtgMessage);
       
   329 	iOtgWatcher->Start();
       
   330 	}
       
   331 
       
   332 void CUsbOtg::Stop()
       
   333 /**
       
   334  * Stop the USB OTG events watcher
       
   335  */
       
   336 	{
       
   337 	LOG_FUNC
       
   338 
       
   339 	LOGTEXT2(_L8("about to stop OTG watcher @ %08x"), (TUint32) iOtgWatcher);
       
   340 	
       
   341 	if (iOtgWatcher)
       
   342 		{
       
   343 		iOtgWatcher->Cancel();
       
   344 		delete iOtgWatcher;
       
   345 		iOtgWatcher = NULL;
       
   346 		LOGTEXT(_L8("deleted OTG watcher"));
       
   347 		}
       
   348 	
       
   349 	iLastError = KErrNone;
       
   350 	}
       
   351 
       
   352 TInt CUsbOtg::BusRequest()
       
   353 	{
       
   354 	LOG_FUNC
       
   355 	return iOtgDriver.BusRequest();
       
   356 	}
       
   357 	
       
   358 TInt CUsbOtg::BusRespondSrp()
       
   359 	{
       
   360 	LOG_FUNC
       
   361 	return iOtgDriver.BusRespondSrp();
       
   362 	}
       
   363 
       
   364 TInt CUsbOtg::BusClearError()
       
   365 	{
       
   366 	LOG_FUNC
       
   367 	return iOtgDriver.BusClearError();
       
   368 	}
       
   369 
       
   370 TInt CUsbOtg::BusDrop()
       
   371 	{
       
   372 	LOG_FUNC
       
   373 	return iOtgDriver.BusDrop();
       
   374 	}