usbmgmt/usbmgr/usbman/client/SRC/RUsb.cpp
changeset 0 c9bc50fca66e
child 26 f3a1ae528dee
child 42 f92a4f87e424
equal deleted inserted replaced
-1:000000000000 0:c9bc50fca66e
       
     1 /*
       
     2 * Copyright (c) 2003-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 #include <e32uid.h>
       
    19 #include <usbman.h>
       
    20 #include <usb.h>
       
    21 #include <e32base.h>
       
    22 #include "rusb.h"
       
    23 #include <usb/usblogger.h>
       
    24 
       
    25 #ifdef __FLOG_ACTIVE
       
    26 _LIT8(KLogComponent, "USBMAN");
       
    27 #endif
       
    28 
       
    29 #ifdef __USBMAN_NO_PROCESSES__
       
    30 #include <e32math.h>
       
    31 #endif
       
    32 
       
    33 
       
    34 static TInt StartServer()
       
    35 //
       
    36 // Start the server process or thread
       
    37 //
       
    38 	{
       
    39 	const TUidType serverUid(KNullUid, KNullUid, KUsbmanSvrUid);
       
    40 
       
    41 #ifdef __USBMAN_NO_PROCESSES__
       
    42 	//
       
    43 	// In EKA1 WINS the server is a DLL, the exported entrypoint returns a TInt
       
    44 	// which represents the real entry-point for the server thread
       
    45 	//
       
    46 	RLibrary lib;
       
    47 	TInt err = lib.Load(KUsbmanImg, serverUid);
       
    48 	
       
    49 	if (err != KErrNone)
       
    50 		{
       
    51 		return err;
       
    52 		}
       
    53 
       
    54 	TLibraryFunction ordinal1 = lib.Lookup(1);
       
    55 	TThreadFunction serverFunc = reinterpret_cast<TThreadFunction>(ordinal1());
       
    56 
       
    57 	//
       
    58 	// To deal with the unique thread (+semaphore!) naming in EPOC, and that we may
       
    59 	// be trying to restart a server that has just exited we attempt to create a
       
    60 	// unique thread name for the server.
       
    61 	// This uses Math::Random() to generate a 32-bit random number for the name
       
    62 	//
       
    63 	TName name(KUsbServerName);
       
    64 	name.AppendNum(Math::Random(),EHex);
       
    65 	
       
    66 	RThread server;
       
    67 	err = server.Create (
       
    68 		name,
       
    69 		serverFunc,
       
    70 		KUsbmanStackSize,
       
    71 		NULL,
       
    72 		&lib,
       
    73 		NULL,
       
    74 		KUsbmanMinHeapSize,
       
    75 		KUsbmanMaxHeapSize,
       
    76 		EOwnerProcess
       
    77 	);
       
    78 
       
    79 	lib.Close();	// if successful, server thread has handle to library now
       
    80 #else
       
    81 	//
       
    82 	// EPOC and EKA2 is easy, we just create a new server process. Simultaneous
       
    83 	// launching of two such processes should be detected when the second one
       
    84 	// attempts to create the server object, failing with KErrAlreadyExists.
       
    85 	//
       
    86 	RProcess server;
       
    87 	TInt err = server.Create(KUsbmanImg, KNullDesC, serverUid);
       
    88 #endif //__USBMAN_NO_PROCESSES__
       
    89 	
       
    90 	if (err != KErrNone)
       
    91 		{
       
    92 		return err;
       
    93 		}
       
    94 
       
    95 	TRequestStatus stat;
       
    96 	server.Rendezvous(stat);
       
    97 	
       
    98 	if (stat!=KRequestPending)
       
    99 		server.Kill(0);		// abort startup
       
   100 	else
       
   101 		server.Resume();	// logon OK - start the server
       
   102 
       
   103 	User::WaitForRequest(stat);		// wait for start or death
       
   104 
       
   105 	// we can't use the 'exit reason' if the server panicked as this
       
   106 	// is the panic 'reason' and may be '0' which cannot be distinguished
       
   107 	// from KErrNone
       
   108 	err = (server.ExitType() == EExitPanic) ? KErrServerTerminated : stat.Int();
       
   109 
       
   110 	server.Close();
       
   111 	
       
   112 	LOGTEXT2(_L8("USB server started successfully: err = %d\n"),err);
       
   113 
       
   114 	return err;
       
   115 	}
       
   116 
       
   117 
       
   118 
       
   119 
       
   120 EXPORT_C RUsb::RUsb() 
       
   121 	: iDeviceStatePkg(0), iServiceStatePkg(0), iMessagePkg(0), 
       
   122 	  iHostPkg(TDeviceEventInformation())
       
   123 	{
       
   124 	LOG_LINE
       
   125 	LOG_FUNC
       
   126 	}
       
   127 
       
   128 EXPORT_C RUsb::~RUsb()
       
   129 	{
       
   130 	LOG_LINE
       
   131 	LOG_FUNC
       
   132 	}
       
   133 
       
   134 EXPORT_C TVersion RUsb::Version() const
       
   135 	{
       
   136 	return(TVersion(KUsbSrvMajorVersionNumber,KUsbSrvMinorVersionNumber,KUsbSrvBuildVersionNumber));
       
   137 	}
       
   138 
       
   139 EXPORT_C TInt RUsb::Connect()
       
   140 	{
       
   141 	LOG_LINE
       
   142 	LOG_FUNC
       
   143 
       
   144 	TInt retry = 2;
       
   145 	
       
   146 	FOREVER
       
   147 		{
       
   148 		// Create the session to UsbSrv with 10 asynchronous message slots
       
   149 		TInt err = CreateSession(KUsbServerName, Version(), 10);
       
   150 
       
   151 		if ((err != KErrNotFound) && (err != KErrServerTerminated))
       
   152 			{
       
   153 			return err;
       
   154 			}
       
   155 
       
   156 		if (--retry == 0)
       
   157 			{
       
   158 			return err;
       
   159 			}
       
   160 
       
   161 		err = StartServer();
       
   162 
       
   163 		if ((err != KErrNone) && (err != KErrAlreadyExists))
       
   164 			{
       
   165 			return err;
       
   166 			}
       
   167 		}
       
   168 	}
       
   169 
       
   170 EXPORT_C void RUsb::Start(TRequestStatus& aStatus)
       
   171 	{
       
   172 	LOG_LINE
       
   173 	LOG_FUNC
       
   174 
       
   175 	SendReceive(EUsbStart, aStatus);
       
   176 	}
       
   177 
       
   178 EXPORT_C void RUsb::StartCancel()
       
   179 	{
       
   180 	LOG_LINE
       
   181 	LOG_FUNC
       
   182 
       
   183 	SendReceive(EUsbStartCancel);
       
   184 	}
       
   185 
       
   186 EXPORT_C void RUsb::Stop()
       
   187 	{
       
   188 	LOG_LINE
       
   189 	LOG_FUNC
       
   190 
       
   191 	SendReceive(EUsbStop);
       
   192 	}
       
   193 
       
   194 EXPORT_C void RUsb::Stop(TRequestStatus& aStatus)
       
   195 	{
       
   196 	LOG_LINE
       
   197 	LOG_FUNC
       
   198 
       
   199 	SendReceive(EUsbStop, aStatus);
       
   200 	}
       
   201 
       
   202 EXPORT_C void RUsb::StopCancel()
       
   203 	{
       
   204 	LOG_LINE
       
   205 	LOG_FUNC
       
   206 
       
   207 	SendReceive(EUsbStopCancel);
       
   208 	}
       
   209 
       
   210 EXPORT_C TInt RUsb::GetServiceState(TUsbServiceState& aState)
       
   211 	{
       
   212 	LOG_LINE
       
   213 	LOG_FUNC
       
   214 
       
   215 	TPckg<TUint32> pkg(aState);
       
   216 	TInt ret=SendReceive(EUsbGetCurrentState, TIpcArgs(&pkg));
       
   217 	aState=(TUsbServiceState)pkg();
       
   218 	return ret;
       
   219 	}
       
   220 
       
   221 EXPORT_C TInt RUsb::GetCurrentState(TUsbServiceState& aState)
       
   222 	{
       
   223 	LOG_LINE
       
   224 	LOG_FUNC
       
   225 
       
   226 	return GetServiceState(aState);
       
   227 	}
       
   228 
       
   229 EXPORT_C void RUsb::ServiceStateNotification(TUsbServiceState& aState,
       
   230 	TRequestStatus& aStatus)
       
   231 	{
       
   232 	LOG_LINE
       
   233 	LOG_FUNC
       
   234 
       
   235 	iServiceStatePkg.Set((TUint8*)&aState, sizeof(TUint32), sizeof(TUint32));
       
   236 
       
   237 	SendReceive(EUsbRegisterServiceObserver, TIpcArgs(&iServiceStatePkg), aStatus);
       
   238 	}
       
   239 
       
   240 EXPORT_C void RUsb::ServiceStateNotificationCancel()
       
   241 	{
       
   242 	LOG_LINE
       
   243 	LOG_FUNC
       
   244 
       
   245 	SendReceive(EUsbCancelServiceObserver);
       
   246 	}
       
   247 
       
   248 EXPORT_C TInt RUsb::GetDeviceState(TUsbDeviceState& aState)
       
   249 	{
       
   250 	LOG_LINE
       
   251 	LOG_FUNC
       
   252 
       
   253 	TPckg<TUint32> pkg(aState);
       
   254 	TInt ret=SendReceive(EUsbGetCurrentDeviceState, TIpcArgs(&pkg));
       
   255 	aState=(TUsbDeviceState)pkg();
       
   256 	return ret;
       
   257 	}
       
   258 
       
   259 EXPORT_C void RUsb::DeviceStateNotification(TUint aEventMask, TUsbDeviceState& aState,
       
   260 											TRequestStatus& aStatus)
       
   261 	{
       
   262 	LOG_LINE
       
   263 	LOG_FUNC
       
   264 
       
   265 	iDeviceStatePkg.Set((TUint8*)&aState, sizeof(TUint32), sizeof(TUint32));
       
   266 
       
   267 	SendReceive(EUsbRegisterObserver, TIpcArgs(aEventMask, &iDeviceStatePkg), aStatus);
       
   268 	}
       
   269 
       
   270 EXPORT_C void RUsb::DeviceStateNotificationCancel()
       
   271 	{
       
   272 	LOG_LINE
       
   273 	LOG_FUNC
       
   274 
       
   275 	SendReceive(EUsbCancelObserver);
       
   276 	}
       
   277 
       
   278 EXPORT_C void RUsb::StateNotification(TUint aEventMask, TUsbDeviceState& aState, TRequestStatus& aStatus)
       
   279 	{
       
   280 	LOG_LINE
       
   281 	LOG_FUNC
       
   282 
       
   283 	DeviceStateNotification(aEventMask, aState, aStatus);
       
   284 	}
       
   285 
       
   286 EXPORT_C void RUsb::StateNotificationCancel()
       
   287 	{
       
   288 	LOG_LINE
       
   289 	LOG_FUNC
       
   290 
       
   291 	DeviceStateNotificationCancel();
       
   292 	}
       
   293 	
       
   294 EXPORT_C void RUsb::TryStart(TInt aPersonalityId, TRequestStatus& aStatus)
       
   295 	{
       
   296 	LOG_LINE
       
   297 	LOG_FUNC
       
   298 
       
   299 	TIpcArgs ipcArgs(aPersonalityId);
       
   300 	SendReceive(EUsbTryStart, ipcArgs, aStatus);
       
   301 	}
       
   302 
       
   303 EXPORT_C void RUsb::TryStop(TRequestStatus& aStatus)
       
   304 	{
       
   305 	LOG_LINE
       
   306 	LOG_FUNC
       
   307 
       
   308 	SendReceive(EUsbTryStop, aStatus);
       
   309 	}
       
   310 	
       
   311 EXPORT_C TInt RUsb::CancelInterest(TUsbReqType aMessageId)
       
   312 	{
       
   313 	LOG_LINE
       
   314 	LOG_FUNC
       
   315 
       
   316 	TInt messageId;
       
   317 	switch (aMessageId)
       
   318 		{
       
   319 	case EStart:
       
   320 		messageId = EUsbStart;
       
   321 		break;
       
   322 	case EStop:
       
   323 		messageId = EUsbStop;
       
   324 		break;
       
   325 	case ETryStart:
       
   326 		messageId = EUsbTryStart;
       
   327 		break;
       
   328 	case ETryStop:
       
   329 		messageId = EUsbTryStop;
       
   330 		break;
       
   331 	default:
       
   332 		return KErrNotSupported;
       
   333 		}
       
   334 		
       
   335 	TIpcArgs ipcArgs(messageId);
       
   336 	return SendReceive(EUsbCancelInterest, ipcArgs);
       
   337 	}
       
   338 
       
   339 EXPORT_C TInt RUsb::GetDescription(TInt aPersonalityId, HBufC*& aLocalizedPersonalityDescriptor)
       
   340 	{
       
   341 	LOG_LINE
       
   342 	LOG_FUNC
       
   343 
       
   344 	TInt ret = KErrNone;
       
   345 	// caller is responsible for freeing up memory allocatd for aLocalizedPersonalityDescriptor
       
   346 	TRAP(ret, aLocalizedPersonalityDescriptor = HBufC::NewL(KUsbStringDescStringMaxSize));
       
   347 	if (ret == KErrNone)
       
   348 		{
       
   349 		TPtr ptr = aLocalizedPersonalityDescriptor->Des();
       
   350 		TIpcArgs ipcArgs(0, &ptr);
       
   351 		ipcArgs.Set(0, aPersonalityId);
       
   352 		ret = SendReceive(EUsbGetDescription, ipcArgs);
       
   353 		}
       
   354 	else
       
   355 		{
       
   356 		// just in case caller tries to free the memory before checking the return code
       
   357 		aLocalizedPersonalityDescriptor = NULL;
       
   358 		}
       
   359 
       
   360 	return ret;	
       
   361 	}
       
   362 	
       
   363 EXPORT_C TInt RUsb::GetCurrentPersonalityId(TInt& aPersonalityId)
       
   364 	{
       
   365 	LOG_LINE
       
   366 	LOG_FUNC
       
   367 
       
   368 	TPckg<TInt> pkg0(aPersonalityId);
       
   369 	TInt ret = SendReceive(EUsbGetCurrentPersonalityId, TIpcArgs(&pkg0));
       
   370 	aPersonalityId = static_cast<TInt>(pkg0());
       
   371 	return ret;	
       
   372 	}
       
   373 
       
   374 EXPORT_C TInt RUsb::GetSupportedClasses(TInt aPersonalityId, RArray<TUid>& aClassUids)
       
   375 	{
       
   376 	LOG_LINE
       
   377 	LOG_FUNC
       
   378 
       
   379 	TInt ret = KErrNone;
       
   380 	HBufC8* buf = NULL;
       
   381 	// +1 for the actual count of personality ids
       
   382 	TRAP(ret, buf = HBufC8::NewL((KUsbMaxSupportedClasses + 1)*sizeof (TInt32)));
       
   383 	if (ret != KErrNone)
       
   384 		{
       
   385 		return ret;
       
   386 		}
       
   387 
       
   388 	TPtr8 ptr8 = buf->Des();
       
   389 	ret = SendReceive(EUsbGetSupportedClasses, TIpcArgs(aPersonalityId, &ptr8));
       
   390 		
       
   391 	if (ret == KErrNone)
       
   392 		{
       
   393 		const TInt32* recvedIds = reinterpret_cast<const TInt32*>(buf->Ptr());
       
   394 		if (!recvedIds)
       
   395 			{
       
   396 			delete buf;
       
   397 			return KErrCorrupt;
       
   398 			}
       
   399 			
       
   400 		TInt arraySize = *recvedIds++;
       
   401 		// Copy received supported class ids to aClassUids
       
   402 		for (TInt i = 0; i < arraySize; i++)
       
   403 			{
       
   404 			if (recvedIds)
       
   405 				{
       
   406 				ret = aClassUids.Append(TUid::Uid(*recvedIds++));
       
   407 				if(ret!=KErrNone)
       
   408 					{
       
   409 					//Remove all the ids appended so far (assume the last append failed, because
       
   410 					//the only reason to fail is if the array couldn't grow to accommodate another
       
   411 					//element).
       
   412 					//It would be easier to just reset the array, but we never specified that
       
   413 					//aClassUids should be an empty array, nor did we specify that this method
       
   414 					//might empty the array. To maintain exisiting behaviour we should return
       
   415 					//aClassUids to the state it was in when this method was called.
       
   416 					TInt last = aClassUids.Count() - 1;
       
   417 					while(i>0)
       
   418 						{
       
   419 						aClassUids.Remove(last);
       
   420 						i--;
       
   421 						last--;
       
   422 						}	
       
   423 					break;
       
   424 					}
       
   425 				}
       
   426 			else
       
   427 				{
       
   428 				ret = KErrCorrupt;
       
   429 				break;
       
   430 				}
       
   431 			}
       
   432 		}
       
   433 		
       
   434 	delete buf;
       
   435 	return ret;
       
   436 	}
       
   437 	
       
   438 EXPORT_C TInt RUsb::ClassSupported(TInt aPersonalityId, TUid aClassUid, TBool& aSupported)
       
   439 	{
       
   440 	LOG_LINE
       
   441 	LOG_FUNC
       
   442 
       
   443 	TPckg<TInt32>  	pkg2(aSupported);
       
   444 	TIpcArgs ipcArgs(aPersonalityId, aClassUid.iUid, &pkg2);
       
   445 	
       
   446 	TInt ret = SendReceive(EUsbClassSupported, ipcArgs);
       
   447 	
       
   448 	if (ret == KErrNone)
       
   449 		{
       
   450 		aSupported = static_cast<TBool>(pkg2());		
       
   451 		}
       
   452 		
       
   453 	return ret;
       
   454 	}
       
   455 	
       
   456 EXPORT_C TInt RUsb::GetPersonalityIds(RArray<TInt>& aPersonalityIds)
       
   457 	{
       
   458 	LOG_LINE
       
   459 	LOG_FUNC
       
   460 
       
   461 	TInt ret = KErrNone;
       
   462 	HBufC8* buf = NULL;
       
   463 	// +1 for the actual count of personality ids
       
   464 	TRAP(ret, buf = HBufC8::NewL((KUsbMaxSupportedPersonalities + 1)*sizeof (TInt)));
       
   465 	if (ret != KErrNone)
       
   466 		{
       
   467 		return ret;
       
   468 		}
       
   469 
       
   470 	TPtr8 ptr8 = buf->Des();
       
   471 	ret = SendReceive(EUsbGetPersonalityIds, TIpcArgs(&ptr8));
       
   472 		
       
   473 	if (ret == KErrNone)
       
   474 		{
       
   475 		const TInt* recvedIds = reinterpret_cast<const TInt*>(buf->Ptr());
       
   476 		if (!recvedIds)
       
   477 			{
       
   478 			delete buf;
       
   479 			return KErrCorrupt;
       
   480 			}
       
   481 			
       
   482 		TInt arraySize = *recvedIds++;
       
   483 		// Copy received personality ids to aPersonalityIds
       
   484 		for (TInt i = 0; i < arraySize; i++)
       
   485 			{
       
   486 			if (recvedIds)
       
   487 				{		
       
   488 				ret = aPersonalityIds.Append(*recvedIds++);
       
   489 				
       
   490 				if(ret!=KErrNone)
       
   491 					{
       
   492 					//Remove all the ids appended so far (assume the last append failed, because
       
   493 					//the only reason to fail is if the array couldn't grow to accommodate another
       
   494 					//element).
       
   495 					//It would be easier to just reset the array, but we never specified that
       
   496 					//aPersonalityIds should be an empty array, nor did we specify that this method
       
   497 					//might empty the array. To maintain exisiting behaviour we should return
       
   498 					//aPersonalityIds to the state it was in when this method was called.
       
   499 					TInt last = aPersonalityIds.Count() - 1;
       
   500 					while(i>0)
       
   501 						{
       
   502 						aPersonalityIds.Remove(last);
       
   503 						i--;
       
   504 						last--;
       
   505 						}	
       
   506 					break;
       
   507 					}
       
   508 				}
       
   509 			else
       
   510 				{
       
   511 				ret = KErrCorrupt;
       
   512 				break;
       
   513 				}
       
   514 			}
       
   515 		}
       
   516 		
       
   517 	delete buf;
       
   518 	return ret;
       
   519 	}
       
   520 	
       
   521 EXPORT_C TInt RUsb::__DbgMarkHeap()
       
   522 	{
       
   523 #ifdef _DEBUG
       
   524     return SendReceive(EUsbDbgMarkHeap);
       
   525 #else
       
   526     return KErrNone;
       
   527 #endif
       
   528 	}
       
   529 
       
   530 EXPORT_C TInt RUsb::__DbgCheckHeap(TInt aCount)
       
   531 	{
       
   532 #ifdef _DEBUG
       
   533     return SendReceive(EUsbDbgCheckHeap, TIpcArgs(aCount));
       
   534 #else
       
   535 	(void)aCount; // not used for Release builds
       
   536     return KErrNone;
       
   537 #endif
       
   538 	}
       
   539 
       
   540 EXPORT_C TInt RUsb::__DbgMarkEnd(TInt aCount)
       
   541 	{
       
   542 #ifdef _DEBUG
       
   543     return SendReceive(EUsbDbgMarkEnd, TIpcArgs(aCount));
       
   544 #else
       
   545 	(void)aCount; // not used for Release builds
       
   546     return KErrNone;
       
   547 #endif
       
   548 	}
       
   549 
       
   550 EXPORT_C TInt RUsb::__DbgFailNext(TInt aCount)
       
   551 	{
       
   552 #ifdef _DEBUG
       
   553     return SendReceive(EUsbDbgFailNext, TIpcArgs(aCount));
       
   554 #else
       
   555 	(void)aCount; // not used for Release builds
       
   556     return KErrNone;
       
   557 #endif
       
   558 	}
       
   559 
       
   560 EXPORT_C TInt RUsb::__DbgAlloc()
       
   561 	{
       
   562 #ifdef _DEBUG
       
   563     return SendReceive(EUsbDbgAlloc);
       
   564 #else
       
   565     return KErrNone;
       
   566 #endif
       
   567 	}
       
   568 
       
   569 EXPORT_C void panic()
       
   570 	{
       
   571 	_USB_PANIC(KUsbCliPncCat, EUsbPanicRemovedExport);
       
   572 	}
       
   573 
       
   574 EXPORT_C TInt RUsb::SetCtlSessionMode(TBool aValue)
       
   575 	{
       
   576 	LOG_LINE
       
   577 	LOG_FUNC
       
   578 
       
   579 	TPckg<TBool> pkg(aValue);
       
   580 	return SendReceive(EUsbSetCtlSessionMode, TIpcArgs(&pkg));
       
   581 	}
       
   582 
       
   583 EXPORT_C TInt RUsb::BusRequest()
       
   584 	{
       
   585 	LOG_LINE
       
   586 	LOG_FUNC
       
   587 
       
   588 	return SendReceive(EUsbBusRequest);
       
   589 	}
       
   590 
       
   591 EXPORT_C TInt RUsb::BusRespondSrp()
       
   592 	{
       
   593 	LOG_LINE
       
   594 	LOG_FUNC
       
   595 
       
   596 	return SendReceive(EUsbBusRespondSrp);
       
   597 	}
       
   598 
       
   599 EXPORT_C TInt RUsb::BusClearError()
       
   600 	{
       
   601 	LOG_LINE
       
   602 	LOG_FUNC
       
   603 
       
   604 	return SendReceive(EUsbBusClearError);
       
   605 	}
       
   606 
       
   607 
       
   608 EXPORT_C TInt RUsb::BusDrop()
       
   609 	{
       
   610 	LOG_LINE
       
   611 	LOG_FUNC
       
   612 
       
   613 	return SendReceive(EUsbBusDrop);
       
   614 	}
       
   615 
       
   616 EXPORT_C void RUsb::MessageNotification(TRequestStatus& aStatus, TInt& aMessage)
       
   617 	{
       
   618 	LOG_LINE
       
   619 	LOG_FUNC
       
   620 
       
   621 	iMessagePkg.Set((TUint8*)&aMessage, sizeof(TInt), sizeof(TInt));
       
   622 
       
   623 	SendReceive(EUsbRegisterMessageObserver, TIpcArgs(&iMessagePkg), aStatus);
       
   624 	}
       
   625 
       
   626 EXPORT_C void RUsb::MessageNotificationCancel()
       
   627 	{
       
   628 	LOG_LINE
       
   629 	LOG_FUNC
       
   630 
       
   631 	SendReceive(EUsbCancelMessageObserver);
       
   632 	}
       
   633 
       
   634 EXPORT_C void RUsb::HostEventNotification(TRequestStatus& aStatus,
       
   635 										  TDeviceEventInformation& aDeviceInformation)
       
   636 	{
       
   637 	LOG_LINE
       
   638 	LOG_FUNC
       
   639 
       
   640 	iHostPkg.Set((TUint8*)&aDeviceInformation, sizeof(TDeviceEventInformation), sizeof(TDeviceEventInformation));
       
   641 
       
   642 	SendReceive(EUsbRegisterHostObserver, TIpcArgs(&iHostPkg), aStatus);
       
   643 	}
       
   644 	
       
   645 EXPORT_C void RUsb::HostEventNotificationCancel()
       
   646 	{
       
   647 	LOG_LINE
       
   648 	LOG_FUNC
       
   649 
       
   650 	SendReceive(EUsbCancelHostObserver);
       
   651 	}
       
   652 
       
   653 EXPORT_C TInt RUsb::EnableFunctionDriverLoading()
       
   654 	{
       
   655 	LOG_LINE
       
   656 	LOG_FUNC
       
   657 
       
   658 	return SendReceive(EUsbEnableFunctionDriverLoading);
       
   659 	}
       
   660 
       
   661 EXPORT_C void RUsb::DisableFunctionDriverLoading()
       
   662 	{
       
   663 	LOG_LINE
       
   664 	LOG_FUNC
       
   665 
       
   666 	SendReceive(EUsbDisableFunctionDriverLoading);
       
   667 	}
       
   668 
       
   669 EXPORT_C TInt RUsb::GetSupportedLanguages(TUint aDeviceId, RArray<TUint>& aLangIds)
       
   670 	{
       
   671 	LOG_LINE
       
   672 	LOG_FUNC
       
   673 
       
   674 	aLangIds.Reset();
       
   675 
       
   676 	TInt ret = KErrNone;
       
   677 	HBufC8* buf = NULL;
       
   678 	// +1 for the actual count of language ids
       
   679 	TRAP(ret, buf = HBufC8::NewL((KUsbMaxSupportedLanguageIds + 1)*sizeof (TUint)));
       
   680 	if (ret != KErrNone)
       
   681 		{
       
   682 		return ret;
       
   683 		}
       
   684 
       
   685 	TPtr8 ptr8 = buf->Des();
       
   686 	ret = SendReceive(EUsbGetSupportedLanguages, TIpcArgs(aDeviceId, &ptr8));
       
   687 		
       
   688 	if (ret == KErrNone)
       
   689 		{
       
   690 		const TUint* recvedIds = reinterpret_cast<const TUint*>(buf->Ptr());
       
   691 		if (!recvedIds)
       
   692 			{
       
   693 			delete buf;
       
   694 			return KErrCorrupt;
       
   695 			}
       
   696 			
       
   697 		TInt arraySize = *recvedIds++;
       
   698 		// Copy received language ids to aLangIds
       
   699 		for (TInt i = 0; i < arraySize; i++)
       
   700 			{
       
   701 			ret = aLangIds.Append(*recvedIds++); // increments by sizeof(TUint)
       
   702 			if ( ret )
       
   703 				{
       
   704 				aLangIds.Reset();
       
   705 				break;
       
   706 				}
       
   707 			}
       
   708 		}
       
   709 		
       
   710 	delete buf;	
       
   711 	return ret;
       
   712 	}
       
   713 	
       
   714 EXPORT_C TInt RUsb::GetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
       
   715 	{
       
   716 	LOG_LINE
       
   717 	LOG_FUNC
       
   718 
       
   719 	return SendReceive(EUsbGetManufacturerStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString));
       
   720 	}
       
   721 
       
   722 EXPORT_C TInt RUsb::GetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
       
   723 	{
       
   724 	LOG_LINE
       
   725 	LOG_FUNC
       
   726 
       
   727 	return SendReceive(EUsbGetProductStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString));
       
   728 	}
       
   729 
       
   730 EXPORT_C TInt RUsb::GetOtgDescriptor(TUint aDeviceId, TOtgDescriptor& aDescriptor)
       
   731 	{
       
   732 	LOG_LINE
       
   733 	LOG_FUNC
       
   734 		
       
   735 	TPckg<TOtgDescriptor> otgDescPkg(aDescriptor);
       
   736 	
       
   737 	TIpcArgs args;
       
   738 	args.Set(0, aDeviceId);
       
   739 	args.Set(1, &otgDescPkg);
       
   740 
       
   741 	return SendReceive(EUsbGetOtgDescriptor, args);
       
   742 	}
       
   743 
       
   744 
       
   745 EXPORT_C TInt RUsb::RequestSession()
       
   746 	{
       
   747 	LOG_LINE
       
   748 	LOG_FUNC
       
   749 
       
   750 	return SendReceive(EUsbRequestSession);
       
   751 	}
       
   752 
       
   753 EXPORT_C TInt RUsb::GetDetailedDescription(TInt aPersonalityId, HBufC*& aLocalizedPersonalityDescriptor)
       
   754 	{
       
   755 	LOG_LINE
       
   756 	LOG_FUNC
       
   757 
       
   758  	TInt ret = KErrNone;
       
   759 	// caller is responsible for freeing up memory allocated for aLocalizedPersonalityDescriptor
       
   760 	TRAP(ret, aLocalizedPersonalityDescriptor = HBufC::NewL(KUsbStringDescStringMaxSize));
       
   761 	if (ret == KErrNone)
       
   762 		{
       
   763 		TPtr ptr = aLocalizedPersonalityDescriptor->Des();
       
   764 		TIpcArgs ipcArgs(0, &ptr);
       
   765 		ipcArgs.Set(0, aPersonalityId);
       
   766 		ret = SendReceive(EUsbGetDetailedDescription, ipcArgs);
       
   767 		}
       
   768 	else
       
   769 		{
       
   770 		// just in case caller tries to free the memory before checking the return code
       
   771 		aLocalizedPersonalityDescriptor = NULL;
       
   772 		}
       
   773 
       
   774 	return ret; 
       
   775 	}
       
   776 
       
   777 EXPORT_C TInt RUsb::GetPersonalityProperty(TInt aPersonalityId, TUint32& aProperty)
       
   778 	{
       
   779 	LOG_LINE
       
   780 	LOG_FUNC
       
   781 
       
   782 	TPckg<TUint32> pkg(aProperty);
       
   783 	TInt ret = SendReceive(EUsbGetPersonalityProperty, TIpcArgs(aPersonalityId, &pkg));
       
   784 	if (ret == KErrNone)
       
   785 		{
       
   786 		aProperty = static_cast<TUint32>(pkg());
       
   787 		}
       
   788 	return ret;	
       
   789 	}
       
   790