multimediacommsengine/mmcesrv/mmceserver/src/mcereliablesender.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 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 #include <e32base.h>
       
    22 #include <e32cmn.h>
       
    23 #include <siprackheader.h>
       
    24 #include <sipconnection.h>
       
    25 #include <sipresponseelements.h>
       
    26 #include <siprequestelements.h>
       
    27 #include <sipcseqheader.h> 
       
    28 #include <siprseqheader.h> 
       
    29 #include <centralrepository.h>
       
    30 #include <sipsdkcrkeys.h>
       
    31 #include <stringpool.h>
       
    32 #include "mcesip.h"
       
    33 #include "mcesrvlogs.h"
       
    34 #include "mcereliableobserver.h"
       
    35 #include "mcereliablesender.h"
       
    36 #include "mceeventstatebase.h"
       
    37 
       
    38 // CONSTANTS
       
    39 const TInt KMaxTransTimeOut = 64;
       
    40 const TUint KTransInterval = 2;
       
    41 
       
    42 
       
    43 // -----------------------------------------------------------------------------
       
    44 // CMCEReliableSender::NewL ;
       
    45 // Two-phased constructor. ;
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 CMceReliableSender* CMceReliableSender::NewL( MMceReliableObserver& aObserver )
       
    49     {
       
    50 	CMceReliableSender* self = new( ELeave ) CMceReliableSender( aObserver );
       
    51 	CleanupStack::PushL( self );
       
    52 	self->ConstructL();
       
    53 	CleanupStack::Pop( self );
       
    54 	return self;
       
    55     }
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 // CMceReliableSender::CMceReliableSender
       
    59 // Constructor
       
    60 // -----------------------------------------------------------------------------
       
    61 //
       
    62 CMceReliableSender::CMceReliableSender( MMceReliableObserver& aObserver )
       
    63 : iObserver( &aObserver )
       
    64     {
       
    65     }
       
    66 
       
    67 // -----------------------------------------------------------------------------
       
    68 // Destructor
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 CMceReliableSender::~CMceReliableSender()
       
    72     {
       
    73 	delete iDTimer;
       
    74 	delete iResponseElements;
       
    75     }
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // CMceReliableSender::ConstructL
       
    79 // Symbian 2nd phase constructor.
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 void CMceReliableSender::ConstructL()
       
    83     {
       
    84 	const TUint	KMaxRSec = 0x7fffffff;
       
    85     const TUint	KMinRSec = 1;
       
    86 	TInt timerT1;
       
    87 	CRepository* repository = CRepository::NewLC( KCRUidSIP );
       
    88 	User::LeaveIfError( repository->Get( KSIPTransactionTimerT1, timerT1 ));
       
    89 	CleanupStack::PopAndDestroy( repository );
       
    90     
       
    91     iT1 = timerT1;
       
    92      
       
    93     iRetransTimer = 1;
       
    94     iTotaltime = 0;
       
    95     
       
    96     iSequenceNumber = MceSip::Random( KMinRSec, KMaxRSec );
       
    97 	iTransactionMatched = EFalse;
       
    98 	iTransactionStatus = EFalse;	// No Pending transaction Yet 
       
    99 	iTransTimeoutFlag = EFalse;
       
   100 	
       
   101     // Create the timer entry 
       
   102 	iDTimer = CDeltaTimer::NewL( CActive::EPriorityStandard );
       
   103 		
       
   104 	TCallBack cb( TimerExpire, this );
       
   105 	iDeltaEntry.Set( cb );
       
   106     }
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // CMceReliableSender::Rseq
       
   110 // -----------------------------------------------------------------------------
       
   111 //
       
   112 TUint CMceReliableSender::Rseq( CSIPServerTransaction& aTransaction )
       
   113     {
       
   114     TInt tInProcess = 0;
       
   115 	if  ( iTransactionStatus )
       
   116 	    {
       
   117 	    MCESRV_DEBUG( "CMceReliableSender::Rseq: Transsaction in Process");
       
   118 	    return tInProcess;
       
   119 	    }
       
   120    	else if( &aTransaction == iServerTransaction )
       
   121 	    {
       
   122 		iSequenceNumber = iSequenceNumber + 1;
       
   123 		return iSequenceNumber;
       
   124 	    }
       
   125 	else
       
   126 	    {
       
   127 	    return iSequenceNumber;
       
   128 	    }
       
   129     }
       
   130 
       
   131 // -----------------------------------------------------------------------------
       
   132 // CMceReliableSender::SendResponseL
       
   133 // -----------------------------------------------------------------------------
       
   134 //
       
   135 void CMceReliableSender::SendResponseL( CSIPServerTransaction& aTransaction, 
       
   136                                         CSIPResponseElements* aElements )
       
   137     {
       
   138 	if  ( iTransactionStatus )
       
   139 	    {
       
   140         User::Leave( KErrInUse );
       
   141 	    }
       
   142 
       
   143     iServerTransaction = &aTransaction;
       
   144 	CSIPResponseElements* xResponses;
       
   145 
       
   146 	// Set the Transaction in progree Flag  
       
   147 	
       
   148 	iTransactionStatus = ETrue;
       
   149     TUint queueTimer = 0;
       
   150          	
       
   151 	xResponses = ResponseCloneL( *aElements );
       
   152 	CleanupStack::PushL( xResponses );
       
   153     iServerTransaction->SendResponseL( xResponses );
       
   154     MCESRV_DEBUG_DVALUE( 
       
   155         "CMceReliableSender::SendResponseL - timer value:", iRetransTimer );
       
   156     CleanupStack::Pop( xResponses );
       
   157    	iResponseElements = aElements;  
       
   158    	
       
   159    	queueTimer = iRetransTimer * iT1 *KConversionMilliToMicro;
       
   160 	iDTimer->Queue( queueTimer, iDeltaEntry );
       
   161     iRetransTimer = iRetransTimer * KTransInterval;    
       
   162     }
       
   163 
       
   164 // -----------------------------------------------------------------------------
       
   165 // CMceReliableSender::ResponseCloneL
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 CSIPResponseElements* CMceReliableSender::ResponseCloneL( 
       
   169                                             CSIPResponseElements& aElements )
       
   170     {
       
   171 	CSIPResponseElements* cElements = 
       
   172 	    CSIPResponseElements::NewLC( aElements.StatusCode(), 
       
   173 	                                 aElements.ReasonPhrase() );
       
   174 	// Creating messge Elements
       
   175 	CSIPMessageElements& msgElements = aElements.MessageElements();
       
   176 	CSIPMessageElements& cloneMsgElements = cElements->MessageElements();
       
   177 
       
   178 
       
   179 	// Copying Contents 
       
   180 	if  ( msgElements.Content().Length() )
       
   181 	    {
       
   182     	const CSIPContentTypeHeader* contentType = msgElements.ContentType();
       
   183 		CSIPContentTypeHeader* cloneContentType = 
       
   184 		    static_cast<CSIPContentTypeHeader *>( contentType->CloneL() );
       
   185 		CleanupStack::PushL( cloneContentType );
       
   186 
       
   187 		HBufC8* contentBuffer = HBufC8::NewLC( msgElements.Content().Length() );
       
   188 		TPtr8 contentsPtr = contentBuffer->Des();
       
   189 		contentsPtr.Append( msgElements.Content() );
       
   190     
       
   191 		cloneMsgElements.SetContentL( contentBuffer, cloneContentType );
       
   192 		CleanupStack::Pop( contentBuffer );
       
   193 		CleanupStack::Pop( cloneContentType );
       
   194     	}
       
   195 
       
   196   	// User Headers
       
   197 	const RPointerArray<CSIPHeaderBase>& headers = msgElements.UserHeaders();
       
   198 	if  ( headers.Count() )
       
   199 	    {
       
   200 		RPointerArray<CSIPHeaderBase> tmpHeaders;
       
   201 		CSIPHeaderBase::PushLC( &tmpHeaders );
       
   202 		for(TInt i = 0; i < headers.Count(); i++)
       
   203 		    {
       
   204 			CSIPHeaderBase* userHeader = headers[i]->CloneL();
       
   205 			CleanupStack::PushL( userHeader );
       
   206 			tmpHeaders.AppendL( userHeader );
       
   207 			
       
   208 			CleanupStack::Pop( userHeader );
       
   209 		    }
       
   210 
       
   211 		cloneMsgElements.SetUserHeadersL( tmpHeaders );
       
   212 		CleanupStack::Pop( &tmpHeaders );
       
   213 	    }
       
   214     CleanupStack::Pop( cElements );
       
   215 	return cElements;
       
   216     }
       
   217 
       
   218 // -----------------------------------------------------------------------------
       
   219 // CMceReliableSender::PrackReceived
       
   220 // -----------------------------------------------------------------------------
       
   221 //
       
   222 TBool CMceReliableSender::PrackReceived( CSIPServerTransaction& aPrack )
       
   223     {
       
   224 	TBool transactionMatched = EFalse;
       
   225 	RStringF rackHeaderStr = SIPStrings::StringF( SipStrConsts::ERAckHeader );
       
   226 	RStringF rseqStr = SIPStrings::StringF( SipStrConsts::ERSeqHeader );
       
   227 			
       
   228 	const CSIPRequestElements* reqElements = aPrack.RequestElements();
       
   229 	CSIPHeaderBase*	headerBase = 
       
   230 	    MceSip::FindHeader( reqElements->MessageElements(), rackHeaderStr );
       
   231 	const CSIPRAckHeader* rackHeader = static_cast<CSIPRAckHeader *>( headerBase );
       
   232 	
       
   233 	const CSIPRequestElements* sReqElements = iServerTransaction->RequestElements();    
       
   234     const CSIPCSeqHeader* cseqHeader = sReqElements->CSeqHeader();
       
   235     
       
   236     CSIPHeaderBase* headerBase3 =  
       
   237         MceSip::FindHeader( iResponseElements->MessageElements(), rseqStr );
       
   238     const CSIPRSeqHeader* rseqHeader = static_cast<CSIPRSeqHeader *> ( headerBase3 );
       
   239   
       
   240       
       
   241    	if  ( ( rackHeader && cseqHeader && rseqHeader ) && 
       
   242    	    ( rackHeader->CSeqNum() == cseqHeader->Seq() ) &&
       
   243 	    ( rackHeader->Method() == sReqElements->Method() ) && 
       
   244 	    ( rackHeader->Seq() == rseqHeader->Value()) )
       
   245 
       
   246 	    {
       
   247 	    MCESRV_DEBUG( "CMceReliableSender::PrackReceived: prack matched");
       
   248 	    transactionMatched = ETrue;
       
   249         }
       
   250     
       
   251     if  ( transactionMatched )
       
   252 	    {
       
   253         // Cease the Re-Transmission of Reliable Response 
       
   254                 
       
   255         iDTimer->Remove( iDeltaEntry ); 
       
   256         iTransactionMatched = ETrue;
       
   257         iTransactionStatus = EFalse;    
       
   258    
       
   259       	return ETrue;
       
   260   	    }
       
   261 
       
   262     MCESRV_DEBUG( "CMceReliableSender::PrackReceived: no prack matched");
       
   263     return EFalse;
       
   264     }
       
   265 
       
   266 // -----------------------------------------------------------------------------
       
   267 // CMceReliableSender::TimerExpire
       
   268 // -----------------------------------------------------------------------------
       
   269 //
       
   270 TInt CMceReliableSender::TimerExpire( TAny *aSelf )
       
   271     { 
       
   272     TInt error;
       
   273     TUint queueTimer;
       
   274     TUint tmpTotalTime;
       
   275                
       
   276     CMceReliableSender* me = static_cast<CMceReliableSender *>( aSelf );
       
   277             
       
   278     if ( !me->iTransTimeoutFlag )        
       
   279         {
       
   280         TRAP(error, me->CloneAndSendResponseL());
       
   281   
       
   282         if ( error )
       
   283             {
       
   284             me->iObserver->ReliableFailed( *me->iServerTransaction, error );
       
   285             }
       
   286         }
       
   287         
       
   288     else 
       
   289         {
       
   290         me->TimeOut( me->iServerTransaction );    
       
   291         }
       
   292 		
       
   293 	if ( me->iRetransTimer <= KMaxTransTimeOut && me->iTransactionStatus )
       
   294 		{
       
   295 	    tmpTotalTime = me->iTotaltime;
       
   296 		me->iTotaltime = me->iTotaltime + me->iRetransTimer; // acumlated time
       
   297 			
       
   298 		if ( me->iTotaltime <= KMaxTransTimeOut )
       
   299 		    {
       
   300 		    queueTimer = me->iRetransTimer * me->iT1 * KConversionMilliToMicro;
       
   301 		    }
       
   302         else 
       
   303            {
       
   304             me->iTotaltime = tmpTotalTime;
       
   305             queueTimer = ( KMaxTransTimeOut - me->iTotaltime ) * me->iT1 * KConversionMilliToMicro;
       
   306             me->iTransTimeoutFlag = ETrue;
       
   307             }
       
   308             
       
   309         me->iDTimer->Queue( queueTimer, me->iDeltaEntry );
       
   310         me->iRetransTimer = me->iRetransTimer * KTransInterval;
       
   311         MCESRV_DEBUG_DVALUE( 
       
   312 		"CMceReliableSender::TimerExpire: timer added", me->iRetransTimer );
       
   313           
       
   314 		}
       
   315 
       
   316 	return KErrNone;
       
   317     }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CMceReliableSender::CloneAndSendResponseL 
       
   321 // -----------------------------------------------------------------------------
       
   322 //
       
   323 void CMceReliableSender::CloneAndSendResponseL()
       
   324     {
       
   325     CSIPResponseElements* oResponses;
       
   326     oResponses = ResponseCloneL( *iResponseElements );
       
   327     MCESRV_DEBUG( 
       
   328         "CMceReliableSender::CloneAndSendResponseL: responseElements cloned");
       
   329     CleanupStack::PushL( oResponses );
       
   330     iServerTransaction->SendResponseL( oResponses );
       
   331     MCESRV_DEBUG( 
       
   332         "CMceReliableSender::CloneAndSendResponseL: reliableResponse sent");
       
   333     CleanupStack::Pop( oResponses );
       
   334     }
       
   335 
       
   336 // -----------------------------------------------------------------------------
       
   337 // CMceReliableSender::TimeOut
       
   338 // -----------------------------------------------------------------------------
       
   339 //
       
   340 void CMceReliableSender::TimeOut( CSIPServerTransaction* aTransaction )
       
   341     {  
       
   342 	iObserver->NoPrackReceived( *aTransaction ); 
       
   343 	}
       
   344 
       
   345 // End of File