mmsengine/mmshttptransport/src/mmssession.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2002-2006 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 *     MMS transport session
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include    <httpstringconstants.h>
       
    23 #include    <stringpool.h>
       
    24 #include    <uaproffilter_interface.h>
       
    25 #include    <http/cecomfilter.h>
       
    26 #include    <featmgr.h>
       
    27 
       
    28 #include    "mmssession.h"
       
    29 #include    "mmstransaction.h"
       
    30 #include    "mmsbearerstatus.h"
       
    31 #include    "mmsconst.h"
       
    32 #include    "mmsservercommon.h"
       
    33 #include    "mmserrors.h"
       
    34 #include    "MmsServerDebugLogging.h"
       
    35    
       
    36 // EXTERNAL DATA STRUCTURES
       
    37 
       
    38 // EXTERNAL FUNCTION PROTOTYPES  
       
    39 extern void gPanic( TMmsPanic aPanic );
       
    40 
       
    41 // CONSTANTS
       
    42 // Timervalue used in network transactions (i.e. when using HTTP API)
       
    43 const TInt KMmsTransactionTimer = 900; // 900 sec = 15 min
       
    44 const TInt KMmsSecondsToMicroseconds = 1000000;
       
    45 
       
    46 // MACROS
       
    47 
       
    48 // LOCAL CONSTANTS AND MACROS
       
    49 
       
    50 // MODULE DATA STRUCTURES
       
    51 
       
    52 // LOCAL FUNCTION PROTOTYPES
       
    53 
       
    54 // ==================== LOCAL FUNCTIONS ====================
       
    55 
       
    56 // ================= MEMBER FUNCTIONS =======================
       
    57 
       
    58 // ---------------------------------------------------------
       
    59 // CMmsSession::CMmsSession
       
    60 // ---------------------------------------------------------
       
    61 //
       
    62 CMmsSession::CMmsSession( TInt aPriority )
       
    63     :CActive( aPriority ),    
       
    64     iConnected( EFalse ),
       
    65     iTransaction( NULL ),
       
    66     iRequestStatus( NULL),
       
    67     iSessionStatus( ESessionIdle ),
       
    68     iHeadersCreated( EFalse ),
       
    69     iSessionOpened( EFalse ),
       
    70     iTransferControl( NULL ),
       
    71     iUserAgent( NULL ),
       
    72     iUaProf( NULL )
       
    73     {
       
    74     }
       
    75 
       
    76 // ---------------------------------------------------------
       
    77 // CMmsSession::ConstructL
       
    78 // ---------------------------------------------------------
       
    79 //
       
    80 void CMmsSession::ConstructL(
       
    81     RSocketServ& aSocketServ,
       
    82     RConnection& aConnection )
       
    83     {
       
    84     CActiveScheduler::Add(this);
       
    85 
       
    86     iSocketServ = &aSocketServ;
       
    87     iConnection = &aConnection;
       
    88     
       
    89     // Construct bearer status object
       
    90     iTransferControl = CMmsBearerStatus::NewL( aConnection );
       
    91 
       
    92     // initialize to defaults
       
    93     iTransactionTimeout = KMmsTransactionTimer * KMmsSecondsToMicroseconds;
       
    94     
       
    95     // Open HTTP session
       
    96     iHTTPSession.OpenL( KProtocolHTTP );
       
    97     iSessionOpened = ETrue;
       
    98     }
       
    99 
       
   100 // ---------------------------------------------------------
       
   101 // CMmsSession::NewL
       
   102 // ---------------------------------------------------------
       
   103 //
       
   104 EXPORT_C CMmsSession* CMmsSession::NewL(
       
   105     TInt aPriority,
       
   106     RSocketServ& aSocketServ,
       
   107     RConnection& aConnection )
       
   108     {
       
   109     CMmsSession* self = new(ELeave) CMmsSession( aPriority );
       
   110     CleanupStack::PushL( self );
       
   111     self->ConstructL( aSocketServ, aConnection );
       
   112     CleanupStack::Pop( self );
       
   113     return self;
       
   114     }
       
   115    
       
   116 // ---------------------------------------------------------
       
   117 // CMmsSession::~CMmsSession
       
   118 // ---------------------------------------------------------
       
   119 //
       
   120 CMmsSession::~CMmsSession()
       
   121     {
       
   122     Cancel();
       
   123 
       
   124     // clean up the headers if we have added them
       
   125     if ( iHeadersCreated )
       
   126         {
       
   127         iSessionHeaders.RemoveAllFields();
       
   128         }
       
   129     delete iUserAgent;
       
   130     delete iUaProf;
       
   131     delete iTransaction;
       
   132     delete iTransferControl;
       
   133     if ( iSessionOpened ) // cannot close if not opened
       
   134         {
       
   135         iHTTPSession.Close();
       
   136         }
       
   137     }
       
   138 
       
   139 // ---------------------------------------------------------
       
   140 // CMmsSession::OpenL
       
   141 // ---------------------------------------------------------
       
   142 //
       
   143 EXPORT_C void CMmsSession::OpenL( 
       
   144     const TDesC8& aProxyAddress,
       
   145     const TBool aUseProxy,  
       
   146     const TInt32 aMaxReceiveSize,
       
   147     const TInt32 aMaxSendSize,
       
   148     TRequestStatus& aStatus )
       
   149     {
       
   150     LOG( _L("CMmsSession::OpenL") );
       
   151     __ASSERT_DEBUG( iSessionStatus == ESessionIdle, gPanic( EMmsAlreadyBusy ) );
       
   152 
       
   153     iError = KErrNone;
       
   154     iRequestStatus = &aStatus;
       
   155 
       
   156     // 
       
   157     // Setting max send/receive sizes. 0 means not limited.
       
   158     // Values always come from CMmsSettings.
       
   159     // 
       
   160     iMaxReceiveSize = aMaxReceiveSize;
       
   161     iMaxSendSize = aMaxSendSize;
       
   162   
       
   163     // Get pointer HTTP session headers
       
   164     iSessionHeaders = iHTTPSession.RequestSessionHeadersL();
       
   165     iHeadersCreated = ETrue;
       
   166 
       
   167     // Check if we are connected already
       
   168     if ( iConnected )
       
   169         {
       
   170         aStatus = KRequestPending;                             
       
   171         User::RequestComplete( iRequestStatus, KMmsErrorSessionAlreadyOpen );
       
   172         }
       
   173     else 
       
   174         {
       
   175 
       
   176         // set the session properties
       
   177         // the handle comes from iHTTP session. I think we should not close it.
       
   178         RStringPool strPool = iHTTPSession.StringPool();
       
   179         RHTTPConnectionInfo connInfo = iHTTPSession.ConnectionInfo();
       
   180         connInfo.SetPropertyL( strPool.StringF( HTTP::EHttpSocketServ, RHTTPSession::GetTable() ),
       
   181             THTTPHdrVal( iSocketServ->Handle() ) );
       
   182         TInt connPtr = REINTERPRET_CAST( TInt, iConnection );
       
   183         connInfo.SetPropertyL(
       
   184             strPool.StringF( HTTP::EHttpSocketConnection, RHTTPSession::GetTable() ),
       
   185             THTTPHdrVal( connPtr ) );
       
   186 
       
   187         // Add proxy usage if requested
       
   188         if ( aUseProxy )
       
   189             {
       
   190             THTTPHdrVal proxyUsage( strPool.StringF( HTTP::EUseProxy, RHTTPSession::GetTable() ) );
       
   191             connInfo.SetPropertyL(
       
   192                 strPool.StringF( HTTP::EProxyUsage, RHTTPSession::GetTable() ), proxyUsage );
       
   193         
       
   194             RStringF proxyString = strPool.OpenFStringL( aProxyAddress );
       
   195             CleanupClosePushL( proxyString );
       
   196             THTTPHdrVal proxyAddr( proxyString );
       
   197             connInfo.SetPropertyL(
       
   198                 strPool.StringF( HTTP::EProxyAddress, RHTTPSession::GetTable() ), proxyAddr );
       
   199             CleanupStack::PopAndDestroy( &proxyString );
       
   200             }
       
   201             
       
   202 		// Install MMS X-id header filter if required
       
   203     	FeatureManager::InitializeLibL();
       
   204     	if ( FeatureManager::FeatureSupported( KFeatureIdMmsXidHeaderHttpFilter ) )  
       
   205 	        {
       
   206 	        // Install the MMS X-id header filter explicitly, since only MMS requires this filter.
       
   207 			const TUid KHttpFilterMmsXidHeaderImplementationUid = { 0x1020738D };
       
   208 			CEComFilter::InstallFilterL(iHTTPSession, KHttpFilterMmsXidHeaderImplementationUid);
       
   209 	        }
       
   210     	FeatureManager::UnInitializeLib();
       
   211     	
       
   212         // Install UAProf filter
       
   213         TInt error = KErrNotFound;
       
   214         TRAP( error, CHttpUAProfFilterInterface::InstallFilterL( iHTTPSession ) );
       
   215         if ( error != KErrNone )
       
   216             {
       
   217             LOG2( _L("ERROR: UAProf filter left with code %d. Using hardcoded UserAgent string.."), error );
       
   218             
       
   219             // Manually set UA string
       
   220             SetFixedUserAgentL();
       
   221 
       
   222             // UserAgent header must be added always - either hard coded string or string from ini file
       
   223             SetHeaderL( iSessionHeaders, HTTP::EUserAgent, iUserAgent->Des() );
       
   224 
       
   225             // Add UAProf if available
       
   226             if ( iUaProf && iUaProf->Length() > 0 )
       
   227                 {
       
   228                 RStringF tempString = strPool.OpenFStringL( iUaProf->Des() );
       
   229                 CleanupClosePushL( tempString );
       
   230                 RStringF tempString2 = strPool.OpenFStringL( KXProfile );
       
   231                 CleanupClosePushL( tempString2 );
       
   232                 iSessionHeaders.SetFieldL( tempString2, tempString );
       
   233                 CleanupStack::PopAndDestroy( &tempString2 );
       
   234                 CleanupStack::PopAndDestroy( &tempString );
       
   235                 }
       
   236             }
       
   237 
       
   238         // Accept headers moved to transaction as global filter overrides
       
   239         // session headers
       
   240 
       
   241         // HTTP session, no need for separate connect procedure
       
   242         iConnected = ETrue;
       
   243         // We may or may not get
       
   244         iHTTPSession.SetSessionEventCallback( this );
       
   245         aStatus = KRequestPending;
       
   246         User::RequestComplete( iRequestStatus, KErrNone );
       
   247         }
       
   248     }
       
   249 
       
   250 // ---------------------------------------------------------
       
   251 // CMmsSession::SendMessageL
       
   252 // ---------------------------------------------------------
       
   253 //
       
   254 EXPORT_C void CMmsSession::SendMessageL( 
       
   255     const TDesC& aUri,
       
   256     CBufFlat& aMessageBuffer,                            
       
   257     MMmsCodecDataSupplier&  aDataSupplier,
       
   258     MMmsCodecDataSink&      aDataSink,
       
   259     TRequestStatus& aStatus )
       
   260     {
       
   261     LOG( _L("CMmsSession::SendMessageL ") );
       
   262     __ASSERT_DEBUG( iSessionStatus == ESessionIdle, gPanic(EMmsAlreadyBusy) );
       
   263   
       
   264     TInt method = HTTP::EPOST; 
       
   265    
       
   266     iDataSupplier = &aDataSupplier;
       
   267     iDataSink = &aDataSink;
       
   268     iRequestStatus = &aStatus;
       
   269 
       
   270     // Check if the buffer is empty
       
   271 
       
   272     if ( aMessageBuffer.Size() == 0 )
       
   273         {
       
   274         aStatus = KRequestPending;
       
   275         User::RequestComplete( iRequestStatus, KMmsErrorBufferEmpty );
       
   276         }
       
   277 
       
   278     // Check if we are connected
       
   279     
       
   280     else if ( !iConnected )
       
   281         {        
       
   282         aStatus = KRequestPending;
       
   283         User::RequestComplete( iRequestStatus, KMmsErrorSessionNotOpen );
       
   284         }
       
   285        
       
   286     else
       
   287         {
       
   288         // Start the sending procedures
       
   289        
       
   290         if ( !iTransaction )
       
   291             {
       
   292             iTransaction = CMmsTransaction::NewL();
       
   293             }
       
   294 
       
   295         iTransaction->ExecuteL(
       
   296             iHTTPSession,
       
   297             *iTransferControl,
       
   298             aUri,
       
   299             method,
       
   300             aMessageBuffer,
       
   301             iTransactionTimeout,
       
   302             iMaxReceiveSize,
       
   303             0, // "expected receive size" not needed for sending
       
   304             *iDataSupplier,
       
   305             *iDataSink,
       
   306             iStatus );
       
   307         
       
   308         aStatus = KRequestPending;
       
   309         
       
   310         iSessionStatus = ESessionSending;
       
   311 
       
   312         SetActive();
       
   313         }
       
   314     }
       
   315 
       
   316 // ---------------------------------------------------------
       
   317 // CMmsSession::FetchMessageL
       
   318 // ---------------------------------------------------------
       
   319 //
       
   320 EXPORT_C void CMmsSession::FetchMessageL(
       
   321     const TDesC& aUri,
       
   322     CBufFlat& aMessageBuffer,
       
   323     TInt32 aExpectedReceiveSize,
       
   324     MMmsCodecDataSupplier&  aDataSupplier,
       
   325     MMmsCodecDataSink&      aDataSink,
       
   326     TRequestStatus& aStatus )
       
   327     {
       
   328     LOG( _L("CMmsSession: FetchMessageL ") );
       
   329     __ASSERT_DEBUG( iSessionStatus == ESessionIdle, gPanic(EMmsAlreadyBusy) );
       
   330 
       
   331     TInt method = HTTP::EGET; 
       
   332     
       
   333     iDataSupplier = &aDataSupplier;
       
   334     iDataSink = &aDataSink;
       
   335     iRequestStatus = &aStatus;
       
   336 
       
   337     // Check if we are connected or not.
       
   338     if ( !iConnected )
       
   339         {  
       
   340         aStatus = KRequestPending;
       
   341         User::RequestComplete( iRequestStatus, KMmsErrorSessionNotOpen );
       
   342         }
       
   343     else
       
   344         {
       
   345         // Start the fetching procedures
       
   346         if ( !iTransaction )
       
   347             {
       
   348             iTransaction = CMmsTransaction::NewL();
       
   349             }
       
   350 
       
   351         iTransaction->ExecuteL(
       
   352             iHTTPSession,
       
   353             *iTransferControl,
       
   354             aUri,
       
   355             method,
       
   356             aMessageBuffer,
       
   357             iTransactionTimeout,
       
   358             iMaxReceiveSize,
       
   359             aExpectedReceiveSize,
       
   360             *iDataSupplier,
       
   361             *iDataSink,
       
   362             iStatus );
       
   363         
       
   364         aStatus = KRequestPending;
       
   365         iSessionStatus = ESessionFetching;
       
   366         SetActive();
       
   367         }
       
   368     }
       
   369 
       
   370 // ---------------------------------------------------------
       
   371 // CMmsSession::RunL
       
   372 // ---------------------------------------------------------
       
   373 //
       
   374 void CMmsSession::RunL()
       
   375     {
       
   376     // If WAP stack has terminated, we cannot continue
       
   377     if ( iStatus.Int() == KErrServerTerminated )
       
   378         {
       
   379         iSessionStatus = ESessionIdle;
       
   380         iConnected = EFalse;
       
   381 
       
   382         LOG2( _L("CMmsSession::RunL: Completing with %d"), iStatus.Int() );
       
   383         User::RequestComplete( iRequestStatus, iStatus.Int() );
       
   384         return;
       
   385         }
       
   386     
       
   387     switch ( iSessionStatus )
       
   388         {
       
   389        
       
   390         case ESessionSending:          
       
   391         case ESessionFetching:
       
   392             if ( iStatus == KErrDisconnected )
       
   393                 {
       
   394                 iConnected = EFalse;
       
   395                 // Store the error returned by connect operation to be further returned
       
   396                 // to server mtm after resources are freed 
       
   397                 iError = iStatus.Int();
       
   398                 }
       
   399             break;
       
   400                
       
   401         case ESessionIdle:    
       
   402         default:
       
   403             // We should not get here
       
   404             LOG( _L("CMmsSession::RunL: Illegal status") );
       
   405             iStatus = KErrUnknown;
       
   406             break;
       
   407         }
       
   408     iSessionStatus = ESessionIdle;
       
   409     LOG2( _L("CMmsSession::RunL: Completing with %d"), iStatus.Int() );
       
   410     User::RequestComplete( iRequestStatus, iStatus.Int() );
       
   411     }
       
   412 
       
   413 // ---------------------------------------------------------
       
   414 // CMmsSession::DoCancel
       
   415 // ---------------------------------------------------------
       
   416 //
       
   417 void CMmsSession::DoCancel()
       
   418     {
       
   419     // Cancel whatever is being processed
       
   420     switch( iSessionStatus )
       
   421         {
       
   422         case ESessionSending:
       
   423         case ESessionFetching:
       
   424             iTransaction->Cancel();
       
   425             iSessionStatus = ESessionIdle;                  
       
   426             break;
       
   427         case ESessionIdle:
       
   428             // server has terminated if we get here - nothing to do.
       
   429             break;
       
   430         default:
       
   431             // Severe error if here
       
   432             LOG( _L("CMmsSession::DoCancel: Illegal status") );
       
   433             iStatus = KErrUnknown;
       
   434             break;
       
   435         }
       
   436     // Complete caller with cancel status
       
   437     User::RequestComplete( iRequestStatus, KErrCancel );
       
   438     }
       
   439 
       
   440 // ---------------------------------------------------------
       
   441 // CMmsSession::SetFixedUserAgentL
       
   442 //
       
   443 // ---------------------------------------------------------
       
   444 //
       
   445 void CMmsSession::SetFixedUserAgentL()
       
   446     {
       
   447     LOG( _L("CMmsSession::SetFixedUserAgentL") );
       
   448     // Use hardcoded UA information
       
   449     // Note: this is for testing purposes if uaprof filter keeps failing
       
   450     if ( !iUserAgent || iUserAgent->Length() == 0 )
       
   451         {
       
   452         // static useragent string
       
   453         if ( iUserAgent )
       
   454             {
       
   455             delete iUserAgent;
       
   456             iUserAgent = NULL;
       
   457             }
       
   458         iUserAgent = HBufC8::NewL( sizeof( KMmsDefaultUserAgent ) );
       
   459         iUserAgent->Des().Copy( KMmsDefaultUserAgent );
       
   460         }
       
   461     }
       
   462 
       
   463 // ---------------------------------------------------------
       
   464 // CMmsSession::SetHeaderL
       
   465 //
       
   466 // ---------------------------------------------------------
       
   467 //
       
   468 void CMmsSession::SetHeaderL( RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue )
       
   469     {
       
   470     RStringF valStr = iHTTPSession.StringPool().OpenFStringL( aHdrValue );
       
   471     THTTPHdrVal val( valStr );
       
   472     CleanupClosePushL( valStr );
       
   473     aHeaders.SetFieldL(
       
   474         iHTTPSession.StringPool().StringF( aHdrField, RHTTPSession::GetTable() ), val );
       
   475     CleanupStack::PopAndDestroy( &valStr );
       
   476     }
       
   477 
       
   478 // ---------------------------------------------------------
       
   479 // CMmsSession::MHFSessionRunL
       
   480 //
       
   481 // ---------------------------------------------------------
       
   482 //
       
   483 void CMmsSession::MHFSessionRunL( const THTTPSessionEvent& aEvent )
       
   484     {
       
   485     // We should not get events here.
       
   486     LOG2( _L("CMmsSession::MHFSessionRunL event %d"), aEvent.iStatus );
       
   487     iHTTPEvent = aEvent;
       
   488     }
       
   489         
       
   490 // ---------------------------------------------------------
       
   491 // CMmsSession::MHFSessionRunError
       
   492 //
       
   493 // ---------------------------------------------------------
       
   494 //
       
   495 TInt CMmsSession::MHFSessionRunError(
       
   496     TInt aError,
       
   497     const THTTPSessionEvent& aEvent )
       
   498     {
       
   499     LOG2( _L("CMmsSession::MHFSessionRunError %d"), aError );
       
   500     iHTTPEvent = aEvent;
       
   501     iError = aError;
       
   502     return KErrNone;
       
   503     }
       
   504 
       
   505 // ================= OTHER EXPORTED FUNCTIONS ==============
       
   506 
       
   507 //  End of File  
       
   508