commsfwsupport/commselements/ResponseMsg/src/ResponseMsg.cpp
changeset 0 dfb7c4ff071f
child 21 4ccf8e394726
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwsupport/commselements/ResponseMsg/src/ResponseMsg.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,185 @@
+// Copyright (c) 2005-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
+*/
+
+// Enable logging for debug builds or builds with the comms flogger enabled - must be defined before including e32utrace.h
+#if (defined(_DEBUG) || defined(__FLOG_ACTIVE)) && !defined(SYMBIAN_TRACE_ENABLE)
+#define SYMBIAN_TRACE_ENABLE
+#endif
+#include <e32utrace.h>
+
+#include <elements/responsemsg.h>
+#include <elements/sd_apiextensionclient.h>
+#include <elements/nm_common.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_ElemRespMessRspn, "ElemRespMessRspn");
+#endif
+
+using namespace Elements;
+using namespace Den;
+using namespace Messages;
+
+#ifdef SYMBIAN_TRACE_ENABLE
+class RMLogging
+	{
+public:
+	static void Printf(TRefByValue<const TDesC8> aFmt, ...)
+		{
+		const TInt KPrimaryFilter = 194;
+		TBuf8<200> buf;
+		TDes8IgnoreOverflow overflow;
+		VA_LIST list;
+		VA_START(list, aFmt);
+		buf.AppendFormatList(aFmt, list, &overflow);
+		VA_END(list);
+		UTracePfAny(KPrimaryFilter, KText, ETrue, EFalse, buf.Length(), buf.Ptr(), buf.Length());
+		}
+	};
+#define RMLOG(logArgs) RMLogging::Printf logArgs
+#else
+#define RMLOG(logArgs)
+#endif //#ifdef SYMBIAN_TRACE_ENABLE
+
+
+EXPORT_C RResponseMsg::RResponseMsg(const RMessage2& aMessage, TInt aInterfaceId, TInt aRequestMsgParam, TInt aResponseMsgParam)
+:	RMessage2(aMessage), iInterfaceId(aInterfaceId), iRequestMsgParam(aRequestMsgParam), iResponseMsgParam(aResponseMsgParam)
+	{
+	__ASSERT_DEBUG(aRequestMsgParam >= -1 && aRequestMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 1));
+	__ASSERT_DEBUG(aResponseMsgParam >= -1 && aResponseMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 2));
+	}
+
+EXPORT_C RResponseMsg::RResponseMsg(const RMessage2& aMessage, const Den::TApiExtIdentification& aInterfaceId, TInt aRequestMsgParam, TInt aResponseMsgParam)
+:	RMessage2(aMessage), iInterfaceId(aInterfaceId), iRequestMsgParam(aRequestMsgParam), iResponseMsgParam(aResponseMsgParam)
+	{
+	__ASSERT_DEBUG(aRequestMsgParam >= -1 && aRequestMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 3));
+	__ASSERT_DEBUG(aResponseMsgParam >= -1 && aResponseMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 4));
+	}
+
+EXPORT_C TInt RResponseMsg::InterfaceId() const
+	{
+	return iInterfaceId.InterfaceId();
+	}
+
+EXPORT_C TInt RResponseMsg::ScopeId() const
+	{
+	return iInterfaceId.ScopeId();
+	}
+
+EXPORT_C void RResponseMsg::Complete(TInt aError)
+	{
+  	if (iHandle)
+  		{
+		RMLOG((_L8("RResponseMsg(%08x)::Complete(%08x) with %d"), this, iHandle, aError));
+  		RMessage2::Complete(aError);
+  		}
+	}
+
+EXPORT_C void RResponseMsg::Complete(Meta::SMetaDataECom& aMsg)
+	{
+	__ASSERT_DEBUG(iResponseMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 5));
+
+	RBuf8 buffer;
+	TInt err = buffer.Create(aMsg.Length());
+	if (err == KErrNone)
+		{
+		Complete(aMsg, buffer);
+		}
+	else
+		{
+		Complete(err);
+		}
+	buffer.Close();
+	}
+
+EXPORT_C void RResponseMsg::Complete(Meta::SMetaDataECom& aMsg, TDes8& aDstBuff)
+	{
+	__ASSERT_DEBUG(iResponseMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 6));
+	__ASSERT_DEBUG(aDstBuff.MaxLength() >= aMsg.Length(), User::Panic(KSpecAssert_ElemRespMessRspn, 7));
+	aDstBuff.Zero();
+	TInt err = aMsg.Store(aDstBuff);
+	if (err == KErrNone)
+		{
+		err = RMessage2::Write(iResponseMsgParam, aDstBuff);
+		}
+	Complete(err);
+	}
+
+EXPORT_C void RResponseMsg::Complete(RHandleBase& aHandle) 
+    {
+    RMessage2::Complete(aHandle);
+    }
+
+EXPORT_C void RResponseMsg::Panic(const TDesC& aCategory, TInt aReason) const
+	{
+#ifdef SYMBIAN_TRACE_ENABLE
+	TBuf8<16> cat;
+	cat.Copy(aCategory.Left(16));
+	RMLOG((_L8("RResponseMsg(%08x)::Panic(%08x) with %S:%d"), this, iHandle, &cat, aReason));
+#endif
+	RMessage2::Panic(aCategory, aReason);
+	}
+
+EXPORT_C Meta::SMetaDataNetCtor* RResponseMsg::ReadClientReqMsg(TDes8& aDstBuff)
+	{
+	//Param 3 is used for the subsession handle
+	__ASSERT_DEBUG(iRequestMsgParam >= 0 && iRequestMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 8));
+
+	Meta::SMetaDataNetCtor* msg = NULL;
+	TBuf8<TApiExtReqMsg::KMaxApiExtIpcMsgExternalisedSize> msgSrc;
+	if (0 >= RMessage2::GetDesLength(iRequestMsgParam))
+		{
+  		//Client violated semantics of this api by providing an empty
+  		//buffer (or destroying the buffer prematurely).
+  		//Depending on the state of communication with the client
+  		//(opening an extension/extension call) the client will be
+  		//errored or panicked.
+  		__DEBUGGER(); //diagnostic
+  		return NULL;
+		}
+
+	if (KErrNone==RMessage2::Read(iRequestMsgParam, msgSrc))
+		{
+		TPtrC8 msgSrcPtr(msgSrc);
+		msg = TlsGlobals::Get().VirtualCtor()->New(msgSrcPtr, aDstBuff);
+  		if (NULL == msg)
+  			{
+	  		//Something wrong with provisioning of the msg virtual constructor.
+	  		//This means the client is sendng an unexpected request.
+	  		//It is also possible that the request message is valid and that
+	  		//it wasn't properly requstered during opening of the IPC extension.
+	  		//That would usually be the fault of the client's CExtItfMsgPluginInfo.
+	  		//Depending on the state the client will be errored or panicked.
+  			__DEBUGGER(); //diagnostic
+  			return NULL;
+  			}
+  		}
+
+	//Make a reasonable attempt to release the client's buffer
+	//There is no need to care if that fails or succeeds.
+	//Can be safely done even when a response is expected later on
+	//(since it only has an effect on the default client side buffer
+	//management used for no-responses).
+	RMessage2::Write(iRequestMsgParam, KNullDesC8); // mark client buffer as read
+  	return msg;
+	}
+