--- /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;
+ }
+