--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/ftpengine/ftpprot/DTPCHNL.CPP Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,330 @@
+// Copyright (c) 1998-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:
+// FTP protocol engine
+// Author: Philippe Gabriel
+// Implements objet controling the DTP channel of the FTP protocol
+// Model the DTP Channel as an FSM
+//
+//
+
+/**
+ @file DTPCHNL.CPP
+ @internalComponent
+*/
+
+//#include <in_sock.h>
+//#include <c32comm.h>
+#include "DEBUG.H"
+#include "DTPCHNL.H"
+#include "FTPPROT.H"
+//#include <es_sock.h>
+
+//
+// Definitions
+//
+
+CDTPChannel::CDTPChannel(MDTPChannelNotifier* aNotifier,
+ CFTPSetError* aCFTPSetError)
+ :CActive(CActive::EPriorityStandard)
+/**
+DTP Channel object
+*/
+ {
+ FTPPROTDEBUG(_DBGDtpchnl,_L("CDTPChannel::CDTPChannel called\n"));
+ //Initialise State
+ iDTPChannelState = EDTPChannelIdle;
+ iNotifier = aNotifier;
+ iCFTPSetError = aCFTPSetError;
+ }
+
+CDTPChannel* CDTPChannel::NewL(MDTPChannelNotifier* aNotifier,
+ CFTPSetError* aCFTPSetError,
+ RSocketServ& aSockServ)
+ {
+ CDTPChannel* self = new (ELeave) CDTPChannel(aNotifier,
+ aCFTPSetError);
+ CleanupStack::PushL(self);
+ self->ConstructL(aSockServ);
+ CleanupStack::Pop();
+ return self;
+ }
+
+void CDTPChannel::ConstructL(RSocketServ& aSockServ)
+ {
+ FTPPROTDEBUG(_DBGDtpchnl,_L("CDTPChannel::ConstructL called\n"));
+ iSockServ = aSockServ;
+ CActiveScheduler::Add(this);
+ }
+
+CDTPChannel::~CDTPChannel()
+ {
+ FTPPROTDEBUG(_DBGDtpchnl,_L("CDTPChannel::~CDTPChannel called\n"));
+ Disconnect();
+ }
+
+void CDTPChannel::DoCancel(void)
+ {
+ FTPPROTDEBUG(_DBGDtpchnl,_L("CDTPChannel::DoCancel -state: "));
+ switch(iDTPChannelState)
+ {
+ case EDTPChannelConnected:
+ case EDTPChannelIdle:
+ case EDTPChannelShutingDown:
+ FTPPROTDEBUG(_DBGDtpchnl,_L(" No req pending\n"));
+ //Nothing to do
+ break;
+ case EDTPChannelConnecting:
+ case EDTPChannelListening:
+ case EDTPChannelReceiving:
+ case EDTPChannelSending:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("Req pending - Canceling all "));
+ // Cancel all request
+ iDTPTransferSocket.CancelAll();
+ // Close all sockets
+ iDTPListenSocket.Close();
+ iDTPTransferSocket.Close();
+ // Reset state
+ iDTPChannelState = EDTPChannelIdle;
+ break;
+ default:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("INVALID STATE\n "));
+ // Cannot be activated in that state
+ __ASSERT_DEBUG(FALSE, User::Panic(_L("DTPChannel"), EDTPPanicChannelOutOfState));
+ break;
+ }
+ }
+
+TBool CDTPChannel::Connect(TSockAddr& aNetAddr)
+ {
+ FTPPROTDEBUG(_DBGDtpchnl,_L("CDTPChannel::Connect called\n"));
+ if(KErrNone != iDTPTransferSocket.Open(iSockServ, KAfInet, KSockStream, KProtocolInetTcp))
+ return FALSE;
+ // Connect to peer
+ iDTPTransferSocket.Connect(aNetAddr, iStatus);
+ // Update state
+ iDTPChannelState = EDTPChannelConnecting;
+ // Activate the object
+ SetActive();
+ return TRUE;
+ }
+
+void CDTPChannel::Accept(void)
+ {
+ FTPPROTDEBUG(_DBGDtpchnl,_L("CDTPChannel::Accept called\n"));
+ iDTPListenSocket.Accept(iDTPTransferSocket, iStatus);
+ // Activate the object
+ SetActive();
+ }
+
+TUint CDTPChannel::ListeningPort(void)
+ {
+ FTPPROTDEBUG(_DBGDtpchnl,_L("CDTPChannel::ListeningPort called\n"));
+ if(KErrNone != iDTPListenSocket.Open(iSockServ, KAfInet, KSockStream, KProtocolInetTcp))
+ return 0;
+ if(KErrNone != iDTPTransferSocket.Open(iSockServ))
+ return 0;
+ iLocalAddress.SetPort(0);
+ if(KErrNone != iDTPListenSocket.Bind(iLocalAddress))
+ {
+ Disconnect();
+ return 0;
+ }
+ if(KErrNone != iDTPListenSocket.Listen(1))
+ {
+ Disconnect();
+ return 0;
+ }
+ iDTPChannelState = EDTPChannelListening;
+ return iDTPListenSocket.LocalPort();
+ }
+
+void CDTPChannel::Disconnect(void)
+ {
+ Cancel();
+ iDTPListenSocket.Close();
+ iDTPTransferSocket.Close();
+ iDTPChannelState = EDTPChannelIdle;
+ }
+
+void CDTPChannel::Send(TDesC8& aBuffer)
+ {
+ iDTPTransferSocket.Send(aBuffer,0,iStatus);
+ iDTPChannelState = EDTPChannelSending;
+ SetActive();
+ }
+
+void CDTPChannel::SendEOF(void)
+ {
+ // Following line caused the connection to be closed with a
+ // RST, SunOS ftpd complained about that
+ // iDTPTransferSocket.Shutdown(RSocket::ENormal,iStatus);
+ // Following line to stop on a sending socket
+ // iDTPTransferSocket.Shutdown(RSocket::EStopOutput,iStatus);
+ // Following line to stop on a sending socket
+ iDTPTransferSocket.Shutdown(RSocket::EStopInput,iStatus);
+ iDTPChannelState = EDTPChannelShutingDown;
+ SetActive();
+ }
+
+void CDTPChannel::Recv(TDes8& aBuffer)
+ {
+ FTPPROTDEBUG(_DBGDtpchnl,_L("CDTPChannel::Recv called\n"));
+ iDTPTransferSocket.RecvOneOrMore(aBuffer, 0, iStatus,iRcvLen);
+ iDTPChannelState = EDTPChannelReceiving;
+ SetActive();
+ }
+
+TBool CDTPChannel::Closed(void)
+/**
+@return The state of DTP Channel
+*/
+ {
+ return(iDTPChannelState==EDTPChannelIdle);
+ }
+
+TBool CDTPChannel::Connected(void)
+/**
+@return The state of DTP Channel
+*/
+ {
+ return((iDTPChannelState==EDTPChannelConnected)
+ || (iDTPChannelState==EDTPChannelSending)
+ || (iDTPChannelState==EDTPChannelReceiving));
+ }
+
+void CDTPChannel::RunL()
+ {
+ FTPPROTDEBUG(_DBGDtpchnl,_L("CDTPChannel::RunL -state: "));
+ switch(iDTPChannelState)
+ {
+ case EDTPChannelIdle:
+ FTPPROTDEBUG(_DBGDtpchnl,_L(" Idle -PANIC-\n"));
+ // Cannot be activated in that state
+ __ASSERT_DEBUG(FALSE, User::Panic(_L("DTPChannel"), EDTPPanicChannelOutOfState));
+ // Do error recovery
+ break;
+ case EDTPChannelConnecting:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("EDTPChannelConnecting "));
+ // Check result of connecting request
+ switch (iStatus.Int())
+ {
+ case KErrNone:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("iStatus:OK\n"));
+ // If succeed change state
+ iDTPChannelState = EDTPChannelConnected;
+ // Call notifier
+ iNotifier->DTPChannelOperationCompletion(MDTPChannelNotifier::EDtpConnectComplete);
+ break;
+ default:
+ FTPPROTDEBUG1(_DBGDtpchnl,_L("FAILED iStatus:<%d>\n "),iStatus.Int());
+ // Disconnect DTP Channel
+ Disconnect();
+ iNotifier->DTPChannelOperationError(MDTPChannelNotifier::EDtpConnectFailed);
+ break;
+ }
+ break;
+ case EDTPChannelListening:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("EDTPChannelListening "));
+ // Close listening socket immediately
+ // Don't want open ports hangin round
+ iDTPListenSocket.Close();
+ // Check result of accepting request
+ switch (iStatus.Int())
+ {
+ case KErrNone:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("iStatus:OK\n"));
+ // If succeed change state
+ iDTPChannelState = EDTPChannelConnected;
+ // Call notifier
+ iNotifier->DTPChannelOperationCompletion(MDTPChannelNotifier::EDtpAcceptComplete);
+ break;
+ default:
+ FTPPROTDEBUG1(_DBGDtpchnl,_L("FAILED iStatus:<%d>\n "),iStatus.Int());
+ // Disconnect DTP Channel
+ Disconnect();
+ iNotifier->DTPChannelOperationError(MDTPChannelNotifier::EDtpConnectFailed);
+ break;
+ }
+ break;
+ case EDTPChannelReceiving:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("EDTPChannelReceiving "));
+ switch (iStatus.Int())
+ {
+ case KErrNone:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("iStatus:OK\n"));
+ // Packet received - Call notifier
+ iNotifier->DTPChannelXferNotification(MDTPChannelNotifier::EDtpRcvMoreData);
+ break;
+ case KErrEof:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("iStatus:KErrEof\n"));
+ // Disconnect DTP Channel
+ Disconnect();
+ // Server closed the DTP Channel - Call notifier
+ iNotifier->DTPChannelXferNotification(MDTPChannelNotifier::EDtpRcvComplete);
+ break;
+ default:
+ FTPPROTDEBUG1(_DBGDtpchnl,_L("FAILED iStatus: <%d>\n"),iStatus.Int());
+ // Disconnect DTP Channel
+ Disconnect();
+ // Notify caller
+ iNotifier->DTPChannelOperationError(MDTPChannelNotifier::EDtpRecvAborted);
+ break;
+ }
+ break;
+ case EDTPChannelSending:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("EDTPChannelSending "));
+ switch (iStatus.Int())
+ {
+ case KErrNone:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("iStatus:OK\n"));
+ // Packet sent - Call notifier
+ iNotifier->DTPChannelXferNotification(MDTPChannelNotifier::EDtpSendComplete);
+ break;
+ default:
+ FTPPROTDEBUG1(_DBGDtpchnl,_L("FAILED iStatus: <%d>"),iStatus.Int());
+ // Disconnect DTP Channel
+ Disconnect();
+ // Notify caller
+ iNotifier->DTPChannelOperationError(MDTPChannelNotifier::EDtpSendAborted);
+ break;
+ }
+ break;
+ case EDTPChannelShutingDown:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("EDTPChannelShutingDown "));
+ // Whatever shutdown returns Disconnect DTP Channel
+ Disconnect();
+ switch (iStatus.Int())
+ {
+ // Only do a shutdown on a SendEOF operation
+ case KErrNone:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("iStatus:OK\n"));
+ // DTP transfer socket closed Ok - Call notifier
+ iNotifier->DTPChannelXferNotification(MDTPChannelNotifier::EDtpSendEOFComplete);
+ break;
+ default:
+ // Something wrong with the shutdown, can't assume the peer received the file ok
+ FTPPROTDEBUG1(_DBGDtpchnl,_L("FAILED iStatus: <%d>\n"),iStatus.Int());
+ // Notify caller
+ iNotifier->DTPChannelOperationError(MDTPChannelNotifier::EDtpSendAborted);
+ break;
+ }
+ break;
+ default:
+ FTPPROTDEBUG(_DBGDtpchnl,_L("INVALID STATE\n "));
+ // Cannot be activated in that state
+ __ASSERT_DEBUG(FALSE, User::Panic(_L("DTPChannel"), EDTPPanicChannelOutOfState));
+ break;
+ }
+
+ }