commsfwsupport/commselements/serverden/src/sd_apiextensionclient.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwsupport/commselements/serverden/src/sd_apiextensionclient.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,373 @@
+// Copyright (c) 2008-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:
+// sd_apiextension.cpp
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#include "sd_apiextensionclient.h"
+#include "sd_apiextensionipc.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_ElemSvrDenApiXCC, "ElemSvrDenApiXCC");
+#endif
+
+using namespace Den;
+using namespace Elements;
+
+
+_LIT(KDenApiExtPanic, "API Extension Interface");
+/**
+	API extension interface panic codes
+
+	@internalTechnology
+*/
+
+enum TDenApiExtPanic
+	{
+	EDenApiExtBadSessionHandle = 0,	//< The session handle of the extension interface is invalid
+	EDenApiExtBadSubSessionHandle,	//< The subsession handle of the extension interface is invalid
+	EDenApiExtBadHandle,	//< The session handle of the extension interface is invalid
+	EDenApiExtMetaOverflow,			//< Storing a message into a descriptor has overflowed
+	};
+
+
+// Implementation interface id for messages
+static const TInt KApiExtMsgImplementationUid = 0x10285c89;
+
+enum
+	{
+	EApiExtReqMsg = 1,
+	EApiExtSubSessionReqMsg,
+	EApiExtSessionReqMsg,
+	EApiExtRespMsg
+	};
+
+//
+//TApiExtRespMsg
+//EXPORT_REGISTER_TYPEID(TApiExtReqMsg, KReqMsgImplementationUid, EApiExtReqMsg)
+
+//
+//TApiExtSubSessionReqMsg
+
+EXPORT_REGISTER_TYPEID(TApiExtSubSessionReqMsg, KApiExtMsgImplementationUid, EApiExtSubSessionReqMsg)
+
+//
+//TApiExtHostRoutingReqMsg
+
+EXPORT_REGISTER_TYPEID(TApiExtSessionReqMsg, KApiExtMsgImplementationUid, EApiExtSessionReqMsg)
+
+
+//
+//TApiExtRespMsg
+EXPORT_C TApiExtRespMsg* TApiExtRespMsg::NewL(const Meta::STypeId& aTypeId)
+	{
+	return static_cast<TApiExtRespMsg*>(Meta::SMetaDataECom::NewInstanceL(aTypeId));
+	}
+
+EXPORT_C TApiExtRespMsg* TApiExtRespMsg::NewL(const TDesC8& aMsgBuffer)
+	{
+	TPtrC8 buf(aMsgBuffer.Ptr(), aMsgBuffer.Length());
+	return static_cast<TApiExtRespMsg*>(Meta::SMetaDataECom::LoadL(buf));
+	}
+
+EXPORT_REGISTER_TYPEID(TApiExtRespMsg, KApiExtMsgImplementationUid, EApiExtRespMsg)
+
+//
+//RApiExtBase
+TInt RApiExtCommonBase::PrepareForSending(TApiExtReqMsg& aRequestMsg, TRBuf8*& aBuffer) const
+	{
+	//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)
+			{
+			delete buffer;
+			buffer = NULL;
+			}
+		else
+			{
+			error = aRequestMsg.Store(*buffer);
+			if (error!=KErrNone)
+				{
+				__ASSERT_DEBUG(iBuffers[iBuffers.Count()-1]==buffer, User::Panic(KSpecAssert_ElemSvrDenApiXCC, 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
+				{
+				aBuffer = buffer;
+				}
+			}
+		}
+	return error;
+	}
+
+void RApiExtCommonBase::Close()
+	{
+#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();
+	iIdentification=TApiExtIdentification(0,0);
+	}
+
+//
+//RApiExtSubSessionBase
+EXPORT_C TInt RApiExtSubSessionBase::Open(RExtendableSubSessionBase& aExtendableInterface, TInt aInterfaceId)
+	{
+	__ASSERT_ALWAYS(aExtendableInterface.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSessionHandle));
+
+	TApiExtIdentification identification(aInterfaceId);
+	TInt error = aExtendableInterface.SendReceive(EIpcSubSessionApiExtIfaceOpen, TIpcArgs(&identification));
+	if (error == KErrNone)
+		{
+		iSubSession = aExtendableInterface;
+		iIdentification = identification;
+		}
+	return error;
+	}
+
+EXPORT_C void RApiExtSubSessionBase::Close()
+	{
+	if (!iSubSession.SubSessionHandle())
+		return;
+
+	iSubSession.SendReceive(EIpcSubSessionApiExtIfaceClose, TIpcArgs(&iIdentification));
+	RApiExtCommonBase::Close();
+	}
+
+//Calling this function, the client is responsible for providing a buffer
+//that is big enough to store first the request message and then the response message.
+EXPORT_C void RApiExtSubSessionBase::SendReceive(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+	aReqAndRespBuf.Zero();
+	TInt error = aMsg.Store(aReqAndRespBuf);
+	if (error==KErrNone)
+		{
+		iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, &aReqAndRespBuf), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+EXPORT_C void RApiExtSubSessionBase::SendReceive(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf, TDes8& aReqAndRespBuf2, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+	aReqAndRespBuf.Zero();
+	TInt error = aMsg.Store(aReqAndRespBuf);
+	if (error==KErrNone)
+		{
+		iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, &aReqAndRespBuf, &aReqAndRespBuf2), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+//Calling this function, the client does not have to be concerned about the
+//buffer management that happens underneath
+EXPORT_C void RApiExtSubSessionBase::Send(TApiExtReqMsg& aMsg, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+	TRBuf8* buffer = NULL;
+	TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer);
+	if (error==KErrNone)
+		{
+		iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+EXPORT_C void RApiExtSubSessionBase::Send(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf2, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+	TRBuf8* buffer = NULL;
+	TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer);
+	if (error==KErrNone)
+		{
+		iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer, &aReqAndRespBuf2), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+EXPORT_C void RApiExtSubSessionBase::Send(TApiExtReqMsg& aMsg, const RHandleBase& aHandleBase, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+	TRBuf8* buffer = NULL;
+	TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer);
+	if (error==KErrNone)
+		{
+		iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer, aHandleBase), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+//
+//RApiExtSessionBase
+EXPORT_C TInt RApiExtSessionBase::Open(RExtendableSessionBase& aExtendableInterface, TInt aInterfaceId)
+	{
+	__ASSERT_ALWAYS(aExtendableInterface.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+
+	TApiExtIdentification identification(aInterfaceId);
+	TInt error = aExtendableInterface.SendReceive(EIpcSessionApiExtIfaceOpen, TIpcArgs(&identification));
+	if (error == KErrNone)
+		{
+		iSession = aExtendableInterface;
+		iIdentification = identification;
+		}
+	return error;
+	}
+
+EXPORT_C void RApiExtSessionBase::Close()
+	{
+	if (!iSession.Handle())
+		return;
+
+	iSession.SendReceive(EIpcSessionApiExtIfaceClose, TIpcArgs(&iIdentification));
+	RApiExtCommonBase::Close();
+	}
+
+//Calling this function, the client is responsible for providing a buffer
+//that is big enough to store first the request message and then the response message.
+EXPORT_C void RApiExtSessionBase::SendReceive(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+	aReqAndRespBuf.Zero();
+	TInt error = aMsg.Store(aReqAndRespBuf);
+	if (error==KErrNone)
+		{
+		iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, &aReqAndRespBuf), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+EXPORT_C void RApiExtSessionBase::SendReceive(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf, TDes8& aReqAndRespBuf2, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+	aReqAndRespBuf.Zero();
+	TInt error = aMsg.Store(aReqAndRespBuf);
+	if (error==KErrNone)
+		{
+		iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, &aReqAndRespBuf, &aReqAndRespBuf2), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+//Calling this function, the client does not have to be concerned about the
+//buffer management that happens underneath
+EXPORT_C void RApiExtSessionBase::Send(TApiExtReqMsg& aMsg, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+
+	TRBuf8* buffer = NULL;
+	TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer);
+	if (error==KErrNone)
+		{
+		iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+EXPORT_C void RApiExtSessionBase::Send(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf2, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+
+	TRBuf8* buffer = NULL;
+	TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer);
+	if (error==KErrNone)
+		{
+		iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer, &aReqAndRespBuf2), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+EXPORT_C void RApiExtSessionBase::Send(TApiExtReqMsg& aMsg, const RHandleBase& aHandleBase, TRequestStatus& aStatus) const
+	{
+	__ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle));
+
+	TRBuf8* buffer = NULL;
+	TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer);
+	if (error==KErrNone)
+		{
+		iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer, aHandleBase), aStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status,error);
+		}
+	}
+
+