usbmgmt/usbmgr/host/fdf/production/server/src/fdfsession.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
equal deleted inserted replaced
-1:000000000000 0:c9bc50fca66e
       
     1 /*
       
     2 * Copyright (c) 2007-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 *
       
    16 */
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include "fdfsession.h"
       
    24 #include "fdfserver.h"
       
    25 #include <usb/usblogger.h>
       
    26 #include "utils.h"
       
    27 #include <ecom/ecom.h>
       
    28 #include "fdfapi.h"
       
    29 #include "fdf.h"
       
    30 #include "event.h"
       
    31 
       
    32 #ifdef __FLOG_ACTIVE
       
    33 _LIT8(KLogComponent, "fdf      ");
       
    34 #endif
       
    35 
       
    36 #ifdef _DEBUG
       
    37 PANICCATEGORY("fdfsession");
       
    38 #endif
       
    39 
       
    40 CFdfSession::CFdfSession(CFdf& aFdf, CFdfServer& aServer)
       
    41  :	iFdf(aFdf),
       
    42 	iServer(aServer)
       
    43 	{
       
    44 	LOG_FUNC
       
    45 	}
       
    46 
       
    47 CFdfSession::~CFdfSession()
       
    48 	{
       
    49 	LOG_LINE
       
    50 	LOG_FUNC;
       
    51 
       
    52 	iServer.SessionClosed();
       
    53 	}
       
    54 
       
    55 void CFdfSession::ServiceL(const RMessage2& aMessage)
       
    56 	{
       
    57 	LOG_LINE
       
    58 	LOG_FUNC;
       
    59 	LOGTEXT2(_L8("\taMessage.Function() = %d"), aMessage.Function());
       
    60 
       
    61 	// Switch on the IPC number and call a 'message handler'. Message handlers
       
    62 	// complete aMessage (either with Complete or Panic), or make a note of
       
    63 	// the message for later asynchronous completion.
       
    64 	// Message handlers should not leave- the server does not have an Error
       
    65 	// function.
       
    66 
       
    67 	switch ( aMessage.Function() )
       
    68 		{
       
    69 	case EUsbFdfSrvEnableDriverLoading:
       
    70 		EnableDriverLoading(aMessage);
       
    71 		// This is a sync API- check that the message has been completed.
       
    72 		// (NB We don't check the converse for async APIs because the message
       
    73 		// may have been panicked synchronously.)
       
    74 		ASSERT_DEBUG(aMessage.Handle() == 0);
       
    75 		break;
       
    76 
       
    77 	case EUsbFdfSrvDisableDriverLoading:
       
    78 		DisableDriverLoading(aMessage);
       
    79 		ASSERT_DEBUG(aMessage.Handle() == 0);
       
    80 		break;
       
    81 
       
    82 	case EUsbFdfSrvNotifyDeviceEvent:
       
    83 		NotifyDeviceEvent(aMessage);
       
    84 		break;
       
    85 
       
    86 	case EUsbFdfSrvNotifyDeviceEventCancel:
       
    87 		NotifyDeviceEventCancel(aMessage);
       
    88 		ASSERT_DEBUG(aMessage.Handle() == 0);
       
    89 		break;
       
    90 
       
    91 	case EUsbFdfSrvNotifyDevmonEvent:
       
    92 		NotifyDevmonEvent(aMessage);
       
    93 		break;
       
    94 
       
    95 	case EUsbFdfSrvNotifyDevmonEventCancel:
       
    96 		NotifyDevmonEventCancel(aMessage);
       
    97 		ASSERT_DEBUG(aMessage.Handle() == 0);
       
    98 		break;
       
    99 
       
   100 	case EUsbFdfSrvGetSingleSupportedLanguageOrNumberOfSupportedLanguages:
       
   101 		GetSingleSupportedLanguageOrNumberOfSupportedLanguages(aMessage);
       
   102 		ASSERT_DEBUG(aMessage.Handle() == 0);
       
   103 		break;
       
   104 
       
   105 	case EUsbFdfSrvGetSupportedLanguages:
       
   106 		GetSupportedLanguages(aMessage);
       
   107 		ASSERT_DEBUG(aMessage.Handle() == 0);
       
   108 		break;
       
   109 
       
   110 	case EUsbFdfSrvGetManufacturerStringDescriptor:
       
   111 		GetManufacturerStringDescriptor(aMessage);
       
   112 		ASSERT_DEBUG(aMessage.Handle() == 0);
       
   113 		break;
       
   114 
       
   115 	case EUsbFdfSrvGetProductStringDescriptor:
       
   116 		GetProductStringDescriptor(aMessage);
       
   117 		ASSERT_DEBUG(aMessage.Handle() == 0);
       
   118 		break;
       
   119 		
       
   120 	case EUsbFdfSrvGetOtgDescriptor:
       
   121 		GetOtgDeviceDescriptor(aMessage);
       
   122 		ASSERT_DEBUG(aMessage.Handle() == 0);
       
   123 		break;
       
   124 
       
   125 	// Heap failure testing APIs.
       
   126 	case EUsbFdfSrvDbgFailNext:
       
   127 #ifdef _DEBUG
       
   128 		{
       
   129 		LOGTEXT2(_L8("\tfail next (simulating failure after %d allocation(s))"), aMessage.Int0());
       
   130 		if ( aMessage.Int0() == 0 )
       
   131 			{
       
   132 			__UHEAP_RESET;
       
   133 			}
       
   134 		else
       
   135 			{
       
   136 			__UHEAP_FAILNEXT(aMessage.Int0());
       
   137 			}
       
   138 		}
       
   139 #endif // _DEBUG
       
   140 		CompleteClient(aMessage, KErrNone);
       
   141 		break;
       
   142 
       
   143 	case EUsbFdfSrvDbgAlloc:
       
   144 		{
       
   145 		TInt err = KErrNone;
       
   146 #ifdef _DEBUG
       
   147 		LOGTEXT(_L8("\tallocate on the heap"));
       
   148 		TInt* x = NULL;
       
   149 		TRAP(err, x = new(ELeave) TInt);
       
   150 		delete x;
       
   151 
       
   152 #endif // _DEBUG
       
   153 		CompleteClient(aMessage, err);
       
   154 		}
       
   155 		break;
       
   156 
       
   157 	default:
       
   158 		PANIC_MSG(aMessage, KUsbFdfServerName, EBadIpc);
       
   159 		break;
       
   160 		}
       
   161 	}
       
   162 
       
   163 void CFdfSession::CompleteClient(const RMessage2& aMessage, TInt aError)
       
   164 	{
       
   165 	LOGTEXT2(_L8("\tcompleting client message with %d"), aError);
       
   166 	aMessage.Complete(aError);
       
   167 	}
       
   168 
       
   169 void CFdfSession::EnableDriverLoading(const RMessage2& aMessage)
       
   170 	{
       
   171 	LOG_FUNC
       
   172 
       
   173 	iFdf.EnableDriverLoading();
       
   174 
       
   175 	CompleteClient(aMessage, KErrNone);
       
   176 	}
       
   177 
       
   178 void CFdfSession::DisableDriverLoading(const RMessage2& aMessage)
       
   179 	{
       
   180 	LOG_FUNC
       
   181 
       
   182 	iFdf.DisableDriverLoading();
       
   183 
       
   184 	CompleteClient(aMessage, KErrNone);
       
   185 	}
       
   186 
       
   187 TBool CFdfSession::NotifyDeviceEventOutstanding() const
       
   188 	{
       
   189 	const TBool ret = ( iNotifyDeviceEventMsg.Handle() != 0 );
       
   190 	LOGTEXT2(_L("CFdfSession::NotifyDeviceEventOutstanding returning %d"), ret);
       
   191 	return ret;
       
   192 	}
       
   193 
       
   194 void CFdfSession::NotifyDeviceEvent(const RMessage2& aMessage)
       
   195 	{
       
   196 	LOG_FUNC
       
   197 
       
   198 	if ( iNotifyDeviceEventMsg.Handle() )
       
   199 		{
       
   200 		PANIC_MSG(iNotifyDeviceEventMsg, KUsbFdfServerName, ENotifyDeviceEventAlreadyOutstanding);
       
   201 		}
       
   202 	else
       
   203 		{
       
   204 		iNotifyDeviceEventMsg = aMessage;
       
   205 		TDeviceEvent event;
       
   206 		if ( iFdf.GetDeviceEvent(event) )
       
   207 			{
       
   208 			CompleteDeviceEventNotification(event);
       
   209 			}
       
   210 		}
       
   211 	}
       
   212 
       
   213 void CFdfSession::NotifyDeviceEventCancel(const RMessage2& aMessage)
       
   214 	{
       
   215 	LOG_FUNC
       
   216 
       
   217 	if ( iNotifyDeviceEventMsg.Handle() )
       
   218 		{
       
   219 		CompleteClient(iNotifyDeviceEventMsg, KErrCancel);
       
   220 		}
       
   221 	CompleteClient(aMessage, KErrNone);
       
   222 	}
       
   223 
       
   224 void CFdfSession::DeviceEvent(const TDeviceEvent& aEvent)
       
   225 	{
       
   226 	LOG_FUNC
       
   227 
       
   228 	// This function should only be called if there is a request outstanding.
       
   229 	ASSERT_DEBUG(iNotifyDeviceEventMsg.Handle());
       
   230 
       
   231 	CompleteDeviceEventNotification(aEvent);
       
   232 	}
       
   233 
       
   234 void CFdfSession::CompleteDeviceEventNotification(const TDeviceEvent& aEvent)
       
   235 	{
       
   236 	LOG_FUNC
       
   237 
       
   238 	TRAPD(err, CompleteDeviceEventNotificationL(aEvent));
       
   239 	if ( err )
       
   240 		{
       
   241 		PANIC_MSG(iNotifyDeviceEventMsg, KUsbFdfServerName, EBadNotifyDeviceEventData);
       
   242 		}
       
   243 	}
       
   244 
       
   245 void CFdfSession::CompleteDeviceEventNotificationL(const TDeviceEvent& aEvent)
       
   246 	{
       
   247 	LOG_FUNC
       
   248 
       
   249 	// iNotifyDeviceEventMsg has one IPC arg: a TDeviceEventInformation
       
   250 
       
   251 	ASSERT_DEBUG(iNotifyDeviceEventMsg.Handle());
       
   252 
       
   253 	TPckg<TDeviceEventInformation> info(aEvent.iInfo);
       
   254 	iNotifyDeviceEventMsg.WriteL(0, info);
       
   255 
       
   256 	CompleteClient(iNotifyDeviceEventMsg, KErrNone);
       
   257 	}
       
   258 
       
   259 TBool CFdfSession::NotifyDevmonEventOutstanding() const
       
   260 	{
       
   261 	const TBool ret = ( iNotifyDevmonEventMsg.Handle() != 0 );
       
   262 	LOGTEXT2(_L("CFdfSession::NotifyDevmonEventOutstanding returning %d"), ret);
       
   263 	return ret;
       
   264 	}
       
   265 
       
   266 void CFdfSession::NotifyDevmonEvent(const RMessage2& aMessage)
       
   267 	{
       
   268 	LOG_FUNC
       
   269 
       
   270 	if ( iNotifyDevmonEventMsg.Handle() )
       
   271 		{
       
   272 		PANIC_MSG(iNotifyDevmonEventMsg, KUsbFdfServerName, ENotifyDevmonEventAlreadyOutstanding);
       
   273 		}
       
   274 	else
       
   275 		{
       
   276 		iNotifyDevmonEventMsg = aMessage;
       
   277 		TInt event;
       
   278 		if ( iFdf.GetDevmonEvent(event) )
       
   279 			{
       
   280 			CompleteDevmonEventNotification(event);
       
   281 			}
       
   282 		}
       
   283 	}
       
   284 
       
   285 void CFdfSession::NotifyDevmonEventCancel(const RMessage2& aMessage)
       
   286 	{
       
   287 	LOG_FUNC
       
   288 
       
   289 	if ( iNotifyDevmonEventMsg.Handle() )
       
   290 		{
       
   291 		CompleteClient(iNotifyDevmonEventMsg, KErrCancel);
       
   292 		}
       
   293 	CompleteClient(aMessage, KErrNone);
       
   294 	}
       
   295 
       
   296 void CFdfSession::DevmonEvent(TInt aError)
       
   297 	{
       
   298 	LOG_FUNC
       
   299 
       
   300 	// This function should only be called if there is a request outstanding.
       
   301 	ASSERT_DEBUG(iNotifyDevmonEventMsg.Handle());
       
   302 
       
   303 	CompleteDevmonEventNotification(aError);
       
   304 	}
       
   305 
       
   306 void CFdfSession::CompleteDevmonEventNotification(TInt aError)
       
   307 	{
       
   308 	LOG_FUNC
       
   309 
       
   310 	TRAPD(err, CompleteDevmonEventNotificationL(aError));
       
   311 	if ( err )
       
   312 		{
       
   313 		PANIC_MSG(iNotifyDevmonEventMsg, KUsbFdfServerName, EBadNotifyDevmonEventData);
       
   314 		}
       
   315 	}
       
   316 
       
   317 void CFdfSession::CompleteDevmonEventNotificationL(TInt aEvent)
       
   318 	{
       
   319 	LOG_FUNC
       
   320 
       
   321 	// iNotifyDevmonEventMsg has the following IPC args:
       
   322 	// 0- TInt& aError
       
   323 
       
   324 	ASSERT_DEBUG(iNotifyDevmonEventMsg.Handle());
       
   325 
       
   326 	TPckg<TInt> event(aEvent);
       
   327 	iNotifyDevmonEventMsg.WriteL(0, event);
       
   328 
       
   329 	CompleteClient(iNotifyDevmonEventMsg, KErrNone);
       
   330 	}
       
   331 
       
   332 void CFdfSession::GetSingleSupportedLanguageOrNumberOfSupportedLanguages(const RMessage2& aMessage)
       
   333 	{
       
   334 	LOG_FUNC
       
   335 
       
   336 	// To save IPC operations between client and server, we make use of the
       
   337 	// fact that the majority of devices only support a single language.
       
   338 	// The client is expected to have a buffer big enough to hold a single
       
   339 	// TUint.
       
   340 	// If the device supports 0 languages, the buffer is left empty and the
       
   341 	// request is completed with KErrNotFound.
       
   342 	// If the device supports 1 language, the language ID is put in the buffer
       
   343 	// and the request is completed with KErrNone.
       
   344 	// If the device supports more than 1 language, the number of languages is
       
   345 	// put in the buffer, and the request is completed with
       
   346 	// KErrTooBig. The client then allocates a buffer big enough to hold the
       
   347 	// supported languages and uses EUsbFdfSrvGetSupportedLanguages to get
       
   348 	// them all.
       
   349 	TRAPD(err, GetSingleSupportedLanguageOrNumberOfSupportedLanguagesL(aMessage));
       
   350 	CompleteClient(aMessage, err);
       
   351 	}
       
   352 
       
   353 void CFdfSession::GetSingleSupportedLanguageOrNumberOfSupportedLanguagesL(const RMessage2& aMessage)
       
   354 	{
       
   355 	LOG_FUNC
       
   356 
       
   357 	const TUint deviceId = aMessage.Int0();
       
   358 	LOGTEXT2(_L8("\tdeviceId = %d"), deviceId);
       
   359 	const RArray<TUint>& langIds = iFdf.GetSupportedLanguagesL(deviceId);
       
   360 	const TUint count = langIds.Count();
       
   361 	LOGTEXT2(_L8("\tcount = %d"), count);
       
   362 	switch ( count )
       
   363 		{
       
   364 	case 0:
       
   365 		// Nothing to write to the client's address space, complete with
       
   366 		LEAVEL(KErrNotFound);
       
   367 		break;
       
   368 
       
   369 	case 1:
       
   370 		{
       
   371 		// Write the single supported language to the client, complete with
       
   372 		// KErrNone (or error of course, if their buffer isn't big enough).
       
   373 		TPckg<TUint> buf(langIds[0]);
       
   374 		LEAVEIFERRORL(aMessage.Write(1, buf));
       
   375 		}
       
   376 		break;
       
   377 
       
   378 	default:
       
   379 		{
       
   380 		// Write the number of supported languages to the client, complete
       
   381 		// with KErrTooBig (or error if their buffer wasn't big enough). NB
       
   382 		// This is the point at which this mechanism depends on
       
   383 		// RMessagePtr2::WriteL itself not leaving with KErrTooBig!
       
   384 		TPckg<TUint> buf(count);
       
   385 		LEAVEIFERRORL(aMessage.Write(1, buf));
       
   386 		LEAVEL(KErrTooBig);
       
   387 		}
       
   388 		break;
       
   389 		}
       
   390 	}
       
   391 
       
   392 void CFdfSession::GetSupportedLanguages(const RMessage2& aMessage)
       
   393 	{
       
   394 	LOG_FUNC
       
   395 
       
   396 	TRAPD(err, GetSupportedLanguagesL(aMessage));
       
   397 	CompleteClient(aMessage, err);
       
   398 	}
       
   399 
       
   400 void CFdfSession::GetSupportedLanguagesL(const RMessage2& aMessage)
       
   401 	{
       
   402 	LOG_FUNC
       
   403 
       
   404 	const TUint deviceId = aMessage.Int0();
       
   405 	LOGTEXT2(_L8("\tdeviceId = %d"), deviceId);
       
   406 	const RArray<TUint>& langIds = iFdf.GetSupportedLanguagesL(deviceId);
       
   407 
       
   408 	const TUint count = langIds.Count();
       
   409 	LOGTEXT2(_L8("\tcount = %d"), count);
       
   410 	RBuf8 buf;
       
   411 	buf.CreateL(count * sizeof(TUint));
       
   412 	CleanupClosePushL(buf);
       
   413 	for ( TUint ii = 0 ; ii < count ; ++ii )
       
   414 		{
       
   415 		buf.Append((TUint8*)&(langIds[ii]), sizeof(TUint));
       
   416 		}
       
   417 
       
   418 	// Write back to the client.
       
   419 	LEAVEIFERRORL(aMessage.Write(1, buf));
       
   420 	CleanupStack::PopAndDestroy(&buf);
       
   421 	}
       
   422 
       
   423 void CFdfSession::GetManufacturerStringDescriptor(const RMessage2& aMessage)
       
   424 	{
       
   425 	LOG_FUNC
       
   426 
       
   427 	GetStringDescriptor(aMessage, EManufacturer);
       
   428 	}
       
   429 
       
   430 void CFdfSession::GetProductStringDescriptor(const RMessage2& aMessage)
       
   431 	{
       
   432 	LOG_FUNC
       
   433 
       
   434 	GetStringDescriptor(aMessage, EProduct);
       
   435 	}
       
   436 
       
   437 void CFdfSession::GetStringDescriptor(const RMessage2& aMessage, TStringType aStringType)
       
   438 	{
       
   439 	LOG_FUNC
       
   440 
       
   441 	TRAPD(err, GetStringDescriptorL(aMessage, aStringType));
       
   442 	CompleteClient(aMessage, err);
       
   443 	}
       
   444 
       
   445 void CFdfSession::GetStringDescriptorL(const RMessage2& aMessage, TStringType aStringType)
       
   446 	{
       
   447 	LOG_FUNC
       
   448 
       
   449 	ASSERT_DEBUG(aStringType == EManufacturer || aStringType == EProduct);
       
   450 
       
   451 	TName string;
       
   452 	const TUint deviceId = aMessage.Int0();
       
   453 	const TUint langId = aMessage.Int1();
       
   454 	if ( aStringType == EManufacturer )
       
   455 		{
       
   456 		iFdf.GetManufacturerStringDescriptorL(deviceId, langId, string);
       
   457 		}
       
   458 	else
       
   459 		{
       
   460 		iFdf.GetProductStringDescriptorL(deviceId, langId, string);
       
   461 		}
       
   462 	LOGTEXT2(_L("\tstring = \"%S\""), &string);
       
   463 	LEAVEIFERRORL(aMessage.Write(2, string));
       
   464 	}
       
   465 
       
   466 void CFdfSession::GetOtgDeviceDescriptor(const RMessage2& aMessage)
       
   467 	{
       
   468 	LOG_FUNC
       
   469 	
       
   470 	TOtgDescriptor otgDesc;
       
   471 	const TUint deviceId = aMessage.Int0();
       
   472 	TRAPD(err, iFdf.GetOtgDeviceDescriptorL(deviceId, otgDesc));	
       
   473 	if (KErrNone == err)
       
   474 		{
       
   475 		TPckg<TOtgDescriptor> buf(otgDesc);
       
   476 		err = aMessage.Write(1, buf);
       
   477 		}
       
   478 	CompleteClient(aMessage, err);
       
   479 	}