linklayerprotocols/pppnif/te_ppp/te_incoming_ppp/src/pppendpointimpl.cpp
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linklayerprotocols/pppnif/te_ppp/te_incoming_ppp/src/pppendpointimpl.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,645 @@
+// Copyright (c) 2004-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:
+// Implementation of CPppEndpointImpl class
+// 
+//
+
+/**
+ @file 
+ @internalComponent
+*/
+
+
+
+#include "pppendpointimpl.h"
+
+
+#include <in_sock.h>
+#include <ss_pman.h>
+
+using namespace te_ppploopback; 
+
+/**
+ Constructs the receiver channel.
+ 
+ @param aSocket The socket used by receiver.
+ */
+CRx::CRx(RSocket* aSocket) : CActive(CActive::EPriorityStandard),iRecvLen(MAX_MSG_LEN), iSocket(aSocket)
+	{
+	}
+
+/**
+ Static construction: Constructs the receiver channel.
+ 
+ @param aSocket The socket used by receiver.
+ */
+CRx* CRx::NewL(RSocket* aSocket)
+	{
+	CRx* self = new (ELeave) CRx(aSocket);
+	CleanupStack::PushL(self);
+	CleanupStack::Pop();
+	CActiveScheduler::Add(self);
+	return self;
+	}
+
+
+/**
+ Destroys the receiver channel.
+ 
+ */
+CRx::~CRx()
+	{
+	Cancel(); // cancel ANY outstanding request at time of destruction
+	iObserver = NULL;
+	iSocket = NULL;	
+	}
+
+/**
+ Issues asynchronous read request.
+ 
+ @post Request has been issued.
+ */
+void CRx::RxL()
+	{
+
+	// Issue read request
+	iSocket->RecvFrom(iDataBuffer, iRecvAddr, 0, iStatus);
+	SetActive();
+	}
+
+/**
+ Sets the observer for the events on this channel.
+ 
+ @param aObserver The observer.
+ @post Observer is set.
+ */
+void CRx::SetObserver (MSocketObserver* aObserver)
+	{
+	iObserver = aObserver;
+	}
+
+/**
+ Retrieves the data received on the channel.
+ 
+ @return data buffer.
+ @pre There was data reception notification
+ */
+HBufC16* CRx::GetDataIn(void)
+	{
+	return iDataBuffer16.Alloc();
+	}
+
+/**
+ Retrieves the source address of the data received on the channel.
+ 
+ @return source address
+ @pre There was data reception notification
+ */	
+ TInetAddr CRx::GetSourceInetAddr(void)
+ 	{
+ 	return iRecvAddr;
+ 	}
+ 
+
+/**
+ Notify the channel observer that there was an event.
+ 
+ @param aEvent the event
+ @post Observer is Notified.
+ */
+void CRx::NotifyEvent (TInt aEvent)
+	{
+	iObserver->HandleSocketEvent(CPppEndpointImpl::ESourceRx, aEvent);
+	}
+
+
+/**
+ Service an event on our channel
+ Implementation of ActiveObject::RunL()
+ 
+ @pre There was a request issued.
+ @post event was serviced.
+ */
+void CRx::RunL(void)
+	{
+	if (iStatus==KErrNone) // received some data
+		{
+		// covert binary received to unicode
+		TPtrC16 myPtr (reinterpret_cast<const TUint16*>(iDataBuffer.Ptr()), (iDataBuffer.Size()/2));
+		iDataBuffer16 = myPtr;
+
+		NotifyEvent(CRx::ERxReceiveOK);
+		}
+	else
+		{
+		// some error condition
+		NotifyEvent(CRx::ERxReceiveFailed);
+		}
+	}
+/**
+ Cancels receive events.
+ 
+ @post No more events come from this channel.
+ */
+void CRx::DoCancel (void)
+	{
+	iSocket->CancelRecv();
+	}
+
+
+
+/**
+ Constructs the Transmitter channel.
+ 
+ @param aSocket the channel's socket
+ @param aPeerIpAddr the IP address of the communication peer
+ @param aPeerPort UDP port of the peer.
+ @post Channel is constructed.
+ */
+CTx::CTx(RSocket* aSocket, const TPtrC& aPeerIpAddr, TInt aPeerPort) 
+	: CActive(CActive::EPriorityStandard),
+	iSocket(aSocket)
+	{
+	iSendAddr.Input(aPeerIpAddr);
+	iSendAddr.SetPort(aPeerPort);	
+	}
+/**
+ Static Construction.
+
+ @param aSocket     the channel's socket
+ @param aPeerIpAddr the IP address of the communication peer
+ @param aPeerPort    UDP port of the peer.
+ @post Channel is constructed.
+ */
+CTx* CTx::NewL(RSocket* aSocket, const TPtrC& aPeerIpAddr, TInt aPeerPort)
+	{
+	CTx* self = new (ELeave) CTx(aSocket, aPeerIpAddr, aPeerPort);
+	CleanupStack::PushL(self);
+	CleanupStack::Pop();
+	CActiveScheduler::Add(self);
+	return self;
+	}
+	
+/**
+ Destruction
+
+ @post Channel is destroyed
+ */
+CTx::~CTx()
+	{
+	Cancel(); // cancel ANY outstanding request at time of destruction
+	iObserver = NULL;
+	iSocket = NULL;
+	}
+/**
+ Request to transmit a message, asynchronous.
+
+ @param aData the data to send
+ @post Request was issued.
+ */
+void CTx::TxL (TDesC16& aData)
+	{
+	if (!IsActive())
+		{
+		// Take a copy of the unicode data to be sent as binary.
+		TPtrC8 myPtr (reinterpret_cast<const TUint8*>(aData.Ptr()), aData.Size());
+		iDataBuffer = myPtr;
+
+		iSocket->SendTo(iDataBuffer, iSendAddr, 0, iStatus);
+		SetActive();
+		}
+	}
+/**
+ Sets the observer for this channel
+ 
+ @param aObserver the channel's observer
+ @post Observer is set.
+ */
+void CTx::SetObserver (MSocketObserver* aObserver)
+	{
+	iObserver = aObserver;
+	}
+
+/**
+ Notify the observer about an event on the channel.
+
+ @param aEvent the event
+ @post Observer was notified.
+ */
+void CTx::NotifyEvent (TInt aEvent)
+	{
+	iObserver->HandleSocketEvent(CPppEndpointImpl::ESourceTx, aEvent);
+	}
+
+/**
+ Service an event on the channel
+ Implementation of ActiveObject::RunL()
+
+ @post Event was serviced.
+ */
+void CTx::RunL(void)
+	{
+	if (iStatus==KErrNone) // transmit ok
+		{
+		NotifyEvent(CTx::ETxTransmitOK);
+		}
+	else
+		{
+		NotifyEvent(CTx::ETxTransmitFailed);
+		}
+	}
+
+/**
+ Cancels all outstanding send requests
+ 
+ @post All requests were cancelled.
+ */
+void CTx::DoCancel (void)
+	{
+	iSocket->CancelSend();
+	}
+	
+	
+//******************************************************************************************
+// PPP Endpoint implementation. 
+
+/**
+ Construction
+  
+ @param aIapId Iap Id for this endpoint
+ @param aOwnIpAddr IP address to use with this endpoint
+ @param aOwnPort  Port to used with this endpoint
+ @param aPeerIpAddr the IP address of the communication peer 
+ @param aPeerPort UDP port of the peer.
+ @post Endpiont is constructed
+ */
+CPppEndpointImpl::CPppEndpointImpl(TInt aIapId, const TPtrC& aOwnIpAddr, TInt aOwnPort, const TPtrC& aPeerIpAddr, TInt aPeerPort):
+	 CActive(CActive::EPriorityStandard),
+	 iIapId(aIapId),
+	 iOwnIpAddr(aOwnIpAddr),
+	 iOwnPort(  aOwnPort),
+	 iPeerIpAddr(aPeerIpAddr),	 
+	 iPeerPort(  aPeerPort),
+	 iPppLink(NULL)
+	{
+	}
+
+/**
+ Static Construction
+ 
+ @param aIapId      Id for this endpoint
+ @param aOwnIpAddr  IP address to use with this endpoint
+ @param aOwnPort    Port to used with this endpoint
+ @param aPeerIpAddr the IP address of the communication peer 
+ @param aPeerPort   UDP port of the peer.
+ @post Endpoint had been constructed
+ */
+CPppEndpointImpl* CPppEndpointImpl::NewL(TInt aIapId, const TPtrC& aOwnIpAddr, TInt aOwnPort, const TPtrC& aPeerIpAddr, TInt aPeerPort)
+	{
+	CPppEndpointImpl* self = new (ELeave) CPppEndpointImpl(aIapId, aOwnIpAddr, aOwnPort, aPeerIpAddr, aPeerPort);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	CActiveScheduler::Add(self);
+	return self;
+	}
+
+/**
+ Second phase of construction
+ Creates the simplex channels.
+
+ @post Channels are constructed.
+ */
+void CPppEndpointImpl::ConstructL (void)
+	{	
+	iPppLink = new (ELeave) CPppLinkImpl(this, &iRConn); // PPP link
+	
+	iRxAO = CRx::NewL(&iSocket); // Receiver channel
+	iRxAO->SetObserver(this);
+	
+	iTxAO = CTx::NewL(&iSocket, iPeerIpAddr, iPeerPort); // Transmitter channel	
+	iTxAO->SetObserver(this);	
+	}
+
+
+/**
+ Destruction
+ Cancels all requests.
+
+ @post Endpoint had been destroyed.
+ */
+CPppEndpointImpl::~CPppEndpointImpl()
+	{
+	// Cancel ANY outstanding request - including these requests owned by the channels
+	Cancel();
+	
+	iListener = NULL;
+	delete iRxAO;
+	delete iTxAO;
+	delete iPppLink;
+	}
+	
+	
+void CPppEndpointImpl::NotifyLinkUp(TInt aError)
+	{
+	iListener->OnEvent(iOurId, MPppEndpointListener::ELinkUp, aError);
+	}
+	
+void CPppEndpointImpl::NotifyLinkDown(TInt aError)
+	{
+	iListener->OnEvent(iOurId, MPppEndpointListener::ELinkDown, aError);
+	}
+
+
+
+
+/**
+ Handles an event on a channel
+
+ @param aSource event source
+ @param aReason event cause
+ @post Event was handled.
+ */
+void CPppEndpointImpl::HandleSocketEvent (TInt aSource, TInt aReason)
+	{
+	// Translate and dispatch to our own listener.
+	switch(aSource) // Determine who caused the event
+		{
+		case ESourceRx:
+			if(aReason == CRx::ERxReceiveOK)
+				{
+				iListener->OnEvent(iOurId, MPppEndpointListener::ERecv, KErrNone);
+				}
+			else if(aReason == CRx::ERxReceiveFailed)
+				{
+				iListener->OnEvent(iOurId, MPppEndpointListener::ERecv, KErrGeneral);
+				}
+			else
+				{
+				ASSERT(EFalse);
+				}
+			break; 
+		
+		case ESourceTx :
+			if(aReason == CTx::ETxTransmitOK)
+				{
+				iListener->OnEvent(iOurId, MPppEndpointListener::ESend, KErrNone);
+				}
+			else if(aReason == CTx::ETxTransmitFailed)
+				{
+				iListener->OnEvent(iOurId, MPppEndpointListener::ESend, KErrGeneral);
+				}
+			else
+				{
+				ASSERT(EFalse);
+				}
+			break;		
+			
+		
+		default:
+			ASSERT(EFalse); 
+		}
+	}
+
+
+/**
+ Requests a Connection to the PPP Peer asynchronously
+
+ @post Request was issued.
+ */
+void CPppEndpointImpl::ConnectToPeerL()
+	{	
+	TInt err = KErrNone;;
+	
+	err = iSession.Connect(); // Connect to the socket server
+	User::LeaveIfError(err);		
+	
+	err = iRConn.Open(iSession); 
+	User::LeaveIfError(err);
+	
+	// Set connection preferences to use PPP
+	iConnPref.SetIapId(iIapId);
+	
+	// NOTE: There is an issue with PhoneBook synchronizer as of March 3, 2004.
+	// It may cause the tests to fail, if "ECommDbDialogPrefDoNotPrompt" is specified.
+	// If this is the case, use "ECommDbDialogPrefPromptIfWrongMode" instead.
+	iConnPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
+	
+	
+	// Issue asynchronous request to initialize PPP. This returns immediately.
+	iPppLink->OpenPppLinkL(&iConnPref);
+	}
+	
+
+/**
+ Disconnects from the peer.
+
+ @post Disconnected from the peer.
+ */
+void CPppEndpointImpl::DisconnectFromPeerL()
+	{
+	iPppLink->ClosePppLinkL();
+	iRConn.Close();
+	iSession.Close();		
+	}
+	
+TBool CPppEndpointImpl::IsConnectedToPeer()
+	{
+	return (iRConn.SubSessionHandle() != 0);
+	}
+
+/**
+ Opens a communication channel for this endpoint.
+ Does not affect PPP operation.
+ Used for allow a complete separation of PPP connection / disconnection and data exchange.
+ 
+ @pre Successfully connected to PPP Peer.
+ @post Communication channel is open
+ */
+void CPppEndpointImpl::OpenCommChannelL()
+	{	
+	TInt err = iSocket.Open(iSession, KAfInet, KSockDatagram, KProtocolInetUdp, iRConn);
+	User::LeaveIfError(err);
+
+	// Bind the socket
+	TInetAddr ownAddrOnPort;
+	ownAddrOnPort.Input(iOwnIpAddr);
+	ownAddrOnPort.SetPort(iOwnPort);	
+	User::LeaveIfError(iSocket.Bind(ownAddrOnPort));	
+	}
+	
+/**
+ Closes the communication channel for this endpoint.
+ Does not affect PPP operation.
+ Used for allow a complete separation of PPP connection / disconnection and data exchange.
+ 
+ @post Communication channel is closed
+ */
+void CPppEndpointImpl::CloseCommChannel()
+	{
+	iRxAO->Cancel();
+	iTxAO->Cancel();	
+	iSocket.CancelAll();
+	iSocket.Close();
+	} 	
+	
+
+/**
+ Request to send a message on the channel, asynchronous
+
+ @param aMsg The message
+ @pre Communication channel opened successfully.
+ @post The request was issued
+ */
+void CPppEndpointImpl::SendMessageL (TDesC& aMsg)
+	{
+	iTxAO->TxL(aMsg);
+	}
+
+/**
+ Sets a listener for this PPP endpoint.
+ 
+ @param aListener The listener
+ @param aId the ID for this endpoint
+ @post Listener was set.
+ */
+void CPppEndpointImpl::SetObserver (MPppEndpointListener* aListener, MPppEndpointListener::EEndpointId aId)
+	{
+	iListener = aListener;
+	iOurId = aId;
+	}
+
+/**
+ Request to receive a message on the channel, asynchronous
+ 
+ @pre Communication channel opened successfully.
+ @post The request was issued
+ */
+void CPppEndpointImpl::RequestMessageL (void)
+	{
+	iRxAO->RxL();
+	}
+
+
+/**
+ Retrieves the data received on this channel.
+ 
+ @return the data buffer
+ @pre Communication channel opened successfully.
+ */
+
+HBufC16* CPppEndpointImpl::GetDataIn(void)
+	{
+	return iRxAO->GetDataIn();
+	}
+ 
+	
+/**
+ Retrieves the source address of the data received on this channel.
+ 
+ @return the source address
+ @pre Receive event notification was received. 
+ */
+TInetAddr CPppEndpointImpl::GetSourceInetAddr(void)	
+	{
+	return iRxAO->GetSourceInetAddr();
+	}
+
+
+
+
+/**
+Retrieves the primary and secondary IPv4 DNS addresses of this endpoint
+
+@param aDns1 Set to the primary DNS address on return, if any (should be cleared on entry)
+@param aDns2 Set to the secondary DNS address on return, if any (should be cleared on entry)
+
+@pre must be connected to peer (Because we may need to obtain our DNS address from peer.
+*/
+void CPppEndpointImpl::GetDnsAddrsL(TUint32& aDns1, TUint32& aDns2)
+	{
+	TPckgBuf<TSoInetInterfaceInfo> infoBuf;		// IPv4 stack only
+	TSoInetInterfaceInfo info;					// IPv4 stack only
+	
+	// Open a socket to get the interfaces.
+	RSocket sock;
+	User::LeaveIfError(
+		sock.Open(iSession, KAfInet, KSockStream, KProtocolInetTcp, iRConn));
+
+	// Iterate through all interfaces, looking for DNS servers
+	for (;;)
+		{
+		TInt retc = sock.GetOpt(KSoInetNextInterface,KSolInetIfCtrl,infoBuf);
+		if (retc == KErrNotFound)
+			break;
+		else if (retc != KErrNone)
+			{
+			break;
+			}
+			
+		info = infoBuf();
+		TBool gotAddrs = EFalse;
+		
+		
+		if (info.iState == EIfUp)
+			{
+			if (info.iNameSer1.Address())
+				{
+				aDns1 = info.iNameSer1.Address();
+				gotAddrs = ETrue;
+				}
+			
+			if (info.iNameSer2.Address() && (info.iNameSer2.Address() != info.iNameSer1.Address()))
+				{
+				aDns2 = info.iNameSer2.Address();
+				gotAddrs = ETrue;
+				}
+			}
+
+		if (gotAddrs)
+			break;
+		}
+		
+		sock.Close();
+	}
+
+
+
+
+
+// ActiveObject Implementation.
+
+/**
+ Called by ActiveObject::Cancel()
+ 
+ @post communication channel was closed.
+ */
+void CPppEndpointImpl::DoCancel (void)
+	{
+	CloseCommChannel();	// cancels everything and closes the socket.
+	iPppLink->Cancel();
+	}
+	
+
+/**
+ ActiveObject::RunL() 
+ Never gets called in this implementation
+ 
+*/	
+void CPppEndpointImpl::RunL(void)
+	{
+	}
+	
+
+