--- /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;
+ }