diff -r e9b96e674847 -r 5b2a402e96ac tsrc/testtools/usbman_stub/usbman/client/src/RUsb.cpp --- /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 +#include +#include +#include +#include +#include "rusb.h" +#include +#include +#include "usbmandll_stub.h" +#include + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, "USBMAN"); +#endif + +#ifdef __USBMAN_NO_PROCESSES__ +#include +#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(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 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 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 pkg0(aPersonalityId); + TInt ret = SendReceive(EUsbGetCurrentPersonalityId, TIpcArgs(&pkg0)); + aPersonalityId = static_cast(pkg0()); + return ret; + } + + return beh.iCompleteCode; + } + +EXPORT_C TInt RUsb::GetSupportedClasses(TInt aPersonalityId, RArray& 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(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 pkg2(aSupported); + TIpcArgs ipcArgs(aPersonalityId, aClassUid.iUid, &pkg2); + + TInt ret = SendReceive(EUsbClassSupported, ipcArgs); + + if (ret == KErrNone) + { + aSupported = static_cast(pkg2()); + } + + return ret; + } + +EXPORT_C TInt RUsb::GetPersonalityIds(RArray& 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(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 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& 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(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 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 pkg(aProperty); + TInt ret = SendReceive(EUsbGetPersonalityProperty, TIpcArgs(aPersonalityId, &pkg)); + if (ret == KErrNone) + { + aProperty = static_cast(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; + }