diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/Transaction/src/InviteServerTaStates.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/Transaction/src/InviteServerTaStates.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,482 @@ +// 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 : InviteServerTaStates.cpp +// Part of : Transaction +// Version : SIP/5.0 +// + + + +#include "siperr.h" +#include "siprequest.h" +#include "sipresponse.h" +#include "SipAssert.h" +#include "SIPMessageUtility.h" +#include "sipstrings.h" +#include "sipstrconsts.h" + +#include "InviteServerTa.h" +#include "InviteServerTaStates.h" +#include "ResponseQueueItem.h" + + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Proceeding::CInviteServerTa_Proceeding +// ----------------------------------------------------------------------------- +// +CInviteServerTa_Proceeding::CInviteServerTa_Proceeding() + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Proceeding::~CInviteServerTa_Proceeding +// ----------------------------------------------------------------------------- +// +CInviteServerTa_Proceeding::~CInviteServerTa_Proceeding() + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Proceeding::GetState +// ----------------------------------------------------------------------------- +// +void +CInviteServerTa_Proceeding::GetState(CSIPInternalStates::TState& aState) const + { + aState = CSIPInternalStates::ETransactionProceeding; + } + +#if defined(USE_SIP_LOGS) +// ----------------------------------------------------------------------------- +// CInviteServerTa_Proceeding::Log +// ----------------------------------------------------------------------------- +// +const TDesC8& CInviteServerTa_Proceeding::Log() const + { + _LIT8(KState, "Proceeding"); + return KState; + } +#endif + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Proceeding::SetNeighbourStates +// ----------------------------------------------------------------------------- +// +void +CInviteServerTa_Proceeding::SetNeighbourStates(CTransactionState& aCompleted, + CTransactionState& aSending2xx) + { + iCompleted = &aCompleted; + iSending2xx = &aSending2xx; + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Proceeding::ReceiveL +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Proceeding::ReceiveL(CTransaction& aTransaction, + CSIPRequest* aRequest) const + { + __SIP_ASSERT_LEAVE(aRequest, KErrArgument); + + CInviteServerTransaction& ta = CInviteServerTransaction::Ptr(aTransaction); + if (!ta.RequestPassedToUA()) + { + __ASSERT_ALWAYS(ta.UpdateTransportProtocol(*aRequest), + User::Leave(KErrSIPMalformedMessage)); + ta.Create100L(*aRequest); + } + + //Send the most recent response, unless already being sent + if (!ta.IsTransmitterSending()) + { + ta.SendToTransmitterL(); + } + + if (ta.RequestPassedToUA()) + { + //Absorb retransmissions + delete aRequest; + } + else + { + //Pass the first INVITE to UAS + ta.PassRequestToUserAgentL(aRequest); + } + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Proceeding::SendResponseL +// Queue the new response, if a previous response is being sent. +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Proceeding::SendResponseL(CTransaction& aTransaction, + CSIPResponse* aResp, + RStringF aProtocol, + const TSIPTransportParams& aParams) const + { + __SIP_ASSERT_LEAVE(aResp, KErrArgument); + __SIP_ASSERT_LEAVE(CSIPMessageUtility::CheckTransport(aProtocol), + KErrArgument); + + CInviteServerTransaction& ta = CInviteServerTransaction::Ptr(aTransaction); + TUint respCode = aResp->ResponseCode(); + CResponseQueueItem* respItem = + CResponseQueueItem::NewLC(aResp, aParams, ETrue); + + if (ta.IsTransmitterSending()) + { + ta.AddResponseToSendQueueL(respItem); + } + else + { + /* TimerH is started after the StateChange and sending the Response + * This is done to avoid the timer expiry in proceeding state if + * SendAndStoreResponseL() function leaves and state change doesn't happen + * In proceeding State, timer expiry is not expected and not handled + */ + ta.ResponseSent(respCode, *iSending2xx, *iCompleted); + + ta.SendAndStoreResponseL(respItem, aProtocol); + + if (respCode >= 300) + { + ta.StartTimerHL(); + } + } + CleanupStack::Pop(respItem); + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Proceeding::SendCompleteL +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Proceeding::SendCompleteL(CTransaction& aTransaction) const + { + CInviteServerTransaction& ta = CInviteServerTransaction::Ptr(aTransaction); + CResponseQueueItem* respItem = ta.GetResponseFromSendQueue(); + + /* TimerH is started after the StateChange and sending the Response + * This is done to avoid the timer expiry in proceeding state if + * SendAndStoreResponseL() function leaves and state change doesn't happen + * In proceeding State, timer expiry is not expected and not handled + */ + if (respItem) + { + CleanupStack::PushL(respItem); + + TUint respCode = respItem->Response().ResponseCode(); + + ta.ResponseSent(respCode, *iSending2xx, *iCompleted); + + ta.SendAndStoreResponseL(respItem); + + if (respCode >= 300) + { + ta.StartTimerHL(); + } + CleanupStack::Pop(respItem); + } + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Proceeding::SendFailedL +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Proceeding::SendFailedL(CTransaction& aTransaction, + TInt aError) const + { + aTransaction.TerminatedL(aError); + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Completed::CInviteServerTa_Completed +// ----------------------------------------------------------------------------- +// +CInviteServerTa_Completed::CInviteServerTa_Completed() + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Completed::~CInviteServerTa_Completed +// ----------------------------------------------------------------------------- +// +CInviteServerTa_Completed::~CInviteServerTa_Completed() + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Completed::GetState +// ----------------------------------------------------------------------------- +// +void +CInviteServerTa_Completed::GetState(CSIPInternalStates::TState& aState) const + { + aState = CSIPInternalStates::ETransactionCompleted; + } + +#if defined(USE_SIP_LOGS) +// ----------------------------------------------------------------------------- +// CInviteServerTa_Completed::Log +// ----------------------------------------------------------------------------- +// +const TDesC8& CInviteServerTa_Completed::Log() const + { + _LIT8(KState, "Completed"); + return KState; + } +#endif + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Completed::SetNeighbourStates +// ----------------------------------------------------------------------------- +// +void +CInviteServerTa_Completed::SetNeighbourStates(CTransactionState& aConfirmed) + { + iConfirmed = &aConfirmed; + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Completed::SendCompleteL +// Only one timer G exists at once. It can already exist if: +// 1. Timer G is started +// 2. INVITE is received and response sent +// 3. SendCompleteL event comes while timer G is running +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Completed::SendCompleteL(CTransaction& aTransaction) const + { + if (aTransaction.IsUnreliableTransportUsed()) + { + CInviteServerTransaction::Ptr(aTransaction).StartTimerGUnlessExistsL(); + } + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Completed::SendFailedL +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Completed::SendFailedL(CTransaction& aTransaction, + TInt aError) const + { + aTransaction.TerminatedL(aError); + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Completed::ReceiveL +// Don't pass ACK to UAS. If retransmitted INVITE, retransmit the most recent +// response unless already being sent. +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Completed::ReceiveL(CTransaction& aTransaction, + CSIPRequest* aRequest) const + { + __SIP_ASSERT_LEAVE(aRequest, KErrArgument); + + CInviteServerTransaction& ta = CInviteServerTransaction::Ptr(aTransaction); + + if (CSIPMessageUtility::IsAck(*aRequest)) + { + ta.EnterConfirmedStateL(*iConfirmed); + } + else + { + if ((aRequest->Method() == SIPStrings::StringF(SipStrConsts::EInvite)) + && + !ta.IsTransmitterSending()) + { + ta.SendToTransmitterL(); + } + } + + delete aRequest; + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Completed::TimerExpiredL +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Completed::TimerExpiredL(CTransaction& aTransaction, + TTimerId aTimerId, + TAny* aTimerParam) const + { + __SIP_ASSERT_LEAVE(aTimerParam, KErrArgument); + + HandleTimerExpirationL(aTransaction, aTimerId, aTimerParam); + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Confirmed::CInviteServerTa_Confirmed +// ----------------------------------------------------------------------------- +// +CInviteServerTa_Confirmed::CInviteServerTa_Confirmed() + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Confirmed::~CInviteServerTa_Confirmed +// ----------------------------------------------------------------------------- +// +CInviteServerTa_Confirmed::~CInviteServerTa_Confirmed() + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Confirmed::GetState +// ----------------------------------------------------------------------------- +// +void +CInviteServerTa_Confirmed::GetState(CSIPInternalStates::TState& aState) const + { + aState = CSIPInternalStates::ETransactionConfirmed; + } + +#if defined(USE_SIP_LOGS) +// ----------------------------------------------------------------------------- +// CInviteServerTa_Confirmed::Log +// ----------------------------------------------------------------------------- +// +const TDesC8& CInviteServerTa_Confirmed::Log() const + { + _LIT8(KState, "Confirmed"); + return KState; + } +#endif + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Confirmed::CanContinueWithoutOutgoingMsg +// This is never called for a server side. +// ----------------------------------------------------------------------------- +// +TBool CInviteServerTa_Confirmed::CanContinueWithoutOutgoingMsg() const + { + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Confirmed::SendCompleteL +// Happens if entered Confirmed state before CTransmitter finished sending. +// Nothing is sent anymore, so no need to update transport protocol. +// ----------------------------------------------------------------------------- +// +void +CInviteServerTa_Confirmed::SendCompleteL(CTransaction& /*aTransaction*/) const + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Confirmed::SendFailedL +// No action, wait for timer I to expire. +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Confirmed::SendFailedL(CTransaction& /*aTransaction*/, + TInt /*aError*/) const + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Confirmed::ReceiveL +// Absorb any additional ACKs. +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Confirmed::ReceiveL(CTransaction& /*aTransaction*/, + CSIPRequest* aRequest) const + { + __SIP_ASSERT_LEAVE(aRequest, KErrArgument); + + delete aRequest; + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Confirmed::TimerExpiredL +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Confirmed::TimerExpiredL(CTransaction& aTransaction, + TTimerId aTimerId, + TAny* aTimerParam) const + { + __SIP_ASSERT_LEAVE(aTimerParam, KErrArgument); + + HandleTimerExpirationL(aTransaction, aTimerId, aTimerParam); + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Sending2xx::CInviteServerTa_Sending2xx +// ----------------------------------------------------------------------------- +// +CInviteServerTa_Sending2xx::CInviteServerTa_Sending2xx() + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Sending2xx::~CInviteServerTa_Sending2xx +// ----------------------------------------------------------------------------- +// +CInviteServerTa_Sending2xx::~CInviteServerTa_Sending2xx() + { + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Sending2xx::GetState +// 2xx was sent but SendCompleteL not yet received. Treat state as terminated, +// as "Sending2xx" is implementation's internal state. +// ----------------------------------------------------------------------------- +// +void +CInviteServerTa_Sending2xx::GetState(CSIPInternalStates::TState& aState) const + { + aState = CSIPInternalStates::ETransactionTerminated; + } + +#if defined(USE_SIP_LOGS) +// ----------------------------------------------------------------------------- +// CInviteServerTa_Sending2xx::Log +// Don't log transition to this state, as RFC doesn't specify it. +// ----------------------------------------------------------------------------- +// +const TDesC8& CInviteServerTa_Sending2xx::Log() const + { + return EnteringThisStateIsntLogged(); + } +#endif + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Sending2xx::CanContinueWithoutOutgoingMsg +// This is never called for a server side. +// ----------------------------------------------------------------------------- +// +TBool CInviteServerTa_Sending2xx::CanContinueWithoutOutgoingMsg() const + { + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Sending2xx::SendCompleteL +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Sending2xx::SendCompleteL(CTransaction& aTransaction) const + { + aTransaction.TerminatedL(KErrNone); + } + +// ----------------------------------------------------------------------------- +// CInviteServerTa_Sending2xx::SendFailedL +// ----------------------------------------------------------------------------- +// +void CInviteServerTa_Sending2xx::SendFailedL(CTransaction& aTransaction, + TInt aError) const + { + aTransaction.TerminatedL(aError); + }