webservices/wshostletconnection/src/senhostletconnectionimpl.cpp
changeset 0 62f9d29f7211
child 11 ab1e518f96da
equal deleted inserted replaced
-1:000000000000 0:62f9d29f7211
       
     1 /*
       
     2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:           
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 
       
    28 #include <s32strm.h>
       
    29 #include <SenXmlUtils.h>
       
    30 
       
    31 //#include "SenHostletConnectionLog.h"
       
    32 #include "sendebug.h"
       
    33 #include "senlogger.h"
       
    34 
       
    35 #include "senhostletconnectionimpl.h"
       
    36 #include "MSenHostlet.h"              // public
       
    37 #include "MSenHostletRequest.h"       // public
       
    38 #include "MSenHostletResponse.h"      // public
       
    39 #include "senhostletrequest.h"
       
    40 #include "senhostletresponse.h"
       
    41 
       
    42 #include "rsenhostletconnection.h"
       
    43 
       
    44 #include "senservicemanagerdefines.h" // internal Core\inc  - IPC enumerations
       
    45 
       
    46 #include "SenXmlServiceDescription.h"
       
    47 
       
    48 #include "senguidgen.h"  // internal: Utils\inc - the prefix length constant for WSF GUIDs
       
    49 #include "senchunk.h"
       
    50 #include "senidentifier.h"
       
    51 
       
    52 #include "MSenMessage.h"
       
    53 #include "senconnagentserver.h"
       
    54 #include "senvtcptransportproperties.h"
       
    55 #include "SenXmlReader.h"
       
    56 
       
    57 namespace
       
    58     {
       
    59     _LIT8( KSenCidPostfix, "@example.org" );
       
    60     const TInt KMaxCidLength = 512;
       
    61     }
       
    62 
       
    63 
       
    64 CSenHostletConnectionImpl* CSenHostletConnectionImpl::NewL(MSenHostlet& aProvider)
       
    65     {
       
    66     CSenHostletConnectionImpl* pNew = NewLC(aProvider);
       
    67     CleanupStack::Pop();
       
    68     return(pNew) ;
       
    69     }
       
    70 
       
    71 CSenHostletConnectionImpl* CSenHostletConnectionImpl::NewLC(MSenHostlet& aProvider)
       
    72     {
       
    73     CSenHostletConnectionImpl* pNew = new (ELeave) CSenHostletConnectionImpl(aProvider);
       
    74     CleanupStack::PushL(pNew);
       
    75     pNew->ConstructL();
       
    76     return pNew;
       
    77     }
       
    78 
       
    79 void CSenHostletConnectionImpl::ConstructL()
       
    80     {
       
    81     TInt connErr = iConnection.Connect();
       
    82     TInt connAttemp(0); // max 5 attempts are allowed
       
    83     while ( (connErr == KErrServerTerminated || connErr == KErrServerBusy)
       
    84                      && connAttemp < KSenMaxClientConnectionOpeningAttempts  )
       
    85         {
       
    86 //        TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "CSenHostletConnection::ConstructL - Server busy/going down");
       
    87         User::After(1000000); // wait for a second if server has been shut down
       
    88 //        TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "CSenHostletConnection::ConstructL - Creating connection");
       
    89         connErr = iConnection.Connect();
       
    90         connAttemp++;
       
    91         }
       
    92     if ( connErr != KErrNone )
       
    93         {
       
    94         User::Leave( connErr );
       
    95         }
       
    96 
       
    97     iConnectionID = iConnection.ConnectionID();
       
    98     iTlsLogChannel = KSenHostletConnectionLogChannelBase + iConnectionID;
       
    99 
       
   100     ipRegistrationTimer = CSenRegistrationTimer::NewL( *this );
       
   101 
       
   102 #ifdef _SENDEBUG
       
   103     RThread thread;
       
   104     RProcess process;
       
   105     TFileName logFile;
       
   106     logFile.Append( KSenHostletConnectionLogFile().Left(KSenHostletConnectionLogFile().Length()-4) ); // exclude ".log" file extension
       
   107     logFile.AppendNum( iConnectionID );
       
   108     logFile.Append( KSenUnderline );
       
   109     logFile.Append( process.Name().Left(32));
       
   110     logFile.Append( KSenUnderline );
       
   111     logFile.Append( thread.Name().Left(20));
       
   112     logFile.Append( KSenHostletConnectionLogFile().Right(4) ); // postfix with ".log" file extension
       
   113 
       
   114     // Open connection to the file logger server
       
   115     TLSLOG_OPEN( iTlsLogChannel, KSenHostletConnectionLogLevel, KSenHostletConnectionLogDir, logFile );
       
   116     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnection::ConstructL - About to establish new hostlet connection..");
       
   117     TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L("- Connection ID: (%d)"), iConnectionID));
       
   118 #endif
       
   119 
       
   120     User::LeaveIfError(EstablishConnectionL(iProvider));
       
   121     }
       
   122 
       
   123 CSenHostletConnectionImpl::CSenHostletConnectionImpl(MSenHostlet& aProvider) :
       
   124     iProvider(aProvider),
       
   125     iErrorNumber(0),
       
   126     iErrorNumberBuffer(NULL, 0),
       
   127     iTxnId(KErrNotFound),
       
   128     iTxnIdBuffer(NULL, 0),
       
   129     iHostletTransactionMap(NULL),
       
   130     ipSessionId(NULL),
       
   131     iSessionIdBuffer(NULL, 0),
       
   132     iChunkNameNumber(0),
       
   133     ipChunkName(NULL),
       
   134     iAlive(ETrue),
       
   135     iConnectionID(KErrNotReady),
       
   136     iTlsLogChannel(KSenHostletConnectionLogChannelBase),
       
   137     iCancelSession(EFalse),
       
   138     ipFileProgressObserver(NULL),
       
   139     iRegisterFileObserverDone(EFalse),
       
   140     ipRegistrationTimer(NULL)
       
   141     {
       
   142     CActiveScheduler::Add(this);
       
   143     }
       
   144 
       
   145 CSenHostletConnectionImpl::~CSenHostletConnectionImpl()
       
   146     {
       
   147     delete ipRegistrationTimer; // Invokes connagent registrations & subscribes for RProperty updates
       
   148     delete ipFileProgressObserver; // Subscriber (observer) for RProperty update
       
   149     TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::~CSenHostletConnectionImpl"));
       
   150     CSenHostletConnectionImpl::Cancel(); // Causes call to DoCancel()
       
   151     CSenHostletConnectionImpl::iAlive = EFalse;
       
   152    if (iFilesObserver)
       
   153         {
       
   154         CSenConnAgentServer::Close();
       
   155         }
       
   156     if (iAsyncOpsArray)
       
   157         {
       
   158         TInt count(iAsyncOpsArray->Count());
       
   159         for(TInt i=0; i<count; i++)
       
   160             {
       
   161             CSenAsyncOperation* pOp = (*iAsyncOpsArray)[i];
       
   162             if ( pOp )
       
   163                 {
       
   164                 TRequestStatus* status = &pOp->iStatus;
       
   165                 User::RequestComplete( status, KErrSenCancelled );
       
   166                 pOp->iActive = NULL;
       
   167                 }
       
   168             }
       
   169         iAsyncOpsArray->ResetAndDestroy();
       
   170         delete iAsyncOpsArray;
       
   171         }
       
   172 
       
   173     if ( iHostletTransactionMap )
       
   174         {
       
   175         iHostletTransactionMap->Reset();
       
   176         delete iHostletTransactionMap;
       
   177         }
       
   178 
       
   179     delete ipSessionId;
       
   180     delete ipChunkName;
       
   181 
       
   182     iConnection.Close();
       
   183 
       
   184     // Close the log file and the connection to the server.
       
   185     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "Log file closed.");
       
   186     TLSLOG_CLOSE( iTlsLogChannel );
       
   187     //TLSLOG_CLOSE( KSenHostletConnectionLogChannel );
       
   188     }
       
   189 
       
   190 
       
   191 TInt CSenHostletConnectionImpl::Identifier()
       
   192     {
       
   193     return iConnectionID;    
       
   194     }
       
   195 
       
   196 TInt CSenHostletConnectionImpl::RegisterFilesObserver()
       
   197     {
       
   198     TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::RegisterFilesObserver"));
       
   199     TInt retVal(KErrNone);
       
   200     const TDesC& name = CSenConnAgentServer::Open();
       
   201     if (name == KNullDesC)
       
   202         {
       
   203         return KErrGeneral;
       
   204         }
       
   205     retVal = iConnection.RegisterTransferObserver(&name, iFilesObserver);
       
   206     TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::RegisterFilesObserver Completed"));
       
   207     return retVal; 
       
   208     }
       
   209 
       
   210 TPtrC CSenHostletConnectionImpl::SessionID()
       
   211     {
       
   212     if(ipSessionId)
       
   213         {
       
   214         return *ipSessionId;
       
   215         }
       
   216     else
       
   217         {
       
   218         return KNullDesC();
       
   219         }
       
   220     }
       
   221 
       
   222 TInt CSenHostletConnectionImpl::RespondL(MSenHostletResponse& aResponse)
       
   223     {
       
   224     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::RespondL");
       
   225     TInt retVal(KErrNone);
       
   226     
       
   227     retVal = HostletTransactionMapL().Find(aResponse.RequestId());
       
   228     
       
   229     if ( retVal != KErrNotFound )
       
   230         {
       
   231         CSenHostletTransaction* pTransaction = (CSenHostletTransaction*)HostletTransactionMapL().ValueAt(retVal);
       
   232         CSenChunk* pOperation = (CSenChunk*)pTransaction->Chunk();
       
   233         if ( pOperation )
       
   234             {
       
   235             // First check whether this request has ALREADY BEEN responded (to prevent multiple RespondL
       
   236             // calls performed inside MSenHostlet::ServiceL / per single request):
       
   237             MSenMessage::TDirection direction = pOperation->ChunkHeader().MessageDirection();
       
   238             
       
   239             if( direction == MSenMessage::EOutbound )
       
   240                 {
       
   241                 // Note: direction is always consumers point of view. So outbound here
       
   242                 // means "a request from consumer" - inbound would be "response to consumer".
       
   243                 
       
   244                 // Note: this sort of really double-safety action, since hostlet transport plugin also turns the 
       
   245                 // direction to "inbound" before sending responses to consumers. But better be safe than sorry
       
   246                 pOperation->ChunkHeader().SetMessageDirection( MSenMessage::EInbound );
       
   247 
       
   248 
       
   249                 MSenProperties* pProperties = aResponse.ResponseProperties();
       
   250                 if( pProperties )
       
   251                     {
       
   252                     // Serialize properties
       
   253                     HBufC8* pPropsAsXml = pProperties->AsUtf8LC();
       
   254                     // Store the properties class type into chunk
       
   255                     MSenProperties::TSenPropertiesClassType type
       
   256                         = pProperties->PropertiesClassType();
       
   257                     pOperation->ChunkHeader().SetPropertiesType( type );
       
   258                     // Store response message AND properties into chunk
       
   259                     TPtrC8 properties = pPropsAsXml->Des();
       
   260                     pOperation->DescsToChunk( aResponse.ResponseUtf8(), properties );
       
   261                     CleanupStack::PopAndDestroy(pPropsAsXml);
       
   262                     }
       
   263                 else
       
   264                     {
       
   265                     // There is only a response message. Store it into chunk.
       
   266                     pOperation->ChunkHeader().SetPropertiesType(MSenProperties::ENotInUse);
       
   267                     pOperation->DescToChunk( aResponse.ResponseUtf8() );
       
   268                     }            
       
   269                 CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this);
       
   270                 iConnection.ProvideResponse(pSenAO->iStatus, 
       
   271                                             pSenAO->iErrorNumberBuffer,
       
   272                                             pSenAO->iTxnIdBuffer,
       
   273                                             *pOperation,
       
   274                                             aResponse.ResponseCode());
       
   275                 }
       
   276             else
       
   277                 {
       
   278                 retVal = KErrAlreadyExists; 
       
   279                 }                
       
   280             }
       
   281         else
       
   282             {
       
   283             retVal = KErrNotFound; 
       
   284             }
       
   285         }
       
   286         
       
   287     TLSLOG_FORMAT((iTlsLogChannel, KNormalLogLevel, _L8("- ProvideResponse returned: %d"), retVal));
       
   288     return retVal;
       
   289     }
       
   290 
       
   291 // This method is executed when one of the static constructors of
       
   292 // service connection (NewL or NewLC) is called.
       
   293 TInt CSenHostletConnectionImpl::EstablishConnectionL(MSenHostlet& aProvider)
       
   294     {
       
   295     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::InitializeL");
       
   296 
       
   297 	TInt retVal = KErrNone;
       
   298     ipInterface = NULL;
       
   299     ipInterface = aProvider.GetInterfaceByUid(KSenInterfaceUidFilesObserver);
       
   300     if(ipInterface)
       
   301     {
       
   302         iFilesObserver = (MSenFilesObserver*) ipInterface;
       
   303 
       
   304         
       
   305         if ( !iRegisterFileObserverDone )
       
   306             {
       
   307             TLSLOG_L( iTlsLogChannel, KMinLogLevel, "EstablishConnectionL(): - Calling IssueRegistrations()");
       
   308             ipRegistrationTimer->IssueRegistrations( ETrue );
       
   309                 TLSLOG_L(iTlsLogChannel, KMinLogLevel ,"- RegisterFilesObserver() failed!");
       
   310             } // end of if ( !iRegisterFileObserverDone )
       
   311         
       
   312     }
       
   313     if(retVal == KErrNone)
       
   314         {
       
   315     TPtrC8 endpoint     = aProvider.Endpoint();
       
   316     TPtrC8 contract     = aProvider.Contract();
       
   317     TPtrC8 frameworkId  = aProvider.FrameworkId();
       
   318     CSenXmlServiceDescription* pDescription = CSenXmlServiceDescription::NewLC(endpoint, contract);
       
   319     pDescription->SetFrameworkIdL(frameworkId);
       
   320 
       
   321     aProvider.DescribeServiceL(*pDescription);
       
   322 
       
   323     if(pDescription->Endpoint().Length()==0 && pDescription->Contract().Length()==0)
       
   324         {
       
   325         User::Leave(KErrSenNoContractNoEndPoint);
       
   326         }
       
   327         
       
   328     if ( pDescription->Endpoint().Length() == 0 )
       
   329         {
       
   330 #ifdef EKA2            
       
   331         RProcess process;
       
   332         TSecureId sId = process.SecureId();
       
   333         if ( sId == 0 )
       
   334             {
       
   335             User::Leave(KErrSenNoEndpoint);
       
   336             }
       
   337 
       
   338         TBuf8<128> buf;
       
   339         TUint i(sId);
       
   340         _LIT8(KFormat, "%u");
       
   341         buf.Format(KFormat, i);
       
   342 
       
   343         pDescription->SetEndPointL(buf);
       
   344 #else
       
   345         User::Leave(KErrSenNoEndpoint); // in EKA1, endpoints are not generated!
       
   346 #endif // EKA2/EKA1        
       
   347         }
       
   348 
       
   349     // Ensure that hostlet connection transport-plugin cue is applied,
       
   350     // unless the application has specified some other plug-in:
       
   351     TPtrC8 cue = pDescription->TransportCue();
       
   352     if( cue.Length() == 0 )
       
   353         {
       
   354         // Set the default cue (hostlet connection transport plug-in) to the XML SD:
       
   355         pDescription->SetTransportCueL(KSenTransportCueHostletConnection);
       
   356 //        LOG_WRITEFORMAT((_L8("- Setting the default transport cue: '%S'"), &KSenTransportCueHostletConnection()));
       
   357         }
       
   358 
       
   359 
       
   360 #ifdef _FORCE_DESCRIBED_MSW_2005_08_CONTRACT_TO_2006_10
       
   361     /// // Hard coded workaround for update hostlet contract: // ///
       
   362     //     Update contract from 2005 => 2006
       
   363     _LIT8( KMessaging200508, "http://schemas.live.com/mws/2005/08/messaging" );
       
   364     _LIT8( KMessaging200510, "http://schemas.live.com/mws/2006/10/messaging" );
       
   365     if( pDescription->Contract() == KMessaging200508 )
       
   366         {
       
   367         pDescription->SetContractL( KMessaging200510 );
       
   368         }
       
   369 #endif // _FORCE_DESCRIBED_MSW_2005_08_CONTRACT_TO_2006_10
       
   370 
       
   371 
       
   372 #ifdef _SENDEBUG
       
   373     //TPtrC8 providerID  = ((CSenXmlServiceDescription&)aSD).ProviderId();
       
   374 
       
   375     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|");
       
   376     TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L8("- FrameworkID:  %S"), &frameworkId ));
       
   377     TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L8("- Endpoint:     %S"), &endpoint ));
       
   378     TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L8("- Contract:     %S"), &contract ));
       
   379     TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L8("- TransportCue: %S"), &cue ));
       
   380 //    LOG_WRITEFORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L8("- ProviderID:  %S"), &providerID ));
       
   381     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|");
       
   382 #endif //_SENDEBUG            
       
   383     
       
   384     HBufC8* pServiceDescriptionXml = pDescription->AsXmlL();
       
   385     CleanupStack::PopAndDestroy(pDescription);
       
   386 
       
   387     CleanupStack::PushL(pServiceDescriptionXml);
       
   388 
       
   389 #ifdef _SENDEBUG
       
   390     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::EstablishConnectionL - Service description:");
       
   391     if ( pServiceDescriptionXml )
       
   392         {
       
   393             TPtrC8 xml = pServiceDescriptionXml->Des();
       
   394             TLSLOG_ALL(iTlsLogChannel, KMinLogLevel, (xml));
       
   395         }
       
   396 #endif // _SENDEBUG
       
   397     
       
   398 	 if ( pServiceDescriptionXml )
       
   399 		{
       
   400 			TPtr8 ptrServiceDescriptionXml(pServiceDescriptionXml->Des());
       
   401 
       
   402 			retVal = iConnection.Establish(ptrServiceDescriptionXml);
       
   403 		}
       
   404 		else
       
   405 		{
       
   406 	    TLSLOG_L(iTlsLogChannel, KMinLogLevel, "EstablishConnectionL ---- Returning KErrGeneral");		
       
   407 		retVal = KErrGeneral;
       
   408 		}
       
   409 
       
   410     TLSLOG_FORMAT((iTlsLogChannel, KNormalLogLevel, _L("- Establish returned: %d"), retVal));
       
   411     User::LeaveIfError( retVal );
       
   412 
       
   413     CleanupStack::PopAndDestroy(pServiceDescriptionXml);
       
   414 
       
   415     // Start awaiting for next hostlet request
       
   416     iErrorNumber = 0;
       
   417     iTxnId = 0;
       
   418 
       
   419     CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); // appends itself into array
       
   420 
       
   421     // NOTE, following ASYNC AwaitRequest() will stay as pending IPC -operation; this is the design:
       
   422     iConnection.AwaitRequest(pSenAO->iStatus, pSenAO->iErrorNumberBuffer, pSenAO->iTxnIdBuffer); 
       
   423         }
       
   424 	TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::InitializeL Completed");        
       
   425     return retVal;
       
   426     }
       
   427 
       
   428 void CSenHostletConnectionImpl::RunL()
       
   429     {
       
   430     TLSLOG_FORMAT((iTlsLogChannel, KNormalLogLevel, _L("CSenHostletConnectionImpl::RunL( %d )"),  iStatus.Int()));
       
   431     }
       
   432     
       
   433 void CSenHostletConnectionImpl::HandleErrorFromChildAOL(TInt aError, TInt aTxnId, const TDesC8& aDesc, CSenAsyncOperation& aChild )
       
   434     {
       
   435     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleErrorFromChildAOL");
       
   436     TInt leaveCode(KErrNone);
       
   437     TRAP( leaveCode, iProvider.OnServiceCompleteL(aTxnId, aError, aDesc); )
       
   438     
       
   439     HostletTransactionMapL().RemoveByKey(aTxnId);
       
   440     
       
   441     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleErrorFromChildAOL:");
       
   442 #ifdef _SEDEBUG
       
   443     if( leaveCode != KErrNone ) 
       
   444         {
       
   445         TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L(" - OnServiceCompleteL leaved: %d"), leaveCode));
       
   446         }
       
   447     if( aChild.iStatus.Int() == ESenOnServiceComplete && aError == KErrSenCancelled )
       
   448         {
       
   449         TLSLOG_L(iTlsLogChannel, KMinLogLevel, "- Await was cancelled (ESenOnServiceComplete).");
       
   450         }
       
   451 #endif // _SENDEBUG
       
   452     if( aChild.iStatus.Int() == ESenOnServiceComplete && iAlive )
       
   453         {
       
   454         CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); // appends itself into array
       
   455         iConnection.AwaitRequest(pSenAO->iStatus, pSenAO->iErrorNumberBuffer, pSenAO->iTxnIdBuffer); 
       
   456         }
       
   457     leaveCode = 0; // not used in release builds
       
   458     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleErrorFromChildAOL Completed");
       
   459     }
       
   460     
       
   461 void CSenHostletConnectionImpl::HandleMessageFromChildAOL(TInt aStatus, CSenAsyncOperation& aChild)
       
   462     {
       
   463     TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::HandleMessageFromChildAOL( %d )"), aStatus));
       
   464 
       
   465     iAsyncOpsCount--;
       
   466 //    TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L("One asynchronous operation completed. Pending iAsyncOpsCount: %i"), iAsyncOpsCount));
       
   467     
       
   468     TLSLOG_FORMAT((iTlsLogChannel, KNormalLogLevel, _L("One asynchronous operation completed. Pending iAsyncOpsCount: %i"), iAsyncOpsCount));
       
   469     
       
   470     if ( aStatus == ESenOnServiceComplete) // temporary: implement "acquire request handle" operation and use switch case here..
       
   471         {
       
   472         TInt leaveCode(KErrNone);
       
   473         TRAP(leaveCode, iProvider.OnServiceCompleteL(aChild.iTxnId, aChild.iErrorNumber, KNullDesC8); ) 
       
   474         
       
   475         HostletTransactionMapL().RemoveByKey(aChild.iTxnId);
       
   476         
       
   477         TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleMessageFromChildAOL: ESenOnServiceComplete");
       
   478 #ifdef _SEDEBUG
       
   479         if( leaveCode != KErrNone ) 
       
   480             {
       
   481             TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L(" - OnServiceCompleteL leaved: %d"), leaveCode));
       
   482             }
       
   483         if( aChild.iErrorNumber == KErrSenCancelled )
       
   484             {
       
   485             TLSLOG_L(iTlsLogChannel, KMinLogLevel, "- Await was cancelled.");
       
   486             }
       
   487 #endif // _SENDEBUG
       
   488         if( aChild.iErrorNumber != KErrSenCancelled && iAlive )
       
   489             {
       
   490             CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); // appends itself into array
       
   491 
       
   492             // NOTE, following ASYNC AwaitRequest() will stay as pending IPC -operation; this is the design:
       
   493             iConnection.AwaitRequest(pSenAO->iStatus, pSenAO->iErrorNumberBuffer, pSenAO->iTxnIdBuffer); 
       
   494             }
       
   495         leaveCode = 0; // not used in release builds
       
   496         }
       
   497     else if ( aStatus > KErrNone )
       
   498         {
       
   499         TLSLOG_L(iTlsLogChannel, KMinLogLevel, "- handle received.");
       
   500         CSenChunk* pOperation = CSenChunk::NewLC(KNullDesC);
       
   501         TInt retVal = pOperation->OpenChunkFromHandleNumberL(aStatus);
       
   502         if ( retVal == KErrNone )
       
   503             {
       
   504             CSenHostletTransaction* pHostletTxn = CSenHostletTransaction::NewL(pOperation);
       
   505             CleanupStack::Pop(pOperation);
       
   506             CleanupStack::PushL(pHostletTxn);
       
   507             
       
   508             TInt* pTxnId = new (ELeave) TInt(pOperation->ChunkHeader().TransactionId());
       
   509             CleanupStack::PushL(pTxnId);
       
   510             retVal = HostletTransactionMapL().Append(pTxnId, pHostletTxn);
       
   511             
       
   512             if ( retVal == KErrNone )
       
   513                 {
       
   514                 CleanupStack::Pop(pTxnId);
       
   515                 CleanupStack::Pop(pHostletTxn);
       
   516                 TPtrC8 request;
       
   517                 retVal = pOperation->DescFromChunk(request);
       
   518                 
       
   519                 if ( retVal == KErrNone )
       
   520                     {
       
   521                     RThread thread;
       
   522                     CSenIdentifier* pIdentifier = CSenIdentifier::NewL();
       
   523                     pHostletTxn->SetIdentifier(pIdentifier);
       
   524                     
       
   525                     CSenHostletRequest* pRequest =
       
   526                             CSenHostletRequest::NewL(pOperation->ChunkHeader().TransactionId(),
       
   527                                                      request,
       
   528                                                      thread,
       
   529                                                      *pIdentifier,
       
   530                                                      pOperation);
       
   531                     pHostletTxn->SetRequest(pRequest);
       
   532                                                      
       
   533                     CSenHostletResponse* pResponse = 
       
   534                             CSenHostletResponse::NewL(pOperation->ChunkHeader().TransactionId());
       
   535                     pHostletTxn->SetResponse(pResponse);
       
   536                     
       
   537 					MSenProperties::TSenPropertiesClassType type = MSenProperties::ESenVtcpTransportProperties ;
       
   538 					TPtrC8 properties = pRequest->Properties(type) ;
       
   539 					if (properties != KNullDesC8)
       
   540 						{
       
   541 						CSenXmlReader* pXmlReader = CSenXmlReader::NewL();
       
   542 						if(pXmlReader)	
       
   543 							{
       
   544 							CleanupStack::PushL(pXmlReader);
       
   545 							CSenVtcpTransportProperties * vtcpTransProp = CSenVtcpTransportProperties::NewL(properties, *pXmlReader);
       
   546 							if(vtcpTransProp)
       
   547 							    {
       
   548 							    CleanupStack::PushL(vtcpTransProp);
       
   549 								TBool boolValue = EFalse ;
       
   550 								if (vtcpTransProp->OnewayMessageOnOffL(boolValue) != KErrNotFound
       
   551 									&& boolValue)
       
   552 									{
       
   553 									//Now hostlet implementation can automaticaly reply with zero-length
       
   554 									//string (KNullDesC8)
       
   555 									//NOW SET THE ONE WAY RESPONSE PROPERTY AS WELL
       
   556 									pResponse->SetResponseUtf8L(KNullDesC8(), KErrNone, vtcpTransProp) ;
       
   557 						            iProvider.ServiceL(*pRequest, *pResponse);
       
   558 									//RespondL(*pResponse) ; 
       
   559 									}
       
   560 									else
       
   561 									{
       
   562 						      		iProvider.ServiceL(*pRequest, *pResponse);
       
   563 									//RespondL(*pResponse) ; 
       
   564 									}
       
   565 								CleanupStack::PopAndDestroy(vtcpTransProp) ;
       
   566 								}
       
   567 							CleanupStack::PopAndDestroy(pXmlReader) ;					
       
   568 							}
       
   569 						}
       
   570 					else
       
   571 						{
       
   572 			            iProvider.ServiceL(*pRequest, *pResponse);
       
   573 						}
       
   574 //                    if( iAlive )
       
   575 //                        {
       
   576 //                        CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this); // appends itself into array
       
   577 //                        iConnection.AwaitRequest(pSenAO->iStatus, pSenAO->iErrorNumberBuffer, pSenAO->iTxnIdBuffer); 
       
   578 //                        }
       
   579                     }
       
   580                 else
       
   581                     {
       
   582                     User::Leave(retVal);
       
   583                     }
       
   584                 }
       
   585             else
       
   586                 {
       
   587                 CleanupStack::PopAndDestroy(pTxnId);
       
   588                 CleanupStack::PopAndDestroy(pHostletTxn);
       
   589                 User::Leave(retVal);
       
   590                 }
       
   591             }
       
   592         else
       
   593             {
       
   594             CleanupStack::PopAndDestroy(pOperation);
       
   595             User::Leave(retVal);
       
   596             }
       
   597         }
       
   598     else
       
   599         {
       
   600         User::Leave(aStatus);
       
   601         }
       
   602                   
       
   603     /*                                         
       
   604     switch (aStatus)
       
   605         {
       
   606         case ESenHostletRequestPending:
       
   607             {
       
   608             TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "HandleMessageFromChildAOL: ESenHostletRequestPending");
       
   609             if (iErrorNumber == KErrNone)
       
   610                 {
       
   611                 TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L("- Request from consumer received:"), iSessionIdBuffer.Length()));
       
   612 
       
   613 
       
   614                 //TInt handle = iConnection.AcquireRequestHandle(aChild.iErrorNumberBuffer, aChild.iTxnIdBuffer);
       
   615                 //CSenChunk* pChunk = CSenChunk::OpenChunkFromRMsgL
       
   616 
       
   617                 }
       
   618 
       
   619             }
       
   620         break;
       
   621 
       
   622         case ESenInternalError:
       
   623             {
       
   624             // we could have someting in iErrorNumber in some cases
       
   625             TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "HandleMessageFromChildAOL: ESenInternalError");
       
   626             TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, 
       
   627                 _L("- Last received error from server: (%d)"),
       
   628                     iErrorNumber));
       
   629 
       
   630             //DeliverResponseL(KNullDesC8, KErrSenInternal);
       
   631             }
       
   632             break;
       
   633 
       
   634 
       
   635         default:
       
   636             {
       
   637 #ifdef _SENDEBUG                
       
   638             if(aStatus == KErrPermissionDenied)
       
   639                 {
       
   640                 TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "HandleMessageFromChildAOL: default - KErrPermissionDenied");
       
   641                 }
       
   642             else
       
   643                 {
       
   644                 TLSLOG_L(iTlsLogChannel, KSenHostletConnectionLogLevel, "RunL: default - unexpected error.");
       
   645                 TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L("Last received error from server: (%d)"), iErrorNumber));
       
   646                 }
       
   647             TLSLOG_FORMAT((iTlsLogChannel, KSenHostletConnectionLogLevel, _L("RunL, iStatus.Int(): (%d)"), iStatus.Int()));
       
   648             
       
   649 #endif // _SENDEBUG             
       
   650             // WSF does not generalize errors:
       
   651             //DeliverResponseL(KNullDesC8, aStatus);
       
   652             break ;
       
   653             }
       
   654         }*/
       
   655     TLSLOG_L(iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::HandleMessageFromChildAOL Completed");
       
   656     }
       
   657 
       
   658 void CSenHostletConnectionImpl::DoCancel()
       
   659     {
       
   660     TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::DoCancel"));
       
   661     TInt cancelLeaveCode(KErrNone);
       
   662     if (iCancelSession == EFalse)
       
   663         {
       
   664         CSenAsyncOperation* pSenAO = CSenAsyncOperation::NewL(this);
       
   665         TRAP(cancelLeaveCode, iConnection.CancelSession(pSenAO->iStatus));
       
   666         
       
   667     #ifdef _SENDEBUG
       
   668         if(cancelLeaveCode!=KErrNone)
       
   669             {
       
   670             TLSLOG_FORMAT((iTlsLogChannel, KMinLogLevel, _L("- CancelSession leaved: %d)"), cancelLeaveCode));
       
   671             }
       
   672     #endif
       
   673         cancelLeaveCode=0;   
       
   674         iCancelSession = ETrue; 
       
   675         }
       
   676     TLSLOG(iTlsLogChannel, KMinLogLevel, _L("CSenHostletConnectionImpl::DoCancel Completed"));
       
   677     }
       
   678 RHostletTransactionMap& CSenHostletConnectionImpl::HostletTransactionMapL()
       
   679     {
       
   680     if ( !iHostletTransactionMap )
       
   681         {
       
   682         iHostletTransactionMap = new (ELeave) RHostletTransactionMap(ETrue, ETrue);
       
   683         }
       
   684     return *iHostletTransactionMap;
       
   685     }
       
   686     
       
   687 RPointerArray<CSenAsyncOperation>& CSenHostletConnectionImpl::AsyncOpsArrayL()
       
   688     {
       
   689     if(!iAsyncOpsArray)
       
   690         {
       
   691         iAsyncOpsArray = new (ELeave) RPointerArray<CSenAsyncOperation>;
       
   692         }
       
   693     return *iAsyncOpsArray;
       
   694     }
       
   695 
       
   696 TInt CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL()
       
   697     {
       
   698     TInt retCode( KErrNone );
       
   699 #ifndef RD_SEN_DISABLE_TRANSFER_PROGRESS_FOR_HC        
       
   700     if(iFilesObserver && !iRegisterFileObserverDone)
       
   701     	{
       
   702     	
       
   703   #ifndef RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS // pub&sub not in use for outgoing file progress
       
   704         TLSLOG( iTlsLogChannel, KMinLogLevel,(_L("CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS == FALSE")));
       
   705     	retCode = RegisterFilesObserver();
       
   706   #else // RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS == TRUE
       
   707         TLSLOG( iTlsLogChannel, KMinLogLevel,(_L("CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS == TRUE")));
       
   708     	ipFileProgressObserver = CSenFileProgressObserver::NewL( *iFilesObserver, iConnectionID );
       
   709 
       
   710     #ifdef RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS
       
   711         TLSLOG_L( iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS == TRUE");
       
   712         TLSLOG_L( iTlsLogChannel, KMinLogLevel, "=> calling RegisterFilesObserver()");
       
   713         retCode = RegisterFilesObserver(); // MIXED MODE, using conn agent for SOAP progress..
       
   714     #else // RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS == FALSE
       
   715         TLSLOG_L( iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS == FALSE");
       
   716     #endif // RD_SEN_USE_CONNAGENT_FOR_SOAP_PROGRESS
       
   717 
       
   718   #endif // RD_SEN_USE_PUBSUB_FOR_OUTGOING_FILE_PROGRESS end 	
       
   719     	iRegisterFileObserverDone = ETrue; // register only once
       
   720     	}
       
   721 #else
       
   722     TLSLOG_L( iTlsLogChannel, KMinLogLevel, "CSenHostletConnectionImpl::RegisterAndSubscribeFileProgressObserversL: RD_SEN_DISABLE_TRANSFER_PROGRESS_FOR_HC == TRUE, not registering connagent, nor subscribing for the RProperty");
       
   723 #endif // end of: #ifndef RD_SEN_DISABLE_TRANSFER_PROGRESS_FOR_HC    
       
   724     return retCode;
       
   725     }
       
   726         
       
   727 
       
   728 
       
   729 
       
   730 
       
   731 CSenAsyncOperation* CSenAsyncOperation::NewL(CSenHostletConnectionImpl* aActive)
       
   732     {
       
   733     CSenAsyncOperation* pNew = NewLC(aActive);
       
   734     CleanupStack::Pop();
       
   735     return(pNew);
       
   736     }
       
   737 
       
   738 CSenAsyncOperation* CSenAsyncOperation::NewLC(CSenHostletConnectionImpl* aActive)
       
   739     {
       
   740     CSenAsyncOperation* pNew = new (ELeave) CSenAsyncOperation(aActive);
       
   741     CleanupStack::PushL(pNew);
       
   742     pNew->ConstructL();
       
   743     return pNew;
       
   744     }
       
   745     
       
   746 CSenAsyncOperation::CSenAsyncOperation(CSenHostletConnectionImpl* aActive)
       
   747 :   CActive(EPriorityNormal),
       
   748     iActive(aActive),
       
   749     iErrorNumber(0),
       
   750     iErrorNumberBuffer(NULL, 0),
       
   751     iTxnId(0),
       
   752     iTxnIdBuffer(NULL, 0)
       
   753     {
       
   754     CActiveScheduler::Add(this);
       
   755     }
       
   756 
       
   757 void CSenAsyncOperation::ConstructL()
       
   758     {
       
   759     iErrorNumberBuffer.Set(reinterpret_cast<TUint8*>(&iErrorNumber),
       
   760                            sizeof(TInt),
       
   761                            sizeof(TInt));
       
   762                            
       
   763     iTxnIdBuffer.Set(reinterpret_cast<TUint8*>(&iTxnId),
       
   764                      sizeof(TInt),
       
   765                      sizeof(TInt));
       
   766                      
       
   767     SetActive();
       
   768 #ifdef EKA2
       
   769     iActive->AsyncOpsArrayL().AppendL(this);
       
   770 #else
       
   771     RPointerArray<CSenAsyncOperation>& ops = iActive->AsyncOpsArrayL();
       
   772     User::LeaveIfError(ops.Append(this));
       
   773 #endif
       
   774 
       
   775     iActive->iAsyncOpsCount++;
       
   776     }
       
   777 
       
   778 CSenAsyncOperation::~CSenAsyncOperation()
       
   779     {
       
   780     Cancel(); // invokes CSenAsyncOperation::DoCancel()
       
   781     }
       
   782 
       
   783 void CSenAsyncOperation::RunL()
       
   784     {
       
   785     if ( iActive )
       
   786         {
       
   787         iActive->iErrorNumber = iErrorNumber;
       
   788         iActive->iTxnId = iTxnId;    
       
   789         iActive->HandleMessageFromChildAOL(iStatus.Int(), *this);
       
   790             
       
   791         TInt idx = iActive->AsyncOpsArrayL().Find(this);
       
   792         if (idx >= 0)
       
   793             {
       
   794             iActive->AsyncOpsArrayL().Remove(idx);
       
   795             }
       
   796         }
       
   797     delete this;
       
   798     }
       
   799     
       
   800 TInt CSenAsyncOperation::RunError(TInt aError)
       
   801     {
       
   802     TInt leaveCode( KErrNone );
       
   803     if (iActive)
       
   804         {
       
   805         TRAP( leaveCode, iActive->HandleErrorFromChildAOL(aError, iTxnId, KNullDesC8, *this); ) 
       
   806 
       
   807         RPointerArray<CSenAsyncOperation>* pOps = NULL;
       
   808         TRAP( leaveCode, pOps = &(iActive->AsyncOpsArrayL()); )
       
   809         if ( pOps )
       
   810             {
       
   811             TInt idx = pOps->Find(this);
       
   812             if ( idx != KErrNotFound )
       
   813                 {
       
   814                 pOps->Remove( idx );
       
   815                 }
       
   816             }
       
   817         delete this;
       
   818         }
       
   819     return leaveCode; // return != KErrNone ONLY and ONLY IF the error really could not be handled by this AO!
       
   820     }
       
   821         
       
   822 void CSenAsyncOperation::DoCancel()
       
   823     {
       
   824     }
       
   825 
       
   826 CSenHostletTransaction* CSenHostletTransaction::NewL(CSenChunk* aSenChunk)
       
   827     {
       
   828     CSenHostletTransaction* pNew = NewLC(aSenChunk);
       
   829     CleanupStack::Pop(pNew);
       
   830     return(pNew);
       
   831     }
       
   832 
       
   833 CSenHostletTransaction* CSenHostletTransaction::NewLC(CSenChunk* aSenChunk)
       
   834     {
       
   835     CSenHostletTransaction* pNew = new (ELeave) CSenHostletTransaction(aSenChunk);
       
   836     CleanupStack::PushL(pNew);
       
   837     return pNew;
       
   838     }
       
   839 
       
   840 CSenHostletTransaction::~CSenHostletTransaction()
       
   841     {
       
   842     delete iIdentifier;
       
   843     delete iSenChunk;
       
   844     delete iRequest;
       
   845     delete iResponse;
       
   846     }
       
   847 
       
   848 CSenHostletTransaction::CSenHostletTransaction(CSenChunk* aSenChunk)
       
   849     : iSenChunk( aSenChunk )
       
   850     {
       
   851     }
       
   852 
       
   853 void CSenHostletTransaction::SetChunk(CSenChunk* aChunk)
       
   854     {
       
   855     iSenChunk = aChunk;
       
   856     }
       
   857         
       
   858 CSenChunk* CSenHostletTransaction::Chunk()
       
   859     {
       
   860     return iSenChunk;
       
   861     }
       
   862 
       
   863 void CSenHostletTransaction::SetIdentifier(CSenIdentifier* aIdentifier)
       
   864     {
       
   865     iIdentifier = aIdentifier;
       
   866     }
       
   867     
       
   868 CSenIdentifier* CSenHostletTransaction::Identifier()
       
   869     {
       
   870     return iIdentifier;
       
   871     }
       
   872 
       
   873 void CSenHostletTransaction::SetRequest(CSenHostletRequest* aRequest)
       
   874     {
       
   875     iRequest = aRequest;
       
   876     }
       
   877     
       
   878 CSenHostletRequest* CSenHostletTransaction::Request()
       
   879     {
       
   880     return iRequest;
       
   881     }
       
   882 
       
   883 void CSenHostletTransaction::SetResponse(CSenHostletResponse* aResponse)
       
   884     {
       
   885     iResponse = aResponse;
       
   886     }
       
   887 
       
   888 CSenHostletResponse* CSenHostletTransaction::Response()
       
   889     {
       
   890     return iResponse;
       
   891     }
       
   892     
       
   893 
       
   894 
       
   895 // ------------------------------------------------------------------------------------------------------------
       
   896 
       
   897 CSenFileProgressObserver* CSenFileProgressObserver::NewL( MSenFilesObserver& aObserver,
       
   898                                                           TInt aConnectionID )
       
   899     {
       
   900     CSenFileProgressObserver* pNew = NewLC( aObserver, aConnectionID );
       
   901     CleanupStack::Pop();
       
   902     return(pNew);
       
   903     }
       
   904 
       
   905 CSenFileProgressObserver* CSenFileProgressObserver::NewLC( MSenFilesObserver& aObserver,
       
   906                                                            TInt aConnectionID )
       
   907     {
       
   908     CSenFileProgressObserver* pNew = new (ELeave) CSenFileProgressObserver( aObserver, aConnectionID );
       
   909     CleanupStack::PushL(pNew);
       
   910     pNew->ConstructL();
       
   911     return pNew;
       
   912     }
       
   913     
       
   914     
       
   915 
       
   916 CSenFileProgressObserver::CSenFileProgressObserver( MSenFilesObserver& aObserver,
       
   917                                                     TInt aConnectionID )
       
   918 //:   CActive(EPriorityNormal),
       
   919 :   CActive(EPriorityMore),
       
   920     iFileProgressObserver(&aObserver),
       
   921     iConnectionID(aConnectionID)
       
   922     {
       
   923     }
       
   924 
       
   925 void CSenFileProgressObserver::ConstructL()
       
   926     {
       
   927     _LIT_SECURITY_POLICY_PASS(KReadPropPassAll);
       
   928     _LIT_SECURITY_POLICY_S0(KWritePropSenCoreSidOnlyPolicy, KServerUid3.iUid);
       
   929     
       
   930     // Define the property
       
   931     TInt err = RProperty::Define( KSenInterfaceUidFilesObserver,
       
   932                                   iConnectionID,
       
   933                                   RProperty::ELargeByteArray, 
       
   934                                   KReadPropPassAll,
       
   935                                   KWritePropSenCoreSidOnlyPolicy,
       
   936                                   512 );
       
   937 	// Use KSenInterfaceUidFilesObserver extended consumer interface UID
       
   938 	User::LeaveIfError(iFileProgressProperty.Attach(KSenInterfaceUidFilesObserver,  iConnectionID)); // KSenInterfaceUidFilesObserver UID will be category
       
   939     CActiveScheduler::Add(this);
       
   940     // Initial subscription
       
   941     iFileProgressProperty.Subscribe(iStatus);
       
   942     SetActive();
       
   943     iStatus = KRequestPending;
       
   944     }
       
   945 
       
   946 CSenFileProgressObserver::~CSenFileProgressObserver()
       
   947     {
       
   948     Cancel();
       
   949     iFileProgressProperty.Close();
       
   950     
       
   951     TInt err = RProperty::Delete( KSenInterfaceUidFilesObserver, iConnectionID );
       
   952     
       
   953     }
       
   954 
       
   955 void CSenFileProgressObserver::DoCancel()
       
   956     {
       
   957     iFileProgressProperty.Cancel();
       
   958     }
       
   959 
       
   960 void CSenFileProgressObserver::RunL()
       
   961     {
       
   962     // Resubscribe before processing new value to prevent missing updates(!):
       
   963 	iFileProgressProperty.Subscribe( iStatus );
       
   964     SetActive();
       
   965     iStatus = KRequestPending;
       
   966 
       
   967     TLSLOG_L( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, "CSenFileProgressObserver::RunL" );
       
   968        
       
   969     TPckgBuf<TFileOutgoingTransferProgressBase> progress;
       
   970     TInt getPropertyCode = iFileProgressProperty.Get( progress );
       
   971     if ( getPropertyCode == KErrNone )
       
   972         {
       
   973         TLSLOG_L( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, "CSenFileProgressObserver::RunL [new value published] - Calling TransferProgress" );
       
   974         TFileOutgoingTransferProgressBase data = progress();
       
   975 
       
   976         HBufC8* pCid = HBufC8::NewLC( KMaxCidLength );
       
   977         TPtr8 cid = pCid->Des();
       
   978         cid.Num( data.iCid );
       
   979         if( data.iCid2 != KErrNotFound )
       
   980             {
       
   981             cid.AppendNum( data.iCid2 );
       
   982             }
       
   983         if( data.iHasCidPostfix )
       
   984             {
       
   985             cid.Append( KSenCidPostfix );
       
   986             }
       
   987         TLSLOG_FORMAT(( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, _L8("- txn '%d', progress '%d', isIncoming '%d', cid '%S',  '"), data.iTxnId, data.iProgress, data.iIsIncoming, &cid ));
       
   988         TRAP_IGNORE( iFileProgressObserver->TransferProgress( data.iTxnId, data.iIsIncoming, KNullDesC8, cid, data.iProgress );	)
       
   989         CleanupStack::PopAndDestroy( pCid );
       
   990         }
       
   991 #ifdef _SENDEBUG
       
   992     else
       
   993         {
       
   994         TLSLOG_FORMAT(( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, _L8("- MAJOR: iFileProgressProperty.Get(propertyValue) failed: %d"), getPropertyCode ));
       
   995         }
       
   996 #endif // _SENDEBUG 
       
   997     }
       
   998     
       
   999 TInt CSenFileProgressObserver::RunError( TInt aError )
       
  1000 	{
       
  1001 	TLSLOG_FORMAT(( KSenHostletConnectionLogChannelBase + iConnectionID, KSenServiceConnectionStatusLogLevel, _L8("CSenFileProgressObserver::RunError:[%d]"), aError ));
       
  1002 	// return aError;
       
  1003 	return KErrNone; // ignore the error, this is conscious decision.
       
  1004 	}
       
  1005 
       
  1006 
       
  1007 // ------------------------------------------------------------------------------------------------------------
       
  1008     
       
  1009     
       
  1010 // End of file
       
  1011