tcpiputils/dhcp/src/DHCPServer.cpp
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tcpiputils/dhcp/src/DHCPServer.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,291 @@
+// Copyright (c) 2003-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:
+// Implements a Symbian OS server that exposes the RCDHCP API
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#include <e32svr.h>
+#include <e32base.h>
+#include <e32std.h>
+#include "DHCP_Std.h"
+#include "DHCPServer.h"
+#include "DHCPSess.h"
+#include "DHCPIP4Msg.h"
+#ifdef SYMBIAN_NETWORKING_PLATSEC
+#include <ecom/ecom.h>
+#include "DHCPPolicy.h"
+#endif
+
+#ifdef _DEBUG
+#include <e32property.h>
+#endif
+
+/**
+ *  Holds current debug options of the server
+ *  @internalComponent
+ */
+TInt CDHCPServer::iDebugFlags(0);
+
+CDHCPServer::~CDHCPServer()
+/**
+ *
+ * Destructor
+ *
+ * @internalComponent
+ */
+	{
+	__CFLOG_CLOSE;
+	__CFLOG_DELETE;
+	iEsock.Close();
+	delete iTimer;
+	}
+
+#ifdef SYMBIAN_NETWORKING_PLATSEC
+CDHCPServer::CDHCPServer(): CPolicyServer(EPriorityStandard,Policy,ESharableSessions)
+#elif defined(EKA2)
+CDHCPServer::CDHCPServer(): CServer2(EPriorityStandard)
+#else
+//On  EKA1, session is open in one thread and used in another
+CDHCPServer::CDHCPServer(): CServer2(EPriorityStandard, ESharableSessions)
+#endif
+/**
+ * The CDHCPServer::CDHCPServer method
+ *
+ * Constructor
+ *
+ * @internalComponent
+ */
+	{
+	}
+	
+CDHCPServer* CDHCPServer::NewL()
+/**
+ * Creates and start the CServer2 derived server.
+ * Called inside the MainL() function.
+ *
+ * @return - Instance of the server
+ */
+	{
+	CDHCPServer* server = new (ELeave) CDHCPServer();
+	CleanupStack::PushL(server);
+	server->ConstructL();
+	// CServer2 base class call
+	server->StartL(KDHCPServerName);
+	CleanupStack::Pop(server);
+	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPServer::NewL")));
+	return server;
+	}
+
+void CDHCPServer::ConstructL()
+/**
+  * Second stage construction
+  *
+  * @internalTechnology
+  *
+  */
+	{
+	__CFLOG_CREATEL;
+	__CFLOG_OPEN;
+	User::LeaveIfError(iEsock.Connect());
+#ifdef _DEBUG
+	DebugFlags() = 0;
+#endif
+	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPServer::ConstructL - connected to ESock")));
+	}
+
+
+CSession2* CDHCPServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
+/**
+ *
+ * Create a new If on this server
+ *
+ * @param	&aVersion	Vesion of server
+ * @return	A new CDHCP session to be used for the connection
+ *
+ * @internalTechnology
+ */
+	{
+//	TVersion v(KDHCPSrvMajorVersionNumber,KDHCPSrvMinorVersionNumber,KDHCPSrvBuildVersionNumber);
+
+	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPServer::NewSessionL - creating new session...")));
+
+	//	if (!User::QueryVersionSupported(v, aVersion))
+//		User::Leave(KErrNotSupported);
+	CDHCPSession* ses = CDHCPSession::NewL();
+	SessionConnected();
+	return ses;
+	}
+	
+void CDHCPServer::SessionConnected() const
+/**
+  * Called by session to alert server
+  * that something has connected so
+  * cancel the shutdown timer if there
+  * is one running
+  *
+  */
+  	{
+	if (iTimer)
+		{
+		iTimer->Cancel();
+		}  	
+  	}
+	
+void CDHCPServer::Close(CDHCPSession* /*aDHCPSession*/)
+/**
+  * Reference counting for the server.
+  * When there are no sessions open then
+  * we shutdown, unless the only one open
+  * is oursleves, then we obviously still shutdown...
+  *
+  * @internalTechnology
+  */
+	{
+	iSessionIter.SetToFirst();
+	
+   	TInt count = 0;
+   	while (iSessionIter++!=NULL)
+   		{
+   		count++;
+   		}
+	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPServer::Close - Current Session Count: (%d)") ,count));
+		         
+		         
+	// if we have one session then it is the current one
+	// and ok to shutdown...as this function is called
+	// before the session is destroyed...
+	if (count==1)
+		{
+		if (!iTimer)
+			{
+			TRAPD(ret, iTimer = CExpireTimer::NewL());
+			if (ret!=KErrNone)
+				{
+				// OOM so why not just shut down to free some
+				// seeing as that's the process that's been set
+				// in motion anyway...
+				TimerExpired();
+				return;
+				}
+			}			
+		// wait for 10 seconds before shutting down completely...
+		// in case anyone wants to connect			
+		iTimer->After(TTimeIntervalSeconds(KOneSecond/*10*/), *this);
+		}	
+	REComSession::FinalClose();
+	}
+	
+void CDHCPServer::TimerExpired()
+/**
+  * CExpireTimer interface function to  alert server timer has popped
+  *
+  */
+  	{
+  	// just stop the server if we get here....
+	CActiveScheduler::Stop();
+  	}
+
+TInt& CDHCPServer::DebugFlags()
+/**
+  * Provides acess to debug flags
+  */
+	{
+	return iDebugFlags;
+	}
+
+LOCAL_C void MainL()
+/**
+ * Do the funky stuff, and use Rendezvous to signal completion...
+ */
+	{
+	// Leave the hooks in for platform security
+#if (defined __DATA_CAGING__)
+	RProcess().DataCaging(RProcess::EDataCagingOn);
+	RProcess().SecureApi(RProcess::ESecureApiOn);
+#endif
+
+#if defined(__WINS__) && !defined(EKA2) //WINS emulator
+	User::LeaveIfError(RThread().Rename(KDHCPProcessName));
+#elif !defined(EKA2)
+	User::LeaveIfError(RProcess().Rename(KDHCPProcessName));
+#else //WINCW emulator or any target
+	User::LeaveIfError(RProcess::RenameMe(KDHCPProcessName));
+#endif
+
+#ifdef _DEBUG
+	TInt err = RProperty::Define(KMyPropertyCat, KMyPropertyDestPortv4, RProperty::EInt, TSecurityPolicy(TSecurityPolicy::EAlwaysPass),
+				TSecurityPolicy(ECapabilityWriteDeviceData));
+	if (err == KErrNone)
+		{
+		// not defined by test code
+		RProperty::Define(KMyPropertyCat, KMyPropertyDestPortv6, RProperty::EInt, TSecurityPolicy(TSecurityPolicy::EAlwaysPass),
+					TSecurityPolicy(ECapabilityWriteDeviceData));
+		RProperty::Set(KMyPropertyCat, KMyPropertyDestPortv4, 67);	// set to default values
+		RProperty::Set(KMyPropertyCat, KMyPropertyDestPortv6, 547);	// set to default values
+		RProperty::Define(KMyPropertyCat, KMyDefaultLeaseTime, RProperty::EInt, TSecurityPolicy(TSecurityPolicy::EAlwaysPass),
+					TSecurityPolicy(ECapabilityWriteDeviceData));
+		RProperty::Set(KMyPropertyCat, KMyDefaultLeaseTime, 21600);	// Define and set default values for server lease time
+		}
+#endif
+
+	CActiveScheduler* pScheduler = new(ELeave)CActiveScheduler;
+	CActiveScheduler::Install(pScheduler);
+	CleanupStack::PushL(pScheduler);
+	CDHCPServer* pServer = CDHCPServer::NewL();
+	CleanupStack::PushL(pServer);
+
+	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("MainL - about to start activescheduler")));
+	// Sync with the starter and enter the active scheduler
+#if defined(__WINS__) && !defined(EKA2)
+	RThread::Rendezvous(KErrNone); //WINS emulator
+#else	//WINSCW emulator or any target
+	RProcess::Rendezvous(KErrNone);
+#endif
+	CActiveScheduler::Start();
+	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("MainL - activescheduler has stopped...")));
+	CleanupStack::PopAndDestroy(pServer);
+	CleanupStack::PopAndDestroy(pScheduler);
+	}
+
+
+EXPORT_C TInt E32Main()
+/**
+ * The main thread function, the Ordinal 1!
+ * @return - Standard Epoc error code on exit
+ */
+	{	
+__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	if (cleanup == NULL)
+		{
+		return KErrNoMemory;
+		}
+	TInt err = KErrNone;
+	TRAP(err,MainL());
+	delete cleanup;
+__UHEAP_MARKEND;
+	return err;
+    }
+    
+#if !defined(EKA2)
+GLDEF_C TInt E32Dll(enum TDllReason)
+	{
+	return 0;
+	}
+#endif