servicediscoveryandcontrol/pnp/test/upnp/Server/AppProtIntf/src/app_protintf_tcp.cpp
changeset 0 f5a58ecadc66
equal deleted inserted replaced
-1:000000000000 0:f5a58ecadc66
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "app_protintf_tcp.h"
       
    17 #include <in_sock.h>
       
    18 #include "app_protintf_msgs.h"
       
    19 const TInt KListenQSize = 5;
       
    20 
       
    21 using namespace Messages;
       
    22 
       
    23 CApplicationProtocolIntfBase* CApplicationProtocolIntfTcp::NewL ( TInt aPort )
       
    24 	{
       
    25 	CApplicationProtocolIntfTcp* self = new (ELeave)CApplicationProtocolIntfTcp( aPort );
       
    26 	return self;	
       
    27 	}
       
    28 
       
    29 CApplicationProtocolIntfTcp::CApplicationProtocolIntfTcp ( TInt aPort )
       
    30 : CApplicationProtocolIntfBase ( aPort, KProtocolInetTcp ),iAcceptedSocketHandler (*this)
       
    31 	{
       
    32 	LOG_NODE_CREATE ( KESockFlowTag, CApplicationProtocolIntfTcp );	
       
    33 	}
       
    34 
       
    35 CApplicationProtocolIntfTcp::~CApplicationProtocolIntfTcp ()
       
    36 	{
       
    37 	Shutdown();
       
    38 	LOG_NODE_DESTROY(KESockFlowTag, CApplicationProtocolIntfTcp);
       
    39 	}
       
    40 
       
    41 void CApplicationProtocolIntfTcp::ReceivedL ( const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage )
       
    42 	{
       
    43 	__ASSERT_DEBUG ( aMessage.MessageId ().Realm () == TAppProtIntfMessage::ERealmId, User::Panic ( KAppProtIntfInvalidRealmId, KInvalidReamId ) );
       
    44 	
       
    45 	CApplicationProtocolIntfBase::ReceivedL ( aSender, aRecipient, aMessage );
       
    46 	switch ( aMessage.MessageId ().MessageId () )
       
    47 		{
       
    48 		case TAppProtIntfMessage::TJoin::EId:
       
    49 			{
       
    50 			InitiateLinkL ( address_cast<TNodeCtxId> ( aSender ), KSockStream, KProtocolInetTcp );
       
    51 			}
       
    52 			break;
       
    53 		
       
    54 		case TAppProtIntfMessage::TAcceptConnection::EId:
       
    55 			{
       
    56 			// Transfer the connection
       
    57 			TAppProtIntfMessage::TTransferConnection msg ( iAcceptedSocket, iReceivedData );
       
    58 			PostToLink ( address_cast<TNodeCtxId> ( aSender ), msg );
       
    59 			
       
    60 			RInternalSocket sock;
       
    61 			iAcceptedSocket = sock;	 // Empty the accepted socket, as ownership is transferred
       
    62 			iReceivedData.Init (); // Empty the received data
       
    63 			DoAccept ();
       
    64 			__ASSERT_DEBUG ( iReceivedData.IsEmpty(), User::Invariant() );
       
    65 			}
       
    66 			break;
       
    67 			
       
    68 		case TAppProtIntfMessage::TRejectConnection::EId:
       
    69 			{
       
    70 			// Note: If there is a rejection e should send the data to next links till last, one by one.
       
    71 			// Currently we have only one link. Noone is there to accept this connection. So close the accepted socket
       
    72 			// and keep in accept modefor new connections
       
    73 			
       
    74 			// The link should sent rejected data. If the rejected data is sent and we don't have any more links
       
    75 			// we will send the rejected data and go into an accepting mode. 
       
    76 			// If there is no rejected data we will close the accepted socket && directly go into an accepting mode 
       
    77 			
       
    78 			// For example: In the case of HTTP the link will send an internal error 500 or not found 400 response
       
    79 						
       
    80 			TAppProtIntfMessage::TRejectConnection& msg = message_cast < TAppProtIntfMessage::TRejectConnection > ( aMessage );
       
    81 			iReceivedData.Free ();
       
    82 			if ( msg.iData.Length() > 0 )
       
    83 				{
       
    84 				iAcceptedSocketHandler.Send ( msg.iData );
       
    85 				}
       
    86 			else
       
    87 				{						
       
    88 				iAcceptedSocket.Close();
       
    89 				DoAccept ();
       
    90 				}
       
    91 			}
       
    92 			break;
       
    93 			
       
    94 		case TAppProtIntfMessage::TMoreData::EId:
       
    95 			{
       
    96 			iReceivedData.Init();
       
    97 			iAcceptedSocketHandler.Recv();
       
    98 			break;
       
    99 			}
       
   100 		}
       
   101 	}
       
   102 
       
   103 void CApplicationProtocolIntfTcp::DoAccept ()
       
   104 	{
       
   105 	iSocketHandler.Accept();		
       
   106 	}
       
   107 
       
   108 TInt CApplicationProtocolIntfTcp::Startup ()
       
   109 	{
       
   110 	// Start listening and accepting for new connections
       
   111 	TInt err = iSocket.Listen( KListenQSize ); 
       
   112 	if ( err == KErrNone )
       
   113 		DoAccept ();
       
   114 	return err;		
       
   115 	}
       
   116 
       
   117 void CApplicationProtocolIntfTcp::Shutdown ()
       
   118 	{	
       
   119 	iAcceptedSocketHandler.CancelAll ();
       
   120 	iAcceptedSocket.Close ();
       
   121 	CApplicationProtocolIntfBase::Shutdown ();
       
   122 	}
       
   123 
       
   124 void CApplicationProtocolIntfTcp::AcceptComplete ( RInternalSocket& aSocket )
       
   125 	{
       
   126 	iAcceptedSocket = aSocket;
       
   127 	iAcceptedSocketHandler.Attach ( aSocket );
       
   128 	
       
   129 	iAcceptedSocketHandler.Recv(); // Start receiving the data
       
   130 	}
       
   131 
       
   132 void CApplicationProtocolIntfTcp::RecvComplete ( RMBufChain& aData )
       
   133 	{
       
   134 	// Post the data to the link. We should do this one by one. But for the timebeing we
       
   135 	// are keeping it simple. ie; one link is attached with us.
       
   136 	__ASSERT_DEBUG ( iLinks.Count() > 0, User::Invariant() );
       
   137 	
       
   138 	if ( iLinks[0].Flags() != TClientType::ELeaving )
       
   139 		{
       
   140 		iReceivedData.Append ( aData );
       
   141 		
       
   142 		TAppProtIntfMessage::TNewConnection msg ( iReceivedData );
       
   143 		PostToLink ( iLinks[0], msg );
       
   144 		}
       
   145 	else
       
   146 		{
       
   147 		iAcceptedSocket.Close ();
       
   148 		aData.Free ();
       
   149 		}
       
   150 	}
       
   151 
       
   152 void CApplicationProtocolIntfTcp::SendComplete ( TInt /* aLength */ )
       
   153 	{
       
   154 	// we will send data only for the accepted socket. Send complete means, we don't have anyone to accept
       
   155 	// our connection and typically a error response ( protocol dependent ) will be send to the client and 
       
   156 	// we will close the connection.
       
   157 	// Send completed. Close the accepted socket and move into an accepting mode
       
   158 	iAcceptedSocket.Close ();
       
   159 	DoAccept ();
       
   160 	}
       
   161 
       
   162 void CApplicationProtocolIntfTcp::Error ( TOperation aOperation, TInt aError )
       
   163 	{
       
   164 	// If we have a recv/send failure we should handle it here. otherwise allow the base class to handle the error
       
   165 	if ( ( aOperation == SockHandler::ERecv ) || ( aOperation == SockHandler::EMBufSend ) )
       
   166 		{
       
   167 		DoAccept ();
       
   168 		return;
       
   169 		}
       
   170 	CApplicationProtocolIntfBase::Error ( aOperation, aError );
       
   171 	}