--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Refreshes/src/CSipRefreshMgr.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,593 @@
+// Copyright (c) 2006-2009 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:
+// Name : CSipRefreshMgr.cpp
+// Part of : SIPRefreshes
+// Version : SIP/5.0
+//
+
+
+
+#include "CSipRefreshMgr.h"
+#include "MTransactionUser.h"
+#include "CSipRegisterRefresh.h"
+#include "CSipAnyRefresh.h"
+#include "MTransactionHeaders.h"
+#include "TSIPTransportParams.h"
+#include "siprequest.h"
+#include "sipresponse.h"
+#include "sipfromheader.h"
+#include "sipcontactheader.h"
+#include "sipexpiresheader.h"
+#include "sipcseqheader.h"
+#include "siptoheader.h"
+#include "SipLogs.h"
+#include "DeleteMgr.h"
+#include "SipAssert.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::NewL
+// -----------------------------------------------------------------------------
+//
+CSipRefreshMgr* CSipRefreshMgr::NewL (MTransactionUser& aTU,
+ MTimerManager& aTimerMgr,
+ CSIPSec& aSIPSec)
+ {
+ CSipRefreshMgr* self = new(ELeave)CSipRefreshMgr(aTU,aTimerMgr,aSIPSec);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::CSipRefreshMgr
+// -----------------------------------------------------------------------------
+//
+CSipRefreshMgr::CSipRefreshMgr (
+ MTransactionUser& aTU,
+ MTimerManager& aTimerMgr,
+ CSIPSec& aSIPSec)
+ : iTU(aTU),
+ iTimerMgr(aTimerMgr),
+ iSIPSec(aSIPSec),
+ iNextRefreshId (KMinRefreshId)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::ConstructL ()
+ {
+ iDeleteMgr = CDeleteMgr::NewL();
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::~CSipRefreshMgr
+// -----------------------------------------------------------------------------
+//
+CSipRefreshMgr::~CSipRefreshMgr ()
+ {
+ delete iDeleteMgr;
+ iRefreshes.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::RefreshL
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::RefreshL (TTransactionId& aTransactionId,
+ TRefreshId& aRefreshId,
+ TRegistrationId aRegistrationId,
+ CSIPRequest* aRequest,
+ MRefreshOwner* aOwner,
+ MSIPSecUser& aSIPSecUser,
+ CURIContainer& aRemoteTarget,
+ TBool aDeleteRequest,
+ TBool aPassAllResponsesToOwner)
+ {
+ __SIP_ASSERT_LEAVE (aRequest, KErrArgument);
+
+ __SIP_ASSERT_LEAVE (aRequest->Method().DesC().Length() > 0, KErrArgument);
+
+ __SIP_ASSERT_LEAVE (aRequest->From(), KErrArgument);
+
+ __SIP_ASSERT_LEAVE (aRequest->To(), KErrArgument);
+
+ __SIP_ASSERT_LEAVE (aOwner, KErrArgument);
+
+ __SIP_MESSAGE_LOG ("Refreshes", *aRequest)
+
+ CSipRefreshBase* refresh = NULL;
+
+ // method is register
+ if (aRequest->Method() == SIPStrings::StringF(SipStrConsts::ERegister))
+ {
+ refresh = CSipRegisterRefresh::NewLC(iTU,iTimerMgr,iSIPSec,*this,
+ aRegistrationId,aRequest,aOwner,
+ aSIPSecUser,aRemoteTarget);
+ }
+ else
+ {
+ refresh = CSipAnyRefresh::NewLC(iTU,iTimerMgr,iSIPSec,*this,
+ aRegistrationId,aRequest,aOwner,
+ aSIPSecUser,aRemoteTarget,
+ aPassAllResponsesToOwner);
+ }
+
+ refresh->SendL(aTransactionId, aRequest);
+
+ User::LeaveIfError(iRefreshes.Append(refresh));
+ CleanupStack::Pop(refresh);
+
+ refresh->SetRequest(aRequest,aDeleteRequest);
+ aRefreshId = refresh->Id();
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::RefreshAndGetHeadersL
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+MTransactionHeaders* CSipRefreshMgr::RefreshAndGetHeadersL (
+ TTransactionId& aTransactionId,
+ TRefreshId& aRefreshId,
+ TRegistrationId aRegistrationId,
+ CSIPRequest* aRequest,
+ MRefreshOwner* aOwner,
+ MSIPSecUser& aSIPSecUser,
+ CURIContainer& aRemoteTarget)
+ {
+ __SIP_ASSERT_LEAVE (aRequest, KErrArgument);
+
+ __SIP_ASSERT_LEAVE (aRequest->Method().DesC().Length() != 0, KErrArgument);
+
+ __SIP_ASSERT_LEAVE (aRequest->From(), KErrArgument);
+
+ __SIP_ASSERT_LEAVE (aRequest->To(), KErrArgument);
+
+ __SIP_ASSERT_LEAVE (aOwner, KErrArgument);
+
+ __SIP_MESSAGE_LOG ("Refreshes", *aRequest)
+
+ __ASSERT_ALWAYS (aRequest->Method() !=
+ SIPStrings::StringF(SipStrConsts::ERegister),
+ User::Leave(KErrNotSupported));
+
+ // Only Dialogs uses this function, so any refresh is always created
+ // with flag telling the refresh to pass all the responses up to the owner.
+ CSipRefreshBase* refresh = CSipAnyRefresh::NewLC (iTU, iTimerMgr, iSIPSec,
+ *this, aRegistrationId,
+ aRequest, aOwner,
+ aSIPSecUser,
+ aRemoteTarget, ETrue);
+
+ MTransactionHeaders* headers =
+ refresh->SendAndGetHeadersL (aTransactionId,aRequest);
+
+ TCleanupItem cleanupItem(DeleteTransactionHeaders,headers);
+ CleanupStack::PushL (cleanupItem);
+
+ User::LeaveIfError(iRefreshes.Append(refresh));
+
+ CleanupStack::Pop(1); // cleanupItem
+ CleanupStack::Pop(refresh);
+
+ refresh->SetRequest(aRequest,ETrue);
+
+ aRefreshId = refresh->Id();
+
+ return headers;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::UpdateRefreshL
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::UpdateRefreshL (TTransactionId& aTransactionId,
+ const TRefreshId& aRefreshId,
+ CSIPRequest* aRequest,
+ const MRefreshOwner* aOwner,
+ TBool aDeleteRequest)
+ {
+ __SIP_ASSERT_LEAVE (aRequest, KErrArgument);
+
+ __SIP_MESSAGE_LOG ("Refreshes", *aRequest)
+
+ CSipRefreshBase& refresh = FindRefreshL(aRefreshId,aOwner);
+
+ // increase the request CSeq number if it is none REGISTER request
+ // and if there is CSeqHeader in the request.
+ // since Registration subsystem update CSeq itself for update Request
+ if(aRequest->Method() != SIPStrings::StringF(SipStrConsts::ERegister) &&
+ aRequest->CSeq() != 0)
+ {
+ refresh.UpdateCSeqValueL(*aRequest);
+ }
+
+ refresh.UpdateRequestL(aTransactionId,aRequest);
+
+ refresh.SetRequest(aRequest,aDeleteRequest);
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::TerminateRefreshL
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::TerminateRefreshL (TTransactionId& aTransactionId,
+ const TRefreshId& aRefreshId,
+ CSIPRequest* aRequest,
+ const MRefreshOwner* aOwner,
+ TBool aDeleteRequest)
+ {
+ __SIP_ASSERT_LEAVE (aRequest, KErrArgument);
+
+ __SIP_MESSAGE_LOG ("Refreshes", *aRequest)
+
+ CSipRefreshBase& refresh = FindRefreshL(aRefreshId,aOwner);
+
+ // increase the request CSeq number if it is none REGISTER request
+ // and if there is CSeqHeader in the request.
+ // since Registration subsystem update CSeq itself for terminate Request
+ if(aRequest->Method() != SIPStrings::StringF(SipStrConsts::ERegister) &&
+ aRequest->CSeq() != 0)
+ {
+ refresh.UpdateCSeqValueL(*aRequest);
+ }
+
+ refresh.TerminateRequestL(aTransactionId,aRequest);
+
+ refresh.SetRequest(aRequest,aDeleteRequest);
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::TerminateRefresh
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+TInt CSipRefreshMgr::TerminateRefresh (const TRefreshId& aRefreshId,
+ const MRefreshOwner* aOwner)
+ {
+ TInt index = FindIndex(aRefreshId,aOwner);
+ if (index < 0 || index >= iRefreshes.Count())
+ {
+ return KErrNotFound;
+ }
+ return RemoveRefreshBy(iRefreshes[index]);
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::RemoveRefreshesFor
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+TInt CSipRefreshMgr::RemoveRefreshesFor (const MRefreshOwner* aOwner)
+ {
+ if (!aOwner)
+ {
+ return KErrNotFound;
+ }
+
+ for (TInt i=iRefreshes.Count()-1; i>=0; i--)
+ {
+ if (iRefreshes[i]->Owner() == aOwner)
+ {
+ iRefreshes[i]->StopTimer();
+ iRefreshes[i]->SetRequest(NULL,EFalse);
+ TInt err = RemoveRefreshBy (iRefreshes[i]);
+ if (err)
+ {
+ return err;
+ }
+ }
+ }
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::Request
+// From MSipRefreshMgr:
+// const CSIPRequest* CSipRefreshMgr::Request (const TRefreshId& aRefreshId) const
+// -----------------------------------------------------------------------------
+//
+CSIPRequest* CSipRefreshMgr::Request (const TRefreshId& aRefreshId)
+ {
+ if (aRefreshId == KEmptyRefreshId)
+ {
+ return NULL;
+ }
+ for (TInt i=0; i<iRefreshes.Count(); i++)
+ {
+ if (iRefreshes[i]->Id() == aRefreshId)
+ {
+ return (iRefreshes[i]->Request());
+ }
+ }
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::RemoveRefreshBy
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::SetIntervalL (const TRefreshId& aRefreshId,
+ TInt aInterval)
+ {
+ CSipRefreshBase& refresh = FindRefreshL(aRefreshId,NULL,EFalse);
+ refresh.SetIntervalL(aInterval);
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::RemoveRefreshBy
+// -----------------------------------------------------------------------------
+//
+TInt CSipRefreshMgr::IntervalL (const TRefreshId& aRefreshId)
+ {
+ CSipRefreshBase& refresh = FindRefreshL(aRefreshId,NULL,EFalse);
+ return refresh.Interval();
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::RemoveRefreshBy
+// -----------------------------------------------------------------------------
+//
+TInt CSipRefreshMgr::RemoveRefreshBy (CSipRefreshBase* aRefresh)
+ {
+ for (TInt i=0; i < iRefreshes.Count(); i++)
+ {
+ if (iRefreshes[i] == aRefresh)
+ {
+ // Transaction owner needs to be cleared so that TU will not
+ // call the refresh while it is in DeleteMgr
+ aRefresh->ClearTransactionOwner();
+ TInt err = iDeleteMgr->AddDeleteRequest(aRefresh);
+ if (err == KErrNone)
+ {
+ iRefreshes.Remove (i);
+ }
+ return err;
+ }
+ }
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::CurrentTransactionId
+// -----------------------------------------------------------------------------
+//
+TTransactionId CSipRefreshMgr::CurrentTransactionId(
+ const TRefreshId& aRefreshId) const
+ {
+ TTransactionId transactionId = KEmptyTransactionId;
+ TInt index = FindIndex(aRefreshId,NULL,EFalse);
+ if (index >= 0)
+ {
+ transactionId = iRefreshes[index]->CurrentTransactionId();
+ }
+ return transactionId;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::SIPSecUser
+// -----------------------------------------------------------------------------
+//
+const MSIPSecUser* CSipRefreshMgr::SIPSecUser(
+ const TRefreshId& aRefreshId) const
+ {
+ const MSIPSecUser* sipSecUser = NULL;
+ TInt index = FindIndex(aRefreshId,NULL,EFalse);
+ if (index >= 0)
+ {
+ sipSecUser = iRefreshes[index]->SIPSecUser();
+ }
+ return sipSecUser;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::NextRefreshId
+// -----------------------------------------------------------------------------
+//
+TRefreshId CSipRefreshMgr::NextRefreshId()
+ {
+ TRefreshId refreshId = iNextRefreshId;
+ if (iNextRefreshId == KMaxRefreshId)
+ {
+ iNextRefreshId = KMinRefreshId;
+ }
+ else
+ {
+ iNextRefreshId++;
+ }
+ return refreshId;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::FindIndex
+// -----------------------------------------------------------------------------
+//
+TInt CSipRefreshMgr::FindIndex (const TRefreshId& aRefreshId,
+ const MRefreshOwner* aOwner,
+ TBool aCheckOwner) const
+ {
+ for (TInt i=0; i < iRefreshes.Count(); i++)
+ {
+ CSipRefreshBase* refresh = iRefreshes[i];
+ if (refresh->Id() == aRefreshId)
+ {
+ if (!aCheckOwner || refresh->Owner() == aOwner)
+ {
+ return i;
+ }
+ }
+ }
+ return KErrNotFound;
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::FindRefreshL
+// -----------------------------------------------------------------------------
+//
+CSipRefreshBase& CSipRefreshMgr::FindRefreshL (const TRefreshId& aRefreshId,
+ const MRefreshOwner* aOwner,
+ TBool aCheckOwner)
+ {
+ TInt index = FindIndex(aRefreshId,aOwner,aCheckOwner);
+ if (index < 0)
+ {
+ User::Leave (KErrNotFound);
+ }
+ return *iRefreshes[index];
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::RemoveRefreshByIAPId
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::RemoveRefreshByIAPId(const TUint aIAPId)
+ {
+ for (TInt i=iRefreshes.Count() - 1; i >= 0; i--)
+ {
+ CSipRefreshBase* refresh = iRefreshes[i];
+ if (refresh->IAPId() == aIAPId)
+ {
+ iRefreshes.Remove (i);
+ delete refresh;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::ConnectionStateChangedL
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::ConnectionStateChangedL (TUint32 aIapId,
+ CSIPConnection::TState aState)
+ {
+ if (aState == CSIPConnection::EInactive ||
+ aState == CSIPConnection::EUnavailable)
+ {
+ RemoveRefreshByIAPId(aIapId);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::UpdateRemoteTargetL
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::UpdateRemoteTargetL (const MRefreshOwner* aOwner,
+ CURIContainer& aRemoteTarget)
+ {
+ __SIP_ASSERT_LEAVE (aOwner != 0, KErrArgument);
+
+ for (TInt i=iRefreshes.Count()-1; i>=0; i--)
+ {
+ if (iRefreshes[i]->Owner() == aOwner)
+ {
+ iRefreshes[i]->UpdateRemoteTargetL(aRemoteTarget);
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::UpdateHeaderL
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::UpdateHeaderL (const TRefreshId& aRefreshId,
+ const MRefreshOwner* aOwner,
+ CSIPHeaderBase* aSIPHeader)
+ {
+ TInt index = FindIndex(aRefreshId,aOwner);
+ if (index >= 0)
+ {
+ CSipRefreshBase* refresh = iRefreshes[index];
+ refresh->SetUpdatedHeader(aSIPHeader);
+ }
+ // if no refresh could found by the Id, aSIPHeader is must be deleted
+ // since the ownersip is transferred.
+ else
+ {
+ delete aSIPHeader;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::UpdateRouteSetsL
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::UpdateRouteSetsL (
+ const MRefreshOwner* aOwner,
+ const RPointerArray<CSIPRouteHeader>& aRouteSet)
+ {
+ for (TInt i=0; i < iRefreshes.Count(); i++)
+ {
+ if (iRefreshes[i]->Owner() == aOwner)
+ {
+ iRefreshes[i]->SetUpdatedRouteHeadersL(aRouteSet);
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::RemoveRouteSets
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::RemoveRouteSets (const MRefreshOwner* aOwner)
+ {
+ for (TInt i=0; i < iRefreshes.Count(); i++)
+ {
+ if (iRefreshes[i]->Owner() == aOwner)
+ {
+ iRefreshes[i]->RemoveRouteHeaders();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::SetRegistrationIdsEmpty
+// From MSipRefreshMgr:
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::SetRegistrationIdsEmpty (const MRefreshOwner* aOwner)
+ {
+ for (TInt i=iRefreshes.Count()-1; i>=0; i--)
+ {
+ // iRefreshes[i]->Owner() never could be NULL, aOwner could be NULL
+ if (iRefreshes[i]->Owner() == aOwner)
+ {
+ iRefreshes[i]->ResetRegistrationId();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSipRefreshMgr::DeleteTransactionHeaders
+// -----------------------------------------------------------------------------
+//
+void CSipRefreshMgr::DeleteTransactionHeaders (TAny* aTransactionHeaders)
+ {
+ MTransactionHeaders* transactionHeaders =
+ reinterpret_cast<MTransactionHeaders*>(aTransactionHeaders);
+ delete transactionHeaders;
+ }