diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/Transaction/src/ServerTransaction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/Transaction/src/ServerTransaction.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,287 @@ +// 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 : ServerTransaction.cpp +// Part of : Transaction +// Version : SIP/5.0 +// + + + +#include "SipAssert.h" +#include "siperr.h" +#include "sipstrings.h" +#include "sipstrconsts.h" +#include "siprequest.h" +#include "sipresponse.h" +#include "UserAgentBase.h" +#include "SIPMessageUtility.h" + +#include "ServerTransaction.h" +#include "ResponseQueue.h" +#include "ResponseQueueItem.h" +#include "Transmitter.h" + + +// ----------------------------------------------------------------------------- +// CServerTransaction::CServerTransaction +// ----------------------------------------------------------------------------- +// +CServerTransaction::CServerTransaction(CUserAgentBase& aUserAgent, + CTransmitter& aTransmitter, + MTimerManager& aTimers, + CTransactionState& aInitialState, + TTimerValues& aTimerValues) : + CTransaction(aUserAgent, + aTransmitter, + aTimers, + aInitialState, + aTimerValues) + { + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::ConstructServerTaL +// ----------------------------------------------------------------------------- +// +void CServerTransaction::ConstructServerTaL() + { + iSendQueue = CResponseQueue::NewL(); + iSentResponses = CResponseQueue::NewL(); + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::~CServerTransaction +// ----------------------------------------------------------------------------- +// +CServerTransaction::~CServerTransaction() + { + delete iOutgoingMsg; + delete iSendQueue; + delete iSentResponses; + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::PassRequestToUserAgentL +// ----------------------------------------------------------------------------- +// +void CServerTransaction::PassRequestToUserAgentL(CSIPRequest* aReq) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aReq, KErrArgument); + __SIP_ASSERT_LEAVE(iUserAgent, KErrNotFound); + __SIP_ASSERT_LEAVE(!iRequestPassedToUA, KErrAlreadyExists); + + iUserAgent->ReceiveL(aReq); + iRequestPassedToUA = ETrue; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::RequestPassedToUA +// ----------------------------------------------------------------------------- +// +TBool CServerTransaction::RequestPassedToUA() const + { + __TEST_INVARIANT; + return iRequestPassedToUA; + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::Create100L +// If no To-tag in aReq, it is not added to response. +// iOutgoingMsg can theorically already have 100, if leave occurs after +// Create100L and a retransmitted request is received before transaction stops. +// ----------------------------------------------------------------------------- +// +void CServerTransaction::Create100L(CSIPRequest& aReq) + { + __TEST_INVARIANT; + if (!iOutgoingMsg) + { + CSIPResponse* resp = CSIPResponse::NewLC(100, + SIPStrings::StringF(SipStrConsts::EPhraseTrying)); + + CSIPMessageUtility::CopyHeadersL(aReq, *resp, + SIPStrings::StringF(SipStrConsts::EToHeader)); + CSIPMessageUtility::CopyHeadersL(aReq, *resp, + SIPStrings::StringF(SipStrConsts::EFromHeader)); + CSIPMessageUtility::CopyHeadersL(aReq, *resp, + SIPStrings::StringF(SipStrConsts::ECallIDHeader)); + CSIPMessageUtility::CopyHeadersL(aReq, *resp, + SIPStrings::StringF(SipStrConsts::ECSeqHeader)); + CSIPMessageUtility::CopyHeadersL(aReq, *resp, + SIPStrings::StringF(SipStrConsts::EViaHeader)); + + CleanupStack::Pop(resp); + iOutgoingMsg = resp; + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::SendToTransmitterL +// ----------------------------------------------------------------------------- +// +void CServerTransaction::SendToTransmitterL() + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound); + __SIP_ASSERT_LEAVE(!iOutgoingMsg->IsRequest(), KErrSIPMalformedMessage); + + iTransmitter->SendResponseL(static_cast(*iOutgoingMsg), + iTransportParams, + this, + TransactionId()); + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::SendAndStoreResponseL +// ----------------------------------------------------------------------------- +// +void CServerTransaction::SendAndStoreResponseL(CResponseQueueItem* aRespItem) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aRespItem, KErrArgument); + __SIP_ASSERT_LEAVE(CSIPMessageUtility::CheckTransport(iTransportProtocol), + KErrArgument); + + SendAndStoreResponseL(aRespItem, iTransportProtocol); + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::SendAndStoreResponseL +// ----------------------------------------------------------------------------- +// +void CServerTransaction::SendAndStoreResponseL(CResponseQueueItem* aRespItem, + RStringF aTransportProtocol) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aRespItem, KErrArgument); + __SIP_ASSERT_LEAVE(CSIPMessageUtility::CheckTransport(aTransportProtocol), + KErrArgument); + + CResponseQueueItem* previousRespItem = NULL; + if (iOutgoingMsg) + { + //Earlier response must be a 1xx, as UAS sends only one final response. + __ASSERT_DEBUG(!CSIPMessageUtility::IsFinalResponse( + static_cast(*iOutgoingMsg)), + User::Panic(_L("ServTa:SendAndStoreRespL"), KErrAlreadyExists)); + previousRespItem = + CResponseQueueItem::NewLC(static_cast(iOutgoingMsg), + iTransportParams, + //aRespItem has same value for "is INVITE" + aRespItem->IsRespToInvite()); + } + + iTransmitter->SendResponseL(aRespItem->Response(), + aRespItem->TransportParams(), + this, + TransactionId()); + if (iOutgoingMsg) + { + TInt status = iSentResponses->Add(previousRespItem); + if (status != KErrNone) + { + //ConnectionMgr must not use the response + iTransmitter->CancelSendResponses(TransactionId(), ETrue); + User::Leave(status); + } + CleanupStack::Pop(previousRespItem); + } + + iTransportProtocol = aTransportProtocol; + iTransportParams = aRespItem->TransportParams(); + + iOutgoingMsg = &aRespItem->Response(); + aRespItem->SetResponseOwnership(EFalse); + delete aRespItem; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::AddResponseToSendQueueL +// ----------------------------------------------------------------------------- +// +void +CServerTransaction::AddResponseToSendQueueL(CResponseQueueItem* aRespItem) const + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aRespItem, KErrArgument); + + User::LeaveIfError(iSendQueue->Add(aRespItem)); + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::GetResponseFromSendQueue +// ----------------------------------------------------------------------------- +// +CResponseQueueItem* CServerTransaction::GetResponseFromSendQueue() const + { + __TEST_INVARIANT; + return iSendQueue->GetNext(); + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::IcmpErrorL +// ServerTransaction ignores ICMP error +// ----------------------------------------------------------------------------- +// +void CServerTransaction::IcmpErrorL(const TInetAddr& /*aAddress*/, + CSipConnectionMgr::TICMPError /*aError*/) + { + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::TerminatedL +// ----------------------------------------------------------------------------- +// +void CServerTransaction::TerminatedL(TInt aReason) + { + __TEST_INVARIANT; + + if (!iTerminated) + { + if (iTransmitter) + { + //Responses will be deleted, ConnectionMgr must not use them. + iTransmitter->CancelSendResponses(TransactionId(), + !IsInviteTransaction()); + } + + CTransaction::TerminatedL(aReason); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CServerTransaction::__DbgTestInvariant +// ----------------------------------------------------------------------------- +// + +void CServerTransaction::__DbgTestInvariant() const + { + if (!iSendQueue || !iSentResponses) + { + User::Invariant(); + } + } +