diff -r 000000000000 -r c9bc50fca66e usbmgmt/usbmgr/host/fdf/production/client/src/session.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbmgmt/usbmgr/host/fdf/production/client/src/session.cpp Tue Feb 02 02:02:59 2010 +0200 @@ -0,0 +1,366 @@ +/* +* Copyright (c) 2007-2009 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: +* +*/ + +/** + @file + @internalComponent +*/ + +#include +#include +#include "usbhoststack.h" +#include "fdfapi.h" + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, "usbhstcli"); +#endif + +/** +Starts the server process. +*/ +static TInt StartServer() + { + LOG_STATIC_FUNC_ENTRY + + const TUidType serverUid(KNullUid, KNullUid, KUsbFdfUid); + + // + // 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(KUsbFdfImg, KNullDesC, serverUid); + LOGTEXT2(_L8("\terr = %d"), err); + + if ( err != KErrNone ) + { + return err; + } + + TRequestStatus stat; + server.Rendezvous(stat); + + if ( stat != KRequestPending ) + { + LOGTEXT(_L8("\taborting startup")); + server.Kill(0); // abort startup + } + else + { + LOGTEXT(_L8("\tresuming")); + 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 + LOGTEXT2(_L8("\tstat.Int = %d"), stat.Int()); + err = (server.ExitType() == EExitPanic) ? KErrServerTerminated : stat.Int(); + + server.Close(); + + LOGTEXT2(_L8("\terr = %d"), err); + return err; + } + +EXPORT_C RUsbHostStack::RUsbHostStack() + // these are all arbitrary initialisations + : iDeviceEventPckg(TDeviceEventInformation()), + iDevmonEventPckg(0) + { + LOGTEXT(_L8("*** Search on '***USB HOST STACK' to find device events.")); + + LOG_LINE + LOG_FUNC + } + +EXPORT_C TVersion RUsbHostStack::Version() const + { + LOG_LINE + LOG_FUNC + + return(TVersion( KUsbFdfSrvMajorVersionNumber, + KUsbFdfSrvMinorVersionNumber, + KUsbFdfSrvBuildNumber + ) + ); + } + +EXPORT_C TInt RUsbHostStack::Connect() + { + LOG_LINE + LOG_FUNC; + + TInt err = DoConnect(); + + LOGTEXT2(_L8("\terr = %d"), err); + return err; + } + +/** +Connects the session, starting the server if necessary +@return Error. +*/ +TInt RUsbHostStack::DoConnect() + { + LOG_FUNC + + TInt retry = 2; + + FOREVER + { + // Use message slots from the global pool. + TInt err = CreateSession(KUsbFdfServerName, Version(), -1); + LOGTEXT2(_L8("\terr = %d"), err); + + if ((err != KErrNotFound) && (err != KErrServerTerminated)) + { + LOGTEXT(_L8("\treturning after CreateSession")); + return err; + } + + if (--retry == 0) + { + LOGTEXT(_L8("\treturning after running out of retries")); + return err; + } + + err = StartServer(); + LOGTEXT2(_L8("\terr = %d"), err); + + if ((err != KErrNone) && (err != KErrAlreadyExists)) + { + LOGTEXT(_L8("\treturning after StartServer")); + return err; + } + } + } + +EXPORT_C TInt RUsbHostStack::EnableDriverLoading() + { + LOG_LINE + LOG_FUNC + + TInt ret = SendReceive(EUsbFdfSrvEnableDriverLoading); + LOGTEXT2(_L8("\tret = %d"), ret); + return ret; + } + +EXPORT_C void RUsbHostStack::DisableDriverLoading() + { + LOG_LINE + LOG_FUNC + + TInt ret = SendReceive(EUsbFdfSrvDisableDriverLoading); + LOGTEXT2(_L8("\tret = %d"), ret); + (void)ret; + } + +EXPORT_C void RUsbHostStack::NotifyDeviceEvent(TRequestStatus& aStat, TDeviceEventInformation& aDeviceEventInformation) + { + LOG_LINE + LOG_FUNC + + TIpcArgs args; + iDeviceEventPckg.Set((TUint8*)&aDeviceEventInformation, sizeof(TDeviceEventInformation), sizeof(TDeviceEventInformation)); + args.Set(0, &iDeviceEventPckg); + + SendReceive(EUsbFdfSrvNotifyDeviceEvent, args, aStat); + } + +EXPORT_C void RUsbHostStack::NotifyDeviceEventCancel() + { + LOG_LINE + LOG_FUNC + + TInt ret = SendReceive(EUsbFdfSrvNotifyDeviceEventCancel); + LOGTEXT2(_L8("\tret = %d"), ret); + (void)ret; + } + +EXPORT_C void RUsbHostStack::NotifyDevmonEvent(TRequestStatus& aStat, TInt& aEvent) + { + LOG_LINE + LOG_FUNC + + TIpcArgs args; + iDevmonEventPckg.Set((TUint8*)&aEvent, sizeof(TInt), sizeof(TInt)); + args.Set(0, &iDevmonEventPckg); + + SendReceive(EUsbFdfSrvNotifyDevmonEvent, args, aStat); + } + +EXPORT_C void RUsbHostStack::NotifyDevmonEventCancel() + { + LOG_LINE + LOG_FUNC + + TInt ret = SendReceive(EUsbFdfSrvNotifyDevmonEventCancel); + LOGTEXT2(_L8("\tret = %d"), ret); + (void)ret; + } + +EXPORT_C TInt RUsbHostStack::GetSupportedLanguages(TUint aDeviceId, RArray& aLangIds) + { + LOG_LINE + LOG_FUNC + + aLangIds.Reset(); + + TUint singleLangIdOrNumLangs = 0; + TPckg singleLangIdOrNumLangsBuf(singleLangIdOrNumLangs); + TInt ret = SendReceive(EUsbFdfSrvGetSingleSupportedLanguageOrNumberOfSupportedLanguages, TIpcArgs(aDeviceId, &singleLangIdOrNumLangsBuf)); + LOGTEXT2(_L8("\tsingleLangIdOrNumLangs = %d"), singleLangIdOrNumLangs); + switch ( ret ) + { + case KErrNotFound: + LOGTEXT2(_L8("\tThere is no language available or the wrong device id %d was supplied"),aDeviceId); + ret = KErrNotFound; + break; + + case KErrNone: + // The buffer is now either empty or contains the single supported language ID + ret = CopyLangIdsToArray(aLangIds, singleLangIdOrNumLangsBuf); + break; + + case KErrTooBig: + { + // The buffer now contains the number of supported languages (not 0 or 1). + // Lang IDs are TUints. + RBuf8 buf; + ret = buf.Create(singleLangIdOrNumLangs * sizeof(TUint)); + if ( ret == KErrNone ) + { + ret = SendReceive(EUsbFdfSrvGetSupportedLanguages, TIpcArgs(aDeviceId, &buf)); + if ( ret == KErrNone ) + { + ret = CopyLangIdsToArray(aLangIds, buf); + } + buf.Close(); + } + } + break; + + default: + // Regular failure. + break; + } + + LOGTEXT2(_L8("\tret = %d"), ret); + return ret; + } + +TInt RUsbHostStack::CopyLangIdsToArray(RArray& aLangIds, const TDesC8& aBuffer) + { + LOG_FUNC + + ASSERT(!(aBuffer.Size() % 4)); + const TUint numLangs = aBuffer.Size() / 4; + LOGTEXT2(_L8("\tnumLangs = %d"), numLangs); + + TInt ret = KErrNone; + const TUint* ptr = reinterpret_cast(aBuffer.Ptr()); + for ( TUint ii = 0 ; ii < numLangs ; ++ii ) + { + ret = aLangIds.Append(*ptr++); // increments by sizeof(TUint) + if ( ret ) + { + aLangIds.Reset(); + break; + } + } + + LOGTEXT2(_L8("\tret = %d"), ret); + return ret; + } + +EXPORT_C TInt RUsbHostStack::GetManufacturerStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString) + { + LOG_LINE + LOG_FUNC + + TInt ret = SendReceive(EUsbFdfSrvGetManufacturerStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString)); +#ifdef __FLOG_ACTIVE + if ( !ret ) + { + LOGTEXT2(_L("\taString = \"%S\""), &aString); + } +#endif + LOGTEXT2(_L8("\tret = %d"), ret); + return ret; + } + +EXPORT_C TInt RUsbHostStack::GetProductStringDescriptor(TUint aDeviceId, TUint aLangId, TName& aString) + { + LOG_LINE + LOG_FUNC + + TInt ret = SendReceive(EUsbFdfSrvGetProductStringDescriptor, TIpcArgs(aDeviceId, aLangId, &aString)); +#ifdef __FLOG_ACTIVE + if ( !ret ) + { + LOGTEXT2(_L("\taString = \"%S\""), &aString); + } +#endif + LOGTEXT2(_L8("\tret = %d"), ret); + return ret; + } + +EXPORT_C TInt RUsbHostStack::GetOtgDescriptor(TUint aDeviceId, TOtgDescriptor& aDescriptor) + { + LOG_LINE + LOG_FUNC + + TPckg otgDescriptorPckg(aDescriptor); + + TIpcArgs args; + args.Set(0, aDeviceId); + args.Set(1, &otgDescriptorPckg); + + TInt ret = SendReceive(EUsbFdfSrvGetOtgDescriptor, args); +#ifdef __FLOG_ACTIVE + if ( !ret ) + { + LOGTEXT2(_L("\taDescriptor.iDeviceId = %d"), aDescriptor.iDeviceId); + LOGTEXT2(_L("\taDescriptor.iAttributes = %d"), aDescriptor.iAttributes); + } +#endif + LOGTEXT2(_L8("\tret = %d"), ret); + return ret; + } + +EXPORT_C TInt RUsbHostStack::__DbgFailNext(TInt aCount) + { +#ifdef _DEBUG + return SendReceive(EUsbFdfSrvDbgFailNext, TIpcArgs(aCount)); +#else + (void)aCount; + return KErrNone; +#endif + } + +EXPORT_C TInt RUsbHostStack::__DbgAlloc() + { +#ifdef _DEBUG + return SendReceive(EUsbFdfSrvDbgAlloc); +#else + return KErrNone; +#endif + }