datacommsserver/esockserver/ssock/ss_apiext_messages.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/ssock/ss_apiext_messages.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,239 @@
+// Copyright (c) 2006-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:
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#include "ss_apiext_messages.h"
+#include <comms-infras/ss_api_ext.h>
+#include <comms-infras/ss_thread.h>
+#include <ss_glob.h>
+#include <comms-infras/es_api_ext.h>
+
+using namespace ESock;
+using namespace Elements;
+using namespace Messages;
+using namespace MeshMachine;
+
+// ----- TOpenExtensionInterface -----
+
+void TOpenExtensionInterface::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient)
+    {
+    const TNodeId& nodeId = address_cast<TNodeId>(aRecipient);
+	TAny* itf = FetchInterfaceOrForwardMsgL(aSender, *this, nodeId.Node(), iInterfaceId);
+
+	if(itf)
+		{
+		AExtensionInterfaceThickBase& baseItf = *static_cast<AExtensionInterfaceThickBase*>(itf);
+
+		//This fn will not allow an interface to be reqistered twice
+		SockManGlobals::Get()->iCommsApiExtRegister.RegisterInterfaceL(iInterfaceId, baseItf.MsgImplTid(), iClientId);
+
+		//When completed with an error code (!=KErrNone), this responder will deregister interface for this client
+		baseItf.OpenExtensionInterface(iClientId, nodeId, CCommsApiExtIpcOpenResponder::NewL(iInterfaceId, iClientId, iMessage));
+		// coverity [memory_leak] - the ownership of CCommsApiExtIpcOpenResponder::NewL(iInterfaceId, iClientId, iMessage) 
+		// is taken by the function, OpenExtensionInterface. No need to setup cleanup stack for memory leak
+		}
+	}
+
+void TOpenExtensionInterface::Error(const TRuntimeCtxId& /*aSender*/, const TRuntimeCtxId& /*aRecipient*/, TInt aError)
+	{
+   	if (aError==KErrNotFound)
+   		{
+   		//This IPC call has not been served.
+   		aError=KErrNotSupported;
+   		}
+
+	iMessage.Complete(aError);
+	}
+
+DEFINE_MVIP_CTR(TOpenExtensionInterface)
+
+START_ATTRIBUTE_TABLE(TOpenExtensionInterface, KExtItfMsgImplementationUid, EOpenExtensionInterface)
+	REGISTER_ATTRIBUTE(TOpenExtensionInterface, iClientId, TMeta<TUint>)
+	REGISTER_ATTRIBUTE(TOpenExtensionInterface, iInterfaceId, TMeta<TSupportedCommsApiExt>)
+END_ATTRIBUTE_TABLE_BASE(TCFSigRMessage2Ext, ESignatureRMessage2)
+
+// ----- TCloseExtensionInterface -----
+
+void TCloseExtensionInterface::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient)
+    {
+    const TNodeId& nodeId = address_cast<TNodeId>(aRecipient);
+	TAny* itf = FetchInterfaceOrForwardMsgL(aSender, *this, nodeId.Node(), iInterfaceId);
+
+	if(itf)
+		{
+		AExtensionInterfaceThickBase& baseItf = *static_cast<AExtensionInterfaceThickBase*>(itf);
+		baseItf.CloseExtensionInterface(iClientId);
+		SockManGlobals::Get()->iCommsApiExtRegister.DeRegisterInterface(iInterfaceId, iClientId);
+		iMessage.Complete(KErrNone);
+		}
+	}
+
+void TCloseExtensionInterface::Error(const TRuntimeCtxId& /*aSender*/, const TRuntimeCtxId& /*aRecipient*/, TInt /*aError*/)
+	{
+	// Anything to do?
+	}
+
+DEFINE_MVIP_CTR(TCloseExtensionInterface)
+
+START_ATTRIBUTE_TABLE(TCloseExtensionInterface, KExtItfMsgImplementationUid, ECloseExtensionInterface)
+	REGISTER_ATTRIBUTE(TCloseExtensionInterface, iClientId, TMeta<TUint>)
+	REGISTER_ATTRIBUTE(TCloseExtensionInterface, iInterfaceId, TMeta<TSupportedCommsApiExt>)
+END_ATTRIBUTE_TABLE_BASE(TCFSigRMessage2Ext, ESignatureRMessage2)
+
+// ----- TCancelAndCloseAllClientExtItf -----
+
+void TCancelAndCloseAllClientExtItf::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient)
+	{
+	CancelCloseAllAndForwardMsgL(aSender, *this, address_cast<TNodeId>(aRecipient).Node());
+	}
+
+void TCancelAndCloseAllClientExtItf::Error(const TRuntimeCtxId& /*aSender*/, const TRuntimeCtxId& /*aRecipient*/, TInt /*aError*/)
+   	{
+   	// Anything to do?
+   	}
+
+TBool ESock::TCommsClientSideApiExt::IsSupported(TSupportedCommsApiExt aApiExtensionId)
+	{
+	const TInt KEndOfUidListSentinelUid = 0x102864E6;
+
+	const TSupportedCommsApiExt iList[] = 
+		{
+		EMobilityApiExt,
+		ELegacySubConnectionActiveApiExt,
+		EDataMonitoringApiExt,
+		ELegacyEnumerateSubConnectionsApiExt,
+		// End of list
+		(TSupportedCommsApiExt)KEndOfUidListSentinelUid
+		};
+
+	for(TInt index = 0; iList[index] != KEndOfUidListSentinelUid; index++)
+		{
+		if(iList[index] == aApiExtensionId)
+			{
+			return ETrue;
+			}
+		}
+	
+	return EFalse;
+	}
+
+//MZ: This current hard-coded routing (and closing) behaviour is not ideal.
+//We should migrate ESockSvr to the solution in Den,
+//where each session & subsession has its own API ext register
+//and closes all opened extension when going out of scope.
+void TCancelAndCloseAllClientExtItf::CancelCloseAllAndForwardMsgL(const TRuntimeCtxId& aSender, TSignalBase& aMessage, Messages::ANode& aNode)
+	{
+	NetInterfaces::TInterfaceControl* ic = aNode.FetchNodeInterfaceControlL(AMMNodeBase::KInterfaceId);
+	NetInterfaces::TInterfaceIter itfIter(*ic);
+
+	TCommsApiExtRegister& itfRegister = SockManGlobals::Get()->iCommsApiExtRegister;
+	TAny* itf = itfIter[0];
+
+	while(itf)
+		{
+		TInt itfId = itfIter.ItfId();
+
+		if(TCommsClientSideApiExt::IsSupported((TSupportedCommsApiExt)itfId))
+			{
+			AExtensionInterfaceThickBase& baseItf = *static_cast<AExtensionInterfaceThickBase*>(itf);
+			if (iClientId!=0)
+				{
+				baseItf.CancelExtensionInterface(iClientId);
+				baseItf.CloseExtensionInterface(iClientId);
+				itfRegister.DeRegisterInterface(itfId, iClientId);
+				}
+			else
+				{
+				//TCommsApiExtRegisterClientIter clientIter(itfId, itfRegister);
+				TUint client = itfRegister.FirstClient(itfId);
+				while (client!=0)
+					{
+					baseItf.CancelExtensionInterface(client);
+					baseItf.CloseExtensionInterface(client);
+					client = itfRegister.DeRegisterInterface(itfId, client);
+					}
+				}
+			}
+		itf = itfIter++;
+		}
+	ForwardMessageL(aSender, aMessage, aNode);
+	}
+
+DEFINE_MVIP_CTR(TCancelAndCloseAllClientExtItf)
+
+START_ATTRIBUTE_TABLE(TCancelAndCloseAllClientExtItf, KExtItfMsgImplementationUid, ECancelAndCloseAllClientExtItf)
+	REGISTER_ATTRIBUTE(TCancelAndCloseAllClientExtItf, iClientId, TMeta<TUint>)
+END_ATTRIBUTE_TABLE()
+
+// ----- TApiExtMsgDispatcher -----
+
+void TApiExtMsgDispatcher::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient)
+	{
+	const TNodeId& nodeId = address_cast<const TNodeId>(aRecipient);
+	NetInterfaces::TInterfaceControl* tic = FetchInterfaceControlOrForwardMsgL(aSender, *this, nodeId.Node(), iResponseMsg.InterfaceId());
+
+	if (tic)
+	    {
+		TBuf8<KMaxExtApiIpcMsgLength> msgDst;
+		TCommsApiExtReqMsg* msg = static_cast<TCommsApiExtReqMsg*>(iResponseMsg.ReadClientReqMsg(msgDst));
+		User::LeaveIfError(msg? KErrNone : KErrNotSupported);
+		//TODO: ASSERT(msg->IsTypeOf(TCommsApiExtReqMsg::TypeId()));
+		msg->DispatchL(*tic, iClientId, iResponseMsg);
+	    }
+	}
+
+void TApiExtMsgDispatcher::Error(const TRuntimeCtxId& /*aSender*/, const TRuntimeCtxId& /*aRecipient*/, TInt aError)
+   	{
+   	if (aError==KErrNotFound)
+   		{
+   		//This IPC call has not been served.
+   		aError=KErrNotSupported;
+   		}
+
+   	iResponseMsg.Complete(aError);
+   	}
+
+DEFINE_MVIP_CTR(TApiExtMsgDispatcher)
+
+START_ATTRIBUTE_TABLE(TApiExtMsgDispatcher, KExtItfMsgImplementationUid, EApiExtMsgDispatcher)
+	REGISTER_ATTRIBUTE(TApiExtMsgDispatcher, iClientId, TMeta<TUint>)
+	REGISTER_ATTRIBUTE(TApiExtMsgDispatcher, iResponseMsg, TMeta<Elements::RResponseMsg>)
+END_ATTRIBUTE_TABLE()
+
+const TImplementationProxy ExtItfMsgImplementationTable[] =
+	{
+	MVIP_CTR_ENTRY(EApiExtMsgDispatcher, TApiExtMsgDispatcher),
+	MVIP_CTR_ENTRY(EOpenExtensionInterface, TOpenExtensionInterface),
+	MVIP_CTR_ENTRY(ECloseExtensionInterface, TCloseExtensionInterface),
+	MVIP_CTR_ENTRY(ECancelAndCloseAllClientExtItf, TCancelAndCloseAllClientExtItf)
+	};
+
+void TExtItfMsgTables::RegisterL()
+	{
+	TlsGlobals::Get().RegisterInterfaceL(TUid::Uid(KExtItfMsgImplementationUid), sizeof(ExtItfMsgImplementationTable) / sizeof(ExtItfMsgImplementationTable[0]), ExtItfMsgImplementationTable);
+	}
+
+void TExtItfMsgTables::DeRegister()
+	{
+	TlsGlobals::Get().DeregisterInterface(TUid::Uid(KExtItfMsgImplementationUid));
+	}
+
+
+
+