--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/mmcesrv/mmceserver/src/mcereliablesender.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,345 @@
+/*
+* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+
+#include <e32base.h>
+#include <e32cmn.h>
+#include <siprackheader.h>
+#include <sipconnection.h>
+#include <sipresponseelements.h>
+#include <siprequestelements.h>
+#include <sipcseqheader.h>
+#include <siprseqheader.h>
+#include <centralrepository.h>
+#include <sipsdkcrkeys.h>
+#include <stringpool.h>
+#include "mcesip.h"
+#include "mcesrvlogs.h"
+#include "mcereliableobserver.h"
+#include "mcereliablesender.h"
+#include "mceeventstatebase.h"
+
+// CONSTANTS
+const TInt KMaxTransTimeOut = 64;
+const TUint KTransInterval = 2;
+
+
+// -----------------------------------------------------------------------------
+// CMCEReliableSender::NewL ;
+// Two-phased constructor. ;
+// -----------------------------------------------------------------------------
+//
+CMceReliableSender* CMceReliableSender::NewL( MMceReliableObserver& aObserver )
+ {
+ CMceReliableSender* self = new( ELeave ) CMceReliableSender( aObserver );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceReliableSender::CMceReliableSender
+// Constructor
+// -----------------------------------------------------------------------------
+//
+CMceReliableSender::CMceReliableSender( MMceReliableObserver& aObserver )
+: iObserver( &aObserver )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CMceReliableSender::~CMceReliableSender()
+ {
+ delete iDTimer;
+ delete iResponseElements;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceReliableSender::ConstructL
+// Symbian 2nd phase constructor.
+// -----------------------------------------------------------------------------
+//
+void CMceReliableSender::ConstructL()
+ {
+ const TUint KMaxRSec = 0x7fffffff;
+ const TUint KMinRSec = 1;
+ TInt timerT1;
+ CRepository* repository = CRepository::NewLC( KCRUidSIP );
+ User::LeaveIfError( repository->Get( KSIPTransactionTimerT1, timerT1 ));
+ CleanupStack::PopAndDestroy( repository );
+
+ iT1 = timerT1;
+
+ iRetransTimer = 1;
+ iTotaltime = 0;
+
+ iSequenceNumber = MceSip::Random( KMinRSec, KMaxRSec );
+ iTransactionMatched = EFalse;
+ iTransactionStatus = EFalse; // No Pending transaction Yet
+ iTransTimeoutFlag = EFalse;
+
+ // Create the timer entry
+ iDTimer = CDeltaTimer::NewL( CActive::EPriorityStandard );
+
+ TCallBack cb( TimerExpire, this );
+ iDeltaEntry.Set( cb );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceReliableSender::Rseq
+// -----------------------------------------------------------------------------
+//
+TUint CMceReliableSender::Rseq( CSIPServerTransaction& aTransaction )
+ {
+ TInt tInProcess = 0;
+ if ( iTransactionStatus )
+ {
+ MCESRV_DEBUG( "CMceReliableSender::Rseq: Transsaction in Process");
+ return tInProcess;
+ }
+ else if( &aTransaction == iServerTransaction )
+ {
+ iSequenceNumber = iSequenceNumber + 1;
+ return iSequenceNumber;
+ }
+ else
+ {
+ return iSequenceNumber;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMceReliableSender::SendResponseL
+// -----------------------------------------------------------------------------
+//
+void CMceReliableSender::SendResponseL( CSIPServerTransaction& aTransaction,
+ CSIPResponseElements* aElements )
+ {
+ if ( iTransactionStatus )
+ {
+ User::Leave( KErrInUse );
+ }
+
+ iServerTransaction = &aTransaction;
+ CSIPResponseElements* xResponses;
+
+ // Set the Transaction in progree Flag
+
+ iTransactionStatus = ETrue;
+ TUint queueTimer = 0;
+
+ xResponses = ResponseCloneL( *aElements );
+ CleanupStack::PushL( xResponses );
+ iServerTransaction->SendResponseL( xResponses );
+ MCESRV_DEBUG_DVALUE(
+ "CMceReliableSender::SendResponseL - timer value:", iRetransTimer );
+ CleanupStack::Pop( xResponses );
+ iResponseElements = aElements;
+
+ queueTimer = iRetransTimer * iT1 *KConversionMilliToMicro;
+ iDTimer->Queue( queueTimer, iDeltaEntry );
+ iRetransTimer = iRetransTimer * KTransInterval;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceReliableSender::ResponseCloneL
+// -----------------------------------------------------------------------------
+//
+CSIPResponseElements* CMceReliableSender::ResponseCloneL(
+ CSIPResponseElements& aElements )
+ {
+ CSIPResponseElements* cElements =
+ CSIPResponseElements::NewLC( aElements.StatusCode(),
+ aElements.ReasonPhrase() );
+ // Creating messge Elements
+ CSIPMessageElements& msgElements = aElements.MessageElements();
+ CSIPMessageElements& cloneMsgElements = cElements->MessageElements();
+
+
+ // Copying Contents
+ if ( msgElements.Content().Length() )
+ {
+ const CSIPContentTypeHeader* contentType = msgElements.ContentType();
+ CSIPContentTypeHeader* cloneContentType =
+ static_cast<CSIPContentTypeHeader *>( contentType->CloneL() );
+ CleanupStack::PushL( cloneContentType );
+
+ HBufC8* contentBuffer = HBufC8::NewLC( msgElements.Content().Length() );
+ TPtr8 contentsPtr = contentBuffer->Des();
+ contentsPtr.Append( msgElements.Content() );
+
+ cloneMsgElements.SetContentL( contentBuffer, cloneContentType );
+ CleanupStack::Pop( contentBuffer );
+ CleanupStack::Pop( cloneContentType );
+ }
+
+ // User Headers
+ const RPointerArray<CSIPHeaderBase>& headers = msgElements.UserHeaders();
+ if ( headers.Count() )
+ {
+ RPointerArray<CSIPHeaderBase> tmpHeaders;
+ CSIPHeaderBase::PushLC( &tmpHeaders );
+ for(TInt i = 0; i < headers.Count(); i++)
+ {
+ CSIPHeaderBase* userHeader = headers[i]->CloneL();
+ CleanupStack::PushL( userHeader );
+ tmpHeaders.AppendL( userHeader );
+
+ CleanupStack::Pop( userHeader );
+ }
+
+ cloneMsgElements.SetUserHeadersL( tmpHeaders );
+ CleanupStack::Pop( &tmpHeaders );
+ }
+ CleanupStack::Pop( cElements );
+ return cElements;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceReliableSender::PrackReceived
+// -----------------------------------------------------------------------------
+//
+TBool CMceReliableSender::PrackReceived( CSIPServerTransaction& aPrack )
+ {
+ TBool transactionMatched = EFalse;
+ RStringF rackHeaderStr = SIPStrings::StringF( SipStrConsts::ERAckHeader );
+ RStringF rseqStr = SIPStrings::StringF( SipStrConsts::ERSeqHeader );
+
+ const CSIPRequestElements* reqElements = aPrack.RequestElements();
+ CSIPHeaderBase* headerBase =
+ MceSip::FindHeader( reqElements->MessageElements(), rackHeaderStr );
+ const CSIPRAckHeader* rackHeader = static_cast<CSIPRAckHeader *>( headerBase );
+
+ const CSIPRequestElements* sReqElements = iServerTransaction->RequestElements();
+ const CSIPCSeqHeader* cseqHeader = sReqElements->CSeqHeader();
+
+ CSIPHeaderBase* headerBase3 =
+ MceSip::FindHeader( iResponseElements->MessageElements(), rseqStr );
+ const CSIPRSeqHeader* rseqHeader = static_cast<CSIPRSeqHeader *> ( headerBase3 );
+
+
+ if ( ( rackHeader && cseqHeader && rseqHeader ) &&
+ ( rackHeader->CSeqNum() == cseqHeader->Seq() ) &&
+ ( rackHeader->Method() == sReqElements->Method() ) &&
+ ( rackHeader->Seq() == rseqHeader->Value()) )
+
+ {
+ MCESRV_DEBUG( "CMceReliableSender::PrackReceived: prack matched");
+ transactionMatched = ETrue;
+ }
+
+ if ( transactionMatched )
+ {
+ // Cease the Re-Transmission of Reliable Response
+
+ iDTimer->Remove( iDeltaEntry );
+ iTransactionMatched = ETrue;
+ iTransactionStatus = EFalse;
+
+ return ETrue;
+ }
+
+ MCESRV_DEBUG( "CMceReliableSender::PrackReceived: no prack matched");
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceReliableSender::TimerExpire
+// -----------------------------------------------------------------------------
+//
+TInt CMceReliableSender::TimerExpire( TAny *aSelf )
+ {
+ TInt error;
+ TUint queueTimer;
+ TUint tmpTotalTime;
+
+ CMceReliableSender* me = static_cast<CMceReliableSender *>( aSelf );
+
+ if ( !me->iTransTimeoutFlag )
+ {
+ TRAP(error, me->CloneAndSendResponseL());
+
+ if ( error )
+ {
+ me->iObserver->ReliableFailed( *me->iServerTransaction, error );
+ }
+ }
+
+ else
+ {
+ me->TimeOut( me->iServerTransaction );
+ }
+
+ if ( me->iRetransTimer <= KMaxTransTimeOut && me->iTransactionStatus )
+ {
+ tmpTotalTime = me->iTotaltime;
+ me->iTotaltime = me->iTotaltime + me->iRetransTimer; // acumlated time
+
+ if ( me->iTotaltime <= KMaxTransTimeOut )
+ {
+ queueTimer = me->iRetransTimer * me->iT1 * KConversionMilliToMicro;
+ }
+ else
+ {
+ me->iTotaltime = tmpTotalTime;
+ queueTimer = ( KMaxTransTimeOut - me->iTotaltime ) * me->iT1 * KConversionMilliToMicro;
+ me->iTransTimeoutFlag = ETrue;
+ }
+
+ me->iDTimer->Queue( queueTimer, me->iDeltaEntry );
+ me->iRetransTimer = me->iRetransTimer * KTransInterval;
+ MCESRV_DEBUG_DVALUE(
+ "CMceReliableSender::TimerExpire: timer added", me->iRetransTimer );
+
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceReliableSender::CloneAndSendResponseL
+// -----------------------------------------------------------------------------
+//
+void CMceReliableSender::CloneAndSendResponseL()
+ {
+ CSIPResponseElements* oResponses;
+ oResponses = ResponseCloneL( *iResponseElements );
+ MCESRV_DEBUG(
+ "CMceReliableSender::CloneAndSendResponseL: responseElements cloned");
+ CleanupStack::PushL( oResponses );
+ iServerTransaction->SendResponseL( oResponses );
+ MCESRV_DEBUG(
+ "CMceReliableSender::CloneAndSendResponseL: reliableResponse sent");
+ CleanupStack::Pop( oResponses );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceReliableSender::TimeOut
+// -----------------------------------------------------------------------------
+//
+void CMceReliableSender::TimeOut( CSIPServerTransaction* aTransaction )
+ {
+ iObserver->NoPrackReceived( *aTransaction );
+ }
+
+// End of File