datacommsserver/esockserver/csock/cs_api_ext.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/csock/cs_api_ext.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,262 @@
+// Copyright (c) 1997-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
+*/
+
+#include <comms-infras/es_api_ext.h>
+#include <comms-infras/es_connectionservermessages.h>
+#include <comms-infras/api_ext_msg.h>
+#include <comms-infras/sockmes.h>
+
+
+#ifdef _DEBUG
+// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
+// (if it could happen through user error then you should give it an explicit, documented, category + code)
+_LIT(KSpecAssert_ESockCSockcsp_xt, "ESockCSockcsp_xt");
+#endif
+
+using namespace Elements;
+
+
+CCommsSessionApiExtProvider::CCommsSessionApiExtProvider(RCommsSession& session)
+: iSession(session)
+	{
+	}
+	
+CCommsSessionApiExtProvider *CCommsSessionApiExtProvider::Open(
+		RCommsSession& aExtensionProvider, TSupportedCommsApiExt aInterfaceId, TInt &error)
+	{
+	__ASSERT_ALWAYS(aExtensionProvider.Handle(), User::Panic(KApiExtPanic, EApiExtBadHandle));
+	CCommsSessionApiExtProvider *provider = new CCommsSessionApiExtProvider(aExtensionProvider);
+	if (!provider)
+		{
+		error = KErrNoMemory;
+		return NULL;
+		}
+		
+	error = aExtensionProvider.SendReceive(ECMApiExtBindIface, TIpcArgs(aInterfaceId));
+
+	if (KErrNone != error)
+		{
+		delete provider;
+		return NULL;
+		}
+	return provider;
+	}
+	
+TInt CCommsSessionApiExtProvider::Close(const TIpcArgs& aArgs) const	
+	{
+	return iSession.SendReceive(ECMApiExtIfaceClose, aArgs);
+	}
+
+TInt CCommsSessionApiExtProvider::Handle() const
+	{
+	return iSession.Handle();
+	}
+
+TInt CCommsSessionApiExtProvider::Send(const TIpcArgs& aArgs) const	
+	{
+	return iSession.SendReceive(ECMApiExtIfaceSend, aArgs);
+	}
+
+void CCommsSessionApiExtProvider::SendReceive(const TIpcArgs& aArgs,TRequestStatus& aStatus) const
+	{
+	iSession.SendReceive(ECMApiExtIfaceSendReceive, aArgs, aStatus);
+	}
+
+void CCommsSessionApiExtProvider::Release()
+	{
+	delete this;
+	}
+
+CCommsSubSessionApiExtProvider::CCommsSubSessionApiExtProvider(RCommsSubSession& subsession)
+: iSubSession(subsession)
+	{
+	}
+
+CCommsSubSessionApiExtProvider *CCommsSubSessionApiExtProvider::Open(
+		RCommsSubSession& aExtensionProvider, TSupportedCommsApiExt aInterfaceId, TInt &error)
+	{
+	__ASSERT_ALWAYS(aExtensionProvider.SubSessionHandle(), User::Panic(KApiExtPanic, EApiExtBadHandle));
+	CCommsSubSessionApiExtProvider *provider = new CCommsSubSessionApiExtProvider(aExtensionProvider);
+	if (!provider)
+		{
+		error = KErrNoMemory;
+		return NULL;
+		}
+		
+	error = aExtensionProvider.SendReceive(ECommsApiExtBindIface, TIpcArgs(aInterfaceId));
+
+	if (KErrNone != error)
+		{
+		delete provider;
+		return NULL;
+		}
+	return provider;
+	}
+
+TInt CCommsSubSessionApiExtProvider::Close(const TIpcArgs& aArgs) const	
+	{
+	return iSubSession.SendReceive(ECommsApiExtIfaceClose, aArgs);
+	}
+
+TInt CCommsSubSessionApiExtProvider::Handle() const
+	{
+	return iSubSession.SubSessionHandle();
+	}
+
+TInt CCommsSubSessionApiExtProvider::Send(const TIpcArgs& aArgs) const	
+	{
+	return iSubSession.SendReceive(ECommsApiExtIfaceSend, aArgs);
+	}
+
+void CCommsSubSessionApiExtProvider::SendReceive(const TIpcArgs& aArgs,TRequestStatus& aStatus) const
+	{
+	iSubSession.SendReceive(ECommsApiExtIfaceSendReceive, aArgs, aStatus);
+	}
+
+void CCommsSubSessionApiExtProvider::Release()
+	{
+	delete this;
+	}
+
+
+EXPORT_C RCommsApiExtensionBase::RCommsApiExtensionBase()
+: iProvider(0)
+    {
+    }
+
+EXPORT_C TInt RCommsApiExtensionBase::Open(RCommsSession& aExtensionProvider, TSupportedCommsApiExt aInterfaceId)
+	{
+	if (iProvider)
+		{
+		return KErrInUse;
+		}
+
+	TInt error = KErrNone;
+	iProvider = CCommsSessionApiExtProvider::Open(aExtensionProvider, aInterfaceId, error);
+	
+	if (error == KErrNone)
+		{
+		iInterfaceId = aInterfaceId;
+		}	
+	return error;
+	}
+
+EXPORT_C TInt RCommsApiExtensionBase::Open(RCommsSubSession& aExtensionProvider, TSupportedCommsApiExt aInterfaceId)
+	{
+	if (iProvider)
+		{
+		return KErrInUse;
+		}
+
+	TInt error = KErrNone;
+	iProvider = CCommsSubSessionApiExtProvider::Open(aExtensionProvider, aInterfaceId, error);
+	
+	if (error == KErrNone)
+		{
+		iInterfaceId = aInterfaceId;
+		}	
+	return error;
+	}
+
+
+EXPORT_C void RCommsApiExtensionBase::Close()
+	{
+	if (iProvider && iProvider->Handle())
+		{
+		iProvider->Close(TIpcArgs(iInterfaceId));
+		iProvider->Release();
+		iProvider = NULL;
+		}
+	
+#if defined( _DEBUG )
+	for (TInt index = iBuffers.Count() - 1; index >= 0; --index)
+		{
+		if (iBuffers[index]->Length()!=0)
+			{
+			User::Invariant(); //The request has not been processed by the server yet
+			}
+		}
+#endif
+
+	iBuffers.ResetAndDestroy();
+	}
+
+EXPORT_C void RCommsApiExtensionBase::SendRequest(TCommsApiExtReqMsg& aRequestMsg, TDes8& aResponseBuf, TRequestStatus& aStatus)
+	{
+	__ASSERT_ALWAYS(iProvider && iProvider->Handle(), User::Panic(KApiExtPanic, EApiExtBadHandle));
+
+	//clean up all used up buffers
+	for (TInt index = iBuffers.Count() - 1; index >= 0; --index)
+		{
+		if (iBuffers[index]->Length()==0)
+			{
+			delete iBuffers[index];
+			iBuffers.Remove(index);
+			}
+		}
+
+	TInt error = KErrNoMemory;
+	TRBuf8* buffer = TRBuf8::New(aRequestMsg.Length());
+	if (buffer!=NULL)
+		{
+		error = iBuffers.Append(buffer); //stick new buffer into the array
+		if (error==KErrNone)
+			{
+			error = aRequestMsg.Store(*buffer);
+			if (error==KErrNone)
+				{
+				iProvider->SendReceive(TIpcArgs(iInterfaceId,buffer,&aResponseBuf), aStatus);
+				}
+			else
+				{
+				__ASSERT_DEBUG(iBuffers[iBuffers.Count()-1]==buffer, User::Panic(KSpecAssert_ESockCSockcsp_xt, 1)); //make sure we are removing what we believe we are removing
+				iBuffers.Remove(iBuffers.Count()-1); //remove the buffer
+				delete buffer;
+				buffer = NULL;
+				}
+			}
+		else
+			{
+			delete buffer;
+			buffer = NULL;
+			}
+		}
+
+	if (error!=KErrNone)
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		return;
+		}
+	}
+
+EXPORT_C void RCommsApiExtensionBase::SendMessage(TCommsApiExtReqMsg& aRequestMsg)
+	{
+	__ASSERT_ALWAYS(iProvider && iProvider->Handle(), User::Panic(KApiExtPanic, EApiExtBadHandle));
+	__ASSERT_ALWAYS((aRequestMsg.Length() <= KMaxExtApiIpcMsgLength), User::Panic(KApiExtPanic, EApiExtMetaOverflow));
+
+	TBuf8<KMaxExtApiIpcMsgLength> buffer;
+	if (aRequestMsg.Store(buffer) != KErrNone)
+		{
+		User::Panic(KApiExtPanic, EApiExtMetaOverflow);
+		}
+		
+	iProvider->Send(TIpcArgs(iInterfaceId, &buffer));
+	}
+