diff -r 000000000000 -r 094583676ce7 IMPSengine/client/src/impsclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IMPSengine/client/src/impsclient.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,555 @@ +/* +* Copyright (c) 2002-2005 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: +* class for imps server. +* +*/ + + +// INCLUDE FILES +#include +#include +#include "impsservercommon.h" +#include "impshandler.h" +#include "impsclient.h" +#include "impserrors.h" +#include "impsutils.h" +#include "impsclientsrv.h" +#include "impsconst.h" + +// CONSTANTS +const TInt KWaitForServerRetries = 3; + +// MACROS +#ifndef _DEBUG +#define _NO_IMPS_LOGGING_ +#endif + +// ================= MEMBER FUNCTIONS ======================= + +// ---------------------------------------------------------------------------- +// RImpsEng::RImpsEng +// ---------------------------------------------------------------------------- +EXPORT_C RImpsEng::RImpsEng() +: RSessionBase(), + iSessionOk (EFalse ) + { + } + +// ---------------------------------------------------------------------------- +// RImpsEng::Connect +// ---------------------------------------------------------------------------- +EXPORT_C TInt RImpsEng::Connect( TInt aRate /*, TBool aReqular*/ ) + { + // This has similar functionality than old version RImpsClient + TInt err = KErrNone; + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client: Connect rate=0x%x"), aRate); +#endif + + for ( TInt tries = 0; tries < KWaitForServerRetries ; tries++ ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client: Calling CreateSession ")); +#endif + err = CreateSession( + KImpsServerName, Version(), KImpsDefaultMessageSlots ); + + if ( err == KErrNone ) + { + iSessionOk = ETrue; + break; // connected to existing server - ok + } + + // problems other than server not here - propagate error + if ( err != KErrNotFound && err != KErrServerTerminated ) + { + break; + } + + err = StartServer( aRate, 0 ); // start a new server + } +#ifndef _NO_IMPS_LOGGING_ + const TSecureId currentSID( RProcess().SecureId() ); + CImpsClientLogger::Log(_L("Client Connect returns=0x%x currentSID=0x%x"), err, (TInt)currentSID); + + TBuf<256> name; + RProcess currentProcess; + name.Append( RProcess().FullName() ); + CImpsClientLogger::Log( _L("Client CONNECT Process name: %S"), &name ); +#endif + return err; + } + +// ---------------------------------------------------------------------------- +// RImpsEng::Close +// ---------------------------------------------------------------------------- +EXPORT_C void RImpsEng::Close() + { +#ifndef _NO_IMPS_LOGGING_ + const TSecureId currentSID( RProcess().SecureId() ); + CImpsClientLogger::Log(_L("Client Close currentSID=0x%x"), (TInt)currentSID); + + TBuf<256> name; + RProcess currentProcess; + name.Append( RProcess().FullName() ); + CImpsClientLogger::Log( _L("Client CLOSE Process name: %S"), &name ); +#endif + + iSessionOk = EFalse; + RSessionBase::Close(); // deletes session object + } + +// ---------------------------------------------------------------------------- +// RImpsEng::StartServer +// ---------------------------------------------------------------------------- +TInt RImpsEng::StartServer( TInt aRate, TInt /*aRound*/ ) + { + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client: StartServer rate=0x%x"), aRate); +#endif + + TInt ret( KErrNone ); + TRequestStatus status = KRequestPending; + TImpsSignal signal( aRate ); + + if ( !IsServerStarted() ) + { + // launch server process + + + RProcess server; +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client: PROCESS TO START")); +#endif + + ret = server.Create( + KImpsServerExe, + signal.Get() ); + + if ( ret ) + { + // we are lost +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client: process START FAILED")); +#endif + return ret; + } + + + + server.Rendezvous( status ); + if ( status != KRequestPending ) + { + server.Kill(0); // abort startup + } + else + { + server.Resume(); // logon OK - start the server + } +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client: WaitForAnyRequest")); +#endif + // wait for start or death + User::WaitForRequest( status ); + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("WaitForRequest return=%d"), status.Int() ); +#endif + // 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 + ret = (server.ExitType() == EExitPanic) ? KErrGeneral : status.Int(); + server.Close(); + + } // if !IsStarted + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("StartServer return=0x%x"), ret); +#endif + return ret; + } + +// ---------------------------------------------------------------------------- +// RImpsEng::IsServerStarted +// ---------------------------------------------------------------------------- +TBool RImpsEng::IsServerStarted() + { + TFindServer findServer( KImpsServerName ); + TFullName name; + return ( findServer.Next( name ) == KErrNone ); + } + +// ---------------------------------------------------------------------------- +// RImpsEng::Version() +// Returns the client side version number. +// ---------------------------------------------------------------------------- +TVersion RImpsEng::Version() const + { + return TVersion( KImpsServMajorVersionNumber, KImpsServMinorVersionNumber, + KImpsServBuildVersionNumber ); + } + +// ---------------------------------------------------------------------------- +// RImpsEng::CspIdentifier() +// ---------------------------------------------------------------------------- +TImpsCspIdentifier* RImpsEng::CspIdentifier() + { + return &iCspId; + } + +// ---------------------------------------------------------------------------- +// RImpsEng::SetCspIdentifier() +// ---------------------------------------------------------------------------- +void RImpsEng::SetCspIdentifier( TImpsCspIdentifier aCspId ) + { + TInt err ( KErrNone ); + TRAP ( err, iCspId.SetSapL( aCspId.Sap() ) ); + TRAP ( err, iCspId.SetUserIdL( aCspId.UserId() ) ); + } + +// --------------------------------------------------------- +// RImpsClient2::RImpsClient2 +// --------------------------------------------------------- +// +EXPORT_C RImpsClient2::RImpsClient2() : + iHandler( NULL ), + iActiveCommand( NULL ), + iRunning( EFalse ), + iOpId( 0 ), + iLimitUpperValue( 0 ), + iLimitLowerValue( 0 ), + iEngine( NULL ) + {} + +// --------------------------------------------------------- +// RImpsClient2::DoAssign +// --------------------------------------------------------- +// +TInt RImpsClient2::DoAssign( + const TDesC& aClientId ) + { + TInt err = KErrNone; + TPtrC myId; + myId.Set( aClientId ); + err = SendReceive( EImpsServAssign, TIpcArgs( &myId ) ); + return err; + } + +// --------------------------------------------------------- +// RImpsClient2::DoUnregister +// SubSession Close +// --------------------------------------------------------- +// +void RImpsClient2::DoUnregister() + { + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client: DoUnregister cli=%d"), (TInt)this); +#endif + if ( iRunning ) + { + // Send cancel message to the server thread + TInt srvRet = SendReceive( EImpsServCloseSub, TIpcArgs() ); + + // Server completes pending next event request message for this subsession + __ASSERT_DEBUG( iHandler, + User::Panic( KImpsPanicCategory, + EImpsNotifyHandlerMissing ) ); + if ( !srvRet && iHandler->IsActive() ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client2: WaitForRequest START %d"), srvRet); +#endif + User::WaitForRequest( iHandler->iStatus ); + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client2: WaitForRequest END")); +#endif + } + + iRunning = EFalse; + RSubSessionBase::CloseSubSession( EImpsServDeleteSub ); + } + + // Cancel active objects before deleting them. + // Server is informed about cancel above so that it will not send data. + if ( iHandler ) + { + iHandler->Cancel(); + } + if ( iActiveCommand ) + { + iActiveCommand->Cancel(); + } + + // Now this is safe, i.e. no requests outstanding for the handler + delete iHandler; + iHandler = NULL; + + delete iActiveCommand; + iActiveCommand = NULL; + } + + +// ---------------------------------------------------------------------------- +// RImpsClient2::RegisterStatusObserverL +// ---------------------------------------------------------------------------- +EXPORT_C void RImpsClient2::RegisterStatusObserverL( + MImpsStatusHandler2* aObserver ) + { + if ( !iHandler ) + { + // Register must have been done in derived client API! + User::Leave( KImpsErrorNotRegistered ); + } + + if ( iHandler->StatusHandler() == NULL ) + { + iHandler->SetStatusHandlerL( aObserver ); + } + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::UnregisterStatusObserverL +// ---------------------------------------------------------------------------- +EXPORT_C void RImpsClient2::UnregisterStatusObserverL( ) + { + // Check if null if somebody calls this after Unregister anyway ... + if ( iHandler ) + { + if ( iHandler->StatusHandler() != NULL ) + { + iHandler->SetStatusHandlerL( NULL ); + } + } + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::RegisterErrorObserverL +// ---------------------------------------------------------------------------- +EXPORT_C void RImpsClient2::RegisterErrorObserverL( + MImpsErrorHandler2& aObserver ) + { + + if ( !iHandler ) + { + // Register must have been done in derived client API! + User::Leave( KImpsErrorNotRegistered ); + } + + if ( iHandler->ErrorHandler() == NULL ) + { + iHandler->SetErrorHandlerL( &aObserver ); + } + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::UnregisterErrorObserverL +// ---------------------------------------------------------------------------- +EXPORT_C void RImpsClient2::UnregisterErrorObserverL( ) + { + // Check if null if somebody calls this after Unregister anyway ... + if ( iHandler ) + { + if ( iHandler->ErrorHandler() != NULL ) + { + iHandler->SetErrorHandlerL( NULL ); + } + } + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::MaxTransactionContentLengthL +// ---------------------------------------------------------------------------- +EXPORT_C TInt RImpsClient2::MaxTransactionContentLengthL( ) + { + TInt ret = SendReceive( EImpsServBuffSizeReq, TIpcArgs() ); + if ( ret < 0 ) + { + User::Leave( ret ); + } + return ret; + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::ErrorHandlerL +// ---------------------------------------------------------------------------- +MImpsErrorHandler2* RImpsClient2::ErrorHandler() + { + if ( iHandler ) + { + return ( iHandler->ErrorHandler() ); + } + return (MImpsErrorHandler2*)NULL; + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::GetServicesL +// ---------------------------------------------------------------------------- +EXPORT_C void RImpsClient2::GetServicesL( TImpsServices& aServices ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client2: GetServicesL starts")); +#endif + + // result buffer + TBuf myBuf( sizeof( TImpsServices ) + 4 ); + + // Server will write the data to myservices + TInt ret = SendReceive( EImpsServServices, TIpcArgs( &myBuf ) ); +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client2: GetServicesL SendReceive ret=%d"), ret ); +#endif + User::LeaveIfError( ret ); + + // convert descriptor to TImpsServices + TInt32 tempSize = 0; + const TUint8* textPtr = (const TUint8*)myBuf.Ptr(); + Mem::Copy( &tempSize, textPtr, sizeof( tempSize) ); +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client2: GetServicesL tempSize=%d"), tempSize); +#endif + textPtr = textPtr + sizeof( tempSize ); + // copy result to the call parameter + Mem::Copy( (void*)&aServices, textPtr, tempSize ); +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client2: GetServicesL ends Ok")); +#endif + + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::WVVersionL +// ---------------------------------------------------------------------------- + +EXPORT_C TPtrC RImpsClient2::WVVersionL() + { + TInt ret = SendReceive( EImpsServCspVersion, TIpcArgs() ); + if ( ret == EImpsCspVersion12 ) + { + return TPtrC( KImpsVersionStr ); + } + return TPtrC( KImpsVersionStr12 ); + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::CspIdentifierL( ) +// ---------------------------------------------------------------------------- +EXPORT_C TImpsCspIdentifier* RImpsClient2::CspIdentifierL( ) + { + TInt ret = SendReceive( EImpsServIsLogged, TIpcArgs() ); + if ( ret < 0 ) + { + User::Leave( KErrNotFound ); + } + return iEngine->CspIdentifier(); + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::CancelTransaction +// ---------------------------------------------------------------------------- +EXPORT_C void RImpsClient2::CancelTransaction( TInt aOperationId ) + { + TInt ret = SendReceive( EImpsServCancelTrans, TIpcArgs( aOperationId ) ); +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("RImpsClient2::CancelTransaction opId=%d ret=%d"), aOperationId, ret ); +#endif + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::SetExpiryTime +// ---------------------------------------------------------------------------- +EXPORT_C void RImpsClient2::SetExpiryTime( TInt aSeconds ) + { + TInt ret = SendReceive( EImpsServSetExpiry, TIpcArgs( aSeconds ) ); +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("RImpsClient2::SetExpiryTime time=%d ret=%d"), aSeconds, ret ); +#endif + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::IncreaseOpId +// ---------------------------------------------------------------------------- +void RImpsClient2::IncreaseOpId( ) + { + iOpId++; + if( iOpId >= iLimitUpperValue ) + { + iOpId = iLimitLowerValue; + } + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::SetOpIdRange +// ---------------------------------------------------------------------------- +void RImpsClient2::SetOpIdRange( ) + { + iLimitLowerValue = REINTERPRET_CAST(TInt, Dll::Tls() ); + iLimitUpperValue = iLimitLowerValue + 100; + // Check that counter does not go around + if ( iLimitUpperValue & KImpsOOMReply ) + { + // start from 50, if this ever happens + iLimitLowerValue = 50; + iLimitUpperValue = iLimitLowerValue + 100; + } + Dll::SetTls( REINTERPRET_CAST(TAny*, iLimitUpperValue ) ); + iOpId = iLimitLowerValue; + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::DoRegister2 +// ---------------------------------------------------------------------------- +TInt RImpsClient2::DoRegister2( + RImpsEng& aEngine, CImpsHandler2* aHandler, TInt aReq ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log(_L("Client2: DoRegister2 cli=%d"), (TInt)this); +#endif + + iEngine = &aEngine; + // add bit mask for extra info (handle-new and any-content) + TInt srvReg = aReq; + TInt bits = 0; + bits = ( bits & ~KImpsReqHandleNew ) + | ( iHandleNew ? KImpsReqHandleNew : 0x0000 ); + bits = ( bits & ~KImpsReqAnyContent ) + | ( iAnyContent ? KImpsReqAnyContent : 0x0000 ); + bits = bits << 16; + srvReg = srvReg | bits; + + TImpsServRequest req = (TImpsServRequest)srvReg; + TInt err = CreateSubSession( aEngine, req ); + if ( !err ) + { + iRunning = ETrue; + aHandler->EventHandled(); + } + return err; + } + +// ---------------------------------------------------------------------------- +// RImpsClient2::CspIdentifier( ) +// ---------------------------------------------------------------------------- +TImpsCspIdentifier* RImpsClient2::CspIdentifier( ) + { + return iEngine->CspIdentifier(); + } + + +// End of File +