diff -r 000000000000 -r f5a58ecadc66 servicediscoveryandcontrol/pnp/test/upnp/Server/AppProtIntf/src/app_protintf_tcp.cpp --- /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 +#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 ( aSender ), KSockStream, KProtocolInetTcp ); + } + break; + + case TAppProtIntfMessage::TAcceptConnection::EId: + { + // Transfer the connection + TAppProtIntfMessage::TTransferConnection msg ( iAcceptedSocket, iReceivedData ); + PostToLink ( address_cast ( 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 ); + }