|
1 /* |
|
2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Class for imps sub session. |
|
15 * |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include "impsserver.h" |
|
22 #include "impsutils.h" |
|
23 #include "impssession.h" |
|
24 #include "impsfields.h" |
|
25 #include "impserrors.h" |
|
26 #include "impstimer.h" |
|
27 #include "impssdatautils.h" |
|
28 #include "impspacked.h" |
|
29 #include "impssubsession.h" |
|
30 #include "impstdataaccessor.h" |
|
31 #include "impsmessageinterpreterapi.h" |
|
32 #include "impsliterals.h" |
|
33 #include "ImpsVariantAPI.h" |
|
34 |
|
35 #ifdef _FAKE_RESPONSE |
|
36 #include "impssrvtestutils.h" |
|
37 #endif |
|
38 |
|
39 // MACROS |
|
40 #ifndef _DEBUG |
|
41 #define _NO_IMPS_LOGGING_ |
|
42 #endif |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 // ================= MEMBER FUNCTIONS ======================= |
|
48 |
|
49 // C++ default constructor can NOT contain any code, that |
|
50 // might leave. |
|
51 // |
|
52 CImpsSubSession::CImpsSubSession( ) |
|
53 : iEventList( _FOFF( CWvEvent, iLink ) ), //lint !e413 |
|
54 iRequestList( _FOFF( CRequest, iLink ) ), //lint !e413 |
|
55 iStatusObserver( EFalse ), |
|
56 iDetailedError( EFalse ), |
|
57 iLastEvent( EImpsMessageNone ), |
|
58 iExpiryTime( 0 ) |
|
59 { |
|
60 #ifndef _NO_IMPS_LOGGING_ |
|
61 CImpsClientLogger::Log( _L( "SubSession: CREATE subses=%d" ), ( TInt )this ); |
|
62 #endif |
|
63 } |
|
64 |
|
65 // Destructor |
|
66 // Session destructor calls this |
|
67 CImpsSubSession::~CImpsSubSession() |
|
68 { |
|
69 DeleteAllRequests(); |
|
70 DeleteAllEvents(); |
|
71 delete iVariant; |
|
72 |
|
73 // complete event msg |
|
74 CompleteEventMsg( KErrCancel ); |
|
75 |
|
76 #ifndef _NO_IMPS_LOGGING_ |
|
77 CImpsClientLogger::Log( _L( "SubSession: DELETE subses=%d" ), ( TInt )this ); |
|
78 #endif |
|
79 } |
|
80 |
|
81 // --------------------------------------------------------- |
|
82 // CImpsSubSession::NewL() |
|
83 // --------------------------------------------------------- |
|
84 CImpsSubSession* CImpsSubSession::NewL( |
|
85 CImpsSession* aSession, |
|
86 TImpsEventType aType, |
|
87 const RMessage2 aMessage ) |
|
88 { |
|
89 CImpsSubSession* self = new ( ELeave ) CImpsSubSession(); |
|
90 // CleanupStack::PushL( self ); |
|
91 // Close method has to be called since this is derived from CObject. |
|
92 CleanupClosePushL( *self ); |
|
93 self->ConstructL( aSession, aType, aMessage ); |
|
94 CleanupStack::Pop(); |
|
95 return self; |
|
96 } |
|
97 |
|
98 // --------------------------------------------------------- |
|
99 // CImpsSubSession::ConstructL() |
|
100 // --------------------------------------------------------- |
|
101 void CImpsSubSession::ConstructL( |
|
102 CImpsSession* aSession, |
|
103 TImpsEventType aType, |
|
104 const RMessage2 aMessage ) |
|
105 { |
|
106 iServiceType = aType; |
|
107 iSession = aSession; |
|
108 TInt msg = aMessage.Function(); |
|
109 |
|
110 // get bit mask in an upper byte |
|
111 TInt flags = ( msg >> 16 ); |
|
112 |
|
113 iOOMErr.Reset(); |
|
114 |
|
115 #ifdef _FAKE_RESPONSE |
|
116 // ********************************** |
|
117 // MODULE TEST for auxiliary classes |
|
118 |
|
119 TImpsSrvTestUtils::TestOOMList(); |
|
120 |
|
121 // ********************************** |
|
122 #endif |
|
123 |
|
124 iHandleNew = ( flags & KImpsReqHandleNew ) ? ETrue : EFalse; |
|
125 iVariant = CImpsVariant::NewLC( ); |
|
126 CleanupStack::Pop( ); // >> iVariant |
|
127 // default value used ubtil client request to change it. |
|
128 iExpiryTime = Server()->ExpirySeconds( iServiceType ); |
|
129 } |
|
130 |
|
131 // ----------------------------------------------------------------------------- |
|
132 // CImpsSubSession::Unregister() |
|
133 // ----------------------------------------------------------------------------- |
|
134 void CImpsSubSession::Unregister() |
|
135 { |
|
136 #ifndef _NO_IMPS_LOGGING_ |
|
137 CImpsClientLogger::Log( _L( "SubSession: Unregister subses=%d h=%d type=%d" ), |
|
138 ( TInt )this, Handle(), ( TInt )iServiceType ); |
|
139 #endif |
|
140 iCanceled = ETrue; |
|
141 DeleteAllRequests(); |
|
142 |
|
143 // Complete new message observer |
|
144 CompleteEventMsg( KErrCancel ); |
|
145 |
|
146 ( void ) DeleteAllEvents(); |
|
147 } |
|
148 |
|
149 // ----------------------------------------------------------------------------- |
|
150 // CImpsSubSession::DeleteSub() |
|
151 // ----------------------------------------------------------------------------- |
|
152 void CImpsSubSession::DeleteSub() |
|
153 { |
|
154 #ifndef _NO_IMPS_LOGGING_ |
|
155 CImpsClientLogger::Log( _L( "SubSession: DeleteSub subses=%d type=%d" ), ( TInt )this, ( TInt )iServiceType ); |
|
156 #endif |
|
157 // Calculate new expiry timer value |
|
158 Server()->ResetExpiryTimer( iExpiryTime ); |
|
159 // Delete this entity |
|
160 RMessage2 myMsg( Message() ); |
|
161 iSession->DeleteSubSession( myMsg.Int3() ); |
|
162 } |
|
163 |
|
164 // --------------------------------------------------------- |
|
165 // CImpsSubSession::AssignIdL() |
|
166 // --------------------------------------------------------- |
|
167 void CImpsSubSession::AssignIdL( TImpsSessIdent aCSP ) |
|
168 { |
|
169 #ifndef _NO_IMPS_LOGGING_ |
|
170 CImpsClientLogger::Log( _L( "SubSession: AssignIdL subses=%d" ), ( TInt )this ); |
|
171 #endif |
|
172 // create an event for each orphan message |
|
173 CImpsFields* msg = NULL; |
|
174 msg = Server()->NextOrphanLC( iSession->ApplicationId(), iServiceType, aCSP ); |
|
175 while ( msg ) |
|
176 { |
|
177 SendEvent( msg, 0, EImpsServNone, EImpsMessageNone ); |
|
178 CleanupStack::PopAndDestroy(); |
|
179 msg = Server()->NextOrphanLC( iSession->ApplicationId(), iServiceType, aCSP ); |
|
180 } |
|
181 } |
|
182 |
|
183 // --------------------------------------------------------- |
|
184 // CImpsSubSession::HandleAllOrphans() |
|
185 // --------------------------------------------------------- |
|
186 void CImpsSubSession::HandleAllOrphans( TImpsSessIdent aCSP ) |
|
187 { |
|
188 #ifndef _NO_IMPS_LOGGING_ |
|
189 CImpsClientLogger::Log( _L( "SubSession: HandleAllOrphans subses=%d" ), ( TInt )this ); |
|
190 #endif |
|
191 TInt err = KErrNone; |
|
192 TRAP( err, AssignIdL( aCSP ) ); |
|
193 } |
|
194 |
|
195 // ----------------------------------------------------------------------------- |
|
196 // CImpsSubSession::DeleteAllEvents() |
|
197 // ----------------------------------------------------------------------------- |
|
198 TInt CImpsSubSession::DeleteAllEvents( ) |
|
199 { |
|
200 #ifndef _NO_IMPS_LOGGING_ |
|
201 CImpsClientLogger::Log( _L( "SubSession: DeleteAllEvents subses=%d" ), ( TInt )this ); |
|
202 #endif |
|
203 |
|
204 TInt ret = 0; |
|
205 |
|
206 // Reset OOM_LIST too |
|
207 iOOMErr.Reset(); |
|
208 |
|
209 // Delete all buffered events from this client, |
|
210 |
|
211 TDblQueIter<CWvEvent> rIter( iEventList ); |
|
212 |
|
213 rIter.SetToFirst(); |
|
214 |
|
215 while ( rIter ) |
|
216 { |
|
217 CWvEvent* event = rIter; |
|
218 rIter++; |
|
219 if ( event->iSent ) |
|
220 { |
|
221 ret++; |
|
222 } |
|
223 event->Destroy(); |
|
224 } |
|
225 |
|
226 return ret; |
|
227 } |
|
228 |
|
229 // ----------------------------------------------------------------------------- |
|
230 // CImpsSubSession::DeleteAllRequests() |
|
231 // ----------------------------------------------------------------------------- |
|
232 void CImpsSubSession::DeleteAllRequests( ) |
|
233 { |
|
234 #ifndef _NO_IMPS_LOGGING_ |
|
235 CImpsClientLogger::Log( _L( "SubSession: DeleteAllRequests" ) ); |
|
236 #endif |
|
237 // Delete all buffered requests from this client. |
|
238 |
|
239 TDblQueIter<CRequest> rIter( iRequestList ); |
|
240 |
|
241 rIter.SetToFirst(); |
|
242 |
|
243 while ( rIter ) |
|
244 { |
|
245 CRequest* requ = rIter; |
|
246 rIter++; |
|
247 #ifndef _NO_IMPS_LOGGING_ |
|
248 CImpsClientLogger::Log( _L( "SubSession: DeleteAllRequests TID=%S" ), &( requ->iTID ) ); |
|
249 #endif |
|
250 requ->Destroy(); |
|
251 } |
|
252 } |
|
253 |
|
254 // --------------------------------------------------------- |
|
255 // CImpsSubSession::LoginL() |
|
256 // --------------------------------------------------------- |
|
257 void CImpsSubSession::LoginL( TBool aReactive ) |
|
258 { |
|
259 #ifndef _NO_IMPS_LOGGING_ |
|
260 CImpsClientLogger::Log( _L( "SubSession: LoginL begins reactive=%d subses=%d" ), |
|
261 aReactive, ( TInt )this ); |
|
262 #endif |
|
263 |
|
264 // OPID |
|
265 RMessage2 myMsg( Message() ); |
|
266 TInt opId = myMsg.Int1(); |
|
267 #ifndef _NO_IMPS_LOGGING_ |
|
268 CImpsClientLogger::Log( _L( "SubSession: Login opid=%d" ), opId ); |
|
269 #endif |
|
270 |
|
271 // Read PACKED ARRAY |
|
272 CDesCArrayFlat* tempArr = new ( ELeave )CDesCArrayFlat( 7 ); |
|
273 CleanupStack::PushL( tempArr ); // << tempArr |
|
274 |
|
275 HBufC8* stream = *StreamBufAddr(); |
|
276 if ( iSession->ReadBuffer8L( 0, stream ) ) |
|
277 { |
|
278 HBufC8** stream2 = StreamBufAddr(); |
|
279 *stream2 = stream; |
|
280 } |
|
281 TImpsPackedEntity packedMessage( stream ); |
|
282 const TUint8* pS = stream->Ptr(); |
|
283 packedMessage.DoUnpackArrayL( pS, tempArr ); |
|
284 |
|
285 __ASSERT_DEBUG( |
|
286 tempArr->MdcaCount() == 7, |
|
287 User::Panic( KImpsPanicCategory, |
|
288 EImpsCorrupted ) ); |
|
289 TPtrC tid; |
|
290 TPtrC tempUser = tempArr->MdcaPoint( 0 ); |
|
291 TPtrC tempPassword = tempArr->MdcaPoint( 1 ); |
|
292 TPtrC tempCliId = tempArr->MdcaPoint( 2 ); |
|
293 TPtrC tempSAP = tempArr->MdcaPoint( 3 ); |
|
294 TPtrC key1 = tempArr->MdcaPoint( 4 ); |
|
295 TPtrC key2 = tempArr->MdcaPoint( 5 ); |
|
296 TPtrC ap = tempArr->MdcaPoint( 6 ); |
|
297 |
|
298 // convert AP back |
|
299 TLex lex; |
|
300 TUint32 myAp; |
|
301 lex.Assign( ap ); |
|
302 lex.Val( myAp, EDecimal ); |
|
303 |
|
304 // Multi: update session's user-id and SAP. |
|
305 iSession->SetUserIdL( tempUser ); |
|
306 iSession->SetSAPL( tempSAP ); |
|
307 |
|
308 TImpsSessIdent csp( KNullDesC, tempSAP, tempUser ); |
|
309 TPtrC p; |
|
310 if ( Server()->IsLogged( csp, &p ) ) |
|
311 { |
|
312 #ifndef _NO_IMPS_LOGGING_ |
|
313 CImpsClientLogger::Log( _L( "SubSession: CSP already logged ín subses=%d" ), ( TInt )this ); |
|
314 #endif |
|
315 // check password: if it does not match then return an error. |
|
316 if ( p.CompareF( tempPassword ) ) |
|
317 { |
|
318 User::Leave( KImpsErrorUnauthorized ); |
|
319 } |
|
320 |
|
321 // Update session SID and other CSP identification data. |
|
322 iSession->ModifySIDL( Server()->SID( csp ) ); |
|
323 iSession->SetSAPL( tempSAP ); |
|
324 iSession->SetUserIdL( tempUser ); |
|
325 |
|
326 // multi: Share existing CSP session |
|
327 // Send callback reponse to a client |
|
328 // Complete the open asyncronous request first and |
|
329 // after that send login event (callback). |
|
330 iSession->CompleteMe( KErrNone ); |
|
331 SendLoginEvent( KErrNone, opId ); |
|
332 if ( Server()->IsNegotiated( csp ) ) |
|
333 { |
|
334 // On-line event too if CSP is negotiated. |
|
335 // Must sent via Session to all subsessions |
|
336 iSession->SendEvent( EInternal_ON_LINE ); |
|
337 // Check orphan messages because of IM subsessions |
|
338 // may be registered before login request, |
|
339 // Create an event for each orphan message |
|
340 Server()->HandleAllOrphans(); |
|
341 } |
|
342 tempArr->Reset(); |
|
343 CleanupStack::PopAndDestroy( 1 ); // >> tempArr |
|
344 return; |
|
345 } |
|
346 |
|
347 |
|
348 // Save login expiry time and give it to CSP session too. |
|
349 TTime loginExpiry = Server()->ExpiryTime( iExpiryTime ); |
|
350 |
|
351 tid.Set( Server()->LoginL( tempUser, tempPassword, tempCliId, |
|
352 tempSAP, myAp, key1, key2, this, loginExpiry, aReactive ) ); |
|
353 |
|
354 tempArr->Reset(); |
|
355 CleanupStack::PopAndDestroy( 1 ); // >> tempArr |
|
356 |
|
357 // Update request queue |
|
358 // Add request into queue |
|
359 CRequest* request = new ( ELeave ) CRequest( |
|
360 tid, // tid |
|
361 opId, // op-id |
|
362 EImpsServWVLogin, |
|
363 loginExpiry, |
|
364 EImpsLoginReq |
|
365 ); |
|
366 |
|
367 iRequestList.AddLast( *request ); |
|
368 |
|
369 #ifndef _NO_IMPS_LOGGING_ |
|
370 CImpsClientLogger::Log( _L( "SubSession: LoginL ends TID=%S" ), &tid ); |
|
371 #endif |
|
372 |
|
373 } |
|
374 |
|
375 // --------------------------------------------------------- |
|
376 // CImpsSubSession::LogoutL() |
|
377 // --------------------------------------------------------- |
|
378 TPtrC CImpsSubSession::LogoutL( TImpsSessIdent aCSP, TBool aCancel ) |
|
379 { |
|
380 #ifndef _NO_IMPS_LOGGING_ |
|
381 CImpsClientLogger::Log( _L( "SubSession: LogoutL begins subses=%d" ), ( TInt )this ); |
|
382 #endif |
|
383 |
|
384 RMessage2 myMsg( Message() ); |
|
385 TInt opId = myMsg.Int0(); |
|
386 #ifndef _NO_IMPS_LOGGING_ |
|
387 CImpsClientLogger::Log( _L( "SubSession: Logout opid=%d" ), opId ); |
|
388 #endif |
|
389 |
|
390 TPtrC tid; |
|
391 |
|
392 // Login-cancel. |
|
393 if ( aCancel ) |
|
394 { |
|
395 // Check that request still exists, if not then leave KErrNotFound |
|
396 TBool found( EFalse ); |
|
397 TDblQueIter<CRequest> requestIter( iRequestList ); |
|
398 requestIter.SetToFirst(); |
|
399 while ( requestIter ) |
|
400 { |
|
401 CRequest* request = requestIter; |
|
402 requestIter++; |
|
403 if ( request->iOpId == opId ) |
|
404 { |
|
405 found = ETrue; |
|
406 break; |
|
407 } |
|
408 } |
|
409 if ( !found ) |
|
410 { |
|
411 User::Leave( KErrNotFound ); |
|
412 } |
|
413 } |
|
414 |
|
415 // Send logout request forward to CSP session entity |
|
416 TRAPD( errL, tid.Set( iSession->Server()->LogoutL( aCancel, aCSP ) ) ); |
|
417 |
|
418 // If canceling login operation then client needs to get only one callback method call, |
|
419 // so do not save new CRequest entity then. The CSP session entity will call later |
|
420 // SendEvent to respond to the cancelled login operation if there is something |
|
421 // to cancel. |
|
422 if ( aCancel ) |
|
423 { |
|
424 if ( errL ) |
|
425 { |
|
426 // If the previous request leaves then there is nothing to cancel. |
|
427 // Therefore delete the login request entity now and verify that CSP entity |
|
428 // clear the particular transaction data, |
|
429 CancelTrans( myMsg, aCSP ); |
|
430 User::Leave( errL ); |
|
431 } |
|
432 // CSPSession will call back later and delete the request and send a response |
|
433 // event to cancel request when everyting is clear regarding cancel of login |
|
434 // transaction.. |
|
435 return TPtrC(); |
|
436 } |
|
437 if ( errL == KImpsErrorTerminalOffLine ) |
|
438 { |
|
439 // Logout requested in such a situation where Logout request is |
|
440 // not needed nor not possible to be sent to SAP server. |
|
441 // We have to generate a response here |
|
442 // because of Logout must not fail in client API. |
|
443 SendLogoutEvent( KErrNone, opId ); |
|
444 // Send NOT_LOGGED events to subhandles |
|
445 iSession->SendEvent( EInternal_NOT_LOGGED ); |
|
446 return TPtrC(); |
|
447 } |
|
448 else if ( errL ) |
|
449 { |
|
450 // Unexpeted error situation |
|
451 User::Leave( errL ); |
|
452 } |
|
453 |
|
454 // Add request into request queue |
|
455 CRequest* request = new ( ELeave ) CRequest( |
|
456 tid, |
|
457 opId, |
|
458 EImpsServWVLogout, |
|
459 Server()->ExpiryTime( iExpiryTime ), |
|
460 EImpsLogoutReq |
|
461 ); |
|
462 iRequestList.AddLast( *request ); |
|
463 |
|
464 #ifndef _NO_IMPS_LOGGING_ |
|
465 CImpsClientLogger::Log( _L( "SubSession: LogoutL ends with tid=%S" ), &tid ); |
|
466 #endif |
|
467 return tid; |
|
468 } |
|
469 |
|
470 // --------------------------------------------------------- |
|
471 // CImpsSubSession::Message() |
|
472 // --------------------------------------------------------- |
|
473 // return message - get it from session |
|
474 const RMessagePtr2 CImpsSubSession::Message() const |
|
475 { |
|
476 return iSession->Message(); |
|
477 } |
|
478 |
|
479 // --------------------------------------------------------- |
|
480 // CImpsSubSession::Server() |
|
481 // --------------------------------------------------------- |
|
482 // return message - get it from session |
|
483 CImpsServer* CImpsSubSession::Server() |
|
484 { |
|
485 return iSession->Server(); |
|
486 } |
|
487 |
|
488 // --------------------------------------------------------- |
|
489 // CImpsSubSession::DoSendStatusEvent() |
|
490 // --------------------------------------------------------- |
|
491 void CImpsSubSession::DoSendStatusEvent( CWvEvent& aEvent ) |
|
492 { |
|
493 |
|
494 // Status event is lighter than a regular event in a sense that |
|
495 // it does not write data to client thread, but updates iStatus |
|
496 // of the handler active object in a client thread only. |
|
497 if ( iEventMsg.IsNull() ) |
|
498 { |
|
499 #ifndef _NO_IMPS_LOGGING_ |
|
500 CImpsClientLogger::Log( _L( "SubSession: DoSendStatusEvent NULL MSG subses=%d" ), |
|
501 ( TInt )this ); |
|
502 #endif |
|
503 return; |
|
504 } |
|
505 |
|
506 TInt newStatus = ConvertStatusCode( ( EImpsInternalStatus )aEvent.iAux ); |
|
507 |
|
508 #ifndef _NO_IMPS_LOGGING_ |
|
509 CImpsClientLogger::Log( _L( "SubSession: DoSendStatusEvent stat=%d subses=%d" ), |
|
510 newStatus, ( TInt )this ); |
|
511 #endif |
|
512 CompleteEventMsg( newStatus ); |
|
513 |
|
514 aEvent.iSent = ETrue; |
|
515 } |
|
516 |
|
517 // --------------------------------------------------------- |
|
518 // CImpsSubSession::SendEvent() |
|
519 // --------------------------------------------------------- |
|
520 void CImpsSubSession::SendEvent( |
|
521 CImpsFields *aFields, |
|
522 TInt aOpId, |
|
523 TImpsServRequest aRequestType, |
|
524 TImpsMessageType aReqMsgType ) |
|
525 { |
|
526 |
|
527 TInt memErr = KErrNone; |
|
528 // It is possible that the cancel request from client is not |
|
529 // complete and this session entity is still waiting deletion. |
|
530 if ( iCanceled ) |
|
531 { |
|
532 #ifndef _NO_IMPS_LOGGING_ |
|
533 CImpsClientLogger::Log( |
|
534 _L( "SubSession: SendEvent cancelled subses=%d ****" ), ( TInt )this ); |
|
535 #endif |
|
536 return; |
|
537 } |
|
538 |
|
539 #ifndef _NO_IMPS_LOGGING_ |
|
540 CImpsClientLogger::Log( _L( "SubSession: SendEvent begins" ) ); |
|
541 #endif |
|
542 |
|
543 |
|
544 TDblQueIter<CWvEvent> eventIter( iEventList ); |
|
545 |
|
546 // Check if too many events waiting |
|
547 CWvEvent* event = NULL; |
|
548 |
|
549 // check if there is unhandled events for this session |
|
550 TBool thisFirst = ( NbrEvents() > 0 || iOOMErr.Exists() ) ? EFalse : ETrue; |
|
551 |
|
552 // Split GroupChangeNotice up to three parts for |
|
553 // HandleNewUsersL, HandleLeftUsersL and HandleGroupProperties |
|
554 if ( aFields->MessageType() == EImpsGroupChangeNotice ) |
|
555 { |
|
556 TRAP( memErr, DoSplitGroupChangeL( aOpId, aRequestType, aFields ) ); |
|
557 } |
|
558 else |
|
559 { |
|
560 TRAP( memErr, DoCreateEventL( aOpId, aRequestType, aReqMsgType, aFields ) ); |
|
561 } |
|
562 |
|
563 // Now the event is ready to be sent. |
|
564 // Send the event to client thread if this is first one |
|
565 if ( thisFirst && !memErr ) |
|
566 { |
|
567 // This should be a new event just created |
|
568 eventIter.SetToFirst(); |
|
569 event = eventIter; |
|
570 __ASSERT_DEBUG( |
|
571 !event->iSent, |
|
572 User::Panic( KImpsPanicCategory, |
|
573 EImpsCorrupted ) ); |
|
574 // Select between base event and EventBody |
|
575 DoSendBaseEvent( *event ); |
|
576 } |
|
577 // Notice: CSP negotiation requests (client capabilities and service |
|
578 // negotiaion) are internal for CSP class entity and they are not |
|
579 // originated from client. Thus corresponding negotiation phase |
|
580 // errors are not guaranted to be sent to a client in OOM situation. |
|
581 // In those cases the aOpId is NULL. |
|
582 // |
|
583 else if ( memErr && aOpId ) |
|
584 { |
|
585 // send/store OOM error message ( KErrNoMemory, aOpId ) |
|
586 iOOMErr.StoreOOM( aOpId ); |
|
587 if ( thisFirst ) |
|
588 { |
|
589 ( void )SendOOMError(); |
|
590 } |
|
591 } |
|
592 |
|
593 #ifndef _NO_IMPS_LOGGING_ |
|
594 CImpsClientLogger::Log( _L( "SubSession: SendEvent ends" ) ); |
|
595 #endif |
|
596 } |
|
597 |
|
598 // --------------------------------------------------------- |
|
599 // CImpsSubSession::SendEvent() |
|
600 // Lighter version for engine status event |
|
601 // Notice: CSP status changes are guaranted to |
|
602 // to be sent to a client in OOM situation too. |
|
603 // --------------------------------------------------------- |
|
604 void CImpsSubSession::SendEvent( |
|
605 EImpsInternalStatus aStatus ) |
|
606 { |
|
607 |
|
608 // It is possible that the cancel request from client is not |
|
609 // complete and this session entity is still waiting deletion. |
|
610 if ( iCanceled || !iStatusObserver ) |
|
611 { |
|
612 return; |
|
613 } |
|
614 |
|
615 #ifndef _NO_IMPS_LOGGING_ |
|
616 CImpsClientLogger::Log( _L( "SubSession: SendEvent (status) subses=%d" ), ( TInt )this ); |
|
617 #endif |
|
618 |
|
619 // check if there is unhandled events for this session |
|
620 TBool thisFirst = ( NbrEvents() > 0 || iOOMErr.Exists() ) ? EFalse : ETrue; |
|
621 |
|
622 // Prefer reqular event queue then OOM error queue in order |
|
623 // to save the logical order of events. |
|
624 TRAPD( memErr, DoCreateEventL( aStatus ) ); |
|
625 |
|
626 if ( thisFirst && !memErr ) |
|
627 { |
|
628 TDblQueIter<CWvEvent> eventIter( iEventList ); |
|
629 CWvEvent* event = NULL; |
|
630 // This should be a new event just created |
|
631 eventIter.SetToFirst(); |
|
632 event = eventIter; |
|
633 __ASSERT_DEBUG( |
|
634 !event->iSent, |
|
635 User::Panic( KImpsPanicCategory, |
|
636 EImpsCorrupted ) ); |
|
637 // Send the event immediately |
|
638 DoSendStatusEvent( *event ); |
|
639 } |
|
640 |
|
641 else if ( memErr ) |
|
642 { |
|
643 // send/store OOM error message ( status, aOpId ) |
|
644 TInt retCode = ConvertStatusCode( aStatus ); |
|
645 iOOMErr.StoreOOM( retCode ); |
|
646 if ( thisFirst ) |
|
647 { |
|
648 ( void )SendOOMError(); |
|
649 } |
|
650 } |
|
651 |
|
652 #ifndef _NO_IMPS_LOGGING_ |
|
653 CImpsClientLogger::Log( _L( "SubSession: SendEvent ends" ) ); |
|
654 #endif |
|
655 } |
|
656 |
|
657 // --------------------------------------------------------- |
|
658 // CImpsSubSession::DoSendBaseEvent() |
|
659 // --------------------------------------------------------- |
|
660 void CImpsSubSession::DoSendBaseEvent( CWvEvent& aEvent ) |
|
661 { |
|
662 TInt bufSize = EventMsgBufSize(); |
|
663 TInt messageLength = aEvent.iPackedMessage ? |
|
664 aEvent.iPackedMessage->Length() : 0; |
|
665 if ( bufSize > 0 && bufSize >= messageLength ) |
|
666 { |
|
667 // Message body can be sent immediately. |
|
668 // This sends message headers too. |
|
669 DoSendEventBody( aEvent ); |
|
670 } |
|
671 else |
|
672 { |
|
673 // No message body or client is asked to increase the buffer |
|
674 DoSendEventHeader( aEvent ); |
|
675 } |
|
676 } |
|
677 |
|
678 // --------------------------------------------------------- |
|
679 // CImpsSubSession::DoSendEventHeader() |
|
680 // --------------------------------------------------------- |
|
681 void CImpsSubSession::DoSendEventHeader( CWvEvent& aEvent ) |
|
682 { |
|
683 #ifndef _NO_IMPS_LOGGING_ |
|
684 CImpsClientLogger::Log( _L( "SubSession: DoSendEventHeader type=%d subses=%d" ), |
|
685 aEvent.iType, ( TInt )this ); |
|
686 #endif |
|
687 RMessagePtr2 ptrMsg = EventMsg(); |
|
688 if ( ptrMsg.IsNull() ) |
|
689 { |
|
690 #ifndef _NO_IMPS_LOGGING_ |
|
691 CImpsClientLogger::Log( _L( "SubSession: DoSendEventHeader NULL MSG subses=%d" ), |
|
692 ( TInt )this ); |
|
693 #endif |
|
694 return; |
|
695 } |
|
696 // Create the header information |
|
697 |
|
698 TBuf < sizeof( SImpsEventData ) > |
|
699 eventBuf( sizeof( SImpsEventData ) ); |
|
700 |
|
701 SImpsEventData* eventData = |
|
702 ( SImpsEventData* )eventBuf.Ptr(); |
|
703 |
|
704 DoCreateEventIPC( aEvent, eventData ); |
|
705 |
|
706 // Write the message header to client thread via a message. |
|
707 TInt err = KErrNone; |
|
708 |
|
709 |
|
710 err = DoWriteEventHeaders( ptrMsg, eventBuf ); |
|
711 |
|
712 // We use NotifyHandler status parameter to pass the size of the |
|
713 // packed message! |
|
714 TInt messageLength = aEvent.iPackedMessage ? |
|
715 aEvent.iPackedMessage->Length() : 0; |
|
716 if ( err == KErrNone ) |
|
717 { |
|
718 err = messageLength; |
|
719 } |
|
720 |
|
721 // Signal event handler in a client thread |
|
722 CompleteEventMsg( err ); |
|
723 |
|
724 aEvent.iSent = ETrue; |
|
725 } |
|
726 |
|
727 // --------------------------------------------------------- |
|
728 // CImpsSubSession::DoSendEventBody() |
|
729 // --------------------------------------------------------- |
|
730 void CImpsSubSession::DoSendEventBody( CWvEvent& aEvent ) |
|
731 { |
|
732 #ifndef _NO_IMPS_LOGGING_ |
|
733 CImpsClientLogger::Log( _L( "SubSession: DoSendEventBody type=%d subses=%d" ), |
|
734 aEvent.iType, ( TInt )this ); |
|
735 #endif |
|
736 |
|
737 RMessagePtr2 ptrMsg = EventMsg(); |
|
738 if ( ptrMsg.IsNull() ) |
|
739 { |
|
740 #ifndef _NO_IMPS_LOGGING_ |
|
741 CImpsClientLogger::Log( _L( "SubSession: DoSendEventBody NULL MSG subses=%d" ), |
|
742 ( TInt )this ); |
|
743 #endif |
|
744 return; |
|
745 } |
|
746 |
|
747 // This writes both headers and body. |
|
748 // This increases the robustenss and thre client thread do not need |
|
749 // to store data between these transactions, because of it receives |
|
750 // all the necessary data at once. |
|
751 |
|
752 TBuf < sizeof( SImpsEventData ) > |
|
753 eventBuf( sizeof( SImpsEventData ) ); |
|
754 |
|
755 SImpsEventData* eventData = |
|
756 ( SImpsEventData* )eventBuf.Ptr(); |
|
757 |
|
758 DoCreateEventIPC( aEvent, eventData ); |
|
759 eventData->iMessageBody = ( aEvent.iPackedMessage ? ETrue : EFalse ); |
|
760 |
|
761 // Write the message header to client thread via a message. |
|
762 TInt err = KErrNone; |
|
763 err = DoWriteEventHeaders( ptrMsg, eventBuf ); |
|
764 |
|
765 if ( !err ) |
|
766 { |
|
767 // Write the message body |
|
768 err = DoWriteEventBody( ptrMsg, aEvent ); |
|
769 // We use NotifyHandler status parameter to pass the size of the |
|
770 // packed message! |
|
771 TInt messageLength = aEvent.iPackedMessage ? |
|
772 aEvent.iPackedMessage->Length() : 0; |
|
773 if ( err == KErrNone ) |
|
774 { |
|
775 err = messageLength; |
|
776 } |
|
777 } |
|
778 |
|
779 // Signal event handler in a client thread |
|
780 CompleteEventMsg( err ); |
|
781 |
|
782 aEvent.iSent = ETrue; |
|
783 } |
|
784 |
|
785 // --------------------------------------------------------- |
|
786 // CImpsSubSession::SendLogoutEvent |
|
787 // --------------------------------------------------------- |
|
788 void CImpsSubSession::SendLogoutEvent( TInt aRespStatus, TInt aOpId ) |
|
789 { |
|
790 // transfer CSP error code if any |
|
791 if ( aRespStatus > 0 ) |
|
792 { |
|
793 aRespStatus = ErrorCode( aRespStatus ); |
|
794 } |
|
795 |
|
796 // check session type first and filter sending |
|
797 // of the same logout twice |
|
798 if ( iServiceType != EImpsEventServerLogin || |
|
799 ( iLastEvent == EImpsDisconnect && aOpId == 0 ) ) |
|
800 { |
|
801 return; |
|
802 } |
|
803 |
|
804 #ifndef _NO_IMPS_LOGGING_ |
|
805 CImpsClientLogger::Log( _L( "SubSession: SendLogoutEvent in action subses=%d" ), |
|
806 ( TInt )this ); |
|
807 #endif |
|
808 |
|
809 TDblQueIter<CWvEvent> eventIter( iEventList ); |
|
810 CWvEvent* event = NULL; |
|
811 |
|
812 // check if there is unhandled events for this session |
|
813 TBool thisFirst = ( NbrEvents() > 0 || iOOMErr.Exists() ) ? EFalse : ETrue; |
|
814 |
|
815 // Let this behave like real SAP initiated Disconnect primitive |
|
816 TRAPD( memErr, DoCreateEventL( aOpId, aRespStatus, |
|
817 EImpsMessageNone, EImpsDisconnect, EImpsServWVLogout ) ); |
|
818 // Since WV 1,2 logout messages may be either disconnect or Status, |
|
819 // harmomize them here in order to avoid sending logout message |
|
820 // with opid=actual_id and opid=0. |
|
821 iLastEvent = EImpsDisconnect; |
|
822 |
|
823 // Now the event is ready to be sent. |
|
824 // Send the event to client thread if this is first one |
|
825 if ( thisFirst && !memErr ) |
|
826 { |
|
827 // This should be a new event just created |
|
828 eventIter.SetToFirst(); |
|
829 event = eventIter; |
|
830 __ASSERT_DEBUG( |
|
831 !event->iSent, |
|
832 User::Panic( KImpsPanicCategory, |
|
833 EImpsCorrupted ) ); |
|
834 // Logout event does not contain body in this case |
|
835 DoSendEventHeader( *event ); |
|
836 } |
|
837 else if ( memErr && aOpId ) |
|
838 { |
|
839 // send/store OOM error message ( KErrNoMemory, aOpId ) |
|
840 iOOMErr.StoreOOM( aOpId ); |
|
841 if ( thisFirst ) |
|
842 { |
|
843 ( void )SendOOMError(); |
|
844 } |
|
845 } |
|
846 } |
|
847 |
|
848 // --------------------------------------------------------- |
|
849 // CImpsSubSession::SendLoginEvent |
|
850 // Multi: new method to generate events when CSP session |
|
851 // already exists |
|
852 // --------------------------------------------------------- |
|
853 void CImpsSubSession::SendLoginEvent( TInt aRespStatus, TInt aOpId ) |
|
854 { |
|
855 // transfer CSP error code if any |
|
856 if ( aRespStatus > 0 ) |
|
857 { |
|
858 aRespStatus = ErrorCode( aRespStatus ); |
|
859 } |
|
860 |
|
861 // check session type first and filter sending |
|
862 // of the same logout twice |
|
863 if ( iServiceType != EImpsEventServerLogin ) |
|
864 { |
|
865 return; |
|
866 } |
|
867 |
|
868 #ifndef _NO_IMPS_LOGGING_ |
|
869 CImpsClientLogger::Log( _L( "SubSession: SendLoginEvent in action subses=%d" ), |
|
870 ( TInt )this ); |
|
871 #endif |
|
872 |
|
873 TDblQueIter<CWvEvent> eventIter( iEventList ); |
|
874 CWvEvent* event = NULL; |
|
875 |
|
876 // check if there is unhandled events for this session |
|
877 TBool thisFirst = ( NbrEvents() > 0 || iOOMErr.Exists() ) ? EFalse : ETrue; |
|
878 |
|
879 // Let this behave like real SAP initiated Disconnect primitive |
|
880 TRAPD( memErr, DoCreateEventL( aOpId, aRespStatus, |
|
881 EImpsMessageNone, EImpsLoginRes, EImpsServWVLogin ) ); |
|
882 |
|
883 // Now the event is ready to be sent. |
|
884 // Send the event to client thread if this is first one |
|
885 if ( thisFirst && !memErr ) |
|
886 { |
|
887 // This should be a new event just created |
|
888 eventIter.SetToFirst(); |
|
889 event = eventIter; |
|
890 __ASSERT_DEBUG( |
|
891 !event->iSent, |
|
892 User::Panic( KImpsPanicCategory, |
|
893 EImpsCorrupted ) ); |
|
894 // Logout event does not contain body in this case |
|
895 DoSendEventHeader( *event ); |
|
896 } |
|
897 else if ( memErr && aOpId ) |
|
898 { |
|
899 // send/store OOM error message ( KErrNoMemory, aOpId ) |
|
900 iOOMErr.StoreOOM( aOpId ); |
|
901 if ( thisFirst ) |
|
902 { |
|
903 ( void )SendOOMError(); |
|
904 } |
|
905 } |
|
906 } |
|
907 |
|
908 // --------------------------------------------------------- |
|
909 // CImpsSubSession::SendOOMError |
|
910 // --------------------------------------------------------- |
|
911 TBool CImpsSubSession::SendOOMError( ) |
|
912 { |
|
913 |
|
914 if ( iEventMsg.IsNull() ) |
|
915 { |
|
916 #ifndef _NO_IMPS_LOGGING_ |
|
917 CImpsClientLogger::Log( |
|
918 _L( "SubSession: SendOOMError NULL MSG subses=%d" ), ( TInt )this ); |
|
919 #endif |
|
920 return EFalse; |
|
921 } |
|
922 |
|
923 TInt opId = iOOMErr.GetOOM(); |
|
924 if ( opId != 0 ) |
|
925 { |
|
926 if ( opId > 0 ) |
|
927 { |
|
928 CompleteEventMsg( KImpsOOMReply | opId ); |
|
929 #ifndef _NO_IMPS_LOGGING_ |
|
930 CImpsClientLogger::Log( |
|
931 _L( "SubSession: SendOOMError completes opid=%d ****" ), opId ); |
|
932 #endif |
|
933 } |
|
934 else |
|
935 { |
|
936 // Status change special error code etc |
|
937 CompleteEventMsg( opId ); |
|
938 #ifndef _NO_IMPS_LOGGING_ |
|
939 CImpsClientLogger::Log( |
|
940 _L( "SubSession: SendOOMError completes status=%d ****" ), opId ); |
|
941 #endif |
|
942 } |
|
943 return ETrue; |
|
944 } |
|
945 else |
|
946 { |
|
947 return EFalse; |
|
948 } |
|
949 } |
|
950 |
|
951 // --------------------------------------------------------- |
|
952 // CImpsSubSession::SendPrimitiveL() |
|
953 // --------------------------------------------------------- |
|
954 void CImpsSubSession::SendPrimitiveL( TInt aFunction, TImpsSessIdent aCSP ) |
|
955 { |
|
956 RMessage2 myMsg( Message() ); |
|
957 TInt opId = myMsg.Int1(); |
|
958 #ifndef _NO_IMPS_LOGGING_ |
|
959 CImpsClientLogger::Log( _L( "SubSession: SendPrimitiveL begins %d opid=%d" ), |
|
960 aFunction, opId ); |
|
961 #endif |
|
962 |
|
963 switch ( aFunction ) |
|
964 { |
|
965 case EImpsServWVSendOnly: |
|
966 case EImpsServBlock: |
|
967 // Check availability of the service in general |
|
968 TImpsSrvUtils::CheckServiceL( EIMFeat, |
|
969 Server()->Services( aCSP ) ); |
|
970 break; |
|
971 case EImpsServGroup: |
|
972 TImpsSrvUtils::CheckServiceL( EGroupFeat, |
|
973 Server()->Services( aCSP ) ); |
|
974 break; |
|
975 case EImpsServPres: |
|
976 TImpsSrvUtils::CheckServiceL( EPresenceFeat, |
|
977 Server()->Services( aCSP ) ); |
|
978 break; |
|
979 case EImpsServFundSearch: |
|
980 case EImpsServFundInvite: |
|
981 TImpsSrvUtils::CheckServiceL( EFundamentalFeat, |
|
982 Server()->Services( aCSP ) ); |
|
983 break; |
|
984 default: |
|
985 break; |
|
986 } |
|
987 // Get data to iFields |
|
988 GetWVDataL(); |
|
989 |
|
990 TImpsMessageType myMesType = ( TImpsMessageType ) ImpsFields()->MessageType(); |
|
991 |
|
992 // Check primitive if this is pure subsession |
|
993 // Discard anything that does not belong to presence service |
|
994 if ( iServiceType == EImpsEventPresencePure && |
|
995 impsService( iVariant, TImpsMessageType( myMesType ) ) != EImpsEventPresence ) |
|
996 { |
|
997 User::Leave( KImpsErrorUnknownMessageType ); |
|
998 } |
|
999 |
|
1000 // Add sender if it is empty in new IM message |
|
1001 if ( aFunction == EImpsServWVSendOnly ) |
|
1002 { |
|
1003 TPtrC sender; |
|
1004 TPtrC group; |
|
1005 CImpsKey* myKey = CImpsKey::NewLC(); // <<< myKey |
|
1006 TImpsSDataUtils::AddValuesFromArrayL( |
|
1007 myKey, |
|
1008 KSendMessageElements, |
|
1009 sizeof( KSendMessageElements ) / |
|
1010 sizeof( KSendMessageElements[0] ) ); |
|
1011 myKey->AddL( CREATEKEY( EImpsKeyMessageInfo, 0 ) ); |
|
1012 TImpsDataAccessor myAc( ImpsFields() ); |
|
1013 TImpsSDataUtils::GetSenderL( myKey, &myAc, sender, group ); |
|
1014 if ( sender.Length() == 0 ) |
|
1015 { |
|
1016 TPtrC userId = iSession->UserId(); |
|
1017 // Set Sender( User( UserID )) if sender not specified |
|
1018 // in client API |
|
1019 // Notice: Here we could add assigned clientID if wanted so. |
|
1020 TImpsSDataUtils::SetSenderL( |
|
1021 myKey, |
|
1022 &myAc, |
|
1023 &userId, |
|
1024 NULL ); |
|
1025 } |
|
1026 |
|
1027 TPtrC applicationID( iSession->ApplicationId() ); |
|
1028 if ( applicationID.Length() != 0 ) |
|
1029 { |
|
1030 // insert the ExtBlock |
|
1031 myKey->PopL( 3 ); |
|
1032 myKey->AddL( CREATEKEY( EImpsKeyExtBlock, 0 ) ); |
|
1033 myKey->AddL( CREATEKEY( EImpsKeyAPIClient, 0 ) ); |
|
1034 myAc.StoreDescL( myKey, applicationID ); |
|
1035 } |
|
1036 |
|
1037 |
|
1038 CleanupStack::PopAndDestroy( 1 ); // >>> myKey |
|
1039 |
|
1040 } |
|
1041 |
|
1042 TPtrC tid; |
|
1043 |
|
1044 // Send data may in certain situation change iFields, |
|
1045 // so copy data address to safe. |
|
1046 tid.Set( Server()->SendDataL( this, aCSP ) ); |
|
1047 |
|
1048 // Add request into queue |
|
1049 CRequest* request = new ( ELeave ) CRequest( |
|
1050 tid, // tid |
|
1051 opId, // op-id |
|
1052 ( TImpsServRequest )aFunction, |
|
1053 Server()->ExpiryTime( iExpiryTime ), |
|
1054 myMesType ); |
|
1055 iRequestList.AddLast( *request ); |
|
1056 |
|
1057 } |
|
1058 |
|
1059 // --------------------------------------------------------- |
|
1060 // CImpsSubSession::SendGetBlockedL() |
|
1061 // This is for IM GetBlocked, only ID received from client |
|
1062 // --------------------------------------------------------- |
|
1063 void CImpsSubSession::SendGetBlockedL( TImpsSessIdent aCSP ) |
|
1064 { |
|
1065 |
|
1066 RMessage2 myMsg( Message() ); |
|
1067 TInt opId = myMsg.Int1(); |
|
1068 |
|
1069 #ifndef _NO_IMPS_LOGGING_ |
|
1070 CImpsClientLogger::Log( _L( "SubSession: SendGetBlockedL opid=%d" ), opId ); |
|
1071 #endif |
|
1072 |
|
1073 // Check availability of the service in general |
|
1074 TImpsSrvUtils::CheckServiceL( EIMFeat, Server()->Services( aCSP ) ); |
|
1075 |
|
1076 // Generate the stuff. Server thread finalizes the message adding |
|
1077 // session-id etc |
|
1078 |
|
1079 ImpsFields()->Reset(); |
|
1080 ImpsFields()->SetMessageType( EImpsGetBlockedListReq ); |
|
1081 |
|
1082 CImpsDataAccessor* myAc = CImpsDataAccessor::NewL( ImpsFields() ); |
|
1083 CleanupStack::PushL( myAc ); // <<< myAc |
|
1084 CImpsKey* myKey = CImpsKey::NewLC(); // <<< myKey |
|
1085 |
|
1086 TImpsSDataUtils::AddValuesFromArrayL( |
|
1087 myKey, |
|
1088 KTransContentElements, |
|
1089 sizeof( KTransContentElements ) / |
|
1090 sizeof( KTransContentElements[0] ) ); |
|
1091 myKey->AddL( CREATEKEY( EImpsKeyGetBlockedList_Request, 0 ) ); |
|
1092 myAc->StoreEmptyL( myKey ); |
|
1093 |
|
1094 TPtrC tid; |
|
1095 |
|
1096 // Send data may in certain situation change iFields, |
|
1097 // so copy data to safe. |
|
1098 tid.Set( Server()->SendDataL( this, aCSP ) ); |
|
1099 |
|
1100 // Update request queue |
|
1101 // Add request into queue |
|
1102 CRequest* request = new ( ELeave ) CRequest( |
|
1103 tid, // tid |
|
1104 opId, // op-id |
|
1105 EImpsServGetBlocked, |
|
1106 Server()->ExpiryTime( iExpiryTime ), |
|
1107 EImpsGetBlockedListReq ); |
|
1108 iRequestList.AddLast( *request ); |
|
1109 |
|
1110 CleanupStack::PopAndDestroy( 2 ); // >>> myAc, myKey |
|
1111 } |
|
1112 |
|
1113 // --------------------------------------------------------- |
|
1114 // CImpsSubSession::DoNextEvent() |
|
1115 // --------------------------------------------------------- |
|
1116 void CImpsSubSession::DoNextEvent() |
|
1117 { |
|
1118 |
|
1119 // check OOM_LIST first |
|
1120 iOOMErr.RemoveOOM(); |
|
1121 TInt errId = SendOOMError(); |
|
1122 if ( errId ) |
|
1123 { |
|
1124 return; |
|
1125 } |
|
1126 |
|
1127 // Delete the event that was sent and send next |
|
1128 TDblQueIter<CWvEvent> eventIter( iEventList ); |
|
1129 eventIter.SetToFirst(); |
|
1130 |
|
1131 while ( eventIter ) |
|
1132 { |
|
1133 CWvEvent* event = eventIter; |
|
1134 eventIter++; |
|
1135 |
|
1136 if ( event->iSent ) |
|
1137 { |
|
1138 event->Destroy(); |
|
1139 } |
|
1140 else |
|
1141 { |
|
1142 if ( event->iRequestType != EImpsServStatusReg ) |
|
1143 { |
|
1144 DoSendBaseEvent( *event ); |
|
1145 } |
|
1146 else |
|
1147 { |
|
1148 DoSendStatusEvent( *event ); |
|
1149 } |
|
1150 // Only one event at a time is possible |
|
1151 break; |
|
1152 } |
|
1153 } |
|
1154 } |
|
1155 |
|
1156 // --------------------------------------------------------- |
|
1157 // CImpsSubSession::DoEventBodyL() |
|
1158 // --------------------------------------------------------- |
|
1159 void CImpsSubSession::DoEventBodyL() |
|
1160 { |
|
1161 // Check that the first event (headers) in the queue |
|
1162 // is sent |
|
1163 TDblQueIter<CWvEvent> eventIter( iEventList ); |
|
1164 eventIter.SetToFirst(); |
|
1165 CWvEvent* event = eventIter; |
|
1166 if ( !event || !event->iSent ) |
|
1167 { |
|
1168 // This ensures that if the synchronization between client-server |
|
1169 // is lost the next messages are handled because of the |
|
1170 // client asks next event after this error. |
|
1171 User::Leave( KImpsGeneralError ); |
|
1172 } |
|
1173 |
|
1174 // Write the body to the client thread |
|
1175 DoSendEventBody( *event ); |
|
1176 } |
|
1177 |
|
1178 // --------------------------------------------------------- |
|
1179 // CImpsSubSession::DiscardRequests() |
|
1180 // Expiry detection |
|
1181 // --------------------------------------------------------- |
|
1182 void CImpsSubSession::DiscardRequests( |
|
1183 TTime aExpiryTime, |
|
1184 TImpsEventType aServiceType, |
|
1185 MImpsCSPSession* aSess ) |
|
1186 { |
|
1187 |
|
1188 // It is possible that the cancel request from client is not |
|
1189 // complete and this session entity is still waiting deletion. |
|
1190 if ( iCanceled ) |
|
1191 { |
|
1192 return; |
|
1193 } |
|
1194 |
|
1195 if ( !( aServiceType & iServiceType ) ) |
|
1196 { |
|
1197 return; |
|
1198 } |
|
1199 |
|
1200 // check if there is unhandled events for this session |
|
1201 TBool thisFirst = ( NbrEvents() > 0 || iOOMErr.Exists() ) ? EFalse : ETrue; |
|
1202 |
|
1203 TDblQueIter<CRequest> requestIter( iRequestList ); |
|
1204 requestIter.SetToFirst(); |
|
1205 while ( requestIter ) |
|
1206 { |
|
1207 CRequest* request = requestIter; |
|
1208 requestIter++; |
|
1209 if ( request->iExpiry < aExpiryTime ) |
|
1210 { |
|
1211 // expired entry found |
|
1212 // Create error event for UI API |
|
1213 #ifndef _NO_IMPS_LOGGING_ |
|
1214 CImpsClientLogger::Log( |
|
1215 _L( "SubSession: Entry EXPIRED type=%d subses=%d" ), |
|
1216 request->iRequestType, ( TInt )this ); |
|
1217 #endif |
|
1218 // Delete the message from server queues if not send |
|
1219 Server()->CancelTrans( request->iTID, aSess ); |
|
1220 // Create event for client |
|
1221 TRAPD( memErr, DoCreateEventL( |
|
1222 request->iOpId, |
|
1223 KErrTimedOut, |
|
1224 request->iMessageType ) ); |
|
1225 |
|
1226 // store OOM error message if necessary ( KErrNoMemory, aOpId ) |
|
1227 if ( memErr ) |
|
1228 { |
|
1229 iOOMErr.StoreOOM( request->iOpId ); |
|
1230 } |
|
1231 |
|
1232 // Send an event if this is first |
|
1233 if ( thisFirst ) |
|
1234 { |
|
1235 DoNextEvent(); |
|
1236 thisFirst = EFalse; |
|
1237 } |
|
1238 // delete request from queue |
|
1239 #ifndef _NO_IMPS_LOGGING_ |
|
1240 CImpsClientLogger::Log( |
|
1241 _L( "SubSession: DiscardRequests TID=%S" ), &( request->iTID ) ); //lint !e525 |
|
1242 #endif |
|
1243 request->Destroy(); |
|
1244 } |
|
1245 } |
|
1246 } |
|
1247 |
|
1248 // --------------------------------------------------------- |
|
1249 // CImpsSubSession::DiscardRequests() |
|
1250 // Discrad all requests |
|
1251 // --------------------------------------------------------- |
|
1252 void CImpsSubSession::DiscardRequests( |
|
1253 TInt aError, |
|
1254 TImpsEventType aServiceType, |
|
1255 MImpsCSPSession* aSess ) |
|
1256 { |
|
1257 |
|
1258 // It is possible that the cancel request from client is not |
|
1259 // complete and this session entity is still waiting deletion. |
|
1260 if ( iCanceled ) |
|
1261 { |
|
1262 return; |
|
1263 } |
|
1264 |
|
1265 if ( !( aServiceType & iServiceType ) ) |
|
1266 { |
|
1267 return; |
|
1268 } |
|
1269 |
|
1270 // check if there is unhandled events for this session |
|
1271 TBool thisFirst = ( NbrEvents() > 0 || iOOMErr.Exists() ) ? EFalse : ETrue; |
|
1272 |
|
1273 TDblQueIter<CRequest> requestIter( iRequestList ); |
|
1274 requestIter.SetToFirst(); |
|
1275 while ( requestIter ) |
|
1276 { |
|
1277 CRequest* request = requestIter; |
|
1278 requestIter++; |
|
1279 |
|
1280 #ifndef _NO_IMPS_LOGGING_ |
|
1281 CImpsClientLogger::Log( |
|
1282 _L( "SubSession: Entry DISCARDED type=%d subses=%d" ), |
|
1283 request->iRequestType, ( TInt )this ); |
|
1284 #endif |
|
1285 // Delete the message from server queues if not send |
|
1286 Server()->CancelTrans( request->iTID, aSess ); |
|
1287 // Create event for client |
|
1288 TRAPD( memErr, DoCreateEventL( |
|
1289 request->iOpId, |
|
1290 aError, |
|
1291 request->iMessageType ) ); |
|
1292 |
|
1293 if ( memErr ) |
|
1294 { |
|
1295 iOOMErr.StoreOOM( request->iOpId ); |
|
1296 } |
|
1297 |
|
1298 // Try to send event if this is first |
|
1299 if ( thisFirst ) |
|
1300 { |
|
1301 DoNextEvent(); |
|
1302 thisFirst = EFalse; |
|
1303 } |
|
1304 // delete request from queue |
|
1305 #ifndef _NO_IMPS_LOGGING_ |
|
1306 CImpsClientLogger::Log( |
|
1307 _L( "SubSession: DiscardRequests TID=%S" ), &( request->iTID ) ); //lint !e525 |
|
1308 #endif |
|
1309 request->Destroy(); |
|
1310 |
|
1311 } |
|
1312 } |
|
1313 |
|
1314 // --------------------------------------------------------- |
|
1315 // CImpsSubSession::DiscardRequest() |
|
1316 // Discard a single request |
|
1317 // --------------------------------------------------------- |
|
1318 TBool CImpsSubSession::DiscardRequest( |
|
1319 const TDesC& aTid, |
|
1320 TImpsEventType aServiceType, |
|
1321 TInt aCode ) |
|
1322 { |
|
1323 |
|
1324 // It is possible that the cancel request from client is not |
|
1325 // complete and this session entity is still waiting deletion. |
|
1326 if ( iCanceled ) |
|
1327 { |
|
1328 return EFalse; |
|
1329 } |
|
1330 |
|
1331 TBool ret( EFalse ); |
|
1332 if ( aServiceType != iServiceType ) |
|
1333 { |
|
1334 return ret; |
|
1335 } |
|
1336 |
|
1337 // check if there is unhandled events for this session |
|
1338 TBool thisFirst = ( NbrEvents() > 0 || iOOMErr.Exists() ) ? EFalse : ETrue; |
|
1339 |
|
1340 #ifndef _NO_IMPS_LOGGING_ |
|
1341 CImpsClientLogger::Log( _L( "SubSession: DiscardRequest subses=%d" ), ( TInt )this ); |
|
1342 #endif |
|
1343 |
|
1344 TDblQueIter<CRequest> requestIter( iRequestList ); |
|
1345 requestIter.SetToFirst(); |
|
1346 while ( requestIter ) |
|
1347 { |
|
1348 CRequest* request = requestIter; |
|
1349 requestIter++; |
|
1350 if ( !request->iTID.Compare( aTid ) ) |
|
1351 { |
|
1352 // entry found |
|
1353 // Create error event for UI API |
|
1354 #ifndef _NO_IMPS_LOGGING_ |
|
1355 CImpsClientLogger::Log( _L( "SubSession: entry DISCARDED" ) ); |
|
1356 #endif |
|
1357 TRAPD( memErr, DoCreateEventL( request->iOpId, |
|
1358 aCode, |
|
1359 request->iMessageType ) ); |
|
1360 |
|
1361 if ( memErr ) |
|
1362 { |
|
1363 // store OOM error message ( KErrNoMemory, aOpId ) |
|
1364 iOOMErr.StoreOOM( request->iOpId ); |
|
1365 } |
|
1366 |
|
1367 // The following is NOT called because of server has called this. |
|
1368 // Server()->CancelTrans( request->iTID ); |
|
1369 // delete request from queue |
|
1370 request->Destroy(); |
|
1371 ret = ETrue; |
|
1372 break; |
|
1373 } |
|
1374 } |
|
1375 |
|
1376 // Send the new event only if no old events in queue |
|
1377 if ( ret && thisFirst ) |
|
1378 { |
|
1379 DoNextEvent(); |
|
1380 } |
|
1381 |
|
1382 return ret; |
|
1383 } |
|
1384 |
|
1385 // --------------------------------------------------------- |
|
1386 // CImpsSubSession::CheckNotification() |
|
1387 // --------------------------------------------------------- |
|
1388 TBool CImpsSubSession::CheckNotification( CImpsFields* aFields ) |
|
1389 { |
|
1390 |
|
1391 TBool ret ( EFalse ); |
|
1392 TRAPD( errx, ( ret = DoCheckNotificationL( aFields ) ) ); |
|
1393 if ( ret && !errx ) |
|
1394 { |
|
1395 return ETrue; |
|
1396 } |
|
1397 else |
|
1398 { |
|
1399 return EFalse; |
|
1400 } |
|
1401 } |
|
1402 |
|
1403 // --------------------------------------------------------- |
|
1404 // CImpsSubSession::DoCheckNotificationL() |
|
1405 // Notice: MessageNotifiction not supported. |
|
1406 // --------------------------------------------------------- |
|
1407 TBool CImpsSubSession::DoCheckNotificationL( CImpsFields* aFields ) |
|
1408 { |
|
1409 |
|
1410 // It is possible that the cancel request from client is not |
|
1411 // complete and this session entity is still waiting deletion. |
|
1412 if ( iCanceled ) |
|
1413 { |
|
1414 return EFalse; |
|
1415 } |
|
1416 |
|
1417 // Filter new messages out if necessary |
|
1418 if ( !iHandleNew ) |
|
1419 { |
|
1420 #ifndef _NO_IMPS_LOGGING_ |
|
1421 CImpsClientLogger::Log( _L( "SubSession: new msg FILTERED OUT" ) ); |
|
1422 #endif |
|
1423 return EFalse; |
|
1424 } |
|
1425 |
|
1426 TImpsDataAccessor myAc( aFields ); |
|
1427 TPtrC msgContentType; |
|
1428 TBool retVal = EFalse; |
|
1429 TInt messageType = aFields->MessageType(); |
|
1430 |
|
1431 // Handle SAP initiated transactions here. |
|
1432 // |
|
1433 switch ( this->iServiceType ) |
|
1434 { |
|
1435 case EImpsEventMessage: |
|
1436 if ( messageType == EImpsNewMessage ) |
|
1437 { |
|
1438 retVal = ETrue; |
|
1439 // Checking the ApplicationID |
|
1440 // Consider client-id routing if media type is ok |
|
1441 /* |
|
1442 * 1) Get the ApplicationID from the message |
|
1443 * 2) Get the ApplicationID from the corresponding session |
|
1444 * ownClientId = iSession->ApplicationID(); |
|
1445 * 3) if ownClientId == messageClientId -> retVal = ETrue, |
|
1446 * this includes the case when both are empty |
|
1447 * 4) otherwise retVal = EFalse |
|
1448 */ |
|
1449 TPtrC messageAppID; // The recipient's ApplicationID |
|
1450 |
|
1451 TImpsSDataUtils::GetApplicationIDL( &myAc, messageAppID ); |
|
1452 |
|
1453 if ( !messageAppID.Compare( iSession->ApplicationId() ) ) |
|
1454 { |
|
1455 // The ClientIDs are matching |
|
1456 retVal = ETrue; |
|
1457 } |
|
1458 else |
|
1459 { |
|
1460 retVal = EFalse; |
|
1461 } |
|
1462 } |
|
1463 else if ( messageType == EImpsDeliveryReportReq ) |
|
1464 { |
|
1465 retVal = ETrue; |
|
1466 } |
|
1467 break; |
|
1468 case EImpsEventServerLogin: |
|
1469 if ( messageType == EImpsDisconnect ) |
|
1470 { |
|
1471 retVal = ETrue; |
|
1472 } |
|
1473 break; |
|
1474 case EImpsEventGroup: |
|
1475 if ( messageType == EImpsLeaveGroupRes || |
|
1476 messageType == EImpsGroupChangeNotice ) |
|
1477 { |
|
1478 retVal = ETrue; |
|
1479 } |
|
1480 break; |
|
1481 case EImpsEventCommon: |
|
1482 if ( messageType == EImpsInviteUserReq || |
|
1483 messageType == EImpsInviteRes || |
|
1484 messageType == EImpsCancelInviteUserReq ) |
|
1485 { |
|
1486 retVal = ETrue; |
|
1487 } |
|
1488 break; |
|
1489 case EImpsEventPresence: |
|
1490 case EImpsEventPresencePure: |
|
1491 if ( messageType == EImpsPresenceNotification || |
|
1492 messageType == EImpsPresenceAuthReq || |
|
1493 messageType == EImpsPureData ) |
|
1494 { |
|
1495 retVal = ETrue; |
|
1496 } |
|
1497 break; |
|
1498 default: |
|
1499 retVal = EFalse; |
|
1500 break; |
|
1501 } |
|
1502 |
|
1503 return retVal; |
|
1504 } |
|
1505 |
|
1506 // --------------------------------------------------------- |
|
1507 // CImpsSubSession::CheckRequests() |
|
1508 // --------------------------------------------------------- |
|
1509 TBool CImpsSubSession::CheckRequests( |
|
1510 const TDesC& aTid, |
|
1511 TInt& aOpId, |
|
1512 TImpsServRequest& aRequestType, |
|
1513 TImpsMessageType& aReqMsgType ) |
|
1514 { |
|
1515 // It is possible that the cancel request from client is not |
|
1516 // complete and this session entity is still waiting deletion. |
|
1517 if ( iCanceled ) |
|
1518 { |
|
1519 return EFalse; |
|
1520 } |
|
1521 |
|
1522 aRequestType = EImpsServNone; |
|
1523 aReqMsgType = EImpsMessageNone; |
|
1524 |
|
1525 TDblQueIter<CRequest> requestIter( iRequestList ); |
|
1526 |
|
1527 requestIter.SetToFirst(); |
|
1528 |
|
1529 while ( requestIter ) |
|
1530 { |
|
1531 CRequest* request = requestIter; |
|
1532 requestIter++; |
|
1533 |
|
1534 #ifndef _NO_IMPS_LOGGING_ |
|
1535 CImpsClientLogger::Log( _L( "SubSession: CheckRequests subses=%d aTID=%S reg.TID=%S" ), |
|
1536 ( TInt )this, &aTid, &request->iTID ); |
|
1537 #endif |
|
1538 |
|
1539 if ( !request->iTID.Compare( aTid ) ) |
|
1540 { |
|
1541 aOpId = request->iOpId; |
|
1542 aRequestType = request->iRequestType; |
|
1543 aReqMsgType = request->iMessageType; |
|
1544 return ETrue; |
|
1545 } |
|
1546 } |
|
1547 |
|
1548 return EFalse; |
|
1549 } |
|
1550 |
|
1551 // ----------------------------------------------------------------------------- |
|
1552 // CImpsSubSession::DeleteRequest |
|
1553 // ----------------------------------------------------------------------------- |
|
1554 TBool CImpsSubSession::DeleteRequest( TInt aOpId ) |
|
1555 { |
|
1556 #ifndef _NO_IMPS_LOGGING_ |
|
1557 CImpsClientLogger::Log( _L( "SubSession: DeleteRequest opid=%d, subses=%d" ), aOpId, ( TInt )this ); |
|
1558 #endif |
|
1559 // Delete one buffered requests from this client, |
|
1560 TDblQueIter<CRequest> rIter( iRequestList ); |
|
1561 |
|
1562 rIter.SetToFirst(); |
|
1563 |
|
1564 while ( rIter ) |
|
1565 { |
|
1566 CRequest* requ = rIter; |
|
1567 rIter++; |
|
1568 if ( requ->iOpId == aOpId ) |
|
1569 { |
|
1570 #ifndef _NO_IMPS_LOGGING_ |
|
1571 CImpsClientLogger::Log( _L( "SubSession: DeleteRequest TID=%S" ), &( requ->iTID ) ); //lint !e525 |
|
1572 #endif |
|
1573 requ->Destroy(); |
|
1574 return ETrue; |
|
1575 } |
|
1576 } |
|
1577 #ifndef _NO_IMPS_LOGGING_ |
|
1578 CImpsClientLogger::Log( _L( "SubSession: DeleteRequest failed" ) ); |
|
1579 #endif |
|
1580 return EFalse; |
|
1581 } |
|
1582 |
|
1583 // --------------------------------------------------------- |
|
1584 // CImpsSubSession::NextEventL() |
|
1585 // --------------------------------------------------------- |
|
1586 void CImpsSubSession::NextEventL( const RMessage2& aMsg ) |
|
1587 { |
|
1588 #ifndef _NO_IMPS_LOGGING_ |
|
1589 CImpsClientLogger::Log( _L( "SubSession: NextEventL begins subses=%d" ), ( TInt )this ); |
|
1590 #endif |
|
1591 if ( iCanceled ) |
|
1592 { |
|
1593 User::Leave( KErrCancel ); |
|
1594 } |
|
1595 StoreEventMsg( aMsg ); |
|
1596 DoNextEvent(); |
|
1597 } |
|
1598 |
|
1599 // --------------------------------------------------------- |
|
1600 // CImpsSubSession::SendEventBodyL() |
|
1601 // --------------------------------------------------------- |
|
1602 void CImpsSubSession::SendEventBodyL( const RMessage2& aMsg ) |
|
1603 { |
|
1604 #ifndef _NO_IMPS_LOGGING_ |
|
1605 CImpsClientLogger::Log( _L( "SubSession: SendEventBodyL subses=%d" ), ( TInt )this ); |
|
1606 #endif |
|
1607 if ( iCanceled ) |
|
1608 { |
|
1609 User::Leave( KErrCancel ); |
|
1610 } |
|
1611 |
|
1612 StoreEventMsg( aMsg ); |
|
1613 DoEventBodyL(); |
|
1614 } |
|
1615 |
|
1616 // --------------------------------------------------------- |
|
1617 // CImpsSubSession::DoCreateEventL |
|
1618 // --------------------------------------------------------- |
|
1619 void CImpsSubSession::DoCreateEventL( |
|
1620 TInt aOpId, |
|
1621 TImpsServRequest aRequestType, |
|
1622 TImpsMessageType aReqMesType, |
|
1623 CImpsFields* aFields ) |
|
1624 { |
|
1625 |
|
1626 #ifdef _DEBUG |
|
1627 TInt rate = 0; |
|
1628 if ( !rate ) |
|
1629 { |
|
1630 __UHEAP_RESET; |
|
1631 } |
|
1632 else |
|
1633 { |
|
1634 __UHEAP_FAILNEXT( rate ); |
|
1635 } |
|
1636 #endif |
|
1637 |
|
1638 // Create an event |
|
1639 CWvEvent* myEvent = new ( ELeave ) CWvEvent( iServiceType ); |
|
1640 CleanupStack::PushL( myEvent ); // <<< myEvent |
|
1641 myEvent->iOpCode = aOpId; |
|
1642 myEvent->iStatus = aFields->Status(); |
|
1643 myEvent->iRequestType = aRequestType; |
|
1644 myEvent->iMessageType = ( TImpsMessageType )aFields->MessageType(); |
|
1645 myEvent->iReqMesType = aReqMesType; |
|
1646 |
|
1647 // convert CSP error code if any |
|
1648 TInt32 resstatus = aFields->ResponseStatusL(); |
|
1649 if ( resstatus != KImpsStatusOk && |
|
1650 resstatus != KErrNone ) |
|
1651 { |
|
1652 myEvent->iStatus = ErrorCode( resstatus ); |
|
1653 } |
|
1654 |
|
1655 TImpsMessageType msgType = ( TImpsMessageType )myEvent->iMessageType; |
|
1656 |
|
1657 // ********************************************************* |
|
1658 // Handle pure client responses in different way |
|
1659 // In that case XML-formatted response needed in a client |
|
1660 if ( iServiceType == EImpsEventPresencePure ) |
|
1661 { |
|
1662 if ( msgType == EImpsStatus || |
|
1663 impsService( iVariant, TImpsMessageType( msgType ) ) == EImpsEventPresence ) |
|
1664 { |
|
1665 myEvent->iMessageType = EImpsPureData; |
|
1666 msgType = EImpsPureData; |
|
1667 } |
|
1668 } |
|
1669 //*********************************************************/ |
|
1670 |
|
1671 // List of responses having serialized CImpsFields |
|
1672 // Notice: Check this list if new methods in API presented |
|
1673 if ( // im client |
|
1674 msgType == EImpsNewMessage || |
|
1675 msgType == EImpsGetBlockedListRes || |
|
1676 msgType == EImpsSendMessageRes || |
|
1677 msgType == EImpsDeliveryReportReq || |
|
1678 // group client |
|
1679 msgType == EImpsJoinGroupRes || |
|
1680 msgType == EImpsLeaveGroupRes || |
|
1681 msgType == EImpsGroupMembersRes || |
|
1682 msgType == EImpsGroupPropertiesRes || |
|
1683 msgType == EImpsGroupRejectListRes || |
|
1684 msgType == EImpsNewUsers || |
|
1685 msgType == EImpsLeftUsers || |
|
1686 msgType == EImpsGroupChangeNotice || |
|
1687 // Pure data |
|
1688 msgType == EImpsPureData || |
|
1689 // fundamental |
|
1690 impsService( iVariant, TImpsMessageType( msgType ) ) == EImpsEventCommon || |
|
1691 // presence |
|
1692 impsService( iVariant, TImpsMessageType( msgType ) ) == EImpsEventPresence ) |
|
1693 // access service has nothing to pack in responses |
|
1694 { |
|
1695 HBufC8* dataBuffer = NULL; |
|
1696 TRAPD( errx, ( dataBuffer = HBufC8::NewL( aFields->Size() ) ) ); |
|
1697 if ( errx ) |
|
1698 { |
|
1699 myEvent->iStatus = errx; |
|
1700 myEvent->iPackedMessage = NULL; |
|
1701 } |
|
1702 else |
|
1703 { |
|
1704 TImpsPackedEntity packed( dataBuffer ); |
|
1705 // Check data length if enough |
|
1706 User::LeaveIfError ( packed.PackEntity( *aFields ) ); |
|
1707 myEvent->iPackedMessage = dataBuffer; |
|
1708 } |
|
1709 } |
|
1710 |
|
1711 // detailed error data code in special format |
|
1712 // notice: avoid to pack in vain |
|
1713 if ( msgType == EImpsStatus && iDetailedError ) |
|
1714 { |
|
1715 HBufC8* dataBuffer = HBufC8::NewLC( aFields->Size() ); |
|
1716 TImpsPackedEntity packed( dataBuffer ); |
|
1717 // Check data length if enough |
|
1718 User::LeaveIfError ( packed.PackEntity( *aFields ) ); |
|
1719 myEvent->iPackedMessage = dataBuffer; |
|
1720 CleanupStack::Pop(); // dataBuffer |
|
1721 } |
|
1722 |
|
1723 // list of responses having one byte response |
|
1724 if ( aFields->MessageType() == EImpsSubsGroupNoticeRes ) |
|
1725 { |
|
1726 CImpsKey* myKey = CImpsKey::NewLC(); // <<< myKey |
|
1727 CImpsDataAccessor* myAc = CImpsDataAccessor::NewL( aFields ); |
|
1728 CleanupStack::PushL( myAc ); // <<< myAc |
|
1729 TBool groupNotice = TImpsSDataUtils::SubGroupNoticeResponseL( |
|
1730 myKey, |
|
1731 myAc ); |
|
1732 myEvent->iAux = groupNotice; |
|
1733 CleanupStack::PopAndDestroy( 2 ); // >>> myKey, myAc |
|
1734 } |
|
1735 |
|
1736 // New event created succesfully |
|
1737 CleanupStack::Pop( 1 ); // >>> myEvent |
|
1738 // Since WV 1,2 logout messages may be either disconnect or Status, |
|
1739 // harmomize them here in order to avoid sending logout message |
|
1740 // with opid=actual_id and opid=0. |
|
1741 if ( aRequestType == EImpsServWVLogout ) |
|
1742 { |
|
1743 iLastEvent = EImpsDisconnect; |
|
1744 } |
|
1745 else |
|
1746 { |
|
1747 iLastEvent = myEvent->iMessageType; |
|
1748 } |
|
1749 iEventList.AddLast( *myEvent ); |
|
1750 } |
|
1751 |
|
1752 // --------------------------------------------------------- |
|
1753 // CImpsSubSession::DoCreateEventL |
|
1754 // This creates wv engine online status event |
|
1755 // --------------------------------------------------------- |
|
1756 void CImpsSubSession::DoCreateEventL( |
|
1757 EImpsInternalStatus aStatus ) |
|
1758 { |
|
1759 #ifdef _DEBUG |
|
1760 TInt rate = 0; |
|
1761 if ( !rate ) |
|
1762 { |
|
1763 __UHEAP_RESET; |
|
1764 } |
|
1765 else |
|
1766 { |
|
1767 __UHEAP_FAILNEXT( rate ); |
|
1768 } |
|
1769 #endif |
|
1770 // Create an event |
|
1771 CWvEvent* myEvent = new ( ELeave ) CWvEvent( iServiceType ); |
|
1772 // No need for CleanupStack, no leave before inserted to queue |
|
1773 myEvent->iOpCode = 0; |
|
1774 myEvent->iStatus = KErrNone; |
|
1775 myEvent->iRequestType = EImpsServStatusReg; |
|
1776 myEvent->iMessageType = EImpsMessageNone; |
|
1777 myEvent->iReqMesType = 0; |
|
1778 myEvent->iAux = aStatus; |
|
1779 |
|
1780 // New event created succesfully |
|
1781 iEventList.AddLast( *myEvent ); |
|
1782 |
|
1783 // Notice: this does not update iLastEvent |
|
1784 } |
|
1785 |
|
1786 // --------------------------------------------------------- |
|
1787 // CImpSsubSession::DoCreateEventL |
|
1788 // This creates wv engine expiry events and other internal messages |
|
1789 // --------------------------------------------------------- |
|
1790 void CImpsSubSession::DoCreateEventL( |
|
1791 TInt aOpCode, |
|
1792 TInt aStatus, |
|
1793 TImpsMessageType aReqMesType, |
|
1794 TImpsMessageType aRcvMesType, |
|
1795 TImpsServRequest aReqType ) |
|
1796 { |
|
1797 #ifdef _DEBUG |
|
1798 TInt rate = 0; |
|
1799 if ( !rate ) |
|
1800 { |
|
1801 __UHEAP_RESET; |
|
1802 } |
|
1803 else |
|
1804 { |
|
1805 __UHEAP_FAILNEXT( rate ); |
|
1806 } |
|
1807 #endif |
|
1808 // Create an event |
|
1809 CWvEvent* myEvent = new ( ELeave ) CWvEvent( iServiceType ); |
|
1810 // No need for CleanupStack, no leave before inserted to queue |
|
1811 myEvent->iOpCode = aOpCode; |
|
1812 myEvent->iStatus = aStatus; |
|
1813 myEvent->iMessageType = aRcvMesType; |
|
1814 myEvent->iReqMesType = aReqMesType; |
|
1815 myEvent->iRequestType = aReqType; |
|
1816 |
|
1817 // New event created succesfully |
|
1818 iLastEvent = myEvent->iMessageType; |
|
1819 iEventList.AddLast( *myEvent ); |
|
1820 } |
|
1821 |
|
1822 // --------------------------------------------------------- |
|
1823 // CImpsSubSession::DoSplitGroupChangeL |
|
1824 // --------------------------------------------------------- |
|
1825 void CImpsSubSession::DoSplitGroupChangeL( |
|
1826 TInt aOpId, |
|
1827 TImpsServRequest aRequestType, |
|
1828 CImpsFields* aFields ) |
|
1829 { |
|
1830 |
|
1831 CImpsKey* myKey = CImpsKey::NewLC(); // <<< myKey |
|
1832 CImpsDataAccessor* myAc = CImpsDataAccessor::NewL( aFields ); |
|
1833 CleanupStack::PushL( myAc ); // myAc |
|
1834 |
|
1835 TImpsSDataUtils::AddValuesFromArrayL( |
|
1836 myKey, |
|
1837 KTransContentElements, |
|
1838 sizeof( KTransContentElements ) / |
|
1839 sizeof( KTransContentElements[0] ) ); |
|
1840 myKey->AddL( CREATEKEY( EImpsKeyGroupChangeNotice, 0 ) ); |
|
1841 |
|
1842 // First get GroupId |
|
1843 TDesC* pId; // for GroupID |
|
1844 myKey->AddL( CREATEKEY( EImpsKeyGroupID, 0 ) ); |
|
1845 if ( myAc->RestoreDescL( myKey, pId ) ) |
|
1846 { |
|
1847 myKey->PopL(); |
|
1848 } |
|
1849 else |
|
1850 { |
|
1851 // This means illegal data from transport. |
|
1852 User::Leave( EImpsCorrupted ); |
|
1853 } |
|
1854 |
|
1855 // Search if new users |
|
1856 myKey->AddL( CREATEKEY( EImpsKeyJoined, 0 ) ); |
|
1857 if ( myAc->CheckBranchExistenceL( myKey ) ) |
|
1858 { |
|
1859 CImpsFields* newFields = CImpsFields::NewL(); |
|
1860 CleanupStack::PushL( newFields ); // <<< newFields |
|
1861 |
|
1862 // Copy message type etc important |
|
1863 newFields->SetStatus( aFields->Status( ) ); |
|
1864 |
|
1865 // set special internal message type |
|
1866 newFields->SetMessageType( EImpsNewUsers ); |
|
1867 |
|
1868 // Copy data, only Joined users list |
|
1869 CImpsDataAccessor* myAc2 = CImpsDataAccessor::NewLC( newFields ); |
|
1870 TImpsDataUtils::CopyNewUsersL( *myAc, *myAc2 ); |
|
1871 |
|
1872 // Add Group Id |
|
1873 myKey->ReplaceLastL( CREATEKEY( EImpsKeyGroupID, 0 ) ); |
|
1874 myAc2->StoreDescL( myKey, *pId ); |
|
1875 // Make a request entity into queue |
|
1876 DoCreateEventL( aOpId, aRequestType, EImpsMessageNone, newFields ); |
|
1877 |
|
1878 CleanupStack::PopAndDestroy( 2 ); // >>> myAc2, newFields |
|
1879 } |
|
1880 |
|
1881 // Search if LeftUsers |
|
1882 myKey->ReplaceLastL( CREATEKEY( EImpsKeyLeft, 0 ) ); |
|
1883 if ( myAc->CheckBranchExistenceL( myKey ) ) |
|
1884 { |
|
1885 CImpsFields* newFields = CImpsFields::NewL(); |
|
1886 CleanupStack::PushL( newFields ); // <<< newFields |
|
1887 |
|
1888 // Copy message type etc important |
|
1889 newFields->SetStatus( aFields->Status( ) ); |
|
1890 |
|
1891 // set special internal message type |
|
1892 newFields->SetMessageType( EImpsLeftUsers ); |
|
1893 |
|
1894 // Copy data, only Left users list |
|
1895 CImpsDataAccessor* myAc2 = CImpsDataAccessor::NewLC( newFields ); |
|
1896 TImpsDataUtils::CopyLeftUsersL( *myAc, *myAc2 ); |
|
1897 |
|
1898 // Add Group Id |
|
1899 myKey->ReplaceLastL( CREATEKEY( EImpsKeyGroupID, 0 ) ); |
|
1900 myAc2->StoreDescL( myKey, *pId ); |
|
1901 |
|
1902 // Make a request entity into queue |
|
1903 DoCreateEventL( aOpId, aRequestType, EImpsMessageNone, newFields ); |
|
1904 |
|
1905 CleanupStack::PopAndDestroy( 2 ); // >>> myAc2, newFields |
|
1906 } |
|
1907 |
|
1908 CImpsFields* newFields = CImpsFields::NewL(); |
|
1909 CleanupStack::PushL( newFields ); // <<< newFields |
|
1910 |
|
1911 // Copy message type etc important |
|
1912 newFields->SetStatus( aFields->Status( ) ); |
|
1913 |
|
1914 // set special internal message type |
|
1915 newFields->SetMessageType( EImpsGroupChangeNotice ); |
|
1916 |
|
1917 // Search if GroupProperties |
|
1918 CImpsDataAccessor* myAc2 = CImpsDataAccessor::NewLC( newFields ); |
|
1919 myKey->ReplaceLastL( CREATEKEY( EImpsKeyGroupProperties, 0 ) ); |
|
1920 if ( myAc->CheckBranchExistenceL( myKey ) ) |
|
1921 { |
|
1922 TImpsDataUtils::CopyGroupPropertiesL( *myAc, *myAc2 ); |
|
1923 } |
|
1924 // Search if ownproperties |
|
1925 myKey->ReplaceLastL( CREATEKEY( EImpsKeyOwnProperties, 0 ) ); |
|
1926 if ( myAc->CheckBranchExistenceL( myKey ) ) |
|
1927 { |
|
1928 TImpsDataUtils::CopyOwnPropertiesL( *myAc, *myAc2 ); |
|
1929 } |
|
1930 |
|
1931 // Add Group Id |
|
1932 myKey->ReplaceLastL( CREATEKEY( EImpsKeyGroupID, 0 ) ); |
|
1933 myAc2->StoreDescL( myKey, *pId ); |
|
1934 |
|
1935 // Make a request entity into queue |
|
1936 DoCreateEventL( aOpId, aRequestType, EImpsMessageNone, newFields ); |
|
1937 |
|
1938 CleanupStack::PopAndDestroy( 4 ); // >>> myAc2, newFields |
|
1939 // myKey, myAc |
|
1940 } |
|
1941 |
|
1942 // --------------------------------------------------------- |
|
1943 // CImpsSubSession::NbrEvents |
|
1944 // --------------------------------------------------------- |
|
1945 TInt CImpsSubSession::NbrEvents() |
|
1946 { |
|
1947 TDblQueIter<CWvEvent> eventIter( iEventList ); |
|
1948 CWvEvent* event = NULL; |
|
1949 TInt counter = 0; |
|
1950 |
|
1951 eventIter.SetToFirst(); |
|
1952 event = eventIter; |
|
1953 while ( event ) |
|
1954 { |
|
1955 counter++; |
|
1956 eventIter++; |
|
1957 event = eventIter; |
|
1958 } |
|
1959 |
|
1960 return counter; |
|
1961 } |
|
1962 |
|
1963 // --------------------------------------------------------- |
|
1964 // CImpsSubSession::GetWVDataL() |
|
1965 // Generic data converter from packed data to internal data structure. |
|
1966 // --------------------------------------------------------- |
|
1967 void CImpsSubSession::GetWVDataL() |
|
1968 { |
|
1969 #ifndef _NO_IMPS_LOGGING_ |
|
1970 CImpsClientLogger::Log( _L( "SubSession: GetWVDataL begins" ) ); |
|
1971 #endif |
|
1972 |
|
1973 // serialized message is always in ptr0 |
|
1974 HBufC8* stream = *StreamBufAddr(); |
|
1975 if ( iSession->ReadBuffer8L( 0, stream ) ) |
|
1976 { |
|
1977 HBufC8** stream2 = StreamBufAddr(); |
|
1978 *stream2 = stream; |
|
1979 } |
|
1980 ImpsFields()->Reset(); |
|
1981 TImpsPackedEntity packedMessage( *StreamBufAddr() ); |
|
1982 packedMessage.UnpackEntityL( *ImpsFields() ); |
|
1983 #ifndef _NO_IMPS_LOGGING_ |
|
1984 CImpsClientLogger::Log( _L( "Session: GetWVDataL ends" ) ); |
|
1985 #endif |
|
1986 } |
|
1987 |
|
1988 // --------------------------------------------------------- |
|
1989 // CImpsSubSession::ErrorCode |
|
1990 // --------------------------------------------------------- |
|
1991 TInt CImpsSubSession::ErrorCode( TInt aCSPError ) |
|
1992 { |
|
1993 |
|
1994 if ( aCSPError >= 100 && aCSPError <= 999 ) |
|
1995 { |
|
1996 // Convert the error code if valid input value |
|
1997 return KImpsGeneralError - aCSPError; |
|
1998 } |
|
1999 // This means illagel data from transport. |
|
2000 return KImpsErrorValidate; |
|
2001 |
|
2002 } |
|
2003 |
|
2004 // --------------------------------------------------------- |
|
2005 // CImpsSubSession::DoCreateEventIPC |
|
2006 // --------------------------------------------------------- |
|
2007 void CImpsSubSession::DoCreateEventIPC( |
|
2008 CWvEvent& aEvent, SImpsEventData* aData ) |
|
2009 { |
|
2010 // Set pointers to the data |
|
2011 aData->iOpCode = aEvent.iOpCode; |
|
2012 aData->iMessageType = aEvent.iMessageType; |
|
2013 aData->iRequestType = ( TInt ) aEvent.iRequestType; |
|
2014 aData->iStatus = aEvent.iStatus; |
|
2015 aData->iMessageBody = EFalse; |
|
2016 aData->iReqMesType = aEvent.iReqMesType; |
|
2017 // this is not used in all cases but let's write it every time |
|
2018 aData->iAux = aEvent.iAux; |
|
2019 |
|
2020 // Make a special change for Logout SAP errors to hide the error code |
|
2021 if ( iServiceType == EImpsEventServerLogin && |
|
2022 aEvent.iRequestType == EImpsServWVLogout && |
|
2023 aEvent.iStatus < ( Imps_ERROR_BASE - 200 ) ) |
|
2024 { |
|
2025 aData->iStatus = KErrNone; |
|
2026 #ifndef _NO_IMPS_LOGGING_ |
|
2027 CImpsClientLogger::Log( _L |
|
2028 ( "SubSession: DoCreateEventIPC converts LOGOUT code" ) ); |
|
2029 #endif |
|
2030 } |
|
2031 } |
|
2032 |
|
2033 // --------------------------------------------------------- |
|
2034 // CImpsSubSession::DoWriteEventHeaders |
|
2035 // --------------------------------------------------------- |
|
2036 TInt CImpsSubSession::DoWriteEventHeaders( |
|
2037 RMessagePtr2 aMsg, const TDes& aData ) |
|
2038 { |
|
2039 |
|
2040 TInt err = KErrNone; |
|
2041 |
|
2042 TPtrC ptr( aData ); |
|
2043 |
|
2044 err = aMsg.Write( 0, ptr ); |
|
2045 |
|
2046 __ASSERT_DEBUG( err != KErrBadDescriptor, |
|
2047 aMsg.Panic( KImpsPanicCategory, EImpsCorrupted ) ); |
|
2048 |
|
2049 #ifndef _NO_IMPS_LOGGING_ |
|
2050 SImpsEventData* eventData = ( SImpsEventData* )aData.Ptr(); |
|
2051 CImpsClientLogger::Log( _L( |
|
2052 "SubSession: DoWriteEventHeaders opid=%d msg=0x%x status=%d err=%d subses=%d" ), |
|
2053 eventData->iOpCode, eventData->iMessageType, eventData->iStatus, err, ( TInt )this ); |
|
2054 #endif |
|
2055 |
|
2056 return err; |
|
2057 } |
|
2058 |
|
2059 // --------------------------------------------------------- |
|
2060 // CImpsSubSession::DoWriteEventBody |
|
2061 // --------------------------------------------------------- |
|
2062 TInt CImpsSubSession::DoWriteEventBody( |
|
2063 RMessagePtr2 aMsg, CWvEvent& aEvent ) |
|
2064 { |
|
2065 // Write message body |
|
2066 TPtrC8 ptr8( KNullDesC8 ); |
|
2067 if ( aEvent.iPackedMessage ) |
|
2068 { |
|
2069 ptr8.Set( aEvent.iPackedMessage->Des() ); |
|
2070 } |
|
2071 TInt mLen = aMsg.GetDesMaxLength( 1 ); |
|
2072 __ASSERT_DEBUG( mLen != KErrBadDescriptor, |
|
2073 aMsg.Panic( KImpsPanicCategory, EImpsCorrupted ) ); |
|
2074 __ASSERT_DEBUG( mLen >= ptr8.Length(), |
|
2075 aMsg.Panic( KImpsPanicCategory, EImpsCorrupted ) ); |
|
2076 if ( mLen < ptr8.Length() ) |
|
2077 { |
|
2078 // This is an error situation in a client side |
|
2079 return KErrBadHandle; |
|
2080 } |
|
2081 |
|
2082 #ifndef _NO_IMPS_LOGGING_ |
|
2083 CImpsClientLogger::Log( _L( "SubSession: EventMsg.Write2 subses=%d" ), ( TInt )this ); |
|
2084 TTime testTime1; |
|
2085 testTime1.HomeTime(); |
|
2086 #endif |
|
2087 |
|
2088 TInt err = aMsg.Write( 1, ptr8 ); |
|
2089 __ASSERT_DEBUG( err != KErrBadDescriptor, |
|
2090 aMsg.Panic( KImpsPanicCategory, EImpsCorrupted ) ); |
|
2091 |
|
2092 #ifndef _NO_IMPS_LOGGING_ |
|
2093 CImpsClientLogger::Log( _L( |
|
2094 "SubSession: DoWriteEventBody opid=%d msg=0x%x status=%d err=%d" ), |
|
2095 aEvent.iOpCode, aEvent.iMessageType, aEvent.iStatus, err ); |
|
2096 #endif |
|
2097 |
|
2098 return KErrNone; |
|
2099 } |
|
2100 |
|
2101 // --------------------------------------------------------- |
|
2102 // CImpsSubSession::StoreEventMsg |
|
2103 // --------------------------------------------------------- |
|
2104 void CImpsSubSession::StoreEventMsg( RMessagePtr2 aMsg ) |
|
2105 { |
|
2106 #ifndef _NO_IMPS_LOGGING_ |
|
2107 RMessage2 myMsg( aMsg ); |
|
2108 CImpsClientLogger::Log( _L( "SubSession: StoreEventMsg subses=%d bufSize=%d" ), ( TInt )this, myMsg.Int2() ); |
|
2109 #endif |
|
2110 iEventMsg = aMsg; |
|
2111 } |
|
2112 |
|
2113 // --------------------------------------------------------- |
|
2114 // CImpsSubSession::CompleteEventMsg |
|
2115 // --------------------------------------------------------- |
|
2116 void CImpsSubSession::CompleteEventMsg( TInt aStatus ) |
|
2117 { |
|
2118 #ifndef _NO_IMPS_LOGGING_ |
|
2119 CImpsClientLogger::Log( _L( "SubSession: CompleteEventMsg size=%d subses=%d" ), aStatus, ( TInt )this ); |
|
2120 #endif |
|
2121 if ( iEventMsg.IsNull() ) |
|
2122 { |
|
2123 #ifndef _NO_IMPS_LOGGING_ |
|
2124 CImpsClientLogger::Log( _L( "SubSession: CompleteEventMsg NULL MSG subses=%d" ), ( TInt )this ); |
|
2125 #endif |
|
2126 return; |
|
2127 } |
|
2128 iEventMsg.Complete( aStatus ); |
|
2129 } |
|
2130 |
|
2131 // --------------------------------------------------------- |
|
2132 // CImpsSubSession::EventMsgBufSize |
|
2133 // --------------------------------------------------------- |
|
2134 TInt CImpsSubSession::EventMsgBufSize( ) const |
|
2135 { |
|
2136 if ( iEventMsg.IsNull() ) |
|
2137 { |
|
2138 #ifndef _NO_IMPS_LOGGING_ |
|
2139 CImpsClientLogger::Log( _L( "SubSession: EventMsgBufSize NULL MSG subses=%d" ), ( TInt )this ); |
|
2140 #endif |
|
2141 return 0; |
|
2142 } |
|
2143 RMessage2 myMsg( iEventMsg ); |
|
2144 return myMsg.Int2(); |
|
2145 } |
|
2146 |
|
2147 // --------------------------------------------------------- |
|
2148 // CImpsSubSession::ConvertStatusCode |
|
2149 // --------------------------------------------------------- |
|
2150 TInt CImpsSubSession::ConvertStatusCode( EImpsInternalStatus aStatus ) const |
|
2151 { |
|
2152 TInt newStatus = KImpsOnlineStatus; |
|
2153 if ( aStatus == EInternal_OFF_LINE ) |
|
2154 { |
|
2155 // This is not supported in client API anymore, so this is an error code. |
|
2156 newStatus = KImpsOfflineStatus; |
|
2157 } |
|
2158 else if ( aStatus == EInternal_NOT_LOGGED ) |
|
2159 { |
|
2160 newStatus = KImpsNotLoggedStatus; |
|
2161 } |
|
2162 else if ( aStatus == EInternal_NO_IAP ) |
|
2163 { |
|
2164 newStatus = KImpsNoIapStatus; |
|
2165 } |
|
2166 else if ( aStatus == EInternal_SHUTTING_DOWN ) |
|
2167 { |
|
2168 newStatus = KImpsErrorShuttingDown; |
|
2169 } |
|
2170 return newStatus; |
|
2171 } |
|
2172 |
|
2173 // --------------------------------------------------------- |
|
2174 // CImpsSubSession::CancelTrans |
|
2175 // --------------------------------------------------------- |
|
2176 TBool CImpsSubSession::CancelTrans( |
|
2177 RMessagePtr2 aMsg, TImpsSessIdent aCSP ) |
|
2178 { |
|
2179 // Get operation id from client request messages |
|
2180 RMessage2 myMsg( aMsg ); |
|
2181 TInt opid = myMsg.Int0(); |
|
2182 #ifndef _NO_IMPS_LOGGING_ |
|
2183 CImpsClientLogger::Log( _L( "SubSession: CancelTransL opid=%d subses=%d" ), opid, ( TInt )this ); |
|
2184 #endif |
|
2185 |
|
2186 TBuf<KImpsMaxTID> myTid; |
|
2187 |
|
2188 // delete the request |
|
2189 // If there is no such opid then return an error code |
|
2190 TBool found( EFalse ); |
|
2191 TDblQueIter<CRequest> requestIter( iRequestList ); |
|
2192 requestIter.SetToFirst(); |
|
2193 while ( requestIter ) |
|
2194 { |
|
2195 CRequest* request = requestIter; |
|
2196 requestIter++; |
|
2197 if ( request->iOpId == opid ) |
|
2198 { |
|
2199 myTid = request->iTID; |
|
2200 // entry found and deleted |
|
2201 request->Destroy(); |
|
2202 found = ETrue; |
|
2203 break; |
|
2204 } |
|
2205 } |
|
2206 #ifndef _NO_IMPS_LOGGING_ |
|
2207 CImpsClientLogger::Log( _L( "SubSession: CancelTransL returns %d" ), found ); |
|
2208 #endif |
|
2209 if ( found ) |
|
2210 { |
|
2211 // ok, the session cancels the transport and completes the request |
|
2212 Server()->CancelTrans( myTid, aCSP ); |
|
2213 } |
|
2214 return found; |
|
2215 } |
|
2216 |
|
2217 // --------------------------------------------------------- |
|
2218 // CImpsSubSession::SetExpiryTime |
|
2219 // --------------------------------------------------------- |
|
2220 void CImpsSubSession::SetExpiryTime( RMessagePtr2 aMsg ) |
|
2221 { |
|
2222 RMessage2 myMsg( aMsg ); |
|
2223 TInt time = myMsg.Int0(); |
|
2224 SetExpiryTime( time ); |
|
2225 } |
|
2226 |
|
2227 // --------------------------------------------------------- |
|
2228 // CImpsSubSession::SetExpiryTime |
|
2229 // --------------------------------------------------------- |
|
2230 void CImpsSubSession::SetExpiryTime( TInt aVal ) |
|
2231 { |
|
2232 if ( aVal > 0 ) |
|
2233 { |
|
2234 #ifndef _NO_IMPS_LOGGING_ |
|
2235 CImpsClientLogger::Log( _L( "SubSession: SetExpiryTime %d" ), aVal ); |
|
2236 #endif |
|
2237 iExpiryTime = aVal; |
|
2238 Server()->SetExpiryTimer( aVal, EFalse ); |
|
2239 } |
|
2240 } |
|
2241 |
|
2242 // --------------------------------------------------------- |
|
2243 // CImpsSubSession::ExpiryTime |
|
2244 // --------------------------------------------------------- |
|
2245 TInt CImpsSubSession::ExpiryTime( ) |
|
2246 { |
|
2247 return iExpiryTime; |
|
2248 } |
|
2249 |
|
2250 // --------------------------------------------------------- |
|
2251 // TImpsOOMErrors::StoreOOM |
|
2252 // --------------------------------------------------------- |
|
2253 void TImpsOOMErrors::StoreOOM( TInt aOpCode ) |
|
2254 { |
|
2255 // FIFO, a ring buffer |
|
2256 iOOMList[iW].SetOpId( aOpCode ); |
|
2257 TInt newW = ( iW + 1 ) % KImpsMaxBuffered; |
|
2258 if ( newW != iR ) |
|
2259 { |
|
2260 // overflow, don't increase the index. |
|
2261 // the last free write cell is re-used as needed |
|
2262 iW = newW; |
|
2263 } |
|
2264 } |
|
2265 |
|
2266 // --------------------------------------------------------- |
|
2267 // ImpsOOMErrors::GetOOM |
|
2268 // --------------------------------------------------------- |
|
2269 TInt TImpsOOMErrors::GetOOM() |
|
2270 { |
|
2271 if ( iR != iW ) |
|
2272 { |
|
2273 iOOMList[iR].SetAsSent(); |
|
2274 return iOOMList[iR].OpId(); |
|
2275 } |
|
2276 else |
|
2277 { |
|
2278 return 0; |
|
2279 } |
|
2280 } |
|
2281 |
|
2282 // --------------------------------------------------------- |
|
2283 // ImpsOOMErrors::RemoveOOM |
|
2284 // --------------------------------------------------------- |
|
2285 TInt TImpsOOMErrors::RemoveOOM() |
|
2286 { |
|
2287 if ( iR != iW && iOOMList[iR].IsSent() ) |
|
2288 { |
|
2289 TInt ret = iOOMList[iR].OpId(); |
|
2290 iR = ( ++iR ) % KImpsMaxBuffered; |
|
2291 return ret; |
|
2292 } |
|
2293 else |
|
2294 { |
|
2295 return 0; |
|
2296 } |
|
2297 } |
|
2298 |
|
2299 // --------------------------------------------------------- |
|
2300 // ImpsOOMErrors::Exists |
|
2301 // --------------------------------------------------------- |
|
2302 TBool TImpsOOMErrors::Exists() |
|
2303 { |
|
2304 if ( iR != iW /*&& !iOOMList[iR].IsSent()*/ ) |
|
2305 { |
|
2306 return ETrue; |
|
2307 } |
|
2308 else |
|
2309 { |
|
2310 return EFalse; |
|
2311 } |
|
2312 } |
|
2313 |
|
2314 // --------------------------------------------------------- |
|
2315 // TImpsOOMErrors::Reset |
|
2316 // --------------------------------------------------------- |
|
2317 void TImpsOOMErrors::Reset() |
|
2318 { |
|
2319 iR = 0; |
|
2320 iW = 0; |
|
2321 } |
|
2322 |
|
2323 // --------------------------------------------------------- |
|
2324 // TImpsOOMError::TImpsOOMError |
|
2325 // --------------------------------------------------------- |
|
2326 TImpsOOMError::TImpsOOMError() |
|
2327 { |
|
2328 iOpId = 0; |
|
2329 iSent = EFalse; |
|
2330 } |
|
2331 |
|
2332 // --------------------------------------------------------- |
|
2333 // TImpsOOMError::SetOpId |
|
2334 // --------------------------------------------------------- |
|
2335 void TImpsOOMError::SetOpId( TInt aOpId ) |
|
2336 { |
|
2337 iOpId = aOpId; |
|
2338 iSent = EFalse; |
|
2339 } |
|
2340 |
|
2341 // --------------------------------------------------------- |
|
2342 // TImpsOOMError::OpId |
|
2343 // --------------------------------------------------------- |
|
2344 TInt TImpsOOMError::OpId() |
|
2345 { |
|
2346 return iOpId; |
|
2347 } |
|
2348 |
|
2349 // --------------------------------------------------------- |
|
2350 // TImpsOOMError::SetAsSent |
|
2351 // --------------------------------------------------------- |
|
2352 void TImpsOOMError::SetAsSent( ) |
|
2353 { |
|
2354 iSent = ETrue; |
|
2355 } |
|
2356 |
|
2357 // --------------------------------------------------------- |
|
2358 // TImpsOOMError::IsSent |
|
2359 // --------------------------------------------------------- |
|
2360 TBool TImpsOOMError::IsSent( ) |
|
2361 { |
|
2362 return iSent; |
|
2363 } |
|
2364 |
|
2365 |
|
2366 // End of File |