diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/Transaction/src/Transaction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/Transaction/src/Transaction.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,547 @@ +// 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 : Transaction.cpp +// Part of : Transaction +// Version : SIP/5.0 +// + + + +#include "SipAssert.h" +#include "siperr.h" +#include "sipstrings.h" +#include "sipstrconsts.h" +#include "Lwtimer.h" +#include "siprequest.h" +#include "sipresponse.h" +#include "UserAgentBase.h" +#include "Transmitter.h" +#include "SIPMessageUtility.h" + +#include "CTransaction.h" +#include "TransactionState.h" +#include "SipLogs.h" +// ----------------------------------------------------------------------------- +// CTransaction::CTransaction +// ----------------------------------------------------------------------------- +// +CTransaction::CTransaction(CUserAgentBase& aUserAgent, + CTransmitter& aTransmitter, + MTimerManager& aTimers, + CTransactionState& aInitialState, + TTimerValues& aTimerValues) : + iUserAgent(&aUserAgent), + iTransmitter(&aTransmitter), + iTimers(aTimers), + iTransportProtocol(SIPStrings::StringF(SipStrConsts::EUDP)), + iTransportParams(aUserAgent.TransportParams()), + iTimerValues(aTimerValues), + iTerminated(EFalse), + iState(&aInitialState) + { +#if defined(USE_SIP_LOGS) + WriteStateToLog(*iState); +#endif + } + +// ----------------------------------------------------------------------------- +// CTransaction::~CTransaction +// ----------------------------------------------------------------------------- +// +CTransaction::~CTransaction() + { + } + +// ----------------------------------------------------------------------------- +// CTransaction::TransactionId +// This function is only used by UAS. CClientTransaction overloads this. +// ----------------------------------------------------------------------------- +// +TTransactionId CTransaction::TransactionId() const + { + __TEST_INVARIANT; + __ASSERT_DEBUG(iUserAgent, + User::Panic(_L("CTransaction:TaId"), KErrGeneral)); + return iUserAgent->TransactionId(); + } + +#if defined(USE_SIP_LOGS) +// ----------------------------------------------------------------------------- +// CTransaction::WriteStateToLog +// Only INVITE transactions write logs. +// ----------------------------------------------------------------------------- +// +void CTransaction::WriteStateToLog(const CTransactionState& aState) const + { + const TDesC8& log = aState.Log(); + + if (log.Length() > 0) + { + //If INVITE-UAC stops transaction as a 2xx was received, UAC writes the + //transaction state to log as transaction won't have the TransactionId. + TTransactionId id = TransactionId(); + if (id != KEmptyTransactionId) + { + TBuf8<40> state; + if (iTerminated) + { + state.Copy(_L8("Terminated")); + } + else + { + if (log.Compare( + CTransactionState::EnteringThisStateIsntLogged()) == 0) + { + return; + } + state.Copy(log); + } + + __SIP_INT_LOG1( "TU transaction, taID", id ) + __SIP_DES8_LOG( "TU transaction, state", state ) + } + } + } +#endif + +// ----------------------------------------------------------------------------- +// CTransaction::SendRequestL +// ----------------------------------------------------------------------------- +// +void CTransaction::SendRequestL(CSIPRequest& aReq, + const TInetAddr& aRemoteAddr, + RStringF aProtocol, + TBool aForceUDP, + const TSIPTransportParams& aParams, + CUri8* aOutboundProxy) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(CSIPMessageUtility::CheckTransport(aProtocol), + KErrArgument); + if (iTerminated) + { + User::Leave(KErrSIPInvalidTransactionState); + } + + iState->SendRequestL(*this, + aReq, + aRemoteAddr, + aProtocol, + aForceUDP, + aParams, + aOutboundProxy); + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::SendResponseL +// ----------------------------------------------------------------------------- +// +void CTransaction::SendResponseL(CSIPResponse* aResp, + RStringF aProtocol, + const TSIPTransportParams& aParams) + { + __TEST_INVARIANT; + + CSIPInternalStates::TState state; + this->GetState(state); + __SIP_INT_LOG1("CTransaction::SendResponseL Transaciton state is: ", state) + + + TTransactionId Id= this->TransactionId(); + __SIP_INT_LOG1("CTransaction::SendResponseL Transaciton ID is: ", Id) + + __SIP_ASSERT_LEAVE(aResp, KErrArgument); + __SIP_ASSERT_LEAVE(CSIPMessageUtility::CheckTransport(aProtocol), + KErrArgument); + if (iTerminated) + { + User::Leave(KErrSIPInvalidTransactionState); + } + + iState->SendResponseL(*this, aResp, aProtocol, aParams); + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::ReceiveL +// ----------------------------------------------------------------------------- +// +void CTransaction::ReceiveL(CSIPRequest* aRequest) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aRequest, KErrArgument); + __SIP_MESSAGE_LOG("TransactionUser", *aRequest) + + if (iTerminated) + { + delete aRequest; + } + else + { + iState->ReceiveL(*this, aRequest); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::ReceiveL +// ----------------------------------------------------------------------------- +// +void CTransaction::ReceiveL(CSIPResponse* aResponse) + { + __TEST_INVARIANT; + __SIP_ASSERT_LEAVE(aResponse, KErrArgument); + __SIP_MESSAGE_LOG("TransactionUser", *aResponse) + + if (iTerminated) + { + delete aResponse; + } + else + { + iState->ReceiveL(*this, aResponse); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::UpdateTransportProtocol +// ----------------------------------------------------------------------------- +// +TBool CTransaction::UpdateTransportProtocol(CSIPMessage& aMsg) + { + __TEST_INVARIANT; + return CSIPMessageUtility::TransportProtocol(aMsg, iTransportProtocol); + } + +// ----------------------------------------------------------------------------- +// CTransaction::LeaveOccurred +// Use overloaded TerminatedL (not Terminated), to free detached transaction. +// ----------------------------------------------------------------------------- +// +void CTransaction::LeaveOccurred(TInt aReason) + { + __TEST_INVARIANT; + __ASSERT_DEBUG(aReason != KErrNone, + User::Panic(_L("CTransaction:LeaveOccurred"), KErrArgument)); + + if (aReason != KErrSIPInvalidDialogResponse) + { + TRAP_IGNORE(TerminatedL(aReason)) + + if (iUserAgent) + { + iUserAgent->Stop(aReason); + } + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::TransportParams +// ----------------------------------------------------------------------------- +// +const TSIPTransportParams& CTransaction::TransportParams() const + { + __TEST_INVARIANT; + return iTransportParams; + } + +// ----------------------------------------------------------------------------- +// CTransaction::TimerExpiredL +// Ignore timer if terminated. Occurs e.g. if ClientTransaction has timers E and +// F, timer F expires so transaction terminates, but timer E isn't stopped until +// Transaction is deleted. +// ----------------------------------------------------------------------------- +// +void CTransaction::TimerExpiredL(TTimerId aTimerId, TAny* aTimerParam) + { + __TEST_INVARIANT; + + // Check if it is a Invite transaction + if (IsInviteTransaction()) + { + __SIP_LOG("It is invite transaction CTransaction::TimerExpiredL") + } + else + { + __SIP_LOG("It is non-invite transaction CTransaction::TimerExpiredL") + } + + // Get the transacton state + CSIPInternalStates::TState state; + this->GetState(state); + __SIP_INT_LOG1("CTransaction::TimerExpiredL Transaciton state is: ", state) + + TTransactionId Id= this->TransactionId(); + __SIP_INT_LOG1("CTransaction::TimerExpiredL Transaciton ID is: ", Id) + + if (!iTerminated) + { + iState->TimerExpiredL(*this, aTimerId, aTimerParam); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::SendCompleteL +// ----------------------------------------------------------------------------- +// +void CTransaction::SendCompleteL() + { + __TEST_INVARIANT; + + if (!iTerminated) + { + iState->SendCompleteL(*this); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::SendFailedL +// ----------------------------------------------------------------------------- +// +void CTransaction::SendFailedL(TInt aError) + { + __TEST_INVARIANT; + + if (!iTerminated) + { + iState->SendFailedL(*this, aError); + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::LeaveFromTransmitter +// ----------------------------------------------------------------------------- +// +void CTransaction::LeaveFromTransmitter(TInt aReason) + { + __TEST_INVARIANT; + __ASSERT_DEBUG(aReason != KErrNone, + User::Panic(_L("CTa:LeaveFromTransmitter"), KErrArgument)); + + LeaveOccurred(aReason); + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::IsUnreliableTransportUsed +// ----------------------------------------------------------------------------- +// +TBool CTransaction::IsUnreliableTransportUsed() const + { + __TEST_INVARIANT; + return iTransportProtocol == SIPStrings::StringF(SipStrConsts::EUDP); + } + +// ----------------------------------------------------------------------------- +// CTransaction::IsTransmitterSending +// ----------------------------------------------------------------------------- +// +TBool CTransaction::IsTransmitterSending() const + { + __TEST_INVARIANT; + return iTransmitter && iTransmitter->IsActive(); + } + +// ----------------------------------------------------------------------------- +// CTransaction::IsInviteTransaction +// ----------------------------------------------------------------------------- +// +TBool CTransaction::IsInviteTransaction() const + { + __TEST_INVARIANT; + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CTransaction::State +// ----------------------------------------------------------------------------- +// +const CTransactionState* CTransaction::State() const + { + __TEST_INVARIANT; + return iState; + } + +// ----------------------------------------------------------------------------- +// CTransaction::ChangeState +// ----------------------------------------------------------------------------- +// +void CTransaction::ChangeState(const CTransactionState& aNewState) + { + __TEST_INVARIANT; + + iState = &aNewState; + +#if defined(USE_SIP_LOGS) + WriteStateToLog(aNewState); +#endif + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::ClearSendBuffer +// If buffer has ACK, CInviteClientTransaction created and owns it. +// ----------------------------------------------------------------------------- +// +TBool CTransaction::ClearSendBuffer() + { + __TEST_INVARIANT; + + if (iOutgoingMsg && CSIPMessageUtility::IsAck(*iOutgoingMsg)) + { + return ETrue; + } + + //Can't use iOutgoingMsg anymore. Cancel a possible sending so ConnectionMgr + //won't use it either. + iOutgoingMsg = NULL; + if (iTransmitter) + { + iTransmitter->Cancel(); + } + + //A terminated transaction can continue without iOutgoingMsg + return iTerminated || iState->CanContinueWithoutOutgoingMsg(); + } + +// ----------------------------------------------------------------------------- +// CTransaction::GetState +// ----------------------------------------------------------------------------- +// +void CTransaction::GetState(CSIPInternalStates::TState& aState) + { + __TEST_INVARIANT; + + if (iTerminated) + { + aState = CSIPInternalStates::ETransactionTerminated; + } + else + { + iState->GetState(aState); + } + } + +// ----------------------------------------------------------------------------- +// CTransaction::Terminated +// ----------------------------------------------------------------------------- +// +void CTransaction::Terminated() + { + __TEST_INVARIANT; + + if (!iTerminated) + { + iTerminated = ETrue; + +#if defined(USE_SIP_LOGS) + WriteStateToLog(*iState); +#endif + if (iTransmitter) + { + iTransmitter->DetachCallback(this); + } + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::TerminatedL +// ----------------------------------------------------------------------------- +// +void CTransaction::TerminatedL(TInt aReason) + { + __TEST_INVARIANT; +#if defined(USE_SIP_LOGS) + WriteStateToLog(*iState); +#endif + + if (!iTerminated) + { + Terminated(); + + if (iUserAgent) + { + iUserAgent->TransactionEndsL(aReason); + } + } + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::HasTerminated +// ----------------------------------------------------------------------------- +// +TBool CTransaction::HasTerminated() const + { + __TEST_INVARIANT; + return iTerminated; + } + +// ----------------------------------------------------------------------------- +// CTransaction::DetachFromUserAgent +// ----------------------------------------------------------------------------- +// +void CTransaction::DetachFromUserAgent() + { + __TEST_INVARIANT; + __SIP_ASSERT_RETURN(iUserAgent, KErrNotFound); + + iUserAgent = NULL; + + __TEST_INVARIANT; + } + +// ----------------------------------------------------------------------------- +// CTransaction::TransportProtocol +// ----------------------------------------------------------------------------- +// +RStringF CTransaction::TransportProtocol() const + { + __TEST_INVARIANT; + + return iTransportProtocol; + } + +// ----------------------------------------------------------------------------- +// CTransaction::__DbgTestInvariant +// iUserAgent can be NULL. Detached transaction sets iTransmitter to NULL. +// ----------------------------------------------------------------------------- +// + +void CTransaction::__DbgTestInvariant() const + { + if (!iState) + { + User::Invariant(); + } + } +