diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/Transaction/src/Transmitter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/Transaction/src/Transmitter.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,229 @@ +// 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 : Transmitter.cpp +// Part of : Transaction +// Version : SIP/5.0 +// + + + +#include + +#include "siperr.h" +#include "SipAssert.h" +#include "CSipConnectionMgr.h" +#include "TSIPTransportParams.h" +#include "SipLogs.h" + +#include "Transmitter.h" +#include "SendStatus.h" + +// ----------------------------------------------------------------------------- +// CTransmitter::NewL +// ----------------------------------------------------------------------------- +// +CTransmitter* CTransmitter::NewL(MSipConnectionMgr& aConnectionMgr) + { + return new (ELeave) CTransmitter(aConnectionMgr); + } + +// ----------------------------------------------------------------------------- +// CTransmitter::CTransmitter +// ----------------------------------------------------------------------------- +// +CTransmitter::CTransmitter(MSipConnectionMgr& aConnectionMgr) : + CActive(EPriorityStandard), + iConnectionMgr(aConnectionMgr) + { + CActiveScheduler::Add(this); + } + +// ----------------------------------------------------------------------------- +// CTransmitter::~CTransmitter +// ----------------------------------------------------------------------------- +// +CTransmitter::~CTransmitter() + { + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CTransmitter::SendRequestL +// ----------------------------------------------------------------------------- +// +void CTransmitter::SendRequestL(CSIPRequest& aReq, + const TInetAddr& aAddress, + TBool aForceUDP, + const TSIPTransportParams& aParams, + const CUri8* aOutboundProxy, + MSendStatus* aObserver) + { + __SIP_ASSERT_LEAVE(aObserver, KErrArgument); + + if (IsActive()) + { + User::Leave(KErrAlreadyExists); + } + iConnectionMgr.SendL(aParams, + aReq, + aForceUDP, + aOutboundProxy, + aAddress, + iStatus); + iObserver = aObserver; + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CTransmitter::SendResponseL +// ----------------------------------------------------------------------------- +// +void CTransmitter::SendResponseL(CSIPResponse& aResp, + const TSIPTransportParams& aParams, + MSendStatus* aObserver, + TTransactionId aTransactionId) + { + __SIP_ASSERT_LEAVE(aObserver, KErrArgument); + + if (IsActive()) + { + User::Leave(KErrAlreadyExists); + } + + iConnectionMgr.SendL(aParams, aResp, aTransactionId, iStatus); + iObserver = aObserver; + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CTransmitter::TcpDisconnect +// ----------------------------------------------------------------------------- +// +void CTransmitter::TcpDisconnect(TInetAddr& aRemoteAddr, + const TSIPTransportParams& aParams) const + { + iConnectionMgr.TcpDisconnect(aParams, aRemoteAddr); + } + +// ----------------------------------------------------------------------------- +// CTransmitter::MapErrorCode +// ICMP Errors are seperated with a new Error Code KErrSIPICMPFailure +// ----------------------------------------------------------------------------- +// +TInt CTransmitter::MapErrorCode(TInt aError) const + { + switch (aError) + { + //Connection is (temporarily) not available. Treat as sending error. + case CSIPConnection::ESuspended: + case CSIPConnection::EInactive: + return KErrSIPTransportFailure; + //ICMP errors + case CSipConnectionMgr::EHostUnreachable: + case CSipConnectionMgr::ENetUnreachable: + case CSipConnectionMgr::EPortUnreachable: + case CSipConnectionMgr::EProtocolUnreachable: + return KErrSIPICMPFailure; + + default: + return aError; + } + } + +// ----------------------------------------------------------------------------- +// CTransmitter::DetachCallback +// ----------------------------------------------------------------------------- +// +void CTransmitter::DetachCallback(MSendStatus* aObserver) + { + if (iObserver == aObserver) + { + iObserver = NULL; + Cancel(); + } + } + +// ----------------------------------------------------------------------------- +// CTransmitter::CancelSendResponses +// CTransmitter doesn't cancel its possibly existing send request yet. +// ----------------------------------------------------------------------------- +// +void CTransmitter::CancelSendResponses(TTransactionId aTransactionId, + TBool aAlso2xx) const + { + iConnectionMgr.CancelResponseSend(aTransactionId, aAlso2xx); + } + +// ----------------------------------------------------------------------------- +// CTransmitter::DoCancel +// If ConnectionMgr didn't cancel the request, complete it if iStatus is still +// KRequestPending. If ConnectionMgr used User::RequestComplete but RunL hasn't +// been called, CTransmitter is still active, but iStatus isn't KRequestPending. +// ----------------------------------------------------------------------------- +// +void CTransmitter::DoCancel() + { + __SIP_LOG("CTransmitter::DoCancel") + + if (iConnectionMgr.CancelSend(iStatus) != KErrNone && + iStatus == KRequestPending) + { + __SIP_LOG("CTransmitter::DoCancel cancel own request") + + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrCancel); + } + + __SIP_LOG("CTransmitter::DoCancel ends") + } + +// ----------------------------------------------------------------------------- +// CTransmitter::RunL +// ----------------------------------------------------------------------------- +// +void CTransmitter::RunL() + { + if (iObserver) + { + if (iStatus.Int() == KErrNone) + { + iObserver->SendCompleteL(); + } + else + { + iObserver->SendFailedL(MapErrorCode(iStatus.Int())); + } + } + } + +// ----------------------------------------------------------------------------- +// CTransmitter::RunError +// ----------------------------------------------------------------------------- +// +TInt CTransmitter::RunError(TInt aError) + { + __SIP_INT_LOG1("CTransmitter::RunError, err=", aError) + + if (iObserver) + { + iObserver->LeaveFromTransmitter(aError); + } + + if (aError == KErrNoMemory) + { + return aError; + } + + return KErrNone; + }