--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Msrp/MsrpServer/src/CMSRPConnection.cpp Sat Jun 12 14:30:11 2010 +0530
@@ -0,0 +1,443 @@
+/*
+* Copyright (c) 2009-2010 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:
+* MSRP Implementation
+*
+*/
+
+// CLASS HEADER
+#include "CMSRPConnection.h"
+#include "MSRPCommon.h"
+// INTERNAL INCLUDES
+#include "CMSRPConnector.h"
+#include "CMSRPReader.h"
+#include "CMSRPParser.h"
+#include "CMSRPWriter.h"
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+CMSRPConnection::CMSRPConnection( TInetAddr& aRemoteAddr, MMSRPConnectionManager& aConnMngr ): iHostAddress(aRemoteAddr), iConnMngr(aConnMngr)
+ {
+ MSRPLOG( "CMSRPConnection::CMSRPConnection enter" )
+ MSRPLOG( "CMSRPConnection::CMSRPConnection exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::~CMSRPConnection
+// -----------------------------------------------------------------------------
+//
+CMSRPConnection::~CMSRPConnection()
+ {
+ MSRPLOG( "CMSRPConnection::~CMSRPConnection enter" )
+ iSubsessions.Reset();
+ iSubsessions.Close();
+ delete iListenTimer;
+ delete iConnector;
+ delete iWriter;
+ delete iParser;
+ delete iReader;
+ //delete iBufPool;
+ if(iSocket)
+ {
+ iSocket->Close();
+ delete iSocket;
+ }
+
+ MSRPLOG( "CMSRPConnection::~CMSRPConnection exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection* CMSRPConnection::NewL
+// -----------------------------------------------------------------------------
+//
+/*static*/ MMSRPConnection* CMSRPConnection::NewL( TInetAddr& aRemoteAddr, MMSRPConnectionManager& aConnMngr )
+ {
+ MSRPLOG( "CMSRPConnection::NewL enter" )
+
+ // Perform construction.
+ CMSRPConnection* self = new ( ELeave ) CMSRPConnection(aRemoteAddr, aConnMngr);
+ CleanupStack::PushL( self );
+ self->ConstructL( );
+ CleanupStack::Pop( self );
+
+ MSRPLOG( "CMSRPConnection::NewL exit" )
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::ConstructL( )
+ {
+ MSRPLOG( "CMSRPConnection::ConstructL enter" )
+ iConnectionState = ENotConnected;
+ iListenTimer = CMSRPTimeOutTimer::NewL( *this );
+ MSRPLOG( "CMSRPConnection::ConstructL exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::CheckIfConnected
+// listening state check for validating listener connections
+// -----------------------------------------------------------------------------
+//
+TBool CMSRPConnection::CheckConnection(TInetAddr& aRemoteAddr, TBool aOnlyListen)
+ {
+ MSRPLOG( "CMSRPConnection::CheckConnection enter" )
+ TUint port_stored = iHostAddress.Port();
+ TUint port_connect = aRemoteAddr.Port();
+
+ //if (iHostAddress.CmpAddr(aRemoteAddr))//v4, v6 issue
+ if (iHostAddress.Match(aRemoteAddr) && port_stored == port_connect)
+ {
+ if (aOnlyListen && iConnectionState == EListening) //check if listening
+ return ETrue;
+ else if (!aOnlyListen /*&& iConnectionState <= EConnected */) //not connected, connecting, listening, connected
+ return ETrue;
+ /*else
+ return EFalse;*/ //timed out, disconnecting, disconnected, create a new conn object
+ }
+ MSRPLOG( "CMSRPConnection::CheckConnection exit" )
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::ConnectL
+// -----------------------------------------------------------------------------
+//
+TInt CMSRPConnection::ConnectL(MMSRPConnectionObserver& aSubsession)
+ {
+ MSRPLOG("CMSRPConnection::ConnectL() enter")
+ //subsession to ensure it does not reissue
+ //connection does not check for pre-existent observers
+
+ iSubsessions.AppendL(&aSubsession);
+
+ switch(iConnectionState)
+ {
+ case ENotConnected:
+ //create connector and issue connect
+ //delete iConnector;
+ iConnector = CMSRPConnector::NewL( iConnMngr, *this );
+ iConnector->Connect(iHostAddress);
+ iConnectionState = EConnecting;
+
+ break;
+
+ case EConnecting:
+ break;
+
+ case EListening: //as of now, dont try to issue connect,complete when other party connects
+ //TBD
+ //later change state to connecting and issue connect
+ //if connect completes before listen, then change state to connected
+ // if at all listen completes on same conn object, then check if state == connected and drop listen conn
+ // do vice versa if listen completes before connect
+ break;
+
+ case EConnected:
+ break;
+
+ case EListenTimedOut:
+ case EConnectTimedOut:
+ case EError:
+ //shudn't reach here, if connect issued immediately after/within getConn
+ //User::Leave(MMSRPConnectionObserver::EConnectionStateUnexpected);
+ break;
+
+ }
+ MSRPLOG("CMSRPConnection::ConnectL() exit")
+ return iConnectionState;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::ListenL
+// -----------------------------------------------------------------------------
+//
+TInt CMSRPConnection::ListenL(MMSRPConnectionObserver& aSubsession)
+ {
+ MSRPLOG("CMSRPConnection::ListenL() enter")
+
+ iSubsessions.AppendL(&aSubsession);
+
+
+ switch(iConnectionState)
+ {
+ case ENotConnected:
+ iConnectionState = EListening;
+ iConnMngr.ListenL(this);
+ //iListenTimer->After( KListenTimeoutInSeconds * KSecondinMicroseconds );
+
+ break;
+
+ case EConnecting: //dont issue listen, drop conn if other party connects, change later
+
+ //added check if listening in check connection to prevent accepting conn,
+ //simply allowing will corrupt listen count, TBD: introduce another EListeningandConnecting state
+ break;
+
+ case EListening:
+ break;
+
+ case EConnected:
+ break;
+
+ case EListenTimedOut:
+ case EConnectTimedOut:
+ case EError:
+ //shudn't reach here, if connect issued immediately after/within getConn
+ //User::Leave(MMSRPConnectionObserver::EConnectionStateUnexpected);
+ break;
+
+ }
+ MSRPLOG("CMSRPConnection::ListenL() exit")
+ return iConnectionState;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::ReleaseConnection
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::ReleaseConnection(MMSRPConnectionObserver& aSubsession)
+ {
+ MSRPLOG("CMSRPConnection::ReleaseConnection() enter")
+
+ Remove(&aSubsession);
+
+ if(iSubsessions.Count())
+ {
+ MSRPLOG("CMSRPConnection::ReleaseConnection() exit")
+ return;
+ }
+
+ //if no subsessions (TBD : start timeout timer and disconnect on timeout)
+ /*if(iConnectionState == EConnecting)
+ {
+ //iConnector->CancelConnect();
+ delete iConnector;
+ iConnector = NULL;
+ }
+ else if(iConnectionState == EConnected)*/
+
+ CloseConnection();
+
+
+ //iConnectionState = ENotConnected;
+ MSRPLOG("CMSRPConnection::ReleaseConnection() exit")
+ return;
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::ConnectionEstablishedL
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::ConnectionEstablishedL( TInt aNewState, RSocket* aSocket, TInt aStatus )
+ {
+ MSRPLOG("CMSRPConnection::ConnectionEstablishedL() enter")
+ iListenTimer->Cancel();
+ //if not error
+ if(aNewState == EConnected)
+ {
+ iConnectionState = aNewState;
+ iSocket = aSocket;
+ if(iConnector)
+ {
+ iConnector->ConnectComplete();
+ /*dont delete now,as in case of leave, connector needs 2 b available*/
+ //delete iConnector;
+ //iConnector = NULL;
+ }
+ iWriter = CMSRPWriter::NewL(*iSocket , *this);
+ iParser = CMSRPParser::NewL(*this);
+ iReader = CMSRPReader::NewL(*iSocket , *this);
+
+ iReader->StartReceivingL(iBufPool.ProvideBufferL());
+ }
+
+ /*not deleting connector as yet, notify all could leave in subsession and also delete conn on conn error*/
+ //intimate all subsessions
+ NotifyAllL(aNewState, aStatus );
+
+ //on error or connect timeout close connection, i.e. intimate all subsessions and delete connection obj
+ if(aStatus != KErrNone)
+ {
+ //listenaccepted does not comeback with error intimations, hence safe to decrement listen count
+ //currently no risk of double decrementing listener count
+ //CloseConnection();
+ }
+
+
+
+ MSRPLOG("CMSRPConnection::ConnectionEstablishedL() exit")
+ }
+
+TInt CMSRPConnection::getConnectionState()
+ {
+ return iConnectionState;
+ // iConnection state should not be Tint, it should be MMSRPConnection::TMSRPConnectionState.
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::ReadStatus
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::ReadStatusL(RMsrpBuf& aBuf, TInt aStatus)
+ {
+ MSRPLOG("CMSRPConnection::ReadStatusL() enter")
+ if(aStatus == KErrNone)
+ {
+ //post to parser and return immediate
+ iParser->ParseL(aBuf);
+
+ RMsrpBuf copy(aBuf);
+ if(copy.MsrpRightExtract() > KThreshold)
+ {
+ iReader->StartReceivingL(copy);
+ }
+ else
+ {
+ iReader->StartReceivingL(iBufPool.ProvideBufferL());
+ }
+ return;
+ }
+ //read error or connection error
+ //intimate all subsessions
+ NotifyAllL(EError, aStatus );
+ //CloseConnection();
+
+ MSRPLOG("CMSRPConnection::ReadStatusL() exit")
+ }
+
+void CMSRPConnection::ParseStatusL (CMSRPMessageHandler* aMsg, TInt aStatus)
+ {
+ MSRPLOG("CMSRPConnection::ParseStatus enter")
+ if (aStatus != KErrNone)
+ {
+ NotifyAllL(EError, aStatus );
+ //CloseConnection();
+ return;
+ }
+
+ /*if error, count is zero*/
+ //while msg not consumed try to handover
+ TBool consumed = FALSE;
+ for ( TInt i = 0; (!consumed) && i < iSubsessions.Count(); i++ )
+ {
+ consumed = iSubsessions[ i ]->MessageReceivedL( aMsg );
+ }
+
+ //if unclaimed by any subsession, callback to first subsession
+ if(!consumed && iSubsessions.Count())
+ {
+ iSubsessions[0]->UnclaimedMessageL( aMsg );
+ }
+
+ MSRPLOG("CMSRPConnection::ParseStatus exit")
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::WriteSocketError
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::WriteSocketError(TInt aStatus)
+ {
+ MSRPLOG("CMSRPConnection::WriteSocketError() enter")
+ TInt err =0;
+ TRAP(err, NotifyAllL(EError, aStatus));
+ //CloseConnection();
+ MSRPLOG("CMSRPConnection::WriteSocketError() exit")
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::Send
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::SendL(MMSRPWriterObserver& aMsg)
+ {
+ MSRPLOG("CMSRPConnection::SendL() enter")
+ if(iConnectionState == EConnected)
+ iWriter->RequestSendL(aMsg);
+ MSRPLOG("CMSRPConnection::SendL() exit")
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::TimerExpired
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::TimerExpiredL()
+ {
+ MSRPLOG("CMSRPConnection::TimerExpired() enter")
+ if(iConnectionState == EListening)
+ NotifyAllL(EListenTimedOut, KErrTimedOut);
+ else
+ NotifyAllL(EConnectTimedOut, KErrTimedOut);
+ //iConnMngr.ListenCancel(this);
+ MSRPLOG("CMSRPConnection::TimerExpired() exit")
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::Remove
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::Remove(MMSRPConnectionObserver* aSubsession)
+ {
+ MSRPLOG("CMSRPConnection::Remove() enter")
+ TInt index = iSubsessions.Find(aSubsession);
+ //iSubsessions[index].DisconnectIssued;
+ if(index != KErrNotFound)
+ iSubsessions.Remove(index);
+ MSRPLOG("CMSRPConnection::Remove() exit")
+ }
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::CloseConnection
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::CloseConnection()
+ {
+ MSRPLOG("CMSRPConnection::CloseConnection() enter")
+ //for connected no listen cancel needed
+ //for listener error listener deleted
+ if(/*iConnectionState == EListenConnected ||*/ iConnectionState == EListening || iConnectionState == EListenTimedOut)
+ iConnMngr.ListenCancel(this);
+ else
+ //deleting connection, takes care of issuing cancel connect on connector also (if connecting)
+ iConnMngr.Remove(this);
+ MSRPLOG("CMSRPConnection::CloseConnection() exit")
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CMSRPConnection::NotifyAll
+// -----------------------------------------------------------------------------
+//
+void CMSRPConnection::NotifyAllL(TInt aNewState, TInt aStatus )
+ {
+ MSRPLOG("CMSRPConnection::NotifyAll() enter")
+ iConnectionState = aNewState;
+ for ( TInt i = 0; i < iSubsessions.Count(); i++ )
+ {
+ //make sure connectionstate does not release in notify
+ //else returns a value to reflect the same
+ iSubsessions[ i ]->ConnectionStateL( aNewState, aStatus );
+ }
+ MSRPLOG("CMSRPConnection::NotifyAll() exit")
+ }
+
+
+// End of File