|
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalTechnology |
|
19 */ |
|
20 |
|
21 // Enable logging for debug builds or builds with the comms flogger enabled - must be defined before including e32utrace.h |
|
22 #if (defined(_DEBUG) || defined(__FLOG_ACTIVE)) && !defined(SYMBIAN_TRACE_ENABLE) |
|
23 #define SYMBIAN_TRACE_ENABLE |
|
24 #endif |
|
25 #include <e32utrace.h> |
|
26 |
|
27 #include <elements/responsemsg.h> |
|
28 #include <elements/sd_apiextensionclient.h> |
|
29 #include <elements/nm_common.h> |
|
30 |
|
31 |
|
32 #ifdef _DEBUG |
|
33 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
34 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
35 _LIT(KSpecAssert_ElemRespMessRspn, "ElemRespMessRspn"); |
|
36 #endif |
|
37 |
|
38 using namespace Elements; |
|
39 using namespace Den; |
|
40 using namespace Messages; |
|
41 |
|
42 #ifdef SYMBIAN_TRACE_ENABLE |
|
43 class RMLogging |
|
44 { |
|
45 public: |
|
46 static void Printf(TRefByValue<const TDesC8> aFmt, ...) |
|
47 { |
|
48 const TInt KPrimaryFilter = 194; |
|
49 TBuf8<200> buf; |
|
50 TDes8IgnoreOverflow overflow; |
|
51 VA_LIST list; |
|
52 VA_START(list, aFmt); |
|
53 buf.AppendFormatList(aFmt, list, &overflow); |
|
54 VA_END(list); |
|
55 UTracePfAny(KPrimaryFilter, KText, ETrue, EFalse, buf.Length(), buf.Ptr(), buf.Length()); |
|
56 } |
|
57 }; |
|
58 #define RMLOG(logArgs) RMLogging::Printf logArgs |
|
59 #else |
|
60 #define RMLOG(logArgs) |
|
61 #endif //#ifdef SYMBIAN_TRACE_ENABLE |
|
62 |
|
63 |
|
64 EXPORT_C RResponseMsg::RResponseMsg(const RMessage2& aMessage, TInt aInterfaceId, TInt aRequestMsgParam, TInt aResponseMsgParam) |
|
65 : RMessage2(aMessage), iInterfaceId(aInterfaceId), iRequestMsgParam(aRequestMsgParam), iResponseMsgParam(aResponseMsgParam) |
|
66 { |
|
67 __ASSERT_DEBUG(aRequestMsgParam >= -1 && aRequestMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 1)); |
|
68 __ASSERT_DEBUG(aResponseMsgParam >= -1 && aResponseMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 2)); |
|
69 } |
|
70 |
|
71 EXPORT_C RResponseMsg::RResponseMsg(const RMessage2& aMessage, const Den::TApiExtIdentification& aInterfaceId, TInt aRequestMsgParam, TInt aResponseMsgParam) |
|
72 : RMessage2(aMessage), iInterfaceId(aInterfaceId), iRequestMsgParam(aRequestMsgParam), iResponseMsgParam(aResponseMsgParam) |
|
73 { |
|
74 __ASSERT_DEBUG(aRequestMsgParam >= -1 && aRequestMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 3)); |
|
75 __ASSERT_DEBUG(aResponseMsgParam >= -1 && aResponseMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 4)); |
|
76 } |
|
77 |
|
78 EXPORT_C TInt RResponseMsg::InterfaceId() const |
|
79 { |
|
80 return iInterfaceId.InterfaceId(); |
|
81 } |
|
82 |
|
83 EXPORT_C TInt RResponseMsg::ScopeId() const |
|
84 { |
|
85 return iInterfaceId.ScopeId(); |
|
86 } |
|
87 |
|
88 EXPORT_C void RResponseMsg::Complete(TInt aError) |
|
89 { |
|
90 if (iHandle) |
|
91 { |
|
92 RMLOG((_L8("RResponseMsg(%08x)::Complete(%08x) with %d"), this, iHandle, aError)); |
|
93 RMessage2::Complete(aError); |
|
94 } |
|
95 } |
|
96 |
|
97 EXPORT_C void RResponseMsg::Complete(Meta::SMetaDataECom& aMsg) |
|
98 { |
|
99 __ASSERT_DEBUG(iResponseMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 5)); |
|
100 |
|
101 RBuf8 buffer; |
|
102 TInt err = buffer.Create(aMsg.Length()); |
|
103 if (err == KErrNone) |
|
104 { |
|
105 Complete(aMsg, buffer); |
|
106 } |
|
107 else |
|
108 { |
|
109 Complete(err); |
|
110 } |
|
111 buffer.Close(); |
|
112 } |
|
113 |
|
114 EXPORT_C void RResponseMsg::Complete(Meta::SMetaDataECom& aMsg, TDes8& aDstBuff) |
|
115 { |
|
116 __ASSERT_DEBUG(iResponseMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 6)); |
|
117 __ASSERT_DEBUG(aDstBuff.MaxLength() >= aMsg.Length(), User::Panic(KSpecAssert_ElemRespMessRspn, 7)); |
|
118 aDstBuff.Zero(); |
|
119 TInt err = aMsg.Store(aDstBuff); |
|
120 if (err == KErrNone) |
|
121 { |
|
122 err = RMessage2::Write(iResponseMsgParam, aDstBuff); |
|
123 } |
|
124 Complete(err); |
|
125 } |
|
126 |
|
127 EXPORT_C void RResponseMsg::Complete(RHandleBase& aHandle) |
|
128 { |
|
129 RMessage2::Complete(aHandle); |
|
130 } |
|
131 |
|
132 EXPORT_C void RResponseMsg::Panic(const TDesC& aCategory, TInt aReason) const |
|
133 { |
|
134 #ifdef SYMBIAN_TRACE_ENABLE |
|
135 TBuf8<16> cat; |
|
136 cat.Copy(aCategory.Left(16)); |
|
137 RMLOG((_L8("RResponseMsg(%08x)::Panic(%08x) with %S:%d"), this, iHandle, &cat, aReason)); |
|
138 #endif |
|
139 RMessage2::Panic(aCategory, aReason); |
|
140 } |
|
141 |
|
142 EXPORT_C Meta::SMetaDataNetCtor* RResponseMsg::ReadClientReqMsg(TDes8& aDstBuff) |
|
143 { |
|
144 //Param 3 is used for the subsession handle |
|
145 __ASSERT_DEBUG(iRequestMsgParam >= 0 && iRequestMsgParam < 3, User::Panic(KSpecAssert_ElemRespMessRspn, 8)); |
|
146 |
|
147 Meta::SMetaDataNetCtor* msg = NULL; |
|
148 TBuf8<TApiExtReqMsg::KMaxApiExtIpcMsgExternalisedSize> msgSrc; |
|
149 if (0 >= RMessage2::GetDesLength(iRequestMsgParam)) |
|
150 { |
|
151 //Client violated semantics of this api by providing an empty |
|
152 //buffer (or destroying the buffer prematurely). |
|
153 //Depending on the state of communication with the client |
|
154 //(opening an extension/extension call) the client will be |
|
155 //errored or panicked. |
|
156 __DEBUGGER(); //diagnostic |
|
157 return NULL; |
|
158 } |
|
159 |
|
160 if (KErrNone==RMessage2::Read(iRequestMsgParam, msgSrc)) |
|
161 { |
|
162 TPtrC8 msgSrcPtr(msgSrc); |
|
163 msg = TlsGlobals::Get().VirtualCtor()->New(msgSrcPtr, aDstBuff); |
|
164 if (NULL == msg) |
|
165 { |
|
166 //Something wrong with provisioning of the msg virtual constructor. |
|
167 //This means the client is sendng an unexpected request. |
|
168 //It is also possible that the request message is valid and that |
|
169 //it wasn't properly requstered during opening of the IPC extension. |
|
170 //That would usually be the fault of the client's CExtItfMsgPluginInfo. |
|
171 //Depending on the state the client will be errored or panicked. |
|
172 __DEBUGGER(); //diagnostic |
|
173 return NULL; |
|
174 } |
|
175 } |
|
176 |
|
177 //Make a reasonable attempt to release the client's buffer |
|
178 //There is no need to care if that fails or succeeds. |
|
179 //Can be safely done even when a response is expected later on |
|
180 //(since it only has an effect on the default client side buffer |
|
181 //management used for no-responses). |
|
182 RMessage2::Write(iRequestMsgParam, KNullDesC8); // mark client buffer as read |
|
183 return msg; |
|
184 } |
|
185 |