diff -r 000000000000 -r 62f9d29f7211 webservices/wshostletconnection/src/senhostletconnectionimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webservices/wshostletconnection/src/senhostletconnectionimpl.cpp Thu Jan 07 16:19:19 2010 +0200 @@ -0,0 +1,1011 @@ +/* +* 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: +* +*/ + + + + + + + + + + + +#include +#include + +//#include "SenHostletConnectionLog.h" +#include "sendebug.h" +#include "senlogger.h" + +#include "senhostletconnectionimpl.h" +#include "MSenHostlet.h" // public +#include "MSenHostletRequest.h" // public +#include "MSenHostletResponse.h" // public +#include "senhostletrequest.h" +#include "senhostletresponse.h" + +#include "rsenhostletconnection.h" + +#include "senservicemanagerdefines.h" // internal Core\inc - IPC enumerations + +#include "SenXmlServiceDescription.h" + +#include "senguidgen.h" // internal: Utils\inc - the prefix length constant for WSF GUIDs +#include "senchunk.h" +#include "senidentifier.h" + +#include "MSenMessage.h" +#include "senconnagentserver.h" +#include "senvtcptransportproperties.h" +#include "SenXmlReader.h" + +namespace + { + _LIT8( KSenCidPostfix, "@example.org" ); + const TInt KMaxCidLength = 512; + } + + +CSenHostletConnectionImpl* CSenHostletConnectionImpl::NewL(MSenHostlet& aProvider) + { + CSenHostletConnectionImpl* pNew = NewLC(aProvider); + CleanupStack::Pop(); + return(pNew) ; + } + +CSenHostletConnectionImpl* CSenHostletConnectionImpl::NewLC(MSenHostlet& aProvider) + { + CSenHostletConnectionImpl* pNew = new (ELeave) CSenHostletConnectionImpl(aProvider); + CleanupStack::PushL(pNew); + pNew->ConstructL(); + return pNew; + } + +void CSenHostletConnectionImpl::ConstructL() + { + TInt connErr = iConnection.Connect(); + TInt connAttemp(0); // max 5 attempts are allowed + while ( (connErr == KErrServerTerminated || connErr == KErrServerBusy) + && connAttemp < KSenMaxClientConnectionOpeningAttempts ) + { +// TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "CSenHostletConnection::ConstructL - Server busy/going down"); + User::After(1000000); // wait for a second if server has been shut down +// TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "CSenHostletConnection::ConstructL - Creating connection"); + connErr = iConnection.Connect(); + connAttemp++; + } + if ( connErr != KErrNone ) + { + User::Leave( connErr ); + } + + iConnectionID = iConnection.ConnectionID(); + iTlsLogChannel = KSenHostletConnectionLogChannelBase + iConnectionID; + + ipRegistrationTimer = CSenRegistrationTimer::NewL( *this ); + +#ifdef _SENDEBUG + RThread thread; + RProcess process; + TFileName logFile; + logFile.Append( KSenHostletConnectionLogFile().Left(KSenHostletConnectionLogFile().Length()-4) ); // exclude ".log" file extension + logFile.AppendNum( iConnectionID ); + logFile.Append( KSenUnderline ); + logFile.Append( process.Name().Left(32)); + logFile.Append( KSenUnderline ); + logFile.Append( thread.Name().Left(20)); + logFile.Append( KSenHostletConnectionLogFile().Right(4) ); // postfix with ".log" file extension + + // Open connection to the file logger server + TLSLOG_OPEN( iTlsLogChannel, KSenHostletConnectionLogLevel, KSenHostletConnectionLogDir, logFile ); + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnection::ConstructL - About to establish new hostlet connection.."); + TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L("- Connection ID: (%d)"), iConnectionID)); +#endif + + User::LeaveIfError(EstablishConnectionL(iProvider)); + } + +CSenHostletConnectionImpl::CSenHostletConnectionImpl(MSenHostlet& aProvider) : + iProvider(aProvider), + iErrorNumber(0), + iErrorNumberBuffer(NULL, 0), + iTxnId(KErrNotFound), + iTxnIdBuffer(NULL, 0), + iHostletTransactionMap(NULL), + ipSessionId(NULL), + iSessionIdBuffer(NULL, 0), + iChunkNameNumber(0), + ipChunkName(NULL), + iAlive(ETrue), + iConnectionID(KErrNotReady), + iTlsLogChannel(KSenHostletConnectionLogChannelBase), + iCancelSession(EFalse), + ipFileProgressObserver(NULL), + iRegisterFileObserverDone(EFalse), + ipRegistrationTimer(NULL) + { + CActiveScheduler::Add(this); + } + +CSenHostletConnectionImpl::~CSenHostletConnectionImpl() + { + delete ipRegistrationTimer; // Invokes connagent registrations & subscribes for RProperty updates + delete ipFileProgressObserver; // Subscriber (observer) for RProperty update + TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::~CSenHostletConnectionImpl")); + CSenHostletConnectionImpl::Cancel(); // Causes call to DoCancel() + CSenHostletConnectionImpl::iAlive = EFalse; + if (iFilesObserver) + { + CSenConnAgentServer::Close(); + } + if (iAsyncOpsArray) + { + TInt count(iAsyncOpsArray->Count()); + for(TInt i=0; iiStatus; + User::RequestComplete( status, KErrSenCancelled ); + pOp->iActive = NULL; + } + } + iAsyncOpsArray->ResetAndDestroy(); + delete iAsyncOpsArray; + } + + if ( iHostletTransactionMap ) + { + iHostletTransactionMap->Reset(); + delete iHostletTransactionMap; + } + + delete ipSessionId; + delete ipChunkName; + + iConnection.Close(); + + // Close the log file and the connection to the server. + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "Log file closed."); + TLSLOG_CLOSE( iTlsLogChannel ); + //TLSLOG_CLOSE( KSenHostletConnectionLogChannel ); + } + + +TInt CSenHostletConnectionImpl::Identifier() + { + return iConnectionID; + } + +TInt CSenHostletConnectionImpl::RegisterFilesObserver() + { + TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::RegisterFilesObserver")); + TInt retVal(KErrNone); + const TDesC& name = CSenConnAgentServer::Open(); + if (name == KNullDesC) + { + return KErrGeneral; + } + retVal = iConnection.RegisterTransferObserver(&name, iFilesObserver); + TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::RegisterFilesObserver Completed")); + return retVal; + } + +TPtrC CSenHostletConnectionImpl::SessionID() + { + if(ipSessionId) + { + return *ipSessionId; + } + else + { + return KNullDesC(); + } + } + +TInt CSenHostletConnectionImpl::RespondL(MSenHostletResponse& aResponse) + { + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::RespondL"); + TInt retVal(KErrNone); + + retVal = HostletTransactionMapL().Find(aResponse.RequestId()); + + if ( retVal != KErrNotFound ) + { + CSenHostletTransaction* pTransaction = (CSenHostletTransaction*)HostletTransactionMapL().ValueAt(retVal); + CSenChunk* pOperation = (CSenChunk*)pTransaction->Chunk(); + if ( pOperation ) + { + // First check whether this request has ALREADY BEEN responded (to prevent multiple RespondL + // calls performed inside MSenHostlet::ServiceL / per single request): + MSenMessage::TDirection direction = pOperation->ChunkHeader().MessageDirection(); + + if( direction == MSenMessage::EOutbound ) + { + // Note: direction is always consumers point of view. So outbound here + // means "a request from consumer" - inbound would be "response to consumer". + + // Note: this sort of really double-safety action, since hostlet transport plugin also turns the + // direction to "inbound" before sending responses to consumers. But better be safe than sorry + pOperation->ChunkHeader().SetMessageDirection( MSenMessage::EInbound ); + + + MSenProperties* pProperties = aResponse.ResponseProperties(); + if( pProperties ) + { + // Serialize properties + HBufC8* pPropsAsXml = pProperties->AsUtf8LC(); + // Store the properties class type into chunk + MSenProperties::TSenPropertiesClassType type + = pProperties->PropertiesClassType(); + pOperation->ChunkHeader().SetPropertiesType( type ); + // Store response message AND properties into chunk + TPtrC8 properties = pPropsAsXml->Des(); + pOperation->DescsToChunk( aResponse.ResponseUtf8(), properties ); + CleanupStack::PopAndDestroy(pPropsAsXml); + } + else + { + // There is only a response message. Store it into chunk. + pOperation->ChunkHeader().SetPropertiesType(MSenProperties::ENotInUse); + pOperation->DescToChunk( aResponse.ResponseUtf8() ); + } + CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); + iConnection.ProvideResponse(pSenAO->iStatus, + pSenAO->iErrorNumberBuffer, + pSenAO->iTxnIdBuffer, + *pOperation, + aResponse.ResponseCode()); + } + else + { + retVal = KErrAlreadyExists; + } + } + else + { + retVal = KErrNotFound; + } + } + + TLSLOG_FORMAT((iTlsLogChannel, KNormalLogLevel, _L8("- ProvideResponse returned: %d"), retVal)); + return retVal; + } + +// This method is executed when one of the static constructors of +// service connection (NewL or NewLC) is called. +TInt CSenHostletConnectionImpl::EstablishConnectionL(MSenHostlet& aProvider) + { + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::InitializeL"); + + TInt retVal = KErrNone; + ipInterface = NULL; + ipInterface = aProvider.GetInterfaceByUid(KSenInterfaceUidFilesObserver); + if(ipInterface) + { + iFilesObserver = (MSenFilesObserver*) ipInterface; + + + if ( !iRegisterFileObserverDone ) + { + TLSLOG_L( iTlsLogChannel, KMinLogLevel, "EstablishConnectionL(): - Calling IssueRegistrations()"); + ipRegistrationTimer->IssueRegistrations( ETrue ); + TLSLOG_L(iTlsLogChannel, KMinLogLevel ,"- RegisterFilesObserver() failed!"); + } // end of if ( !iRegisterFileObserverDone ) + + } + if(retVal == KErrNone) + { + TPtrC8 endpoint = aProvider.Endpoint(); + TPtrC8 contract = aProvider.Contract(); + TPtrC8 frameworkId = aProvider.FrameworkId(); + CSenXmlServiceDescription* pDescription = CSenXmlServiceDescription::NewLC(endpoint, contract); + pDescription->SetFrameworkIdL(frameworkId); + + aProvider.DescribeServiceL(*pDescription); + + if(pDescription->Endpoint().Length()==0 && pDescription->Contract().Length()==0) + { + User::Leave(KErrSenNoContractNoEndPoint); + } + + if ( pDescription->Endpoint().Length() == 0 ) + { +#ifdef EKA2 + RProcess process; + TSecureId sId = process.SecureId(); + if ( sId == 0 ) + { + User::Leave(KErrSenNoEndpoint); + } + + TBuf8<128> buf; + TUint i(sId); + _LIT8(KFormat, "%u"); + buf.Format(KFormat, i); + + pDescription->SetEndPointL(buf); +#else + User::Leave(KErrSenNoEndpoint); // in EKA1, endpoints are not generated! +#endif // EKA2/EKA1 + } + + // Ensure that hostlet connection transport-plugin cue is applied, + // unless the application has specified some other plug-in: + TPtrC8 cue = pDescription->TransportCue(); + if( cue.Length() == 0 ) + { + // Set the default cue (hostlet connection transport plug-in) to the XML SD: + pDescription->SetTransportCueL(KSenTransportCueHostletConnection); +// LOG_WRITEFORMAT((_L8("- Setting the default transport cue: '%S'"), &KSenTransportCueHostletConnection())); + } + + +#ifdef _FORCE_DESCRIBED_MSW_2005_08_CONTRACT_TO_2006_10 + /// // Hard coded workaround for update hostlet contract: // /// + // Update contract from 2005 => 2006 + _LIT8( KMessaging200508, "http://schemas.live.com/mws/2005/08/messaging" ); + _LIT8( KMessaging200510, "http://schemas.live.com/mws/2006/10/messaging" ); + if( pDescription->Contract() == KMessaging200508 ) + { + pDescription->SetContractL( KMessaging200510 ); + } +#endif // _FORCE_DESCRIBED_MSW_2005_08_CONTRACT_TO_2006_10 + + +#ifdef _SENDEBUG + //TPtrC8 providerID = ((CSenXmlServiceDescription&)aSD).ProviderId(); + + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|"); + TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L8("- FrameworkID: %S"), &frameworkId )); + TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L8("- Endpoint: %S"), &endpoint )); + TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L8("- Contract: %S"), &contract )); + TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L8("- TransportCue: %S"), &cue )); +// LOG_WRITEFORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L8("- ProviderID: %S"), &providerID )); + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|"); +#endif //_SENDEBUG + + HBufC8* pServiceDescriptionXml = pDescription->AsXmlL(); + CleanupStack::PopAndDestroy(pDescription); + + CleanupStack::PushL(pServiceDescriptionXml); + +#ifdef _SENDEBUG + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::EstablishConnectionL - Service description:"); + if ( pServiceDescriptionXml ) + { + TPtrC8 xml = pServiceDescriptionXml->Des(); + TLSLOG_ALL(iTlsLogChannel, KMinLogLevel, (xml)); + } +#endif // _SENDEBUG + + if ( pServiceDescriptionXml ) + { + TPtr8 ptrServiceDescriptionXml(pServiceDescriptionXml->Des()); + + retVal = iConnection.Establish(ptrServiceDescriptionXml); + } + else + { + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "EstablishConnectionL ---- Returning KErrGeneral"); + retVal = KErrGeneral; + } + + TLSLOG_FORMAT((iTlsLogChannel, KNormalLogLevel, _L("- Establish returned: %d"), retVal)); + User::LeaveIfError( retVal ); + + CleanupStack::PopAndDestroy(pServiceDescriptionXml); + + // Start awaiting for next hostlet request + iErrorNumber = 0; + iTxnId = 0; + + CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); // appends itself into array + + // NOTE, following ASYNC AwaitRequest() will stay as pending IPC -operation; this is the design: + iConnection.AwaitRequest(pSenAO->iStatus, pSenAO->iErrorNumberBuffer, pSenAO->iTxnIdBuffer); + } + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::InitializeL Completed"); + return retVal; + } + +void CSenHostletConnectionImpl::RunL() + { + TLSLOG_FORMAT((iTlsLogChannel, KNormalLogLevel, _L("CSenHostletConnectionImpl::RunL( %d )"), iStatus.Int())); + } + +void CSenHostletConnectionImpl::HandleErrorFromChildAOL(TInt aError, TInt aTxnId, const TDesC8& aDesc, CSenAsyncOperation& aChild ) + { + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleErrorFromChildAOL"); + TInt leaveCode(KErrNone); + TRAP( leaveCode, iProvider.OnServiceCompleteL(aTxnId, aError, aDesc); ) + + HostletTransactionMapL().RemoveByKey(aTxnId); + + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleErrorFromChildAOL:"); +#ifdef _SEDEBUG + if( leaveCode != KErrNone ) + { + TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L(" - OnServiceCompleteL leaved: %d"), leaveCode)); + } + if( aChild.iStatus.Int() == ESenOnServiceComplete && aError == KErrSenCancelled ) + { + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "- Await was cancelled (ESenOnServiceComplete)."); + } +#endif // _SENDEBUG + if( aChild.iStatus.Int() == ESenOnServiceComplete && iAlive ) + { + CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); // appends itself into array + iConnection.AwaitRequest(pSenAO->iStatus, pSenAO->iErrorNumberBuffer, pSenAO->iTxnIdBuffer); + } + leaveCode = 0; // not used in release builds + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleErrorFromChildAOL Completed"); + } + +void CSenHostletConnectionImpl::HandleMessageFromChildAOL(TInt aStatus, CSenAsyncOperation& aChild) + { + TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::HandleMessageFromChildAOL( %d )"), aStatus)); + + iAsyncOpsCount--; +// TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L("One asynchronous operation completed. Pending iAsyncOpsCount: %i"), iAsyncOpsCount)); + + TLSLOG_FORMAT((iTlsLogChannel, KNormalLogLevel, _L("One asynchronous operation completed. Pending iAsyncOpsCount: %i"), iAsyncOpsCount)); + + if ( aStatus == ESenOnServiceComplete) // temporary: implement "acquire request handle" operation and use switch case here.. + { + TInt leaveCode(KErrNone); + TRAP(leaveCode, iProvider.OnServiceCompleteL(aChild.iTxnId, aChild.iErrorNumber, KNullDesC8); ) + + HostletTransactionMapL().RemoveByKey(aChild.iTxnId); + + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleMessageFromChildAOL: ESenOnServiceComplete"); +#ifdef _SEDEBUG + if( leaveCode != KErrNone ) + { + TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L(" - OnServiceCompleteL leaved: %d"), leaveCode)); + } + if( aChild.iErrorNumber == KErrSenCancelled ) + { + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "- Await was cancelled."); + } +#endif // _SENDEBUG + if( aChild.iErrorNumber != KErrSenCancelled && iAlive ) + { + CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); // appends itself into array + + // NOTE, following ASYNC AwaitRequest() will stay as pending IPC -operation; this is the design: + iConnection.AwaitRequest(pSenAO->iStatus, pSenAO->iErrorNumberBuffer, pSenAO->iTxnIdBuffer); + } + leaveCode = 0; // not used in release builds + } + else if ( aStatus > KErrNone ) + { + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "- handle received."); + CSenChunk* pOperation = CSenChunk::NewLC(KNullDesC); + TInt retVal = pOperation->OpenChunkFromHandleNumberL(aStatus); + if ( retVal == KErrNone ) + { + CSenHostletTransaction* pHostletTxn = CSenHostletTransaction::NewL(pOperation); + CleanupStack::Pop(pOperation); + CleanupStack::PushL(pHostletTxn); + + TInt* pTxnId = new (ELeave) TInt(pOperation->ChunkHeader().TransactionId()); + CleanupStack::PushL(pTxnId); + retVal = HostletTransactionMapL().Append(pTxnId, pHostletTxn); + + if ( retVal == KErrNone ) + { + CleanupStack::Pop(pTxnId); + CleanupStack::Pop(pHostletTxn); + TPtrC8 request; + retVal = pOperation->DescFromChunk(request); + + if ( retVal == KErrNone ) + { + RThread thread; + CSenIdentifier* pIdentifier = CSenIdentifier::NewL(); + pHostletTxn->SetIdentifier(pIdentifier); + + CSenHostletRequest* pRequest = + CSenHostletRequest::NewL(pOperation->ChunkHeader().TransactionId(), + request, + thread, + *pIdentifier, + pOperation); + pHostletTxn->SetRequest(pRequest); + + CSenHostletResponse* pResponse = + CSenHostletResponse::NewL(pOperation->ChunkHeader().TransactionId()); + pHostletTxn->SetResponse(pResponse); + + MSenProperties::TSenPropertiesClassType type = MSenProperties::ESenVtcpTransportProperties ; + TPtrC8 properties = pRequest->Properties(type) ; + if (properties != KNullDesC8) + { + CSenXmlReader* pXmlReader = CSenXmlReader::NewL(); + if(pXmlReader) + { + CleanupStack::PushL(pXmlReader); + CSenVtcpTransportProperties * vtcpTransProp = CSenVtcpTransportProperties::NewL(properties, *pXmlReader); + if(vtcpTransProp) + { + CleanupStack::PushL(vtcpTransProp); + TBool boolValue = EFalse ; + if (vtcpTransProp->OnewayMessageOnOffL(boolValue) != KErrNotFound + && boolValue) + { + //Now hostlet implementation can automaticaly reply with zero-length + //string (KNullDesC8) + //NOW SET THE ONE WAY RESPONSE PROPERTY AS WELL + pResponse->SetResponseUtf8L(KNullDesC8(), KErrNone, vtcpTransProp) ; + iProvider.ServiceL(*pRequest, *pResponse); + //RespondL(*pResponse) ; + } + else + { + iProvider.ServiceL(*pRequest, *pResponse); + //RespondL(*pResponse) ; + } + CleanupStack::PopAndDestroy(vtcpTransProp) ; + } + CleanupStack::PopAndDestroy(pXmlReader) ; + } + } + else + { + iProvider.ServiceL(*pRequest, *pResponse); + } +// if( iAlive ) +// { +// CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); // appends itself into array +// iConnection.AwaitRequest(pSenAO->iStatus, pSenAO->iErrorNumberBuffer, pSenAO->iTxnIdBuffer); +// } + } + else + { + User::Leave(retVal); + } + } + else + { + CleanupStack::PopAndDestroy(pTxnId); + CleanupStack::PopAndDestroy(pHostletTxn); + User::Leave(retVal); + } + } + else + { + CleanupStack::PopAndDestroy(pOperation); + User::Leave(retVal); + } + } + else + { + User::Leave(aStatus); + } + + /* + switch (aStatus) + { + case ESenHostletRequestPending: + { + TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "HandleMessageFromChildAOL: ESenHostletRequestPending"); + if (iErrorNumber == KErrNone) + { + TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L("- Request from consumer received:"), iSessionIdBuffer.Length())); + + + //TInt handle = iConnection.AcquireRequestHandle(aChild.iErrorNumberBuffer, aChild.iTxnIdBuffer); + //CSenChunk* pChunk = CSenChunk::OpenChunkFromRMsgL + + } + + } + break; + + case ESenInternalError: + { + // we could have someting in iErrorNumber in some cases + TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "HandleMessageFromChildAOL: ESenInternalError"); + TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, + _L("- Last received error from server: (%d)"), + iErrorNumber)); + + //DeliverResponseL(KNullDesC8, KErrSenInternal); + } + break; + + + default: + { +#ifdef _SENDEBUG + if(aStatus == KErrPermissionDenied) + { + TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "HandleMessageFromChildAOL: default - KErrPermissionDenied"); + } + else + { + TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "RunL: default - unexpected error."); + TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L("Last received error from server: (%d)"), iErrorNumber)); + } + TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L("RunL, iStatus.Int(): (%d)"), iStatus.Int())); + +#endif // _SENDEBUG + // WSF does not generalize errors: + //DeliverResponseL(KNullDesC8, aStatus); + break ; + } + }*/ + TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleMessageFromChildAOL Completed"); + } + +void CSenHostletConnectionImpl::DoCancel() + { + TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::DoCancel")); + TInt cancelLeaveCode(KErrNone); + if (iCancelSession == EFalse) + { + CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); + TRAP(cancelLeaveCode, iConnection.CancelSession(pSenAO->iStatus)); + + #ifdef _SENDEBUG + if(cancelLeaveCode!=KErrNone) + { + TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L("- CancelSession leaved: %d)"), cancelLeaveCode)); + } + #endif + cancelLeaveCode=0; + iCancelSession = ETrue; + } + TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::DoCancel Completed")); + } +RHostletTransactionMap& CSenHostletConnectionImpl::HostletTransactionMapL() + { + if ( !iHostletTransactionMap ) + { + iHostletTransactionMap = new (ELeave) RHostletTransactionMap(ETrue, ETrue); + } + return *iHostletTransactionMap; + } + +RPointerArray& CSenHostletConnectionImpl::AsyncOpsArrayL() + { + if(!iAsyncOpsArray) + { + iAsyncOpsArray = new (ELeave) RPointerArray; + } + return *iAsyncOpsArray; + } + +TInt CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL() + { + TInt retCode( KErrNone ); +#ifndef RD_SEN_DISABLE_TRANSFER_PROGRESS_FOR_HC + if(iFilesObserver && !iRegisterFileObserverDone) + { + + #ifndef RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS // pub&sub not in use for outgoing file progress + TLSLOG( iTlsLogChannel, KMinLogLevel,(_L("CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS == FALSE"))); + retCode = RegisterFilesObserver(); + #else // RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS == TRUE + TLSLOG( iTlsLogChannel, KMinLogLevel,(_L("CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS == TRUE"))); + ipFileProgressObserver = CSenFileProgressObserver::NewL( *iFilesObserver, iConnectionID ); + + #ifdef RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS + TLSLOG_L( iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS == TRUE"); + TLSLOG_L( iTlsLogChannel, KMinLogLevel, "=> calling RegisterFilesObserver()"); + retCode = RegisterFilesObserver(); // MIXED MODE, using conn agent for SOAP progress.. + #else // RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS == FALSE + TLSLOG_L( iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS == FALSE"); + #endif // RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS + + #endif // RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS end + iRegisterFileObserverDone = ETrue; // register only once + } +#else + TLSLOG_L( iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_DISABLE_TRANSFER_PROGRESS_FOR_HC == TRUE, not registering connagent, nor subscribing for the RProperty"); +#endif // end of: #ifndef RD_SEN_DISABLE_TRANSFER_PROGRESS_FOR_HC + return retCode; + } + + + + + +CSenAsyncOperation* CSenAsyncOperation::NewL(CSenHostletConnectionImpl* aActive) + { + CSenAsyncOperation* pNew = NewLC(aActive); + CleanupStack::Pop(); + return(pNew); + } + +CSenAsyncOperation* CSenAsyncOperation::NewLC(CSenHostletConnectionImpl* aActive) + { + CSenAsyncOperation* pNew = new (ELeave) CSenAsyncOperation(aActive); + CleanupStack::PushL(pNew); + pNew->ConstructL(); + return pNew; + } + +CSenAsyncOperation::CSenAsyncOperation(CSenHostletConnectionImpl* aActive) +: CActive(EPriorityNormal), + iActive(aActive), + iErrorNumber(0), + iErrorNumberBuffer(NULL, 0), + iTxnId(0), + iTxnIdBuffer(NULL, 0) + { + CActiveScheduler::Add(this); + } + +void CSenAsyncOperation::ConstructL() + { + iErrorNumberBuffer.Set(reinterpret_cast(&iErrorNumber), + sizeof(TInt), + sizeof(TInt)); + + iTxnIdBuffer.Set(reinterpret_cast(&iTxnId), + sizeof(TInt), + sizeof(TInt)); + + SetActive(); +#ifdef EKA2 + iActive->AsyncOpsArrayL().AppendL(this); +#else + RPointerArray& ops = iActive->AsyncOpsArrayL(); + User::LeaveIfError(ops.Append(this)); +#endif + + iActive->iAsyncOpsCount++; + } + +CSenAsyncOperation::~CSenAsyncOperation() + { + Cancel(); // invokes CSenAsyncOperation::DoCancel() + } + +void CSenAsyncOperation::RunL() + { + if ( iActive ) + { + iActive->iErrorNumber = iErrorNumber; + iActive->iTxnId = iTxnId; + iActive->HandleMessageFromChildAOL(iStatus.Int(), *this); + + TInt idx = iActive->AsyncOpsArrayL().Find(this); + if (idx >= 0) + { + iActive->AsyncOpsArrayL().Remove(idx); + } + } + delete this; + } + +TInt CSenAsyncOperation::RunError(TInt aError) + { + TInt leaveCode( KErrNone ); + if (iActive) + { + TRAP( leaveCode, iActive->HandleErrorFromChildAOL(aError, iTxnId, KNullDesC8, *this); ) + + RPointerArray* pOps = NULL; + TRAP( leaveCode, pOps = &(iActive->AsyncOpsArrayL()); ) + if ( pOps ) + { + TInt idx = pOps->Find(this); + if ( idx != KErrNotFound ) + { + pOps->Remove( idx ); + } + } + delete this; + } + return leaveCode; // return != KErrNone ONLY and ONLY IF the error really could not be handled by this AO! + } + +void CSenAsyncOperation::DoCancel() + { + } + +CSenHostletTransaction* CSenHostletTransaction::NewL(CSenChunk* aSenChunk) + { + CSenHostletTransaction* pNew = NewLC(aSenChunk); + CleanupStack::Pop(pNew); + return(pNew); + } + +CSenHostletTransaction* CSenHostletTransaction::NewLC(CSenChunk* aSenChunk) + { + CSenHostletTransaction* pNew = new (ELeave) CSenHostletTransaction(aSenChunk); + CleanupStack::PushL(pNew); + return pNew; + } + +CSenHostletTransaction::~CSenHostletTransaction() + { + delete iIdentifier; + delete iSenChunk; + delete iRequest; + delete iResponse; + } + +CSenHostletTransaction::CSenHostletTransaction(CSenChunk* aSenChunk) + : iSenChunk( aSenChunk ) + { + } + +void CSenHostletTransaction::SetChunk(CSenChunk* aChunk) + { + iSenChunk = aChunk; + } + +CSenChunk* CSenHostletTransaction::Chunk() + { + return iSenChunk; + } + +void CSenHostletTransaction::SetIdentifier(CSenIdentifier* aIdentifier) + { + iIdentifier = aIdentifier; + } + +CSenIdentifier* CSenHostletTransaction::Identifier() + { + return iIdentifier; + } + +void CSenHostletTransaction::SetRequest(CSenHostletRequest* aRequest) + { + iRequest = aRequest; + } + +CSenHostletRequest* CSenHostletTransaction::Request() + { + return iRequest; + } + +void CSenHostletTransaction::SetResponse(CSenHostletResponse* aResponse) + { + iResponse = aResponse; + } + +CSenHostletResponse* CSenHostletTransaction::Response() + { + return iResponse; + } + + + +// ------------------------------------------------------------------------------------------------------------ + +CSenFileProgressObserver* CSenFileProgressObserver::NewL( MSenFilesObserver& aObserver, + TInt aConnectionID ) + { + CSenFileProgressObserver* pNew = NewLC( aObserver, aConnectionID ); + CleanupStack::Pop(); + return(pNew); + } + +CSenFileProgressObserver* CSenFileProgressObserver::NewLC( MSenFilesObserver& aObserver, + TInt aConnectionID ) + { + CSenFileProgressObserver* pNew = new (ELeave) CSenFileProgressObserver( aObserver, aConnectionID ); + CleanupStack::PushL(pNew); + pNew->ConstructL(); + return pNew; + } + + + +CSenFileProgressObserver::CSenFileProgressObserver( MSenFilesObserver& aObserver, + TInt aConnectionID ) +//: CActive(EPriorityNormal), +: CActive(EPriorityMore), + iFileProgressObserver(&aObserver), + iConnectionID(aConnectionID) + { + } + +void CSenFileProgressObserver::ConstructL() + { + _LIT_SECURITY_POLICY_PASS(KReadPropPassAll); + _LIT_SECURITY_POLICY_S0(KWritePropSenCoreSidOnlyPolicy, KServerUid3.iUid); + + // Define the property + TInt err = RProperty::Define( KSenInterfaceUidFilesObserver, + iConnectionID, + RProperty::ELargeByteArray, + KReadPropPassAll, + KWritePropSenCoreSidOnlyPolicy, + 512 ); + // Use KSenInterfaceUidFilesObserver extended consumer interface UID + User::LeaveIfError(iFileProgressProperty.Attach(KSenInterfaceUidFilesObserver, iConnectionID)); // KSenInterfaceUidFilesObserver UID will be category + CActiveScheduler::Add(this); + // Initial subscription + iFileProgressProperty.Subscribe(iStatus); + SetActive(); + iStatus = KRequestPending; + } + +CSenFileProgressObserver::~CSenFileProgressObserver() + { + Cancel(); + iFileProgressProperty.Close(); + + TInt err = RProperty::Delete( KSenInterfaceUidFilesObserver, iConnectionID ); + + } + +void CSenFileProgressObserver::DoCancel() + { + iFileProgressProperty.Cancel(); + } + +void CSenFileProgressObserver::RunL() + { + // Resubscribe before processing new value to prevent missing updates(!): + iFileProgressProperty.Subscribe( iStatus ); + SetActive(); + iStatus = KRequestPending; + + TLSLOG_L( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, "CSenFileProgressObserver::RunL" ); + + TPckgBuf progress; + TInt getPropertyCode = iFileProgressProperty.Get( progress ); + if ( getPropertyCode == KErrNone ) + { + TLSLOG_L( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, "CSenFileProgressObserver::RunL [new value published] - Calling TransferProgress" ); + TFileOutgoingTransferProgressBase data = progress(); + + HBufC8* pCid = HBufC8::NewLC( KMaxCidLength ); + TPtr8 cid = pCid->Des(); + cid.Num( data.iCid ); + if( data.iCid2 != KErrNotFound ) + { + cid.AppendNum( data.iCid2 ); + } + if( data.iHasCidPostfix ) + { + cid.Append( KSenCidPostfix ); + } + TLSLOG_FORMAT(( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, _L8("- txn '%d', progress '%d', isIncoming '%d', cid '%S', '"), data.iTxnId, data.iProgress, data.iIsIncoming, &cid )); + TRAP_IGNORE( iFileProgressObserver->TransferProgress( data.iTxnId, data.iIsIncoming, KNullDesC8, cid, data.iProgress ); ) + CleanupStack::PopAndDestroy( pCid ); + } +#ifdef _SENDEBUG + else + { + TLSLOG_FORMAT(( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, _L8("- MAJOR: iFileProgressProperty.Get(propertyValue) failed: %d"), getPropertyCode )); + } +#endif // _SENDEBUG + } + +TInt CSenFileProgressObserver::RunError( TInt aError ) + { + TLSLOG_FORMAT(( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, _L8("CSenFileProgressObserver::RunError:[%d]"), aError )); + // return aError; + return KErrNone; // ignore the error, this is conscious decision. + } + + +// ------------------------------------------------------------------------------------------------------------ + + +// End of file +