--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/ftpengine/ftpprot/PICHNL.CPP Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,307 @@
+// 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 PI channel of the FTP protocol
+// Model the PI Channel as an FSM
+// Transitions between states are triggered by PI methods and events
+// coming from ESOCK
+//
+//
+
+/**
+ @file PICHNL.CPP
+ @internalComponent
+*/
+
+//#include <in_sock.h>
+//#include <c32comm.h>
+#include "DEBUG.H"
+#include "PICHNL.H"
+#include "FTPPROT.H"
+#include <e32base.h>
+//#include <es_sock.h>
+//#include <nifman.h>
+
+//
+// Definitions
+//
+
+CPISocketRead::CPISocketRead(MPIChannelNotifier* aNotifier,
+ CPIChannel* aPIChannel)
+ : CActive(EPriorityStandard)
+/**
+CPISocketRead object
+Read Write implementaion.
+*/
+ {
+ iNotifier = aNotifier;
+ iPIChannel = aPIChannel;
+ };
+
+CPISocketRead* CPISocketRead::NewL(MPIChannelNotifier* aNotifier,
+ CPIChannel* aPIChannel)
+ {
+ CPISocketRead* self = new(ELeave) CPISocketRead(aNotifier,aPIChannel);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ };
+
+void CPISocketRead::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ };
+
+void CPISocketRead::DoCancel()
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("CPISocketRead::DoCancel() called"));
+ iSocket->CancelAll();
+ };
+
+void CPISocketRead::RunL()
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("CPISocketRead::RunL() called"));
+ if (iStatus == KErrNone)
+ {
+ // Call our notifier
+ iNotifier->PIChannelRcvNotification();
+ }
+ else
+ {
+ // Uh!!! weird
+ Cancel();
+ //Disconnect Pi Channel
+ iPIChannel->Disconnect();
+ // Notify caller
+ iNotifier->PIChannelOperationError(MPIChannelNotifier::EPiConnectionReset);
+ }
+ };
+
+void CPISocketRead::IssueRead(TDes8& aBuffer)
+/**
+Read Data from a Stream Socket
+*/
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("CPISocketRead::IssueRead() called\n"));
+ if (this->IsActive())
+ return;
+ iSocket->RecvOneOrMore(aBuffer, 0, iStatus,iRcvLen);
+ SetActive();
+ FTPPROTDEBUG(_DBGPichnl,_L("CPISocketRead::IssueRead() recv triggered\n"));
+ };
+
+CPIChannel::CPIChannel(MPIChannelNotifier* aNotifier)
+ :CActive(CActive::EPriorityStandard)
+/**
+PI Channel object
+*/
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("CPIChannel::CPIChannel called\n"));
+ //Initialise State
+ iPIChannelState = EPIChannelIdle;
+ iNotifier = aNotifier;
+ }
+
+CPIChannel* CPIChannel::NewL(MPIChannelNotifier* aNotifier,
+ RSocketServ& aSockServ)
+ {
+ CPIChannel* self = new (ELeave) CPIChannel(aNotifier);
+ CleanupStack::PushL(self);
+ self->ConstructL(aSockServ);
+ CleanupStack::Pop();
+ return self;
+ }
+
+void CPIChannel::ConstructL(RSocketServ& aSockServ)
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("CPIChannel::ConstructL called\n"));
+ iSockServ = aSockServ;
+ iReceiver = CPISocketRead::NewL(iNotifier,this);
+ CActiveScheduler::Add(this);
+ }
+
+CPIChannel::~CPIChannel()
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("CPIChannel::~CPIChannel called\n"));
+ //Abort receive
+ if ( iReceiver )
+ {
+ iReceiver->Cancel();
+ delete iReceiver;
+ }
+ }
+
+void CPIChannel::RunL()
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("Mytest::RunL activated for CPIChannel\n"));
+ switch(iPIChannelState)
+ {
+ case EPIChannelIdle:
+ // Cannot be activated in that state
+ __ASSERT_DEBUG(FALSE, User::Panic(_L("CPIChannel"), EPIPanicOutOfState));
+ break;
+ case EPIChannelConnecting:
+ FTPPROTDEBUG(_DBGPichnl,_L("CPIChannel::RunL state: Connecting\n"));
+ // Check result of connecting request
+ switch (iStatus.Int())
+ {
+ case KErrNone:
+ // If succeed set state to EPIChannelConnected
+ iPIChannelState = EPIChannelConnected;
+ // Call notifier
+ iNotifier->PIChannelOperationCompletion(MPIChannelNotifier::EPiConnectComplete);
+ break;
+ default:
+ // Reset channel to Idle/disconnect socket
+ Disconnect();
+ // Notify caller
+ iNotifier->PIChannelOperationError(MPIChannelNotifier::EPiConnectFailed);
+ break;
+ }
+ break;
+ case EPIChannelDisconnecting:
+ FTPPROTDEBUG(_DBGPichnl,_L("CPIChannel::RunL state: Connecting\n"));
+ // Assume disconnect always work
+ Disconnect();
+ // Notify caller
+ iNotifier->PIChannelOperationCompletion(MPIChannelNotifier::EPiDisconnectComplete);
+ break;
+ case EPIChannelSending:
+ FTPPROTDEBUG(_DBGPichnl,_L("CPIChannel::RunL state: EPIChannelSending\n"));
+ // Check result of send request
+ switch (iStatus.Int())
+ {
+ case KErrNone:
+ // If succeed set state to EPIChannelConnected
+ iPIChannelState = EPIChannelConnected;
+ // Call notifier
+ iNotifier->PIChannelOperationCompletion(MPIChannelNotifier::EPiSendComplete);
+ break;
+ default:
+ // Reset channel to Idle/disconnect socket
+ Disconnect();
+ // Notify caller
+ iNotifier->PIChannelOperationError(MPIChannelNotifier::EPiSendFailed);
+ break;
+ }
+ break;
+ default:
+ __ASSERT_DEBUG(FALSE, User::Panic(_L("CPIChannel::RunL"), 0));
+ break;
+ }
+ }
+
+TBool CPIChannel::Connect(TSockAddr& aNetAddr)
+/**
+@return FALSE if a socket could not be openned
+ Caller must check the result and post an error if appropriate
+*/
+ {
+ // Check this is a valid state for this operation
+ __ASSERT_DEBUG((iPIChannelState == EPIChannelIdle), User::Panic(_L("CPIChannel"), EPIPanicChannelConnected));
+ // Open a socket
+ if(KErrNone != iPiSocket.Open(iSockServ, KAfInet, KSockStream, KProtocolInetTcp))
+ // Socket could not be openned, bail out
+ return FALSE;
+ // Give CPISocketRead the ref to my socket
+ iReceiver->SetSocket(&iPiSocket);
+ // Connect to peer
+ iPiSocket.Connect(aNetAddr, iStatus);
+ // Update state
+ iPIChannelState = EPIChannelConnecting;
+ // Activate the object
+ SetActive();
+ // Everything's OK
+ return TRUE;
+ }
+void CPIChannel::GetLocalAddress(TInetAddr& aLocalAddr)
+ {
+ // get my local address
+ // seems that LocalAddress function does not return
+ // the IP address until you've connected to somewhere
+ // hence I need this function to be called once the
+ // connect has succeeded to discover my IP address
+ iPiSocket.LocalName(aLocalAddr);
+ }
+
+TBool CPIChannel::Busy(void)
+/**
+@return The state of DTP Channel
+*/
+ {
+ return(iPIChannelState != EPIChannelConnected);
+ }
+
+void CPIChannel::Disconnect(void)
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("CPIChannel::Disconnect called\n"));
+ //Close PI socket
+ iReceiver->Cancel();
+ Cancel();
+ iPiSocket.Close();
+ iPIChannelState = EPIChannelIdle;
+ }
+
+void CPIChannel::SendCommand(TDes8& aCommand,TUint aSomeFlags,TBool aSendCRLF)
+ {
+ // If I'm not connected just return don't post error
+ if(iPIChannelState == EPIChannelIdle)
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("!!!!!Not Connected - SendCommand not triggered\n"));
+ return;
+ }
+ //__ASSERT_DEBUG(iPIChannelState != EPIChannelIdle, User::Panic(_L("CPIChannel"), EPIPanicChannelNotConnected));
+ // Update the state
+ iPIChannelState = EPIChannelSending;
+ // Add the Telnet terminator sequence
+ // BIG BIG assumption here !! the buffer is big enough
+ // but FtpProtocol is my friend I trust it
+ if(aSendCRLF)
+ {
+ aCommand.Append(CR);
+ aCommand.Append(LF);
+ }
+ // Send the command
+ iPiSocket.Send(aCommand,aSomeFlags,iStatus);
+ // Activate the object
+ SetActive();
+ }
+
+
+void CPIChannel::GetNextAnswer(TDes8& aBuffer)
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("CPIChannel::GetNextAnswer called\n"));
+ if(iPIChannelState != EPIChannelIdle)
+ // Fetch the reply sent by the server
+ iReceiver->IssueRead(aBuffer);
+ }
+
+void CPIChannel::DoCancel(void)
+ {
+ FTPPROTDEBUG(_DBGPichnl,_L("CPIChannel::DoCancel called\n"));
+ iReceiver->Cancel();
+ switch(iPIChannelState)
+ {
+ case EPIChannelConnecting:
+ iPiSocket.CancelConnect();
+ iPiSocket.Close();
+ iPIChannelState = EPIChannelIdle;
+ break;
+ default:
+ break;
+ }
+ }
+