realtimenetprots/sipfw/SIP/Transaction/src/Transmitter.cpp
changeset 0 307788aac0a8
--- /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 <in_sock.h>
+
+#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;
+	}