|
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 |
|
18 // INCLUDE FILES |
|
19 #include <e32base.h> |
|
20 #include <lbs.h> |
|
21 #include "lbslocservermessageenums.h" |
|
22 #include <lbs/epos_mposmodulesobserver.h> |
|
23 #include <lbs/epos_cposmoduleidlist.h> |
|
24 #include <lbs/epos_cpositioner.h> |
|
25 #include "EPos_PositionerConstructParams.h" |
|
26 #include "lbsdevloggermacros.h" |
|
27 #include "eposuid.hrh" |
|
28 |
|
29 #ifdef _DEBUG |
|
30 #include <lbs/epos_cpostrace.h> |
|
31 #endif |
|
32 |
|
33 #include "EPos_CPosSession.h" |
|
34 #include "EPos_CPosSubSession.h" |
|
35 #include "EPos_CPosServer.h" |
|
36 #include "EPos_CPosSubsessionRegistry.h" |
|
37 #include "EPos_Global.h" |
|
38 #include "EPos_CPosModulesStatus.h" |
|
39 #include "epos_cposmodulessettings.h" |
|
40 |
|
41 |
|
42 // CONSTANTS |
|
43 #ifdef _DEBUG |
|
44 _LIT(KTraceFileName, "EPos_CPosSession.cpp"); |
|
45 #endif |
|
46 |
|
47 const TPositionModuleId KPosDefaultModule = { KPosDefaultPsyImplUid }; |
|
48 const TPositionModuleId KPosStrategyModule = { KPosStrategyPsyImplUid }; |
|
49 |
|
50 const TInt KParamCriteria = 0; |
|
51 const TInt KParamNumModules = 0; |
|
52 const TInt KParamModuleIdOpen = 0; |
|
53 const TInt KParamModuleIdGetInfo = 0; |
|
54 const TInt KParamModuleIdGetStatus = 0; |
|
55 const TInt KParamModuleIdGetDefault = 0; |
|
56 const TInt KParamModuleInfo = 1; |
|
57 const TInt KParamModuleStatusGet = 1; |
|
58 const TInt KParamSubsession = 3; |
|
59 |
|
60 // ================= MEMBER FUNCTIONS ======================= |
|
61 |
|
62 /** |
|
63 * C++ constructor. |
|
64 */ |
|
65 CPosSession::CPosSession(CPosServer& aServer, |
|
66 CPosModuleSettings& aModuleSettings, |
|
67 CPosModulesStatus& aModulesStatus, |
|
68 CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub) |
|
69 : iPosServer(aServer), |
|
70 iModuleSettings(aModuleSettings), |
|
71 iModulesStatus(aModulesStatus), |
|
72 iLocMonitorReqHandlerHub(aLocMonitorReqHandlerHub) |
|
73 { |
|
74 } |
|
75 |
|
76 /** |
|
77 * C++ destructor. |
|
78 */ |
|
79 CPosSession::~CPosSession() |
|
80 { |
|
81 |
|
82 delete iSubSessionRegistry; |
|
83 |
|
84 // The flag iServerShutdown prevents calling the server or its members if |
|
85 // it is already destroyed. |
|
86 if (!iServerShutdown) |
|
87 { |
|
88 iModulesStatus.NotifySessionClosed(this); |
|
89 iLocMonitorReqHandlerHub.NotifySessionClosed( const_cast<const CSession2*>( static_cast<CSession2*> (this) ) ); //TODO ???????????????????????????????????????????? |
|
90 |
|
91 if (iDecrementSessions) |
|
92 { |
|
93 iPosServer.DecrementSessions(); |
|
94 } |
|
95 } |
|
96 } |
|
97 |
|
98 /** |
|
99 * Two-phased constructor. |
|
100 * |
|
101 * @param aServer Pointer to the server Active Object |
|
102 * @param aModules Modules settings. |
|
103 * @param aModulesStatus Pointer to the ModulesStatus object. |
|
104 * @param aLastPositionHandler Last Position Handler. |
|
105 * @return Pointer to a new instance of CPosSession |
|
106 */ |
|
107 CPosSession* CPosSession::NewL(CPosServer& aServer, |
|
108 CPosModuleSettings& aModuleSettings, |
|
109 CPosModulesStatus& aModulesStatus, |
|
110 CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub) |
|
111 { |
|
112 CPosSession* self = new (ELeave) |
|
113 CPosSession( |
|
114 aServer, |
|
115 aModuleSettings, |
|
116 aModulesStatus, |
|
117 aLocMonitorReqHandlerHub); |
|
118 |
|
119 CleanupStack::PushL(self); |
|
120 self->ConstructL(); |
|
121 CleanupStack::Pop(self); |
|
122 return self; |
|
123 } |
|
124 |
|
125 /** |
|
126 * Symbian destructor. |
|
127 */ |
|
128 void CPosSession::ConstructL() |
|
129 { |
|
130 iSubSessionRegistry = CPosSubsessionRegistry::NewL(); |
|
131 |
|
132 // This call will also cancel any server shutdown in progress. |
|
133 iPosServer.IncrementSessions(); |
|
134 iDecrementSessions = ETrue; |
|
135 |
|
136 } |
|
137 |
|
138 /** |
|
139 * From CSession2 |
|
140 * |
|
141 * This function services all requests from clients. |
|
142 */ |
|
143 void CPosSession::ServiceL(const RMessage2& aMessage) |
|
144 { |
|
145 LBSLOG2(ELogP1, "CPosSession::ServiceL function called with Function() = %u\n", aMessage.Function()); |
|
146 |
|
147 switch (aMessage.Function()) |
|
148 { |
|
149 case ELbsPositionerOpenModuleId: |
|
150 OpenFromModuleIdL(aMessage); |
|
151 break; |
|
152 case ELbsPositionerOpen: |
|
153 OpenDefaultPositionerL(aMessage); |
|
154 break; |
|
155 case ELbsPositionerOpenCriteria: |
|
156 OpenPositionerFromCriteriaL(aMessage); |
|
157 break; |
|
158 case ELbsPositionerClose: |
|
159 ClosePositioner(aMessage); |
|
160 break; |
|
161 case ELbsGetDefaultModuleId: |
|
162 GetDefaultModuleIdL(aMessage); |
|
163 break; |
|
164 case ELbsGetNumModules: |
|
165 GetNumModulesL(aMessage); |
|
166 break; |
|
167 case ELbsGetModuleInfoByIndex: |
|
168 GetModuleInfoByIndexL(aMessage); |
|
169 break; |
|
170 case ELbsGetModuleInfoById: |
|
171 GetModuleInfoByIdL(aMessage); |
|
172 break; |
|
173 case ELbsGetModuleStatus: |
|
174 GetModuleStatusL(aMessage); |
|
175 break; |
|
176 case ELbsNotifyModuleStatusEvent: |
|
177 NotifyModuleStatusEventL(aMessage); |
|
178 break; |
|
179 case ELbsEmptyLastKnownPositionStore: |
|
180 EmptyLastKnownPositionStoreL(aMessage); |
|
181 break; |
|
182 case ELbsServerCancelAsyncRequest: |
|
183 LBS_RDEBUG("Client", "LBS", "CancelAsyncRequest"); |
|
184 HandleCancelAsyncRequestL(aMessage); |
|
185 break; |
|
186 default: |
|
187 ForwardToSubSessionL(aMessage); |
|
188 break; |
|
189 } |
|
190 } |
|
191 |
|
192 /** |
|
193 * From CSession2 |
|
194 * |
|
195 * This function is called when ServiceL leaves. |
|
196 */ |
|
197 void CPosSession::ServiceError(const RMessage2& aMessage, TInt aError) |
|
198 { |
|
199 DEBUG_TRACE("Client's request failed with error", aError) |
|
200 CSession2::ServiceError(aMessage, aError); |
|
201 } |
|
202 |
|
203 /** |
|
204 * Called when a change has been detected in the location settings. |
|
205 * @param aEvent Event information |
|
206 */ |
|
207 void CPosSession::HandleSettingsChangeL(TPosModulesEvent aEvent) |
|
208 { |
|
209 // For all subSessions, call HandleSettingsChangeL() |
|
210 TInt nrOfSubSessions = iSubSessionRegistry->Count(); |
|
211 for (TInt i = 0; i < nrOfSubSessions; i++) |
|
212 { |
|
213 CPosSubSession* subSession = |
|
214 static_cast <CPosSubSession*> |
|
215 (iSubSessionRegistry->SubSessionFromIndex(i)); |
|
216 if (subSession) |
|
217 { |
|
218 subSession->HandleSettingsChangeL(aEvent); |
|
219 } |
|
220 } |
|
221 } |
|
222 |
|
223 /** |
|
224 * Called when the server class is shutting down. |
|
225 */ |
|
226 void CPosSession::NotifyServerShutdown() |
|
227 { |
|
228 DEBUG_TRACE("NotifyServerShutdown", __LINE__) |
|
229 |
|
230 iServerShutdown = ETrue; |
|
231 TInt nrOfSubSessions = iSubSessionRegistry->Count(); |
|
232 |
|
233 iLocMonitorReqHandlerHub.NotifyServerShutDown(); //TODO ???????????????????????????????????????????? |
|
234 |
|
235 for (TInt i = 0; i < nrOfSubSessions; i++) |
|
236 { |
|
237 CPosSubSession* subSession = |
|
238 static_cast <CPosSubSession*> |
|
239 (iSubSessionRegistry->SubSessionFromIndex(i)); |
|
240 if (subSession) |
|
241 { |
|
242 subSession->NotifyServerShutdown(); |
|
243 } |
|
244 } |
|
245 } |
|
246 |
|
247 void CPosSession::OpenFromModuleIdL(const RMessage2& aMessage) |
|
248 { |
|
249 DEBUG_TRACE("EPositionerOpenModuleId", __LINE__) |
|
250 |
|
251 TPckgBuf<TPositionModuleId> moduleIdBuf; |
|
252 User::LeaveIfError(Global::Read(aMessage, KParamModuleIdOpen, moduleIdBuf)); |
|
253 CreateSubSessionL(moduleIdBuf(), EFalse, aMessage); |
|
254 RequestComplete(aMessage, KErrNone); |
|
255 } |
|
256 |
|
257 void CPosSession::OpenDefaultPositionerL(const RMessage2& aMessage) |
|
258 { |
|
259 DEBUG_TRACE("EPositionerOpen(Default)", __LINE__) |
|
260 CreateSubSessionL(KPosDefaultModule, ETrue, aMessage); |
|
261 RequestComplete(aMessage, KErrNone); |
|
262 } |
|
263 |
|
264 void CPosSession::OpenPositionerFromCriteriaL(const RMessage2& aMessage) |
|
265 { |
|
266 DEBUG_TRACE("EPositionerOpenCriteria", __LINE__) |
|
267 |
|
268 // Read Criteria |
|
269 TPckgBuf<TPositionCriteria> criteria; |
|
270 User::LeaveIfError(Global::Read(aMessage, KParamCriteria, criteria)); |
|
271 CreateSubSessionL(KPosStrategyModule, ETrue, aMessage); |
|
272 RequestComplete(aMessage, KErrNone); |
|
273 } |
|
274 |
|
275 void CPosSession::ClosePositioner(const RMessage2& aMessage) |
|
276 { |
|
277 |
|
278 iLocMonitorReqHandlerHub.NotifySubSessionClosed(aMessage); |
|
279 |
|
280 TInt handle = aMessage.Int3(); |
|
281 iSubSessionRegistry->CloseSubSession(handle); |
|
282 |
|
283 RequestComplete(aMessage, KErrNone); |
|
284 |
|
285 DEBUG_TRACE("EPositionerClose", __LINE__) |
|
286 } |
|
287 |
|
288 void CPosSession::GetDefaultModuleIdL(const RMessage2& aMessage) |
|
289 { |
|
290 DEBUG_TRACE("EPositionServerGetDefaultModuleId", __LINE__) |
|
291 |
|
292 CPosModuleIdList* moduleList = iModuleSettings.ModuleIdListL(); |
|
293 CleanupStack::PushL( moduleList ); |
|
294 TInt nrOfModules = moduleList->Count(); |
|
295 TInt res = KErrNotFound; |
|
296 |
|
297 for (TInt i = 0; (i < nrOfModules) && (res == KErrNotFound); i++) |
|
298 { |
|
299 TPositionModuleInfo candidate; |
|
300 iModuleSettings.GetModuleInfoL((*moduleList)[i], candidate); |
|
301 |
|
302 if (candidate.IsAvailable()) |
|
303 { |
|
304 TPckg<TPositionModuleId> moduleId(candidate.ModuleId()); |
|
305 User::LeaveIfError(Global::Write(aMessage, KParamModuleIdGetDefault, moduleId)); |
|
306 res = KErrNone; |
|
307 } |
|
308 } |
|
309 |
|
310 CleanupStack::PopAndDestroy(moduleList); |
|
311 RequestComplete(aMessage, res); |
|
312 } |
|
313 |
|
314 void CPosSession::GetNumModulesL(const RMessage2& aMessage) |
|
315 { |
|
316 DEBUG_TRACE("EPositionServerGetNumModules", __LINE__) |
|
317 |
|
318 CPosModuleIdList* moduleList = iModuleSettings.ModuleIdListL(); |
|
319 TInt num = moduleList->Count(); |
|
320 delete moduleList; |
|
321 |
|
322 TPckg<TUint> numPackage(num); |
|
323 User::LeaveIfError(Global::Write(aMessage, KParamNumModules, numPackage)); |
|
324 RequestComplete(aMessage, KErrNone); |
|
325 } |
|
326 |
|
327 void CPosSession::GetModuleInfoByIndexL(const RMessage2& aMessage) |
|
328 { |
|
329 DEBUG_TRACE("EPositionServerGetModuleInfoByIndex in", __LINE__) |
|
330 |
|
331 // module index |
|
332 TInt modIndex = aMessage.Int0(); |
|
333 |
|
334 CPosModuleIdList* moduleIdList = iModuleSettings.ModuleIdListL(); |
|
335 CleanupStack::PushL( moduleIdList ); |
|
336 if (modIndex >= moduleIdList->Count() || modIndex < 0) |
|
337 { |
|
338 User::Leave(KErrNotFound); |
|
339 } |
|
340 TPositionModuleId moduleId = (*moduleIdList)[modIndex]; |
|
341 |
|
342 // module info |
|
343 HBufC8* buffer = Global::CopyClientBuffer8LC(aMessage, KParamModuleInfo); |
|
344 |
|
345 TPositionModuleInfoBase* moduleInfoBase = |
|
346 reinterpret_cast<TPositionModuleInfoBase*>( |
|
347 const_cast<TUint8*>(buffer->Ptr())); |
|
348 |
|
349 Global::ValidatePositionClassBufferL(*moduleInfoBase, buffer->Des()); |
|
350 // TPositionModuleInfo is the only class supported by CPosModules |
|
351 Global::ValidatePositionClassTypeL(*moduleInfoBase, EPositionModuleInfoClass); |
|
352 DEBUG_TRACE("Buffer validation done", __LINE__) |
|
353 |
|
354 CleanupStack::PopAndDestroy(2, moduleIdList); |
|
355 |
|
356 // TPositionModuleInfo contains descriptor. If it is corrupt |
|
357 // (malicious client) then writing to this will panic server |
|
358 // Local instance of TPositionModuleInfo is created to be sure |
|
359 // that module name descriptor is not corrupt |
|
360 |
|
361 TPositionModuleInfo modInfo; |
|
362 iModuleSettings.GetModuleInfoL(moduleId, modInfo); |
|
363 |
|
364 TPckg<TPositionModuleInfo> modInfoPack(modInfo); |
|
365 User::LeaveIfError(Global::Write(aMessage, KParamModuleInfo, modInfoPack)); |
|
366 |
|
367 RequestComplete(aMessage, KErrNone); |
|
368 DEBUG_TRACE("EPositionServerGetModuleInfoByIndex out", __LINE__) |
|
369 } |
|
370 |
|
371 void CPosSession::GetModuleInfoByIdL(const RMessage2& aMessage) |
|
372 { |
|
373 DEBUG_TRACE("EPositionServerGetModuleInfoById in", __LINE__) |
|
374 |
|
375 TPckgBuf<TPositionModuleId> moduleIdBuf; |
|
376 User::LeaveIfError(Global::Read(aMessage, KParamModuleIdGetInfo, moduleIdBuf)); |
|
377 TPositionModuleId moduleId = moduleIdBuf(); |
|
378 |
|
379 HBufC8* buffer = Global::CopyClientBuffer8LC(aMessage, KParamModuleInfo); |
|
380 |
|
381 TPositionModuleInfoBase* moduleInfoBase = |
|
382 reinterpret_cast<TPositionModuleInfoBase*>( |
|
383 const_cast<TUint8*>(buffer->Ptr())); |
|
384 |
|
385 Global::ValidatePositionClassBufferL(*moduleInfoBase, buffer->Des()); |
|
386 // TPositionModuleInfo is the only class supported by CPosModules |
|
387 Global::ValidatePositionClassTypeL(*moduleInfoBase, EPositionModuleInfoClass); |
|
388 DEBUG_TRACE("Buffer validation done", __LINE__) |
|
389 |
|
390 CleanupStack::PopAndDestroy(buffer); |
|
391 |
|
392 // TPositionModuleInfo contains descriptor. If it is corrupt |
|
393 // (malicious client) then writing to this will panic server |
|
394 // Local instance of TPositionModuleInfo is created to be sure |
|
395 // that module name descriptor is not corrupt |
|
396 |
|
397 TPositionModuleInfo modInfo; |
|
398 iModuleSettings.GetModuleInfoL(moduleId, modInfo); |
|
399 |
|
400 TPckg<TPositionModuleInfo> modInfoPack(modInfo); |
|
401 User::LeaveIfError(Global::Write(aMessage, KParamModuleInfo, modInfoPack)); |
|
402 |
|
403 RequestComplete(aMessage, KErrNone); |
|
404 DEBUG_TRACE("EPositionServerGetModuleInfoById out", __LINE__) |
|
405 } |
|
406 |
|
407 void CPosSession::GetModuleStatusL(const RMessage2& aMessage) |
|
408 { |
|
409 DEBUG_TRACE("EPositionServerGetModuleStatus in", __LINE__) |
|
410 |
|
411 TPckgBuf<TPositionModuleId> moduleIdBuf; |
|
412 User::LeaveIfError(Global::Read(aMessage, KParamModuleIdGetStatus, moduleIdBuf)); |
|
413 TPositionModuleId moduleId = moduleIdBuf(); |
|
414 |
|
415 HBufC8* buffer = Global::CopyClientBuffer8LC(aMessage, KParamModuleStatusGet); |
|
416 |
|
417 // Read module status and write back to client |
|
418 TPositionModuleStatusBase* moduleStatusBase = |
|
419 reinterpret_cast<TPositionModuleStatusBase*>( |
|
420 const_cast<TUint8*>(buffer->Ptr())); |
|
421 |
|
422 Global::ValidatePositionClassBufferL(*moduleStatusBase, buffer->Des()); |
|
423 |
|
424 User::LeaveIfError ( |
|
425 iModulesStatus.GetModuleStatus(moduleId, *moduleStatusBase) ); |
|
426 User::LeaveIfError(Global::Write(aMessage, KParamModuleStatusGet, *buffer)); |
|
427 |
|
428 CleanupStack::PopAndDestroy(buffer); |
|
429 RequestComplete(aMessage, KErrNone); |
|
430 DEBUG_TRACE("EPositionServerGetModuleStatus out", __LINE__) |
|
431 } |
|
432 |
|
433 void CPosSession::NotifyModuleStatusEventL(const RMessage2& aMessage) |
|
434 { |
|
435 DEBUG_TRACE("EPositionServerNotifyModuleStatusEvent", __LINE__) |
|
436 |
|
437 iModulesStatus.NotifyModuleStatusEventL(aMessage, this); |
|
438 } |
|
439 |
|
440 void CPosSession::NotifyModuleStatusEventCancelL(const RMessage2& aMessage) |
|
441 { |
|
442 DEBUG_TRACE("EPositionServerNotifyModuleStatusEventCancel", __LINE__) |
|
443 |
|
444 iModulesStatus.CancelNotifyModuleStatusEventL(this); |
|
445 RequestComplete(aMessage, KErrNone); |
|
446 } |
|
447 |
|
448 void CPosSession::HandleCancelAsyncRequestL(const RMessage2& aMessage) |
|
449 { |
|
450 switch (aMessage.Int0()) |
|
451 { |
|
452 case KServerNotifyModuleStatusEventSymbian: |
|
453 case KServerNotifyModuleStatusEventVariant: |
|
454 case ELbsNotifyModuleStatusEvent: // TODO Verify |
|
455 NotifyModuleStatusEventCancelL(aMessage); |
|
456 break; |
|
457 case ELbsEmptyLastKnownPositionStore: |
|
458 EmptyLastKnownPositionStoreCancelL(aMessage); // TODO Verify |
|
459 |
|
460 default: |
|
461 RequestComplete(aMessage, KErrNotSupported); |
|
462 break; |
|
463 } |
|
464 } |
|
465 |
|
466 void CPosSession::EmptyLastKnownPositionStoreL(const RMessage2& aMessage) |
|
467 { |
|
468 |
|
469 iLocMonitorReqHandlerHub.EmptyLastKnownPosStoreReqL(aMessage); |
|
470 |
|
471 } |
|
472 |
|
473 void CPosSession::EmptyLastKnownPositionStoreCancelL(const RMessage2& aMessage) |
|
474 { |
|
475 |
|
476 iLocMonitorReqHandlerHub.CancelEmptyLastKnownPosStoreReqL(aMessage); |
|
477 |
|
478 } |
|
479 |
|
480 |
|
481 void CPosSession::CreateSubSessionL(TPositionModuleId aId, TBool aIsProxy, const RMessage2& aMessage) |
|
482 { |
|
483 CPosSubSession* subSession = CPosSubSession::NewLC( |
|
484 iModuleSettings, |
|
485 iLocMonitorReqHandlerHub, |
|
486 aId, |
|
487 aIsProxy, |
|
488 &iModulesStatus, |
|
489 &iModulesStatus); |
|
490 |
|
491 TInt subSessionHandle = iSubSessionRegistry->AddInstanceL(subSession); |
|
492 CleanupStack::Pop(subSession); // Now owned by registry |
|
493 |
|
494 // Set the client subsession identifier. |
|
495 TPckg<TInt> handlePackage(subSessionHandle); |
|
496 TInt err = Global::Write(aMessage, KParamSubsession, handlePackage); |
|
497 if (err) |
|
498 { |
|
499 iSubSessionRegistry->CloseSubSession(subSessionHandle); |
|
500 User::Leave(err); |
|
501 } |
|
502 DEBUG_TRACE("Subsession created successfully", __LINE__) |
|
503 } |
|
504 |
|
505 void CPosSession::ForwardToSubSessionL(const RMessage2& aMessage) |
|
506 { |
|
507 CPosSubSession* subSession = |
|
508 iSubSessionRegistry->SubSessionFromHandleL(aMessage.Int3()); |
|
509 |
|
510 if (!subSession) |
|
511 { |
|
512 User::Leave(KErrNotSupported); |
|
513 } |
|
514 |
|
515 subSession->ServiceL(aMessage); |
|
516 } |
|
517 |
|
518 void CPosSession::RequestComplete(const RMessage2& aMessage, TInt aCompleteCode) |
|
519 { |
|
520 if (!aMessage.IsNull()) |
|
521 { |
|
522 aMessage.Complete(aCompleteCode); |
|
523 } |
|
524 } |
|
525 |
|
526 // End of File |