diff -r 000000000000 -r 094583676ce7 IMPSengine/engsrv/src/impssendreceive.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IMPSengine/engsrv/src/impssendreceive.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,1178 @@ +/* +* 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 Data send and recevive. +* +* +*/ + + +// INCLUDE FILES +#include +#include +#include "impssendreceive.h" +#include "Impsutils.h" +#include "impserrors.h" +#include "impstimer.h" +#include "impsactiveconnmonitor.h" +#include "Impsdatautils.h" + +// MACROS +#ifndef _DEBUG +#define _NO_IMPS_LOGGING_ +#endif + +#ifdef LOCAL_IMPS +#ifndef _FAKE_RESPONSE +#define _FAKE_RESPONSE +#endif +#endif + +// ================= MEMBER FUNCTIONS ======================= + +// C++ default constructor can NOT contain any code, that +// might leave. +// +CImpsSendReceive2::CImpsSendReceive2( + RFs& aFs, + MImpsCSPSession& aServer, + CBufFlat& aOutputBuffer ) + : iServer( aServer ), + iOutputBuffer( aOutputBuffer ), + iOpenId( 0 ), + iFs( aFs ), + iSender( NULL ), + iRequList( _FOFF( CTrReq, iLink ) ), //lint !e413 + iConnMan( NULL ), + iSAP ( NULL ), + iTrState( EImpsTrInit ) + { + + } + +// default constructor can leave. +void CImpsSendReceive2::ConstructL( TDesC8& aMimeType ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: rel200541.3+" ) ); +#endif + iMimeType = aMimeType; + iConnMan = CImpsConnManager::NewL( *this, CActive::EPriorityUserInput + 1 ); + MMsgConnManager& man = iConnMan->ManagerHandleL(); + iSender = NewImpsSenderL( *this, man, aMimeType ); + } + +// Two-phased constructor. +CImpsSendReceive2* CImpsSendReceive2::NewL( + RFs& aFs, + MImpsCSPSession& aServer, + CBufFlat& aOutputBuffer, + TDesC8& aMimeType ) + { + CImpsSendReceive2* self = new ( ELeave ) CImpsSendReceive2( + aFs, + aServer, + aOutputBuffer ); + + CleanupStack::PushL( self ); + self->ConstructL( aMimeType ); + CleanupStack::Pop(); + + return self; + } + + +// Destructor +CImpsSendReceive2::~CImpsSendReceive2() + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: destructor begins" ) ); +#endif + delete iConnMan; + delete iSAP; + + if ( iSender ) + { + // In error case this may be null + iSender->Destroy(); + } + DeleteAllIds(); + // delete iObserver; + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: destructor ends" ) ); +#endif + + } + +// --------------------------------------------------------- +// CImpsSendReceive2::CloseTr +// --------------------------------------------------------- +// +void CImpsSendReceive2::CloseTr( ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: CloseTr" ) ); +#endif + + DeleteAllIds(); + + if ( iTrState == EImpsTrClosing ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: CloseTr IGNORED ***" ) ); +#endif + return; + } + // cancel open AP + if ( iTrState == EImpsTrAPOpening ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: CANCEL open ***" ) ); +#endif + NewTrState( EImpsTrClosing ); + iConnMan->CloseAP( ETrue ); + return; + } + + if ( iSender ) + { + // In error cases iSender may be null +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: CloseTr CLOSE DATA CHANNEL" ) ); +#endif + iSender->Close( ); + iSender->Destroy(); + iSender = NULL; + NewTrState( EImpsTrAPOpen ); + } + else if ( iTrState == EImpsTrCloseDelayed ) + { + NewTrState( EImpsTrAPOpen ); + } + + if ( iTrState == EImpsTrAPOpen ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: CloseTr START TO CLOSE AP" ) ); +#endif + // This causes APStatusEvent call finally. + NewTrState( EImpsTrClosing ); + iConnMan->CloseAP( ETrue ); + } + + // This is needed in CImpsServer so that transient server can be closed + else if ( iTrState == EImpsTrInit ) + { + iServer.TransportStatus( EInternal_NO_IAP ); + } + } + +// --------------------------------------------------------- +// CImpsSendReceive2::Close2 +// Delayed close operation +// --------------------------------------------------------- +// +TInt CImpsSendReceive2::Close2( ) + { + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: Close2" ) ); +#endif + + __ASSERT_DEBUG( iConnMan, + User::Panic( KImpsPanicCategory, EImpsCorrupted ) ); + + TInt ret = KErrNone; + + if ( iTrState == EImpsTrAPOpening ) + { + CloseTr(); + return ret; + } + else if ( iTrState == EImpsTrClosing || iTrState == EImpsTrCloseDelayed ) + { + // There is pending close request that will call callback sooner or later. +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: Close2 ignored ***" ) ); +#endif + return ret; + } + else if ( iTrState == EImpsTrInit ) + { + // Nothing to do, callback will not be called. + // This error must be handled in calling method. +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: iTrState was EImpsTrInit ***" ) ); +#endif + return KErrCancel; + } + + DeleteAllIds(); + + if ( iSender ) + { + // In error cases iSender may be null +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: Close2 CLOSE DATA CHANNEL" ) ); +#endif + iSender->Close( ); + iSender->Destroy(); + iSender = NULL; + NewTrState( EImpsTrAPOpen ); + } + + // yield control for scheduler before close takes place + iConnMan->StartDelayed( ); + NewTrState( EImpsTrCloseDelayed ); + + return ret; + + } + +// --------------------------------------------------------- +// CImpsSendReceive2::IsConnected +// --------------------------------------------------------- +// +TBool CImpsSendReceive2::isConnected( ) + { + TBool ret( EFalse ); + TRAPD( errx, ( ret = DoIsConnectedL() ) ); + if ( errx || !ret ) + { + return EFalse; + } + + if ( iSender && iTrState == EImpsTrDataOpen ) + { + return ETrue; + } + + return EFalse; + } + +// --------------------------------------------------------- +// CImpsSendReceive2::DoIsConnectedL +// --------------------------------------------------------- +// +TBool CImpsSendReceive2::DoIsConnectedL( ) + { + MMsgConnManager& man = iConnMan->ManagerHandleL(); + if ( !man.Status() ) + { + return EFalse; + } + return ETrue; + } + +// --------------------------------------------------------- +// CImpsSendReceive2::OpenL +// --------------------------------------------------------- +// +void CImpsSendReceive2::OpenL( + const TDesC& aTID, + TInt aXmlLog, + const TDesC& aSAP, + TInt aIAP, + TBool aDelayed ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: OpenL Begins iTrState=%d" ), iTrState ); +#endif + + delete iSAP; + iSAP = NULL; + iSAP = aSAP.AllocL(); + + iIAP = aIAP; + DeleteId( iOpenId ); + iOpenId = 0; + iOpenId = AddIdL( aTID ); // saved so that it can be deleted later + iXmlLog = aXmlLog; + + if ( iTrState == EImpsTrClosing || iTrState == EImpsTrCloseDelayed || + iTrState == EImpsTrClosingPDP ) + { + // just parameters saved +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: Leaves(KErrNotReady) ***" ) ); +#endif + DeleteId( iOpenId ); + iOpenId = 0; + User::Leave( KErrNotReady ); + } + + OpenL( aTID, aDelayed ); + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: OpenL ends" ) ); +#endif + + } + +// --------------------------------------------------------- +// CImpsSendReceive2::OpenL +// --------------------------------------------------------- +// +void CImpsSendReceive2::OpenL( const TDesC& aTID, TBool aDelayed ) + { + // Prevent opening twice data channel or connection + if ( iTrState == EImpsTrAPOpening ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: Leaves(KErrNotReady) ****" ) ); +#endif + User::Leave( KErrNotReady ); + } + + // Handle NULL TID so that Login primitive is not sent later, + // only channels are opened when recovering from flight mode. + // The old state is ignored, because of + // this should be called after NO_IAP only. + + if ( aTID.Length() == 0 ) + { + iOpenId = 0; + } + + if ( iSender && iTrState == EImpsTrDataOpen ) + { + iSender->CancelAll(); + iSender->Destroy(); + iSender = NULL; + NewTrState( EImpsTrAPOpen ); + } + if ( iTrState == EImpsTrAPOpen ) + { + NewTrState( EImpsTrClosing ); + iConnMan->CloseAP( ETrue ); + } + else if ( iTrState == EImpsTrInit ) + { + Open2L( iIAP, aDelayed ); + } + } + +// --------------------------------------------------------- +// CImpsSendReceive2::Open2L +// --------------------------------------------------------- +// +void CImpsSendReceive2::Open2L( TInt aIAP, TBool aDelayed ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: Open2L Begins aIAP=%d" ), aIAP ); +#endif + + __ASSERT_DEBUG( iConnMan, + User::Panic( KImpsPanicCategory, EImpsCorrupted ) ); + + iConnMan->OpenAPL( aIAP, aDelayed ); + NewTrState( EImpsTrAPOpening ); + } + + +// --------------------------------------------------------- +// CImpsSendReceive2::ClosePDP +// --------------------------------------------------------- +// +void CImpsSendReceive2::ClosePDP() + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: ClosePDP iTrState=%d" ), iTrState ); +#endif + + if ( iTrState == EImpsTrInit ) + { + iServer.TransportStatus( EInternal_NO_IAP ); + } + + if ( iTrState != EImpsTrDataOpen ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: ClosePDP error ***" ) ); +#endif + return; + } + + DeleteAllIds(); + + if ( iSender ) + { + // In error cases iSender may be null +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: ClosePDP CLOSE DATA CHANNEL" ) ); +#endif + iSender->Close( ); + iSender->Destroy(); + iSender = NULL; + } + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: ClosePDP START TO CLOSE AP" ) ); +#endif + // This causes APStatusEvent call finally. + NewTrState( EImpsTrClosingPDP ); + iConnMan->CloseAP( EFalse ); + } + +// --------------------------------------------------------- +//CImpsSendReceive2::OpenPDPL +// --------------------------------------------------------- +// +void CImpsSendReceive2::OpenPDPL( + const TDesC& aSAP, + TInt aIAP ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: OpenPDPL iTrState=%d" ), iTrState ); +#endif + + __ASSERT_DEBUG( iConnMan, + User::Panic( KImpsPanicCategory, EImpsCorrupted ) ); + + // Prevent opening twice data channel or connection + if ( iTrState == EImpsTrAPOpening ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: OpenPDPL Leaves(corrupted) ***" ) ); +#endif + User::Leave( EImpsCorrupted ); + } + + delete iSAP; + iSAP = NULL; + iSAP = aSAP.AllocL(); + + iIAP = aIAP; + + if ( iTrState == EImpsTrClosedPDP || iTrState == EImpsTrInit ) + { + iConnMan->OpenAPL( aIAP, EFalse ); + NewTrState( EImpsTrOpeningPDP ); + } + else + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: OpenPDPL Leaves(corrupted) ****" ) ); +#endif + User::Leave( EImpsCorrupted ); + } + } + +// --------------------------------------------------------- +// CImpsSendReceive2::Cancel +// --------------------------------------------------------- +// +void CImpsSendReceive2::Cancel() + { + if ( iSender ) + { + iSender->CancelAll(); + } + } + +// --------------------------------------------------------- +// CImpsSendReceive2::SendAndWaitL +// --------------------------------------------------------- +// +void CImpsSendReceive2::SendAndWaitL( + const TDesC& aTID, + TInt aExpiryTime ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: SendAndWait begins %d" ), iTrState ); +#endif + + if ( !iSender || iTrState != EImpsTrDataOpen ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: SendAndWaitL Leaves(KErrNotReady) ****" ) ); +#endif + User::Leave( KErrNotReady ); + } + + // XML log *************************************************************** +#ifdef _DEBUG + if ( iXmlLog&0x1 ) + { + if ( iXmlLog&0x2 || aTID.Length() > 0 ) // This works with WBXML too + { + TFileName fileName = _L( "c:\\logs\\impss\\" ); + if ( BaflUtils::PathExists( iFs, fileName ) ) + { + _LIT( KRelated, "Sent.xml" ); + iParse.Set( fileName, &KRelated, NULL ); + fileName = iParse.FullName(); + TRAPD( errxy, CApaApplication::GenerateFileName( iFs, fileName ) ); + if ( errxy ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: SendAndWaitL Leaves(%d) ****" ), errxy ); +#endif + User::Leave( errxy ); + } + + RFile file; + TInt xmlError = file.Create( iFs, fileName, EFileWrite | EFileShareExclusive ); + if ( xmlError == KErrNone ) + { + // the data is supposed to be in the encode buffer + TPtr8 ptr = iOutputBuffer.Ptr( 0 ); + file.Write( ptr ); + file.Flush(); + } + + // done - close files + file.Close(); + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: LogFile = %S" ), &fileName ); +#endif + } + } + } +#endif // _DEBUG + // XML log ends ********************************************************** + + TInt myId = AddIdL( aTID ); + +#ifdef _FAKE_RESPONSE + // local transport does not support more than one request at a time + if ( iSender->PendingRequests() >= KImpsMaxPending ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: SendAndWaitL Leaves(KErrInUse) ****" ) ); +#endif + User::Leave( KErrInUse ); + } +#endif + + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: Call transport SendL" ) ); +#endif + + TRAPD( er, iSender->SendL( myId, iOutputBuffer.Ptr( 0 ), aExpiryTime ) ); + if ( er ) + { + // If send fails immediatly the callback is not called and thus + // queue must be cleaned now. + DeleteId( myId ); +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: SendAndWaitL Leaves(%d) ****" ), er ); +#endif + User::Leave( er ); + } + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: SendAndWait ends" ) ); //lint !e539 +#endif + + } + +// --------------------------------------------------------- +// CImpsSendReceive2::CancelTrans +// --------------------------------------------------------- +// +void CImpsSendReceive2::CancelTrans( const TDesC& aTID ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: CancelTrans" ) ); //lint !e539 +#endif + TInt opid = TidToOpid( aTID ); + if ( opid != KImpsNullId ) + { + if ( iSender ) + { + iSender->CancelTransaction( opid ); + } + DeleteId( opid ); + } + } + +// --------------------------------------------------------- +// CImpsSendReceive2::CancelLoginTrans +// --------------------------------------------------------- +// +TBool CImpsSendReceive2::CancelLoginTrans( const TDesC& aTID ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: CancelLoginTransL TID=%S" ), &aTID ); //lint !e539 +#endif + TBool ret( KErrNone ); + if ( iTrState == EImpsTrAPOpening || iTrState == EImpsTrAPOpen ) + { + CloseTr(); + } + else if ( iTrState == EImpsTrDataOpen ) + { + TInt opid = TidToOpid( aTID ); + if ( opid != KImpsNullId ) + { + if ( iSender ) + { + iSender->CancelTransaction( opid ); + } + DeleteId( opid ); + ret = ETrue; + } + } + return ret; + } + +// --------------------------------------------------------- +// CImpsSendReceive2::AddIdL +// --------------------------------------------------------- +// +TInt CImpsSendReceive2::AddIdL( const TDesC& aTid ) + { + GenerateId(); + + CTrReq* requ = new ( ELeave ) CTrReq( + aTid, + iID ); + + iRequList.AddLast( *requ ); + + return iID; + } + +// --------------------------------------------------------- +// CImpsSendReceive2::OpidToTid +// --------------------------------------------------------- +// +TPtrC CImpsSendReceive2::OpidToTid( TInt aId ) + { + TDblQueIter rIter( iRequList ); + + rIter.SetToFirst(); + + while ( rIter ) + { + CTrReq* requ = rIter; + if ( requ->iOpId == aId ) + { + return requ->iTID; + } + rIter++; + } + return TPtrC(); + } + +// --------------------------------------------------------- +// CImpsSendReceive2::TidToOpid +// --------------------------------------------------------- +// +TInt CImpsSendReceive2::TidToOpid( const TDesC& aId ) + { + TDblQueIter rIter( iRequList ); + + rIter.SetToFirst(); + + while ( rIter ) + { + CTrReq* requ = rIter; + if ( !requ->iTID.Compare( aId ) ) + { + return requ->iOpId; + } + rIter++; + } + return KImpsNullId; + } + +// --------------------------------------------------------- +// CImpsSendReceive2::DeleteId +// --------------------------------------------------------- +// +TBool CImpsSendReceive2::DeleteId( TInt aId ) + { + + TDblQueIter rIter( iRequList ); + + rIter.SetToFirst(); + + while ( rIter ) + { + CTrReq* requ = rIter; + rIter++; + if ( requ->iOpId == aId ) + { + requ->Destroy(); + return ETrue; + } + } + return EFalse; + } + +// --------------------------------------------------------- +// CImpsSendReceive2::DeleteAllIds +// --------------------------------------------------------- +// +void CImpsSendReceive2::DeleteAllIds() + { + // Delete all buffered requests from this client, + TDblQueIter rIter( iRequList ); + + rIter.SetToFirst(); + + while ( rIter ) + { + CTrReq* requ = rIter; + rIter++; + requ->Destroy(); + } + } + +// --------------------------------------------------------- +// CImpsSendReceive2::TransportResponse +// --------------------------------------------------------- +// +void CImpsSendReceive2::TransportResponse( + TInt aID, + TInt aError, + TInt aHttpStatus, + HBufC8* aCspMessage ) + { + TInt myErr = KErrNone; + HBufC8** dataPtr = &aCspMessage; + TRAP( myErr, DoTransportResponseL( aID, aError, aHttpStatus, dataPtr ) ); + if ( myErr ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: DoTransportResponseL leaves = %d" ), myErr ); //lint !e725 +#endif + DeleteId( aID ); + } + // This ensures the data buffer deletion in error cases + delete *dataPtr; + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: TransportResponse ends" ), myErr ); +#endif + + } + +// --------------------------------------------------------- +// CImpsSendReceive2::DoTransportResponseL +// --------------------------------------------------------- +// +void CImpsSendReceive2::DoTransportResponseL( + TInt aID, + TInt aError, + TInt aHttpStatus, + HBufC8** aCspPtr ) + { + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: DoTransportResponse start err=%d http=%d" ), aError, aHttpStatus ); +#endif + + HBufC8* cspMsg = *aCspPtr; + + TPtrC tid = OpidToTid( aID ); + TInt origState = iTrState; + // error handling + if ( aError || ( aHttpStatus != 200 && aHttpStatus != 0 ) ) + { + if ( aHttpStatus != 200 && aHttpStatus != 0 ) + { + aError = KImpsErrorResponseStatus; + } + iServer.TransportErrorL( tid, aError ); + DeleteId( aID ); + return; + } + if ( cspMsg && cspMsg->Size() > iServer.MaxParserSize() ) + { + iServer.TransportErrorL( tid, KImpsErrorMessageTooBig ); + DeleteId( aID ); + return; + } + + if ( origState == EImpsTrDataOpen ) + { + + // XML log *************************************************************** +#ifdef _DEBUG + // XML log + if ( iXmlLog&1 && cspMsg ) + { + TPtr8 ptr = cspMsg->Des(); + if ( !( !( iXmlLog&2 ) && !ptr.Length( ) ) ) + { + TFileName fileName = _L( "c:\\logs\\impss\\" ); + if ( BaflUtils::PathExists( iFs, fileName ) ) + { + _LIT( KRelated, "Receive.xml" ); + iParse.Set( fileName, &KRelated, NULL ); + fileName = iParse.FullName(); + User::LeaveIfError( CApaApplication::GenerateFileName( iFs, fileName ) ); + + RFile file; + TInt xmlError = file.Create( iFs, fileName, EFileWrite | EFileShareExclusive ); + if ( xmlError == KErrNone ) + { + TPtr8 ptr2 = cspMsg->Des(); + file.Write( ptr2 ); + file.Flush(); + } + + // done - close files + file.Close(); + +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: LogFile = %S" ), &fileName ); +#endif + } + } + }// if ( iXmlLog&1 && cspMsg ) +#endif // _DEBUG + // XML log ends ********************************************************** + + // we catch error and continue ... + TRAPD( erxx, iServer.TransportResponseL( aCspPtr ) ); + if ( erxx ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2:TransportResponseL ERROR= %d" ), erxx ); +#endif + } + + // This makes csp session ready for next response xxx + iServer.GetNextMessageL(); + } + + DeleteId( aID ); + + return; + } + +// --------------------------------------------------------- +// CImpsSendReceive2::APStatusEvent +// This methods handles both completion of Connection Manager +// operations and connection status events. +// --------------------------------------------------------- +// +void CImpsSendReceive2::APStatusEvent( + TImpsConnectionState aConnectionState, + TInt aStatus, + TBool aOperation, + TBool aAuthClose ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: APStatusEvent %d %d op=%d trstate=%d authClose=%d" ), + ( TInt )aConnectionState, aStatus, aOperation, iTrState, aAuthClose ); +#endif + + TInt errx = KErrNone; + if ( aOperation ) + { + TRAP( errx, DoHandleRespL( aConnectionState, aStatus ) ); + } + else // !oper + { + TRAP( errx, DoHandleTrEventL( aConnectionState, aAuthClose ) ); + } + } + +// --------------------------------------------------------- +// CImpsSendReceive2::DoHandleRespL +// --------------------------------------------------------- +// +void CImpsSendReceive2::DoHandleRespL( + TImpsConnectionState aConnectionState, + TInt aStatus ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: DoHandleRespL %d %d trstate=%d" ), + ( TInt )aConnectionState, aStatus, iTrState ); +#endif + TInt err = aStatus; + TInt errx = KErrNone; + TImpsTrState origTr = iTrState; + + // Regular cases handled here + if ( !err ) + { + switch ( origTr ) + { + case EImpsTrAPOpening: + NewTrState( EImpsTrAPOpen ); + // create iSender if needed + errx = DoOpenDataCh(); + if ( errx ) + { + TPtrC tid = OpidToTid( iOpenId ); + iServer.TransportErrorL( tid, errx ); + } + else + { + NewTrState( EImpsTrDataOpen ); + // This was response for open request! + // If iOpenId is zero then this was a special case just + // to open channels + if ( iOpenId ) + { + // Now we can send the message + // iID is set in Open + TPtrC tid = OpidToTid( iOpenId ); + TRAPD( errxy, SendAndWaitL( tid ) ); + if ( errxy ) + { + // notice: if this leaves then ON_LINE event is + // not sent to a CSP class. + iServer.TransportErrorL( tid, errxy ); + } + } + // Send ON_LINE status after data channel is opened + iServer.TransportStatus( EInternal_ON_LINE ); + } // else + break; + case EImpsTrClosing: + iIAP = 0; + NewTrState( EImpsTrInit ); + iServer.TransportStatus( EInternal_NO_IAP ); + break; + case EImpsTrClosingPDP: + iIAP = 0; + NewTrState( EImpsTrClosedPDP ); + iServer.TransportStatus( EInternal_NO_IAP ); + break; + case EImpsTrOpeningPDP: + NewTrState( EImpsTrAPOpen ); + // create iSender if needed + errx = DoOpenDataCh(); + if ( errx ) + { + NewTrState( EImpsTrAPOpen ); + iServer.TransportStatus( EInternal_OFF_LINE ); + } + else + { + NewTrState( EImpsTrDataOpen ); + // Send ON_LINE status not until data channel is opened + iServer.TransportStatus( EInternal_IAP_OPEN ); + } + break; + default: +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: DoHandleRespL no action ****" ) ); +#endif + break; + }; + } + + // Error handling + else // (err) + { + // Connection command failed +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: DoHandleRespL error case" ) ); //lint !e725 +#endif + + if ( origTr == EImpsTrAPOpening || origTr == EImpsTrClosing ) + { + NewTrState( EImpsTrInit ); + HBufC8* nullPtr = NULL; + TRAP( errx, DoTransportResponseL( iOpenId, err, 200, &nullPtr ) ); + DeleteId( iOpenId ); + iOpenId = 0; + if ( origTr == EImpsTrClosing ) + { + // If closing fails then send NO_IAP event to CSP session so that + // it can start to delete itself. + iServer.TransportStatus( EInternal_NO_IAP ); + } + } + else if ( origTr == EImpsTrOpeningPDP ) + { + // This is error from OpenIAP, not data channel opening +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: err: E2 ****" ) ); //lint !e725 +#endif + NewTrState( EImpsTrClosedPDP ); + DeleteId( iOpenId ); + iOpenId = 0; + // KImpsErrorNoIAP error code has a special error handling + // in CSPSession class. + iServer.TransportErrorL( KNullDesC, KImpsErrorNoIAP ); + } + else if ( origTr == EImpsTrClosingPDP ) + { + // This is error from Close IAP, not data channel closing + // This is handled like Ok case, so don't call transportError callback. + iIAP = 0; + NewTrState( EImpsTrClosedPDP ); + iServer.TransportStatus( EInternal_NO_IAP ); + } + if ( aConnectionState == EImpsNoAP ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L + ( "SendReceive2: APStatusEvent NO_IAP error ****" ) ); +#endif + } + } + } + +// --------------------------------------------------------- +// CImpsSendReceive2::DoHandleTrEventL +// --------------------------------------------------------- +// +void CImpsSendReceive2::DoHandleTrEventL( + TImpsConnectionState aConnectionState, + TBool aAuthClose ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: DoHandleTrEventL %d trstate=%d" ), + ( TInt )aConnectionState, iTrState ); +#endif + + EImpsInternalStatus myStatus = EInternal_NOT_LOGGED; + switch ( aConnectionState ) + { + case EImpsOffline: + myStatus = EInternal_OFF_LINE; + break; + case EImpsNoAP: + if ( iTrState == EImpsTrDataOpen || + iTrState == EImpsTrOpeningPDP ) + { + NewTrState( EImpsTrClosedPDP ); + iSender->Close(); + } + else + { + NewTrState( EImpsTrInit ); + } + // shut down routines + iIAP = 0; + myStatus = aAuthClose ? EInternal_NO_IAP_AUTH : EInternal_NO_IAP; + break; + default: + myStatus = EInternal_ON_LINE; + break; + }; + iServer.TransportStatus( myStatus ); + } +// --------------------------------------------------------- +// CImpsSendReceive2::Destroy +// --------------------------------------------------------- +// +void CImpsSendReceive2::Destroy() + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: Destroy" ) ); +#endif + NewTrState( EImpsTrInit ); + if ( iSender ) + { + iSender->Destroy(); + iSender = NULL; + } + if ( iConnMan ) + { + iConnMan->Destroy(); + delete iConnMan; + iConnMan = NULL; + } + + } + +// --------------------------------------------------------- +// CImpsSendReceive2::ConnManagerHandleL +// --------------------------------------------------------- +// +MMsgConnManager& CImpsSendReceive2::ConnManagerHandleL() + { + return iConnMan->ManagerHandleL(); + } + +// ----------------------------------------------------------------------------- +// CImpsSendReceive2::NewTrState +// ----------------------------------------------------------------------------- +void CImpsSendReceive2::NewTrState( TImpsTrState aNew ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( _L( "SendReceive2: NewTrState old=%d new=%d" ), + iTrState, aNew ); +#endif + iTrState = aNew; + } + +// ----------------------------------------------------------------------------- +// CImpsSendReceive2::DoOpenDataCh() +// This method does not change iTrState itself +// ----------------------------------------------------------------------------- +TInt CImpsSendReceive2::DoOpenDataCh() + { + TInt errx = KErrNone; + if ( ! iSender ) + { + TRAP( errx, + { MMsgConnManager& man = iConnMan->ManagerHandleL(); + iSender = NewImpsSenderL( *this, man, iMimeType ); + } ); + } + if ( errx ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( + _L( "SendReceive2: DataCh open ERROR *** %d" ), errx ); +#endif + return errx; + } + TRAP( errx, iSender->OpenL( SAP() ) ); + if ( errx ) + { +#ifndef _NO_IMPS_LOGGING_ + CImpsClientLogger::Log( + _L( "SendReceive2: DataCh open ERROR **** %d" ), errx ); +#endif + if ( errx != KErrAlreadyExists ) + { + iSender->Close( ); + iSender->Destroy(); + iSender = NULL; + return errx; + } + } + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CTrReq::CTrReq +// ----------------------------------------------------------------------------- + +CTrReq::CTrReq( + const TDesC& aTID, + TInt aOpId ): + iOpId( aOpId ) + { + iTID = aTID; + } + +CTrReq::~CTrReq() + { + + } + +void CTrReq::Destroy() + { + iLink.Deque(); + delete this; + } + + +// End of File