servicediscoveryandcontrol/pnp/test/upnp/Server/AppProtIntf/src/app_protintf_tcp.cpp
changeset 0 f5a58ecadc66
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servicediscoveryandcontrol/pnp/test/upnp/Server/AppProtIntf/src/app_protintf_tcp.cpp	Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,171 @@
+// Copyright (c) 2008-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:
+//
+
+#include "app_protintf_tcp.h"
+#include <in_sock.h>
+#include "app_protintf_msgs.h"
+const TInt KListenQSize = 5;
+
+using namespace Messages;
+
+CApplicationProtocolIntfBase* CApplicationProtocolIntfTcp::NewL ( TInt aPort )
+	{
+	CApplicationProtocolIntfTcp* self = new (ELeave)CApplicationProtocolIntfTcp( aPort );
+	return self;	
+	}
+
+CApplicationProtocolIntfTcp::CApplicationProtocolIntfTcp ( TInt aPort )
+: CApplicationProtocolIntfBase ( aPort, KProtocolInetTcp ),iAcceptedSocketHandler (*this)
+	{
+	LOG_NODE_CREATE ( KESockFlowTag, CApplicationProtocolIntfTcp );	
+	}
+
+CApplicationProtocolIntfTcp::~CApplicationProtocolIntfTcp ()
+	{
+	Shutdown();
+	LOG_NODE_DESTROY(KESockFlowTag, CApplicationProtocolIntfTcp);
+	}
+
+void CApplicationProtocolIntfTcp::ReceivedL ( const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage )
+	{
+	__ASSERT_DEBUG ( aMessage.MessageId ().Realm () == TAppProtIntfMessage::ERealmId, User::Panic ( KAppProtIntfInvalidRealmId, KInvalidReamId ) );
+	
+	CApplicationProtocolIntfBase::ReceivedL ( aSender, aRecipient, aMessage );
+	switch ( aMessage.MessageId ().MessageId () )
+		{
+		case TAppProtIntfMessage::TJoin::EId:
+			{
+			InitiateLinkL ( address_cast<TNodeCtxId> ( aSender ), KSockStream, KProtocolInetTcp );
+			}
+			break;
+		
+		case TAppProtIntfMessage::TAcceptConnection::EId:
+			{
+			// Transfer the connection
+			TAppProtIntfMessage::TTransferConnection msg ( iAcceptedSocket, iReceivedData );
+			PostToLink ( address_cast<TNodeCtxId> ( aSender ), msg );
+			
+			RInternalSocket sock;
+			iAcceptedSocket = sock;	 // Empty the accepted socket, as ownership is transferred
+			iReceivedData.Init (); // Empty the received data
+			DoAccept ();
+			__ASSERT_DEBUG ( iReceivedData.IsEmpty(), User::Invariant() );
+			}
+			break;
+			
+		case TAppProtIntfMessage::TRejectConnection::EId:
+			{
+			// Note: If there is a rejection e should send the data to next links till last, one by one.
+			// Currently we have only one link. Noone is there to accept this connection. So close the accepted socket
+			// and keep in accept modefor new connections
+			
+			// The link should sent rejected data. If the rejected data is sent and we don't have any more links
+			// we will send the rejected data and go into an accepting mode. 
+			// If there is no rejected data we will close the accepted socket && directly go into an accepting mode 
+			
+			// For example: In the case of HTTP the link will send an internal error 500 or not found 400 response
+						
+			TAppProtIntfMessage::TRejectConnection& msg = message_cast < TAppProtIntfMessage::TRejectConnection > ( aMessage );
+			iReceivedData.Free ();
+			if ( msg.iData.Length() > 0 )
+				{
+				iAcceptedSocketHandler.Send ( msg.iData );
+				}
+			else
+				{						
+				iAcceptedSocket.Close();
+				DoAccept ();
+				}
+			}
+			break;
+			
+		case TAppProtIntfMessage::TMoreData::EId:
+			{
+			iReceivedData.Init();
+			iAcceptedSocketHandler.Recv();
+			break;
+			}
+		}
+	}
+
+void CApplicationProtocolIntfTcp::DoAccept ()
+	{
+	iSocketHandler.Accept();		
+	}
+
+TInt CApplicationProtocolIntfTcp::Startup ()
+	{
+	// Start listening and accepting for new connections
+	TInt err = iSocket.Listen( KListenQSize ); 
+	if ( err == KErrNone )
+		DoAccept ();
+	return err;		
+	}
+
+void CApplicationProtocolIntfTcp::Shutdown ()
+	{	
+	iAcceptedSocketHandler.CancelAll ();
+	iAcceptedSocket.Close ();
+	CApplicationProtocolIntfBase::Shutdown ();
+	}
+
+void CApplicationProtocolIntfTcp::AcceptComplete ( RInternalSocket& aSocket )
+	{
+	iAcceptedSocket = aSocket;
+	iAcceptedSocketHandler.Attach ( aSocket );
+	
+	iAcceptedSocketHandler.Recv(); // Start receiving the data
+	}
+
+void CApplicationProtocolIntfTcp::RecvComplete ( RMBufChain& aData )
+	{
+	// Post the data to the link. We should do this one by one. But for the timebeing we
+	// are keeping it simple. ie; one link is attached with us.
+	__ASSERT_DEBUG ( iLinks.Count() > 0, User::Invariant() );
+	
+	if ( iLinks[0].Flags() != TClientType::ELeaving )
+		{
+		iReceivedData.Append ( aData );
+		
+		TAppProtIntfMessage::TNewConnection msg ( iReceivedData );
+		PostToLink ( iLinks[0], msg );
+		}
+	else
+		{
+		iAcceptedSocket.Close ();
+		aData.Free ();
+		}
+	}
+
+void CApplicationProtocolIntfTcp::SendComplete ( TInt /* aLength */ )
+	{
+	// we will send data only for the accepted socket. Send complete means, we don't have anyone to accept
+	// our connection and typically a error response ( protocol dependent ) will be send to the client and 
+	// we will close the connection.
+	// Send completed. Close the accepted socket and move into an accepting mode
+	iAcceptedSocket.Close ();
+	DoAccept ();
+	}
+
+void CApplicationProtocolIntfTcp::Error ( TOperation aOperation, TInt aError )
+	{
+	// If we have a recv/send failure we should handle it here. otherwise allow the base class to handle the error
+	if ( ( aOperation == SockHandler::ERecv ) || ( aOperation == SockHandler::EMBufSend ) )
+		{
+		DoAccept ();
+		return;
+		}
+	CApplicationProtocolIntfBase::Error ( aOperation, aError );
+	}