diff -r f1578314b8da -r 505ad3f0ce5c Msrp/MsrpServer/src/CMSRPConnection.cpp --- /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