networkcontrol/ipscpr/src/deft_scpr.cpp
changeset 37 052078dda061
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networkcontrol/ipscpr/src/deft_scpr.cpp	Tue Jun 29 19:20:22 2010 +0530
@@ -0,0 +1,460 @@
+// 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 file for the IP SubConnection Provider
+// 
+//
+
+/**
+ @file
+*/
+
+#include <e32std.h>
+#include <e32test.h>
+#include <ss_glob.h>
+#include "deft_scpr.h"
+#include "ipscprlog.h"
+#ifdef SYMBIAN_NETWORKING_UMTSR5
+#include "MAppIdInfo.h"
+#include <networking/qos3gpp_subconparams.h>
+#include <ip_subconparams.h>
+#endif //SYMBIAN_NETWORKING_UMTSR5
+
+#ifdef SYMBIAN_NETWORKING_UMTSR5
+	const TUint32 KSIPSecureId  = 270490934;
+	const TUint32 KDHCPSecureId = 270522821;
+	const TUint32 KDNSSecureId  = 268437634;
+#endif //SYMBIAN_NETWORKING_UMTSR5
+
+CEmptySubConnectionProvider::~CEmptySubConnectionProvider()
+	{
+	__IPCPRLOG(IpCprLog::Printf(_L("~CEmptySubConnectionProvider [this=%08x]"), this));
+	if (iConnectionProvider)
+		{
+		iConnectionProvider->Leave(*this);
+		}
+	}
+
+void CEmptySubConnectionProvider::DoControlClientJoiningL(MSubConnectionControlClient& aControlClient)
+	{
+	(void)aControlClient;
+	__IPCPRLOG(IpCprLog::Printf(_L("CEmptySubConnectionProvider [this=%08x]:\tDoControlClientJoiningL() [iControlClients.Count=%d] [aControlClient=%08x]"), this, iControlClients.Count(), &aControlClient));
+	}
+	
+void CEmptySubConnectionProvider::DoControlClientLeaving(MSubConnectionControlClient& aControlClient)
+	{
+	(void)aControlClient;
+	__IPCPRLOG(IpCprLog::Printf(_L("CEmptySubConnectionProvider [this=%08x]:\tDoControlClientLeaving() [iControlClients.Count=%d] [aControlClient=%08x]"), this, iControlClients.Count(), &aControlClient));
+	}
+
+void CEmptySubConnectionProvider::EnumerateClientsL(TUint& aCount, TDes8& aDes, CConnectionProviderBase::TEnumClients aClientType)
+	{
+	STypeId tid = STypeId::CreateSTypeId(KConnectionClientExtUid,EConnectionClientDesc);
+	TInt max = iControlClients.Count();
+	for ( TInt n = 0; n < max; n++ )
+		{
+		MConnectionClientDesc* intf = reinterpret_cast<MConnectionClientDesc*>(iControlClients[n]->FetchInterfaceInstanceL(*this,tid));
+		if ( intf )
+			{
+			TConnectionProcessInfo cinfo;
+			cinfo.GetInfoL(aClientType,aCount, *intf, aDes);
+			}
+		}
+	STypeId tid2 = STypeId::CreateSTypeId(KConnectionClientExtUid,EConnectionEnumerateClients);
+	max = iDataClients.Count();
+	for ( TInt n = 0; n < max; n++ )
+		{
+		MConnectionEnumerateClients* intf = reinterpret_cast<MConnectionEnumerateClients*>(iDataClients[n]->FetchInterfaceInstanceL(*this,tid2));
+		if ( intf )
+			{
+			intf->EnumerateClientsL(aCount,aDes,aClientType);
+			}
+		}
+	}
+
+void CEmptySubConnectionProvider::ConnectionError(TInt /*aStage*/, TInt aError)
+	{//it's comming from connection at the same level so forward it sideways
+	//with an origin EConnection
+	TInt max = iDataClients.Count();
+	for ( TInt n = max - 1; n >= 0; n-- )
+		{
+		iDataClients[n]->SubConnectionError(*this, MSubConnectionDataClient::EConnection, aError);
+		}
+	}
+
+MConnectionDataClient* CEmptySubConnectionProvider::DoSelfConnectionDataClient()
+	{
+	return this;
+	}
+
+
+// Methods to be overriden be derived subconnection provider
+void CDefaultSubConnectionProvider::DoControlClientJoiningL(MSubConnectionControlClient& aControlClient)
+	{
+	(void)aControlClient;
+   __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoControlClientJoiningL [this=%08x]"), this));
+   if (NULL != NextLayer())
+      {
+      __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP exists - joined with provider")));
+      }
+   else
+      {
+      __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP doesn't exists - not joined")));
+      }
+	
+	}
+	
+void CDefaultSubConnectionProvider::DoDataClientJoiningL(MSubConnectionDataClient& aDataClient)
+	{
+#ifdef SYMBIAN_NETWORKING_UMTSR5
+	// This piece of code is being added as per the requirements of PREQ 635 of dedicated PDP signalling 
+	// context. When Primary PDP Context is created Network will return back the code saying whether it 
+	// accepts the request to be dedicated signalling context or not. If Network decided to allow for dedicated
+	// signalling context then UmtsGprs SCPR add the information into the iParameterBundle of the UmtsGprsScpr 
+	
+	// However, if the User doesnt do RSubConnection::SetParamter(EAttachDefault), which actually the user shouldn't do
+	// then we have to Get the parameter from the Next Layer, which again might or might not be UmtsGprs SubConnection Provider.
+	// Nevertheless if we call SetParameter() on iNextLayer then SetParameters across all the Layers below will get called, and 
+	// since I knew that if any of the layer below is UmtsGprsSCpr, it will update the IMCN Signalling flag in the 
+	// parameter Bundle which I will pass with the SetParameter()
+	
+	// We Initialize this variable everytime so that it can it can point to proper next layer 
+	// everytime. Just a safety measure because it will anyway be initialised by the code written 
+	// below
+	iSubConNextLayer = NULL;
+	if (NULL == iNextLayer)
+		{
+		// Find the Next Layer , otherwise iSubConNextLayer will be NULL by default.
+		CConnectionProviderBase* lowerConnectionProvider = iConnectionProvider->NextLayer();
+   		if (lowerConnectionProvider)
+       		{
+			TUint nextLayerFactoryId = lowerConnectionProvider->CanDoSubConnection(RSubConnection::EAttachToDefault);
+			if (nextLayerFactoryId != 0)
+	   			{	
+           		TSockManData* sockManData = SockManGlobals::Get();
+           		CSubConnectionFactoryContainer* subConnectionFactories = sockManData->iSubConnectionFactories;
+   	            XSubConnectionFactoryQuery query(lowerConnectionProvider, RSubConnection::EAttachToDefault);
+       		    iSubConNextLayer = subConnectionFactories->FindOrCreateProviderL(nextLayerFactoryId, query);
+	   			}	
+			        	
+       		}
+   		}
+	else
+		{
+		// We have a NextLayer, Point iSubConNextLayer to the same
+		iSubConNextLayer = iNextLayer;
+		}
+
+	// Get The parameter Bundle for this SubConnectionProvider Instance. if Not available create one
+	// and Get the parameters from the Next Lyer
+	CSubConParameterBundle *tempBundle = NULL;
+	if (iSubConNextLayer != NULL)
+		{
+		tempBundle = iParameterBundle != NULL? iParameterBundle :CSubConParameterBundle::NewL();
+		TRAP_IGNORE(iSubConNextLayer->SetParametersL(*tempBundle));
+		}
+	
+	// Get the family if Available
+	CSubConParameterFamily *imcnFamily = tempBundle != NULL ? tempBundle->FindFamily(KSubConnContextDescrParamsFamily) : NULL;
+	if (imcnFamily)
+		{
+		// Find the family, Look for the IMCN value, using CSubConImsExtParamSet defined in Qos3gpp
+		CSubConImsExtParamSet *imcnSigParams = static_cast<CSubConImsExtParamSet*>
+		(imcnFamily->FindExtensionSet(STypeId::CreateSTypeId(KSubConIPParamsUid,KSubConImsExtParamsType), 
+		CSubConParameterFamily::EGranted));
+		// If Family contains IMCN Signalling Parameters
+		if (imcnSigParams&& imcnSigParams->GetImsSignallingIndicator())	
+			{
+    		// Check and Delete
+			if (tempBundle != iParameterBundle)
+				{
+				tempBundle->Close();
+				tempBundle=NULL;
+				}
+			// Fetch the interface from the connection provider
+			STypeId typeID = STypeId::CreateSTypeId(KConnectionAppInfoInterfaceId,0); // IP Conenction provider factory Uid
+			TAny* intf = iConnectionProvider->FetchInterfaceInstanceL(typeID);
+			if (!intf)
+				{
+				// We are not able to get the AppSId so leaving
+				User::Leave(KErrNotSupported);
+				}
+			MConnectionAppIdInfo  *appIdIP = static_cast<MConnectionAppIdInfo*>(intf);
+			TUint32 appSecureId = appIdIP->GetAppSecureId();
+			
+			// if socket is being opened by any application other than SIP, DHCP, and DNS we need to
+			// restrict the socket from being Created.
+		
+			
+			if ( ( appSecureId==KSIPSecureId || iAppId == KSIPSecureId)  || 
+			     (appSecureId==KDHCPSecureId || iAppId == KDHCPSecureId)  || 
+			     (appSecureId==KDNSSecureId || iAppId == KDNSSecureId) )
+				{
+				aDataClient.JoinComplete(*this);
+				}
+		    else
+	            {
+	            User::Leave(KErrPermissionDenied);
+	            }	     
+			} // if (imcnSigParams&& imcnSigParams->GetImsSignallingIndicator())	
+		else
+		    {
+		    if (iConnectionProvider->IsLayerUp())
+		        {
+		         aDataClient.JoinComplete(*this);
+		        }
+
+	     	}
+		} // if (imcnFamily)
+		// Check and Delete
+		if (tempBundle != iParameterBundle && tempBundle!=NULL)
+		   {
+		    tempBundle->Close();
+	       }
+#else 
+			
+		if (iConnectionProvider->IsLayerUp())
+		  {
+		   aDataClient.JoinComplete(*this);
+		  }
+#endif 	// #ifdef SYMBIAN_NETWORKING_UMTSR5
+
+	}
+
+void CDefaultSubConnectionProvider::DoDataClientLeaving(MSubConnectionDataClient& aDataClient)
+	{
+	aDataClient.LeaveComplete(*this);
+	}
+	
+void CDefaultSubConnectionProvider::DoSourceAddressUpdate(MSubConnectionDataClient& /*aDataClient*/, const TSockAddr& /*aSource*/)
+	{
+	}
+	
+void CDefaultSubConnectionProvider::DoDestinationAddressUpdate(MSubConnectionDataClient& /*aDataClient*/, const TSockAddr& /*aDestination*/)
+	{
+	}
+	
+void CDefaultSubConnectionProvider::DoDataClientRouted(MSubConnectionDataClient& /*aDataClient*/, const TSockAddr& /*aSource*/, const TSockAddr& /*aDestination*/, const TDesC8& /*aConnectionInfo*/)
+	{
+	}
+	
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+void CDefaultSubConnectionProvider::DoParametersAboutToBeSetL(CSubConParameterBundle& aParameterBundle)
+	{
+   __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoParametersAboutToBeSetL [this=%08x]"), this));
+   if (NULL != NextLayer())
+      {
+      __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP exists - forwarding the request")));
+      iNextLayer->SetParametersL(aParameterBundle);
+      }
+   else
+      {
+      __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP doesn't exists - the request not supported")));
+      User::Leave(KErrNotSupported);        
+      }
+   }
+
+#else
+void CDefaultSubConnectionProvider::DoParametersAboutToBeSetL(CSubConParameterBundle& /*)aParameterBundle*/)
+	{//this could potentially fetch a current parameters from GuQoS and return them back as granted ones	
+	User::Leave(KErrNotSupported);
+	}
+#endif
+	
+#ifdef SYMBIAN_NETWORKING_UMTSR5	
+TInt CDefaultSubConnectionProvider::DoControl(TUint aOptionLevel, TUint /*aOptionName*/, TDes8& /*aOption*/)
+#else
+TInt CDefaultSubConnectionProvider::DoControl(TUint /*aOptionLevel*/, TUint /*aOptionName*/, TDes8& /*aOption*/)
+#endif //#ifdef SYMBIAN_NETWORKING_UMTSR5
+	{
+#ifdef SYMBIAN_NETWORKING_UMTSR5
+//This control is used to send application secure ID of Active Connection. This Id 
+//will be used to for adding socket as data client to the subconnection.
+	iAppId=aOptionLevel;
+	return KErrNone;
+#else
+	return KErrNotSupported;
+#endif //#ifdef SYMBIAN_NETWORKING_UMTSR5
+	}
+	
+void CDefaultSubConnectionProvider::DoStartL()
+	{
+   __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoStartL [this=%08x]"), this));
+	}
+	
+void CDefaultSubConnectionProvider::DoStop()
+	{
+   __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoStop [this=%08x]"), this));
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+   if (iNextLayer)
+      {
+      __IPCPRLOG(IpCprLog::Printf(_L("Leaving Lower subconnection provider")));
+      iNextLayer->Leave(*this);
+      iNextLayer = NULL;
+      }
+#endif
+	}
+	
+CSubConnectionProviderBase* CDefaultSubConnectionProvider::DoNextLayer()
+	{
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+   __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tDoNextLayer()"), this));
+   if (NULL == iNextLayer)
+      {
+      CConnectionProviderBase* lowerConnectionProvider = iConnectionProvider->NextLayer();
+      if (!lowerConnectionProvider)
+         {
+         //This could denote the connection isn't started and perhaps should be from here,
+         // but since the selection isn't separated from startup, we don't have enough
+         // information to do it here.
+         __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tDoNextLayer() Connection Provider is missing its NextLayer"), this));
+         return NULL;   // No Lower layer,so leaving rhostresolver without connection.
+         }
+		                                 
+		TUint nextLayerFactoryId = lowerConnectionProvider->CanDoSubConnection(RSubConnection::EAttachToDefault);
+      TRAP_IGNORE(
+      
+   		if (nextLayerFactoryId != 0)
+   		   {
+            //'This' not started yet. The lower layer unknown
+            //This is as much as we can delay with resolving the subconnection stack
+            TSockManData* sockManData = SockManGlobals::Get();
+            CSubConnectionFactoryContainer* subConnectionFactories = sockManData->iSubConnectionFactories;
+      
+            XSubConnectionFactoryQuery query(lowerConnectionProvider, RSubConnection::EAttachToDefault);
+               iNextLayer = subConnectionFactories->FindOrCreateProviderL(nextLayerFactoryId, query);
+   		   }
+   		
+         if (iNextLayer)
+            {
+            __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP found.. Joining")));
+            iNextLayer->JoinL(*this);
+            }
+         else
+            {
+            __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP not found.. Continuing")));
+            }
+         );
+         
+      }
+      
+   return iNextLayer;
+
+#else
+   __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP not supported")));
+	return NULL;
+#endif
+//SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+	}
+	
+CConnDataTransfer& CDefaultSubConnectionProvider::DoDataTransferL()
+	{
+	User::Leave(KErrNotSupported);
+	//unreachable code
+	return iNextLayer->DataTransferL();
+ 	}
+	
+//MConnectionDataClient
+TAny* CDefaultSubConnectionProvider::FetchInterfaceInstanceL(CConnectionProviderBase& /*aProvider*/, const STypeId& aTid)
+	{
+	return (aTid == STypeId::CreateSTypeId(KConnectionClientExtUid,EConnectionEnumerateClients)) ? static_cast<MConnectionEnumerateClients*>(this) : NULL;
+	}
+	
+void CDefaultSubConnectionProvider::ConnectionGoingDown(CConnectionProviderBase& /*aConnProvider*/)
+	{
+	__IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tConnectionGoingDown()"), this));
+	iConnectionProvider = NULL;
+	DeleteMeNow();
+	}
+	
+void CDefaultSubConnectionProvider::Notify(MConnectionDataClient::TNotify aNotifyType, CConnectionProviderBase* /*aConnProvider*/, TInt aError, const CConNotificationEvent* /*aConNotificationEvent*/)
+	{
+	int count = iControlClients.Count();	
+	for (int i = count - 1; i >= 0; --i)
+		{		
+		iControlClients[i]->SubConnectionEvent(*this, aNotifyType, aError, NULL);
+		}
+	if (aNotifyType == ENotifyLayerUp)
+		{//complete outstanding data client joins
+		TInt max = iDataClients.Count();
+		for ( TInt n = max - 1; n >= 0; n-- )
+			{
+			if (aError == KErrNone)
+				{
+				iDataClients[n]->JoinComplete(*this);
+				}
+			else
+				{
+				iDataClients[n]->JoinFailed(*this,aError);
+				}
+			}
+		}
+	}
+	
+void CDefaultSubConnectionProvider::AttachToNext(CSubConnectionProviderBase* /*aSubConnProvider*/)
+	{
+	}
+
+CDefaultSubConnectionProvider::~CDefaultSubConnectionProvider ()
+   {
+	__IPCPRLOG(IpCprLog::Printf(_L("~CDefaultSubConnectionProvider [this=%08x]"), this));
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+   if (iNextLayer) 
+      {
+      iNextLayer->Leave (*this);
+      }
+#endif	
+   }
+	
+	
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+void CDefaultSubConnectionProvider::DoControlClientLeaving(MSubConnectionControlClient& aControlClient)
+   {
+   (void)aControlClient;
+	__IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tDoControlClientLeaving() [iControlClients.Count=%d] [aControlClient=%08x]"), this, iControlClients.Count(), &aControlClient));
+
+    // Note: control client count == 1 because the the client has not been removed yet
+    if (iNextLayer && iControlClients.Count() == 1 && iDataClients.Count() == 0) 
+      {
+      iNextLayer->Leave (*this);
+      iNextLayer = NULL;
+      }
+   }
+
+void CDefaultSubConnectionProvider::SubConnectionEvent(CSubConnectionProviderBase& /*aSubConnProvider*/, MConnectionDataClient::TNotify /*aNotifyType*/, TInt /*aError*/, const CSubConNotificationEvent* aEvent)
+    {
+    NotifyClientEvent(*aEvent);
+    }	
+    
+    
+void CDefaultSubConnectionProvider::SubConnectionGoingDown(CSubConnectionProviderBase& /*aSubConnProvider*/)
+    {
+	TInt max = iControlClients.Count();
+	for ( TInt n = max - 1; n >= 0; n-- )
+		{
+		iControlClients[n]->SubConnectionGoingDown(*this);
+		}
+    }
+    
+    
+void CDefaultSubConnectionProvider::LayerUp(CSubConnectionProviderBase& /*aSubConnProvider*/, TInt /*aError*/)
+   {
+   }
+   
+void CDefaultSubConnectionProvider::IncomingConnection(CSubConnectionProviderBase* /*aSubConnProvider*/, CSubConParameterBundle* /*aParameterBundle*/, TInt /*aError*/)
+   {
+   }
+    
+#endif
+// SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+