// Copyright (c) 2002-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 : CReceiverTcp.cpp
// Part of : ConnectionMgr
// Version : SIP/4.0
//
#include "CReceiverTcp.h"
#include "SipLogs.h"
#include "CSipConnection.h"
#include "MContext.h"
#include "CErrorHandler.h"
#include "CSIPMsgAssembler.h"
#include "CSocketContainer.h"
// -----------------------------------------------------------------------------
// CReceiverTcp::NewL
// -----------------------------------------------------------------------------
//
CReceiverTcp* CReceiverTcp::NewL(MContext& aContext)
{
CReceiverTcp* self = NewLC(aContext);
CleanupStack::Pop(self);
return self;
}
// -----------------------------------------------------------------------------
// CReceiverTcp::NewLC
// -----------------------------------------------------------------------------
//
CReceiverTcp* CReceiverTcp::NewLC(MContext& aContext)
{
CReceiverTcp* self = new (ELeave) CReceiverTcp(aContext);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
// -----------------------------------------------------------------------------
// CReceiverTcp::ConstructL
// -----------------------------------------------------------------------------
//
void CReceiverTcp::ConstructL()
{
iNextLength = CSIPMsgAssembler::EMsgBufferSize;
CActiveScheduler::Add(this);
iMsgAssembler = CSIPMsgAssembler::NewL(*this, *iContext.SigCompHandler());
}
// -----------------------------------------------------------------------------
// CReceiverTcp::RunL
// -----------------------------------------------------------------------------
//
void CReceiverTcp::RunL()
{
TInt status( iStatus.Int() );
TBool disconnected( EFalse );
switch ( iReceiverState )
{
case EConnecting:
{
if ( status == KErrNone )
{
iReceiverState = EConnected;
if ( iContext.ConnectionOpenL() )
{
// Context allowed receiving after connection was established
ReceiveDataL();
}
}
else
{
disconnected = ETrue;
}
break;
}
case EShuttingDown:
{
disconnected = ETrue;
break;
}
default: // EIdle, EConnected
{
if ( status == KErrEof )
{
disconnected = ETrue;
}
if ( status == KErrNone )
{
__SIP_MESSAGE_LOG( "Connection Manager::ReceivedFromNetwork",
*iReceivedMsg )
__SIP_DES8_LOG( "Received data via TCP", *iReceivedMsg )
iMsgAssembler->InputL( iReceivedMsg, iNextLength );
iReceivedMsg = 0; // Ownership was transferred to assembler
ReceiveDataL(); // May lead to self deletion
}
break;
}
}
if ( disconnected )
{
__SIP_INT_LOG1( "TCP connection disconnected, status:", status )
iContext.DisconnectedL(); // Leads to self deletion
}
}
// -----------------------------------------------------------------------------
// CReceiverTcp::MessageCompleteL
// -----------------------------------------------------------------------------
//
void CReceiverTcp::MessageCompleteL(CSIPMessage* aSIPMessage,
TInt aError,
TBool aCompressed)
{
TInetAddr addr;
iContext.SocketContainer().RemoteName(addr);
iContext.ReceivedDataL(aSIPMessage, addr, aError, aCompressed);
}
// -----------------------------------------------------------------------------
// CReceiverTcp::DoCancel
// -----------------------------------------------------------------------------
//
void CReceiverTcp::DoCancel()
{
if ( iReceiverState == EConnected )
{
iContext.SocketContainer().CancelRecv();
}
else
{
iContext.SocketContainer().Socket().CancelAll();
}
RemoveReceived();
}
// -----------------------------------------------------------------------------
// CReceiverTcp::RunError
// -----------------------------------------------------------------------------
//
TInt CReceiverTcp::RunError(TInt /*aError*/)
{
return iContext.Remove();
}
// -----------------------------------------------------------------------------
// CReceiverTcp::ReceiveDataL
// -----------------------------------------------------------------------------
//
void CReceiverTcp::ReceiveDataL()
{
if (!IsActive())
{
RemoveReceived();
// Trying to allocate KMaxTInt/2 or more bytes causes panic
__ASSERT_ALWAYS( iNextLength < KMaxTInt/2, User::Leave(KErrOverflow) );
iReceivedMsg = HBufC8::NewL(iNextLength);
iReceivedMsgPtr.Set(iReceivedMsg->Des());
iContext.SocketContainer().RecvOneOrMore(iReceivedMsgPtr,
0,
iStatus,
iSockLenght);
SetActive();
}
}
// -----------------------------------------------------------------------------
// CReceiverTcp::Connect
// -----------------------------------------------------------------------------
//
void CReceiverTcp::Connect(TInetAddr& aRemoteAddr)
{
if(!IsActive())
{
iContext.SocketContainer().Connect(aRemoteAddr, iStatus);
iReceiverState = EConnecting;
SetActive();
}
}
// -----------------------------------------------------------------------------
// CReceiverTcp::Shutdown
// -----------------------------------------------------------------------------
//
void CReceiverTcp::Shutdown()
{
Cancel();
iContext.SocketContainer().Socket().Shutdown( RSocket::ENormal, iStatus );
iReceiverState = EShuttingDown;
SetActive();
}
// -----------------------------------------------------------------------------
// CReceiverTcp::~CReceiverTcp
// -----------------------------------------------------------------------------
//
CReceiverTcp::~CReceiverTcp()
{
Cancel();
RemoveReceived();
delete iMsgAssembler;
}
// -----------------------------------------------------------------------------
// CReceiverTcp::CReceiverTcp
// -----------------------------------------------------------------------------
//
CReceiverTcp::CReceiverTcp(MContext& aContext) :
CActive(CActive::EPriorityStandard),
iContext(aContext),
iReceivedMsgPtr(0,0,0),
iReceiverState( EIdle )
{
}
// -----------------------------------------------------------------------------
// CReceiverTcp::RemoveReceived
// -----------------------------------------------------------------------------
//
void CReceiverTcp::RemoveReceived()
{
delete iReceivedMsg;
iReceivedMsg = 0;
}
// End of file