748
|
1 |
// Copyright (c) 2006-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 the License "Symbian Foundation License v1.0"
|
|
5 |
// which accompanies this distribution, and is available
|
|
6 |
// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
|
|
7 |
//
|
|
8 |
// Initial Contributors:
|
|
9 |
// Nokia Corporation - initial contribution.
|
|
10 |
//
|
|
11 |
// Contributors:
|
|
12 |
//
|
|
13 |
// Description:
|
|
14 |
//
|
|
15 |
|
|
16 |
#include <e32debug.h>
|
|
17 |
#include "csecuresessionsubsessionbase.h"
|
|
18 |
#include "csubsessionbase.h"
|
|
19 |
#include "lbsmessageenums.h"
|
|
20 |
#include "messageutils.h"
|
|
21 |
#include "lbsdevloggermacros.h"
|
|
22 |
|
|
23 |
/**
|
|
24 |
constructor, call the CSecureSessionBase base class constructor
|
|
25 |
|
|
26 |
@internalTechnology
|
|
27 |
@released
|
|
28 |
*/
|
|
29 |
CSecureSessionSubSessionBase::CSecureSessionSubSessionBase() : CSecureSessionBase()
|
|
30 |
{
|
|
31 |
LBSLOG(ELogP3, "CSecureSessionSubSessionBase::CSecureSessionSubSessionBase()");
|
|
32 |
}
|
|
33 |
|
|
34 |
/**
|
|
35 |
destructor, release the subsession handler container
|
|
36 |
|
|
37 |
@internalTechnology
|
|
38 |
@released
|
|
39 |
*/
|
|
40 |
CSecureSessionSubSessionBase::~CSecureSessionSubSessionBase()
|
|
41 |
{
|
|
42 |
LBSLOG(ELogP3, "->CSecureSessionSubSessionBase::~CSecureSessionSubSessionBase()");
|
|
43 |
|
|
44 |
if (iObjectIx)
|
|
45 |
{
|
|
46 |
TInt count = iObjectIx->Count();
|
|
47 |
for(TInt i=0; i<count; i++)
|
|
48 |
{
|
|
49 |
CObject* theObj = (*iObjectIx)[i];
|
|
50 |
if (theObj)
|
|
51 |
{
|
|
52 |
TInt handle = iObjectIx->At(theObj);
|
|
53 |
// if we reach here somethingbad has happened. The server class
|
|
54 |
// (i.e. the session object) is being closed by the client, BEFORE
|
|
55 |
// the client has closes all of the open subsessions.
|
|
56 |
// So the only reasonable thingto do here is:
|
|
57 |
// delete the subsession - without closing it first. 'Cos this is
|
|
58 |
// _exactly_ what the client side has asked for (for some reason).
|
|
59 |
// The may or may not be legal, or even a good idea depending on the type of server
|
|
60 |
// that is being developeds. But the server framework should NOT
|
|
61 |
// prevent this from happening. Generating a panic is a
|
|
62 |
// server developers choice, not a framework developers choice.
|
|
63 |
// We delete by calling CObjectIdx::Remove(). This will call CObject::Close.
|
|
64 |
// This in turn calls MSubSessionImpl::MRelease::VirtualRelease
|
|
65 |
// which will destroy the sub session for us.
|
|
66 |
// CloseSubSession should not be called directly.
|
|
67 |
iObjectIx->Remove(handle);
|
|
68 |
|
|
69 |
//
|
|
70 |
// If the array length has changed, then update count and move back one space,
|
|
71 |
// so that the same cell will be re-inspected during the next iteration of the
|
|
72 |
// loop This is because we have removed the current cell and therefore the
|
|
73 |
// next cell is actually in iObjectIx[i] (i.e. the current one).
|
|
74 |
TInt newCount = iObjectIx->Count();
|
|
75 |
|
|
76 |
if (newCount != count)
|
|
77 |
{
|
|
78 |
count = newCount;
|
|
79 |
i--;
|
|
80 |
}
|
|
81 |
|
|
82 |
}
|
|
83 |
}
|
|
84 |
delete iObjectIx;
|
|
85 |
}
|
|
86 |
if (iContainerIx)
|
|
87 |
{
|
|
88 |
iContainerIx->Remove(iObjectCon);
|
|
89 |
delete iContainerIx;
|
|
90 |
}
|
|
91 |
// session decrementing handled in the parent class
|
|
92 |
LBSLOG(ELogP3, "<-CSecureSessionSubSessionBase::~CSecureSessionSubSessionBase()");
|
|
93 |
}
|
|
94 |
|
|
95 |
/**
|
|
96 |
called as part of the CSession2 construction.
|
|
97 |
Create subsession handler container and call the session CreateL function to increase the session count
|
|
98 |
|
|
99 |
@internalTechnology
|
|
100 |
@released
|
|
101 |
*/
|
|
102 |
void CSecureSessionSubSessionBase::CreateL()
|
|
103 |
{
|
|
104 |
LBSLOG(ELogP3, "->CSecureSessionSubSessionBase::CreateL");
|
|
105 |
iObjectIx = CObjectIx::NewL();
|
|
106 |
iContainerIx = CObjectConIx::NewL();
|
|
107 |
iObjectCon = iContainerIx->CreateL();
|
|
108 |
CSecureSessionBase::CreateL(); // call the parent class to inc the session count
|
|
109 |
iBaseCreateCalled = ETrue;
|
|
110 |
LBSLOG(ELogP3, "<-CSecureSessionSubSessionBase::CreateL");
|
|
111 |
}
|
|
112 |
|
|
113 |
/**
|
|
114 |
Do the real thing for subsession construction.
|
|
115 |
Check whether the session constructL function is called or not first. If not, panic the server,
|
|
116 |
Create a subsession and push it to stack, get the implementation of subsession and invoke the
|
|
117 |
real subsession creation implementation.
|
|
118 |
|
|
119 |
Add the subsession handler to container and write the handler to client address space through message object
|
|
120 |
Complete the creating message.
|
|
121 |
|
|
122 |
@param aMessage A RMessage2 reference.
|
|
123 |
@internalTechnology
|
|
124 |
@released
|
|
125 |
*/
|
|
126 |
void CSecureSessionSubSessionBase::CreateSubSessionL(const RMessage2& aMessage)
|
|
127 |
{
|
|
128 |
__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
|
|
129 |
CSubSessionBase* subSession = new (ELeave) CSubSessionBase();
|
|
130 |
// Note: Use the CObject::Close() function instead of usual destructor
|
|
131 |
// because it is needed to correctly decrement the reference count.
|
|
132 |
// Close() will destruct subSession anyway if the ref count == 0.
|
|
133 |
CleanupClosePushL(*subSession);
|
|
134 |
|
|
135 |
MSubSessionImpl* impl = subSession->GetImplL(aMessage);
|
|
136 |
CleanupVirtualReleasePushL(*impl); // call Release() on destruction
|
|
137 |
//CleanupVirtualRelease::PushL(*impl);
|
|
138 |
subSession->SetImpl(impl); // will take ownership(!)
|
|
139 |
CleanupStack::Pop(impl);
|
|
140 |
|
|
141 |
// We need to pass a handle to the controllign server down to the subsession object.
|
|
142 |
// Since the subsession impl object is a CBase object (NOT a CSession2 object)
|
|
143 |
// we haev to do this outherwise the subsession will not be able to referene the
|
|
144 |
// server - which seems like a useful thing to do.
|
|
145 |
const CSecureServerBase* server = reinterpret_cast<const CSecureServerBase*>(Server());
|
|
146 |
impl->CreateSubSessionL(aMessage, server);
|
|
147 |
|
|
148 |
iObjectCon->AddL(subSession);
|
|
149 |
TInt handle = iObjectIx->AddL(subSession);
|
|
150 |
TPckgC<TInt> pH(handle);
|
|
151 |
MessageUtils::Write(aMessage, 3, pH);
|
|
152 |
aMessage.Complete(KErrNone);
|
|
153 |
CleanupStack::Pop(subSession);
|
|
154 |
}
|
|
155 |
|
|
156 |
/**
|
|
157 |
Do the real thing for subsession destruction.
|
|
158 |
Check whether the session constructL function is called or not first. If not, panic the server,
|
|
159 |
get a subsession handler from container and complete the message if subsession is already close,
|
|
160 |
if not, close subsession and remove it from container then complete the message.
|
|
161 |
|
|
162 |
@param aMessage A RMessage2 reference.
|
|
163 |
@internalTechnology
|
|
164 |
@released
|
|
165 |
*/
|
|
166 |
void CSecureSessionSubSessionBase::DestroySubSession(const RMessage2& aMessage)
|
|
167 |
{
|
|
168 |
__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
|
|
169 |
CSubSessionBase* subSession = reinterpret_cast<CSubSessionBase*>(iObjectIx->At(aMessage.Int3()));
|
|
170 |
|
|
171 |
if (subSession == NULL)
|
|
172 |
{
|
|
173 |
aMessage.Complete(KErrBadHandle);
|
|
174 |
}
|
|
175 |
else
|
|
176 |
{
|
|
177 |
// we have been asked to close a subsession by the client side so
|
|
178 |
// do just that :). c.f. CSecureSessionSubSessionBase::~CSecureSessionSubSessionBase() above.
|
|
179 |
// In this case we do need to call CloseSubSession before deleting
|
|
180 |
// the subsession object.
|
|
181 |
// We delete by calling CObjectIdx::Remove().This will call CObject::Close.
|
|
182 |
// This in turn calls MSubSessionImpl::MRelease::VirtualRelease
|
|
183 |
// which willdestroy the sub session for us.
|
|
184 |
CSubSessionBase* subSession = static_cast<CSubSessionBase*>(iObjectIx->At(aMessage.Int3()));
|
|
185 |
iObjectIx->Remove(aMessage.Int3());
|
|
186 |
aMessage.Complete(KErrNone);
|
|
187 |
}
|
|
188 |
}
|
|
189 |
|
|
190 |
/**
|
|
191 |
Check whether the session constructL function is called or not first. If not, panic the server,
|
|
192 |
|
|
193 |
Dispatch the message at session level, only two types of message are handled here:
|
|
194 |
SubSession Open and Close.
|
|
195 |
The other messages are fwd to subsession via DispatchMessage.
|
|
196 |
|
|
197 |
@param aMessage A RMessage2 reference.
|
|
198 |
@internalTechnology
|
|
199 |
@released
|
|
200 |
*/
|
|
201 |
void CSecureSessionSubSessionBase::DispatchL(const RMessage2& aMessage)
|
|
202 |
{
|
|
203 |
__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
|
|
204 |
switch(aMessage.Function())
|
|
205 |
{
|
|
206 |
case ESecureSubSessionBaseOpen:
|
|
207 |
CreateSubSessionL(aMessage);
|
|
208 |
break;
|
|
209 |
case ESecureSubSessionBaseClose:
|
|
210 |
DestroySubSession(aMessage);
|
|
211 |
break;
|
|
212 |
default:
|
|
213 |
// the message could be EITHER a session operation - which we have to handle here, or an operation
|
|
214 |
// handled by the subsession which we have to forward
|
|
215 |
DispatchMessageL(aMessage);
|
|
216 |
break;
|
|
217 |
}
|
|
218 |
|
|
219 |
}
|
|
220 |
|
|
221 |
/**
|
|
222 |
Check whether the session constructL function is called or not first. If not, panic the server,
|
|
223 |
|
|
224 |
Check whether the message are for session or subsession
|
|
225 |
Dispatch the message at subsession level
|
|
226 |
get the subsession handler from container and dispatch the message to subsession implementation!
|
|
227 |
|
|
228 |
@param aMessage A RMessage2 reference.
|
|
229 |
@internalTechnology
|
|
230 |
@released
|
|
231 |
*/
|
|
232 |
void CSecureSessionSubSessionBase::DispatchMessageL(const RMessage2& aMessage)
|
|
233 |
{
|
|
234 |
__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
|
|
235 |
// NB the test is intened to ignore a function enum of ELastSessionMessageId - this is not a valid command
|
|
236 |
if(aMessage.Function()<ELastSessionMessageId)
|
|
237 |
{
|
|
238 |
// the message is for the session
|
|
239 |
ServiceMessageL(aMessage); // implmented in the DERIVED CSessionBase class.
|
|
240 |
}
|
|
241 |
else if(aMessage.Function()>ELastSessionMessageId)
|
|
242 |
{
|
|
243 |
// MUST be a message for the subsystem object - delegate
|
|
244 |
CSubSessionBase* subSession = static_cast<CSubSessionBase*>(iObjectIx->At(aMessage.Int3()));
|
|
245 |
subSession->Impl()->DispatchL(aMessage);
|
|
246 |
}
|
|
247 |
}
|
|
248 |
|
|
249 |
/**
|
|
250 |
Return the server
|
|
251 |
|
|
252 |
@return Pointer to server base
|
|
253 |
@internalTechnology
|
|
254 |
@released
|
|
255 |
*/
|
|
256 |
const CSecureServerBase* CSecureSessionSubSessionBase::Server() const
|
|
257 |
{
|
|
258 |
return reinterpret_cast<const CSecureServerBase*>(CSession2::Server());
|
|
259 |
}
|
|
260 |
|
|
261 |
/**
|
|
262 |
Check whether the session constructL function is called or not first. If not, panic the server,
|
|
263 |
|
|
264 |
Dispatch the message at session level, only two types of message are handled here:
|
|
265 |
SubSession Open and Close.
|
|
266 |
If error happened when open subsession, destroy the subsession.
|
|
267 |
|
|
268 |
otherwise, pop the error messages to session or fwd to subsession via DispatchError.
|
|
269 |
|
|
270 |
@param aMessage A RMessage2 reference.
|
|
271 |
@param aError Error code.
|
|
272 |
@internalTechnology
|
|
273 |
@released
|
|
274 |
*/
|
|
275 |
void CSecureSessionSubSessionBase::DispatchError(const RMessage2& aMessage, TInt aError)
|
|
276 |
{
|
|
277 |
__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
|
|
278 |
CSubSessionBase* subSession = NULL;
|
|
279 |
switch(aMessage.Function())
|
|
280 |
{
|
|
281 |
case ESecureSubSessionBaseOpen:
|
|
282 |
if(aError == KErrArgument)
|
|
283 |
{
|
|
284 |
// panic the client we have NO idea what sort
|
|
285 |
// of sub session class the user was tryign to create.
|
|
286 |
// This is a client side failure!, so shoot the client
|
|
287 |
MessageUtils::PanicClient(aMessage, KServerFrameworkPanic, ESecureSubSessionBaseUnknownSubSessionType);
|
|
288 |
// NB there is NOTHING to clean up here, everything is deleted via
|
|
289 |
// the cleanup stack, and the subsession object was never added to the
|
|
290 |
// obejct containers.... See CreateSubSessionL above
|
|
291 |
}
|
|
292 |
else
|
|
293 |
{
|
|
294 |
// CreateSubSessionL() has caused a Leave, so there is
|
|
295 |
// no sub session object to clear up - just complete the
|
|
296 |
// message with an error
|
|
297 |
aMessage.Complete(aError);
|
|
298 |
}
|
|
299 |
break;
|
|
300 |
case ESecureSubSessionBaseClose:
|
|
301 |
// Panic? Non-leaving function that just left?
|
|
302 |
break;
|
|
303 |
default:
|
|
304 |
// DisplatchMessageL above has left - this could be becuase ServiceMessageL left or the subsession DisplatchL
|
|
305 |
// NB the test is intened to ignore a function enum of ELastSessionMessageId - this is not a valid command
|
|
306 |
if(aMessage.Function()<ELastSessionMessageId)
|
|
307 |
{
|
|
308 |
// the message is for the session
|
|
309 |
ServiceMessageError(aMessage, aError); // implmented in the DERIVED CSessionBase class.
|
|
310 |
}
|
|
311 |
else if(aMessage.Function()>ELastSessionMessageId)
|
|
312 |
{
|
|
313 |
// MUST be a message for the subsystem object - delegate
|
|
314 |
subSession = static_cast<CSubSessionBase*>(iObjectIx->At(aMessage.Int3()));
|
|
315 |
subSession->Impl()->DispatchError(aMessage, aError);
|
|
316 |
}
|
|
317 |
break;
|
|
318 |
}
|
|
319 |
}
|