--- /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 <s32strm.h>
+#include <SenXmlUtils.h>
+
+//#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; i<count; i++)
+ {
+ CSenAsyncOperation* pOp = (*iAsyncOpsArray)[i];
+ if ( pOp )
+ {
+ TRequestStatus* status = &pOp->iStatus;
+ 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<CSenAsyncOperation>& CSenHostletConnectionImpl::AsyncOpsArrayL()
+ {
+ if(!iAsyncOpsArray)
+ {
+ iAsyncOpsArray = new (ELeave) RPointerArray<CSenAsyncOperation>;
+ }
+ 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<TUint8*>(&iErrorNumber),
+ sizeof(TInt),
+ sizeof(TInt));
+
+ iTxnIdBuffer.Set(reinterpret_cast<TUint8*>(&iTxnId),
+ sizeof(TInt),
+ sizeof(TInt));
+
+ SetActive();
+#ifdef EKA2
+ iActive->AsyncOpsArrayL().AppendL(this);
+#else
+ RPointerArray<CSenAsyncOperation>& 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<CSenAsyncOperation>* 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<TFileOutgoingTransferProgressBase> 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
+