tsrc/testtools/usbman_stub/usbman/client/src/RUsb.cpp
branchRCL_3
changeset 22 5b2a402e96ac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tsrc/testtools/usbman_stub/usbman/client/src/RUsb.cpp	Thu Aug 19 10:54:11 2010 +0300
@@ -0,0 +1,1031 @@
+/*
+* Copyright (c) 2010 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:
+*
+*/
+
+#include <e32uid.h>
+#include <f32file.h>
+#include <usbman.h>
+#include <usb.h>
+#include <e32base.h>
+#include "rusb.h"
+#include <usb/usblogger.h>
+#include <stubber.h>
+#include "usbmandll_stub.h"
+#include <usbpersonalityids.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "USBMAN");
+#endif
+
+#ifdef __USBMAN_NO_PROCESSES__
+#include <e32math.h>
+#endif
+
+// CONSTANTS
+//const TUint KUsbAllStates = 0xFFFFFFFF;
+
+_LIT8(KLogStub, "[USBMAN] [Stub]");
+
+static TInt StartServer()
+//
+// Start the server process or thread
+//
+	{
+	const TUidType serverUid(KNullUid, KNullUid, KUsbmanSvrUid);
+
+#ifdef __USBMAN_NO_PROCESSES__
+	//
+	// In EKA1 WINS the server is a DLL, the exported entrypoint returns a TInt
+	// which represents the real entry-point for the server thread
+	//
+	RLibrary lib;
+	TInt err = lib.Load(KUsbmanImg, serverUid);
+	
+	if (err != KErrNone)
+		{
+		return err;
+		}
+
+	TLibraryFunction ordinal1 = lib.Lookup(1);
+	TThreadFunction serverFunc = reinterpret_cast<TThreadFunction>(ordinal1());
+
+	//
+	// To deal with the unique thread (+semaphore!) naming in EPOC, and that we may
+	// be trying to restart a server that has just exited we attempt to create a
+	// unique thread name for the server.
+	// This uses Math::Random() to generate a 32-bit random number for the name
+	//
+	TName name(KUsbServerName);
+	name.AppendNum(Math::Random(),EHex);
+	
+	RThread server;
+	err = server.Create (
+		name,
+		serverFunc,
+		KUsbmanStackSize,
+		NULL,
+		&lib,
+		NULL,
+		KUsbmanMinHeapSize,
+		KUsbmanMaxHeapSize,
+		EOwnerProcess
+	);
+
+	lib.Close();	// if successful, server thread has handle to library now
+#else
+	//
+	// EPOC and EKA2 is easy, we just create a new server process. Simultaneous
+	// launching of two such processes should be detected when the second one
+	// attempts to create the server object, failing with KErrAlreadyExists.
+	//
+	RProcess server;
+	TInt err = server.Create(KUsbmanImg, KNullDesC, serverUid);
+#endif //__USBMAN_NO_PROCESSES__
+	
+	if (err != KErrNone)
+		{
+		return err;
+		}
+
+	TRequestStatus stat;
+	server.Rendezvous(stat);
+	
+	if (stat!=KRequestPending)
+		server.Kill(0);		// abort startup
+	else
+		server.Resume();	// logon OK - start the server
+
+	User::WaitForRequest(stat);		// wait for start or death
+
+	// we can't use the 'exit reason' if the server panicked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	err = (server.ExitType() == EExitPanic) ? KErrServerTerminated : stat.Int();
+
+	server.Close();
+	
+	LOGTEXT2(_L8("USB server started successfully: err = %d\n"),err);
+
+	return err;
+	}
+
+
+
+
+EXPORT_C RUsb::RUsb() 
+	: iDeviceStatePkg(0), iServiceStatePkg(0), iMessagePkg(0), 
+	  iHostPkg(TDeviceEventInformation())
+	{
+	LOG_LINE
+	LOG_FUNC
+	}
+
+EXPORT_C RUsb::~RUsb()
+	{
+	LOG_LINE
+	LOG_FUNC
+	}
+
+EXPORT_C TVersion RUsb::Version() const
+	{
+	return(TVersion(KUsbSrvMajorVersionNumber,KUsbSrvMinorVersionNumber,KUsbSrvBuildVersionNumber));
+	}
+
+EXPORT_C TInt RUsb::Connect()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt retry = 2;
+	
+	FOREVER
+		{
+		// Create the session to UsbSrv with 10 asynchronous message slots
+		TInt err = CreateSession(KUsbServerName, Version(), 10);
+
+		if ((err != KErrNotFound) && (err != KErrServerTerminated))
+			{
+			return err;
+			}
+
+		if (--retry == 0)
+			{
+			return err;
+			}
+
+		err = StartServer();		
+		
+		if ((err != KErrNone) && (err != KErrAlreadyExists))
+			{
+			return err;
+			}
+		}
+	}
+
+EXPORT_C void RUsb::Start(TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStart, aStatus);
+	}
+
+EXPORT_C void RUsb::StartCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStartCancel);
+	}
+
+EXPORT_C void RUsb::Stop()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStop);
+	}
+
+EXPORT_C void RUsb::Stop(TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStop, aStatus);
+	}
+
+EXPORT_C void RUsb::StopCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbStopCancel);
+	}
+
+EXPORT_C TInt RUsb::GetServiceState(TUsbServiceState& aState)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	CStubber* stubber = CStubber::NewL();
+	TApiBehavior beh( KUsbManStubAgentDll, EServiceState, 0, 0, KNullDesC8 );
+	stubber -> InvokeApi( beh );
+
+	delete stubber;
+	stubber = NULL;
+
+	if ( beh.iOutput != KNullDesC8 )
+	    {           
+	    if ( !beh.iOutput.Compare( _L8( "EUsbServiceIdle" ) ) )
+	        aState = EUsbServiceIdle;
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbServiceStarting" ) ) )
+            aState = EUsbServiceStarting;
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbServiceStarted" ) ) )
+            aState = EUsbServiceStarted;
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbServiceStopping" ) ) )
+            aState = EUsbServiceStopping;
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbServiceFatalError" ) ) )
+            aState = EUsbServiceFatalError;
+	    else
+	    	{}
+	    }
+    else
+        {
+		TPckg<TUint32> pkg(aState);
+		TInt ret=SendReceive(EUsbGetCurrentState, TIpcArgs(&pkg));
+		aState=(TUsbServiceState)pkg();
+		return ret;
+        }
+	return beh.iCompleteCode;
+	}
+
+EXPORT_C TInt RUsb::GetCurrentState(TUsbServiceState& aState)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return GetServiceState(aState);
+	}
+
+EXPORT_C void RUsb::ServiceStateNotification(TUsbServiceState& aState,
+	TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	iServiceStatePkg.Set((TUint8*)&aState, sizeof(TUint32), sizeof(TUint32));
+
+	SendReceive(EUsbRegisterServiceObserver, TIpcArgs(&iServiceStatePkg), aStatus);
+	}
+
+EXPORT_C void RUsb::ServiceStateNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbCancelServiceObserver);
+	}
+
+EXPORT_C TInt RUsb::GetDeviceState(TUsbDeviceState& aState)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	_LIT8( KLogStubConfigured, "[USBMAN] [StubConfigured]");
+	CUsbLog::Write(KLogStub, KNullDesC8());
+	
+	CStubber* stubber = CStubber::NewL();
+	TApiBehavior beh( KUsbManStubAgentDll, EGetDeviceState, 0, 0, KNullDesC8 );
+	stubber -> InvokeApi( beh );
+
+	delete stubber;
+	stubber = NULL;
+
+	if ( beh.iOutput != KNullDesC8 )
+	    {           
+	    CUsbLog::Write(KLogStub, KNullDesC8());
+	    if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateUndefined" ) ) )
+	        aState = EUsbDeviceStateUndefined;
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateDefault" ) ) )
+            aState = EUsbDeviceStateDefault;
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateAttached" ) ) )
+            aState = EUsbDeviceStateAttached;
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStatePowered" ) ) )
+            aState = EUsbDeviceStatePowered;
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateConfigured" ) ) )
+	    	{
+            aState = EUsbDeviceStateConfigured;
+    	    CUsbLog::Write(KLogStubConfigured, KNullDesC8());
+	    	}
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateAddress" ) ) )
+            aState = EUsbDeviceStateAddress;
+	    else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateSuspended" ) ) )
+            aState = EUsbDeviceStateSuspended;
+	    else
+	    	{}
+	    }
+    else
+        {
+        _LIT8(KLogNoStub, "[USBMAN] [NoStub]");
+        CUsbLog::Write(KLogNoStub, KNullDesC8());
+		TPckg<TUint32> pkg(aState);
+		TInt ret=SendReceive(EUsbGetCurrentDeviceState, TIpcArgs(&pkg));
+		aState=(TUsbDeviceState)pkg();
+		return ret;
+        }
+		
+	return beh.iCompleteCode;
+	}
+
+EXPORT_C void RUsb::DeviceStateNotification(TUint aEventMask, TUsbDeviceState& aState,
+											TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+    CUsbLog::Write(KLogStub, KNullDesC8());
+    CStubber* stubber = CStubber::NewL();
+    TApiBehavior beh( KUsbManStubAgentDll, EDeviceStateNotification, 0, 0, KNullDesC8 );
+    stubber -> InvokeApi( beh );
+
+    delete stubber;
+    stubber = NULL;
+    
+    TRequestStatus* stat = &aStatus;
+    
+    if ( beh.iOutput != KNullDesC8 )
+        {                        
+        if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateUndefined" ) ) )
+            aState = EUsbDeviceStateUndefined;
+        else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateDefault" ) ) )
+            aState = EUsbDeviceStateDefault;
+        else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateAttached" ) ) )
+            aState = EUsbDeviceStateAttached;
+        else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStatePowered" ) ) )
+            aState = EUsbDeviceStatePowered;
+        else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateConfigured" ) ) )
+            aState = EUsbDeviceStateConfigured;
+        else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateAddress" ) ) )
+            aState = EUsbDeviceStateAddress;
+        else if ( !beh.iOutput.Compare( _L8( "EUsbDeviceStateSuspended" ) ) )
+            aState = EUsbDeviceStateSuspended;
+        else
+            {}
+        User::RequestComplete( stat, beh.iAsyncCompleteCode );
+        }
+    else
+        {
+        iDeviceStatePkg.Set((TUint8*)&aState, sizeof(TUint32), sizeof(TUint32));
+        SendReceive(EUsbRegisterObserver, TIpcArgs(aEventMask, &iDeviceStatePkg), aStatus);
+        }
+
+	}
+
+EXPORT_C void RUsb::DeviceStateNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+    CStubber* stubber = CStubber::NewL();
+    TApiBehavior beh( KUsbManStubAgentDll, EDeviceStateNotificationCancel, 0, 0, KNullDesC8 );
+    stubber -> InvokeApi( beh );
+
+    delete stubber;
+    stubber = NULL;
+    
+    if ( beh.iOutput != KNullDesC8 )
+        {        
+        
+        }
+    else 
+    	{
+    	SendReceive(EUsbCancelObserver);
+    	}
+	}
+
+EXPORT_C void RUsb::StateNotification(TUint aEventMask, TUsbDeviceState& aState, TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	DeviceStateNotification(aEventMask, aState, aStatus);
+	}
+
+EXPORT_C void RUsb::StateNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	DeviceStateNotificationCancel();
+	}
+	
+EXPORT_C void RUsb::TryStart(TInt aPersonalityId, TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+    CStubber* stubber = CStubber::NewL();
+    TApiBehavior beh( KUsbManStubAgentDll, ETryStartAsync, 0, 0, KNullDesC8 );
+    stubber -> InvokeApi( beh );
+    
+    delete stubber;
+    stubber = NULL;
+    
+    if ( beh.iOutput != KNullDesC8 )
+        {
+        TRequestStatus* stat = &aStatus;
+        User::RequestComplete( stat, beh.iAsyncCompleteCode );
+        }
+    else
+        {    
+		TIpcArgs ipcArgs(aPersonalityId);
+		SendReceive(EUsbTryStart, ipcArgs, aStatus);
+        }
+	}
+
+EXPORT_C void RUsb::TryStop(TRequestStatus& aStatus)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+    CStubber* stubber = CStubber::NewL();
+    TApiBehavior beh( KUsbManStubAgentDll, ETryStopAsync, 0, 0, KNullDesC8 );
+    stubber -> InvokeApi( beh );
+    
+    delete stubber;
+    stubber = NULL;
+    
+    if ( beh.iOutput != KNullDesC8 )
+        {
+        TRequestStatus* stat = &aStatus;
+        User::RequestComplete( stat, beh.iAsyncCompleteCode );
+        }
+    else
+    	SendReceive(EUsbTryStop, aStatus);
+	}
+	
+EXPORT_C TInt RUsb::CancelInterest(TUsbReqType aMessageId)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+    CStubber* stubber = CStubber::NewL();
+    TApiBehavior beh( KUsbManStubAgentDll, ECancelInterest, 0, 0, KNullDesC8 );
+    stubber -> InvokeApi( beh );
+    
+    delete stubber;
+    stubber = NULL;
+	
+    if ( beh.iOutput != KNullDesC8 )
+        {
+        
+        }
+    else
+        {
+		TInt messageId;
+		switch (aMessageId)
+			{
+		case EStart:
+			messageId = EUsbStart;
+			break;
+		case EStop:
+			messageId = EUsbStop;
+			break;
+		case ETryStart:
+			messageId = EUsbTryStart;
+			break;
+		case ETryStop:
+			messageId = EUsbTryStop;
+			break;
+		default:
+			return KErrNotSupported;
+			}
+			
+		TIpcArgs ipcArgs(messageId);
+		return SendReceive(EUsbCancelInterest, ipcArgs);
+        }
+
+    return beh.iCompleteCode;
+	}
+
+EXPORT_C TInt RUsb::GetDescription(TInt aPersonalityId, HBufC*& aLocalizedPersonalityDescriptor)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	// caller is responsible for freeing up memory allocatd for aLocalizedPersonalityDescriptor
+	TRAP(ret, aLocalizedPersonalityDescriptor = HBufC::NewL(KUsbStringDescStringMaxSize));
+	if (ret == KErrNone)
+		{
+		TPtr ptr = aLocalizedPersonalityDescriptor->Des();
+		TIpcArgs ipcArgs(0, &ptr);
+		ipcArgs.Set(0, aPersonalityId);
+		ret = SendReceive(EUsbGetDescription, ipcArgs);
+		}
+	else
+		{
+		// just in case caller tries to free the memory before checking the return code
+		aLocalizedPersonalityDescriptor = NULL;
+		}
+
+	return ret;	
+	}
+	
+EXPORT_C TInt RUsb::GetCurrentPersonalityId(TInt& aPersonalityId)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+    CUsbLog::Write(KLogStub, KNullDesC8());
+    CStubber* stubber = CStubber::NewL();
+    TApiBehavior beh( KUsbManStubAgentDll, EGetCurrentPersonalityId, 0, 0, KNullDesC8 );
+    stubber -> InvokeApi( beh );
+    
+    delete stubber;
+    stubber = NULL;    
+    
+    if ( beh.iOutput != KNullDesC8 )
+        {
+        if ( !beh.iOutput.Compare( _L8( "KUsbPersonalityIdPCSuite" ) ) )
+            aPersonalityId = KUsbPersonalityIdPCSuite;
+        else if ( !beh.iOutput.Compare( _L8( "KUsbPersonalityIdMS" ) ) )
+            aPersonalityId = KUsbPersonalityIdMS;
+        else if ( !beh.iOutput.Compare( _L8( "KUsbPersonalityIdPTP" ) ) )
+            aPersonalityId = KUsbPersonalityIdPTP;
+        else if ( !beh.iOutput.Compare( _L8( "KUsbPersonalityIdMTP" ) ) )
+            aPersonalityId = KUsbPersonalityIdMTP;
+        else if ( !beh.iOutput.Compare( _L8( "KUsbPersonalityIdPCSuite" ) ) )
+            aPersonalityId = KUsbPersonalityIdPCSuite;
+        else
+        	{}
+        }
+    else
+        {
+		TPckg<TInt> pkg0(aPersonalityId);
+		TInt ret = SendReceive(EUsbGetCurrentPersonalityId, TIpcArgs(&pkg0));
+		aPersonalityId = static_cast<TInt>(pkg0());
+		return ret;	
+        }
+
+    return beh.iCompleteCode;
+	}
+
+EXPORT_C TInt RUsb::GetSupportedClasses(TInt aPersonalityId, RArray<TUid>& aClassUids)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	HBufC8* buf = NULL;
+	// +1 for the actual count of personality ids
+	TRAP(ret, buf = HBufC8::NewL((KUsbMaxSupportedClasses + 1)*sizeof (TInt32)));
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+
+	TPtr8 ptr8 = buf->Des();
+	ret = SendReceive(EUsbGetSupportedClasses, TIpcArgs(aPersonalityId, &ptr8));
+		
+	if (ret == KErrNone)
+		{
+		const TInt32* recvedIds = reinterpret_cast<const TInt32*>(buf->Ptr());
+		if (!recvedIds)
+			{
+			delete buf;
+			return KErrCorrupt;
+			}
+			
+		TInt arraySize = *recvedIds++;
+		// Copy received supported class ids to aClassUids
+		for (TInt i = 0; i < arraySize; i++)
+			{
+			if (recvedIds)
+				{
+				ret = aClassUids.Append(TUid::Uid(*recvedIds++));
+				if(ret!=KErrNone)
+					{
+					//Remove all the ids appended so far (assume the last append failed, because
+					//the only reason to fail is if the array couldn't grow to accommodate another
+					//element).
+					//It would be easier to just reset the array, but we never specified that
+					//aClassUids should be an empty array, nor did we specify that this method
+					//might empty the array. To maintain exisiting behaviour we should return
+					//aClassUids to the state it was in when this method was called.
+					TInt last = aClassUids.Count() - 1;
+					while(i>0)
+						{
+						aClassUids.Remove(last);
+						i--;
+						last--;
+						}	
+					break;
+					}
+				}
+			else
+				{
+				ret = KErrCorrupt;
+				break;
+				}
+			}
+		}
+		
+	delete buf;
+	return ret;
+	}
+	
+EXPORT_C TInt RUsb::ClassSupported(TInt aPersonalityId, TUid aClassUid, TBool& aSupported)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TPckg<TInt32>  	pkg2(aSupported);
+	TIpcArgs ipcArgs(aPersonalityId, aClassUid.iUid, &pkg2);
+	
+	TInt ret = SendReceive(EUsbClassSupported, ipcArgs);
+	
+	if (ret == KErrNone)
+		{
+		aSupported = static_cast<TBool>(pkg2());		
+		}
+		
+	return ret;
+	}
+	
+EXPORT_C TInt RUsb::GetPersonalityIds(RArray<TInt>& aPersonalityIds)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	TInt ret = KErrNone;
+	HBufC8* buf = NULL;
+	// +1 for the actual count of personality ids
+	TRAP(ret, buf = HBufC8::NewL((KUsbMaxSupportedPersonalities + 1)*sizeof (TInt)));
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+
+	TPtr8 ptr8 = buf->Des();
+	ret = SendReceive(EUsbGetPersonalityIds, TIpcArgs(&ptr8));
+		
+	if (ret == KErrNone)
+		{
+		const TInt* recvedIds = reinterpret_cast<const TInt*>(buf->Ptr());
+		if (!recvedIds)
+			{
+			delete buf;
+			return KErrCorrupt;
+			}
+			
+		TInt arraySize = *recvedIds++;
+		// Copy received personality ids to aPersonalityIds
+		for (TInt i = 0; i < arraySize; i++)
+			{
+			if (recvedIds)
+				{		
+				ret = aPersonalityIds.Append(*recvedIds++);
+				
+				if(ret!=KErrNone)
+					{
+					//Remove all the ids appended so far (assume the last append failed, because
+					//the only reason to fail is if the array couldn't grow to accommodate another
+					//element).
+					//It would be easier to just reset the array, but we never specified that
+					//aPersonalityIds should be an empty array, nor did we specify that this method
+					//might empty the array. To maintain exisiting behaviour we should return
+					//aPersonalityIds to the state it was in when this method was called.
+					TInt last = aPersonalityIds.Count() - 1;
+					while(i>0)
+						{
+						aPersonalityIds.Remove(last);
+						i--;
+						last--;
+						}	
+					break;
+					}
+				}
+			else
+				{
+				ret = KErrCorrupt;
+				break;
+				}
+			}
+		}
+		
+	delete buf;
+	return ret;
+	}
+	
+EXPORT_C TInt RUsb::__DbgMarkHeap()
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgMarkHeap);
+#else
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C TInt RUsb::__DbgCheckHeap(TInt aCount)
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgCheckHeap, TIpcArgs(aCount));
+#else
+	(void)aCount; // not used for Release builds
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C TInt RUsb::__DbgMarkEnd(TInt aCount)
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgMarkEnd, TIpcArgs(aCount));
+#else
+	(void)aCount; // not used for Release builds
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C TInt RUsb::__DbgFailNext(TInt aCount)
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgFailNext, TIpcArgs(aCount));
+#else
+	(void)aCount; // not used for Release builds
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C TInt RUsb::__DbgAlloc()
+	{
+#ifdef _DEBUG
+    return SendReceive(EUsbDbgAlloc);
+#else
+    return KErrNone;
+#endif
+	}
+
+EXPORT_C void panic()
+	{
+	_USB_PANIC(KUsbCliPncCat, EUsbPanicRemovedExport);
+	}
+
+EXPORT_C TInt RUsb::SetCtlSessionMode(TBool aValue)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+//    CUsbLog::Write(KLogStub, KNullDesC8());
+//    CStubber* stubber = CStubber::NewL();
+//    TApiBehavior beh( KUsbManStubAgentDll, ESetCtlSessionMode, 0, 0, KNullDesC8 );
+//    stubber -> InvokeApi( beh );
+//    
+//    delete stubber;
+//    stubber = NULL;    
+//    
+//    if ( beh.iOutput != KNullDesC8 )
+//        {
+//        return KErrNone;
+//        }
+//    else
+//        {
+        TPckg<TBool> pkg(aValue);
+        return SendReceive(EUsbSetCtlSessionMode, TIpcArgs(&pkg)); 
+//        }
+    
+	}
+
+EXPORT_C TInt RUsb::BusRequest()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbBusRequest);
+	}
+
+EXPORT_C TInt RUsb::BusRespondSrp()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbBusRespondSrp);
+	}
+
+EXPORT_C TInt RUsb::BusClearError()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbBusClearError);
+	}
+
+
+EXPORT_C TInt RUsb::BusDrop()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbBusDrop);
+	}
+
+EXPORT_C void RUsb::MessageNotification(TRequestStatus& aStatus, TInt& aMessage)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	iMessagePkg.Set((TUint8*)&aMessage, sizeof(TInt), sizeof(TInt));
+
+	SendReceive(EUsbRegisterMessageObserver, TIpcArgs(&iMessagePkg), aStatus);
+	}
+
+EXPORT_C void RUsb::MessageNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbCancelMessageObserver);
+	}
+
+EXPORT_C void RUsb::HostEventNotification(TRequestStatus& aStatus,
+										  TDeviceEventInformation& aDeviceInformation)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	iHostPkg.Set((TUint8*)&aDeviceInformation, sizeof(TDeviceEventInformation), sizeof(TDeviceEventInformation));
+
+	SendReceive(EUsbRegisterHostObserver, TIpcArgs(&iHostPkg), aStatus);
+	}
+	
+EXPORT_C void RUsb::HostEventNotificationCancel()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbCancelHostObserver);
+	}
+
+EXPORT_C TInt RUsb::EnableFunctionDriverLoading()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbEnableFunctionDriverLoading);
+	}
+
+EXPORT_C void RUsb::DisableFunctionDriverLoading()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	SendReceive(EUsbDisableFunctionDriverLoading);
+	}
+
+EXPORT_C TInt RUsb::GetSupportedLanguages(TUint aDeviceId, RArray<TUint>& aLangIds)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	aLangIds.Reset();
+
+	TInt ret = KErrNone;
+	HBufC8* buf = NULL;
+	// +1 for the actual count of language ids
+	TRAP(ret, buf = HBufC8::NewL((KUsbMaxSupportedLanguageIds + 1)*sizeof (TUint)));
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+
+	TPtr8 ptr8 = buf->Des();
+	ret = SendReceive(EUsbGetSupportedLanguages, TIpcArgs(aDeviceId, &ptr8));
+		
+	if (ret == KErrNone)
+		{
+		const TUint* recvedIds = reinterpret_cast<const TUint*>(buf->Ptr());
+		if (!recvedIds)
+			{
+			delete buf;
+			return KErrCorrupt;
+			}
+			
+		TInt arraySize = *recvedIds++;
+		// Copy received language ids to aLangIds
+		for (TInt i = 0; i < arraySize; i++)
+			{
+			ret = aLangIds.Append(*recvedIds++); // increments by sizeof(TUint)
+			if ( ret )
+				{
+				aLangIds.Reset();
+				break;
+				}
+			}
+		}
+		
+	delete buf;	
+	return ret;
+	}
+	
+EXPORT_C TInt RUsb::GetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbGetManufacturerStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString));
+	}
+
+EXPORT_C TInt RUsb::GetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbGetProductStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString));
+	}
+
+EXPORT_C TInt RUsb::GetOtgDescriptor(TUint aDeviceId, TOtgDescriptor& aDescriptor)
+	{
+	LOG_LINE
+	LOG_FUNC
+		
+	TPckg<TOtgDescriptor> otgDescPkg(aDescriptor);
+	
+	TIpcArgs args;
+	args.Set(0, aDeviceId);
+	args.Set(1, &otgDescPkg);
+
+	return SendReceive(EUsbGetOtgDescriptor, args);
+	}
+
+
+EXPORT_C TInt RUsb::RequestSession()
+	{
+	LOG_LINE
+	LOG_FUNC
+
+	return SendReceive(EUsbRequestSession);
+	}
+
+EXPORT_C TInt RUsb::GetDetailedDescription(TInt aPersonalityId, HBufC*& aLocalizedPersonalityDescriptor)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+ 	TInt ret = KErrNone;
+	// caller is responsible for freeing up memory allocated for aLocalizedPersonalityDescriptor
+	TRAP(ret, aLocalizedPersonalityDescriptor = HBufC::NewL(KUsbStringDescStringMaxSize));
+	if (ret == KErrNone)
+		{
+		TPtr ptr = aLocalizedPersonalityDescriptor->Des();
+		TIpcArgs ipcArgs(0, &ptr);
+		ipcArgs.Set(0, aPersonalityId);
+		ret = SendReceive(EUsbGetDetailedDescription, ipcArgs);
+		}
+	else
+		{
+		// just in case caller tries to free the memory before checking the return code
+		aLocalizedPersonalityDescriptor = NULL;
+		}
+
+	return ret; 
+	}
+
+EXPORT_C TInt RUsb::GetPersonalityProperty(TInt aPersonalityId, TUint32& aProperty)
+	{
+	LOG_LINE
+	LOG_FUNC
+
+    CUsbLog::Write(KLogStub, KNullDesC8());
+	TPckg<TUint32> pkg(aProperty);
+	TInt ret = SendReceive(EUsbGetPersonalityProperty, TIpcArgs(aPersonalityId, &pkg));
+	if (ret == KErrNone)
+		{
+		aProperty = static_cast<TUint32>(pkg());
+		}
+
+//    CUsbLog::Write(KLogStub, KNullDesC8());
+//    CStubber* stubber = CStubber::NewL();
+//    TApiBehavior beh( KUsbManStubAgentDll, EGetPersonalityProperty, 0, 0, KNullDesC8 );
+//    stubber -> InvokeApi( beh );
+//    
+//    delete stubber;
+//    stubber = NULL;
+//
+//    if ( beh.iOutput != KNullDesC8 )
+//        {
+//        if ( !beh.iOutput.Compare( _L8( "stub" ) ) )
+//            {
+//            CUsbLog::Write(KLogStub, KNullDesC8());
+//            TRequestStatus stat;
+//            TInt message;
+//            MessageNotification(stat,message);
+//            DeviceStateNotificationCancel();
+//            TUsbDeviceState aState;
+//            GetDeviceState(aState);
+//            DeviceStateNotification( KUsbAllStates, aState, stat );
+//            TryStop(stat);
+//            User::WaitForRequest(stat);
+//            TInt personalityId;
+//            GetCurrentPersonalityId(personalityId);
+//            TryStart(personalityId,stat);
+//            User::WaitForRequest(stat);
+//            }
+//        else
+//            {}
+//        }
+    
+	return ret;	
+	}