|
1 /* |
|
2 * Copyright (c) 2004 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // Include Files |
|
21 |
|
22 #include <e32std.h> // GLDEF_C |
|
23 #include <s32mem.h> // RDesReadStream |
|
24 #include <Gsmumsg.h> // CSmsMessage |
|
25 #include <gsmubuf.h> // CSmsBuffer |
|
26 #include <smut.h> // KUidMsgTypeSMS |
|
27 #include <msvuids.h> // KUidMsvMessageEntry |
|
28 #include <smsclnt.h> // CSmsClientMtm |
|
29 #include <mtclreg.h> // CClientMtmRegistry |
|
30 #include <mtmuibas.h> // CBaseMtmUi |
|
31 #include <txtrich.h> // CRichText |
|
32 #include <smutset.h> // CSmsSettings |
|
33 #include <smuthdr.h> // CSmsHeader |
|
34 #include <e32property.h> // RProperty |
|
35 #include "MsgRelay.h" |
|
36 |
|
37 static const TInt KMaxSubjectLength = 30; |
|
38 |
|
39 const TUid KPSUidIdleInformation = {0x102071C0}; |
|
40 const TUint32 KTelephonyIdleStatus = 0x00000001; |
|
41 enum TPSTelephonyIdleStatus { EPSTelephonyNotIdle, EPSTelephonyIdle }; |
|
42 const TUid KPSUidAiInformation = {0x102750F0}; // ActiveIdle2 SID |
|
43 const TUint KActiveIdleState = 0x00000002; // Contains one value from following emuneration |
|
44 enum EPSActiveIdleState { EPSAiBackground = 0,EPSAiForeground, EPSAiNumberEntry }; |
|
45 |
|
46 TVersion MessageRelayVersion = TVersion(1, 0, 0); |
|
47 |
|
48 /**************************************************************************** |
|
49 * CRelaySession |
|
50 ***************************************************************************** |
|
51 * |
|
52 * |
|
53 * |
|
54 ****************************************************************************/ |
|
55 /* Implements actual functionality for clients. */ |
|
56 class CRelaySession : public CSession2 |
|
57 { |
|
58 CMessageRelay *iOwner; |
|
59 |
|
60 /* Is the session listening for messages. */ |
|
61 TBool iListening; |
|
62 |
|
63 /* The port that is listened, if iListening is ETrue. |
|
64 Port 0 means that port is not specified. */ |
|
65 TUint iListenPort; |
|
66 |
|
67 /* The message type that is listened. */ |
|
68 TMessageType iListenType; |
|
69 |
|
70 /* Notifies new messages to client...*/ |
|
71 TRequestStatus *iListenStatus; |
|
72 |
|
73 /* Used for message passing. */ |
|
74 RMessage2 iRcvMessage; |
|
75 |
|
76 void ConstructL(); |
|
77 |
|
78 CRelaySession(CMessageRelay *aOwner); |
|
79 public: |
|
80 |
|
81 static CRelaySession *NewL(CMessageRelay *aOwner); |
|
82 static CRelaySession *NewLC(CMessageRelay *aOwner); |
|
83 |
|
84 ~CRelaySession(); |
|
85 |
|
86 void ServiceL(const RMessage2& aMessage); |
|
87 |
|
88 /* If message is accepted ETrue is returned, otherwise EFalse. |
|
89 An accepted message is relayed to the client listening for the |
|
90 messages or to the system Inbox(if no port specified). */ |
|
91 TBool AcceptL(TPtr8 &aMessage, TUint aPort, TMessageType aType); |
|
92 |
|
93 /* Returns ETrue, is the port is already listened for. */ |
|
94 TBool IsListening(TUint aPort, TMessageType aType); |
|
95 |
|
96 }; |
|
97 |
|
98 CRelaySession::CRelaySession(CMessageRelay *aOwner) : |
|
99 CSession2(), |
|
100 iOwner(aOwner), |
|
101 iListening(EFalse) |
|
102 { |
|
103 |
|
104 } |
|
105 |
|
106 void CRelaySession::ConstructL() |
|
107 { |
|
108 |
|
109 } |
|
110 |
|
111 CRelaySession *CRelaySession::NewL(CMessageRelay *aOwner) |
|
112 { |
|
113 CRelaySession *self = CRelaySession::NewLC(aOwner); |
|
114 CleanupStack::Pop(); |
|
115 return self; |
|
116 } |
|
117 |
|
118 CRelaySession *CRelaySession::NewLC(CMessageRelay *aOwner) |
|
119 { |
|
120 CRelaySession *self = new (ELeave) CRelaySession(aOwner); |
|
121 CleanupStack::PushL(self); |
|
122 self->ConstructL(); |
|
123 return self; |
|
124 } |
|
125 |
|
126 CRelaySession::~CRelaySession() |
|
127 { |
|
128 for( int i = 0; i < iOwner->iSessions->Count(); i++) |
|
129 { |
|
130 if( iOwner->iSessions->At( i ) == this) |
|
131 { |
|
132 iOwner->iSessions->Delete( i ); |
|
133 break; |
|
134 } |
|
135 } |
|
136 } |
|
137 |
|
138 /* Returns ETrue, is the port is already listened for. */ |
|
139 TBool CRelaySession::IsListening(TUint aPort, TMessageType aType) |
|
140 { |
|
141 if (iListening == EFalse) |
|
142 return EFalse; |
|
143 |
|
144 if (aType != iListenType) |
|
145 return EFalse; |
|
146 |
|
147 if (aPort != iListenPort) |
|
148 return EFalse; |
|
149 |
|
150 return ETrue; |
|
151 } |
|
152 |
|
153 void CRelaySession::ServiceL(const RMessage2& aMessage) |
|
154 { |
|
155 HBufC8 *newMessage = NULL; |
|
156 TMessageType type; |
|
157 TUint port; |
|
158 |
|
159 switch (aMessage.Function()) |
|
160 { |
|
161 case KNewMessage: |
|
162 { |
|
163 if (iOwner == NULL) |
|
164 User::Leave(KErrNotReady); |
|
165 |
|
166 if (iOwner->iWriter == NULL) |
|
167 User::Leave(KErrNotReady); |
|
168 |
|
169 newMessage = HBufC8::NewL(aMessage.Int0()); |
|
170 TPtr8 ptr(newMessage->Des()); |
|
171 aMessage.ReadL( 1, ptr ); |
|
172 |
|
173 type = (TMessageType)aMessage.Int2(); |
|
174 iOwner->iWriter->WriteMessageL(ptr, type); |
|
175 |
|
176 aMessage.Complete(KErrNone); |
|
177 |
|
178 delete newMessage; |
|
179 |
|
180 break; |
|
181 } |
|
182 case KReceive: |
|
183 |
|
184 if (iListening) { |
|
185 if (!iRcvMessage.IsNull()) { |
|
186 iRcvMessage.Complete(KErrCancel); |
|
187 } |
|
188 iRcvMessage = aMessage; |
|
189 iOwner->TraverseInboxL(); |
|
190 } |
|
191 else { |
|
192 aMessage.Complete(KErrNotReady); |
|
193 } |
|
194 break; |
|
195 case KCancelReceive: |
|
196 if (!iRcvMessage.IsNull()) { |
|
197 iRcvMessage.Complete(KErrCancel); |
|
198 } |
|
199 aMessage.Complete(KErrNone); |
|
200 break; |
|
201 case KStartListening: |
|
202 |
|
203 if (iOwner == NULL) |
|
204 User::Leave(KErrNotReady); |
|
205 |
|
206 type = (TMessageType)aMessage.Int1(); |
|
207 port = (TUint)aMessage.Int2(); |
|
208 |
|
209 if (iOwner->IsAnyBodyListening(port, type) != EFalse) |
|
210 { |
|
211 aMessage.Complete(KErrInUse); |
|
212 return; |
|
213 } |
|
214 |
|
215 iListenType = type; |
|
216 iListenPort = port; |
|
217 iListening = ETrue; |
|
218 aMessage.Complete(KErrNone); |
|
219 break; |
|
220 |
|
221 case KStopListening: |
|
222 iListening = EFalse; |
|
223 if (!iRcvMessage.IsNull()) { |
|
224 iRcvMessage.Complete(KErrCancel); |
|
225 } |
|
226 aMessage.Complete(KErrNone); |
|
227 break; |
|
228 |
|
229 default: |
|
230 User::Leave(KErrNotSupported); |
|
231 } |
|
232 |
|
233 } |
|
234 |
|
235 /* If message is accepted ETrue is returned, otherwise EFalse. |
|
236 An accepted message is relayed to the client listening for the |
|
237 messages. */ |
|
238 TBool CRelaySession::AcceptL(TPtr8 &aMessage, TUint aPort, TMessageType aType) |
|
239 { |
|
240 if (IsListening(aPort, aType) == EFalse) |
|
241 return EFalse; |
|
242 |
|
243 /* Write data to client */ |
|
244 if (!iRcvMessage.IsNull()) { |
|
245 iRcvMessage.WriteL(0, aMessage); |
|
246 iRcvMessage.Complete(KErrNone); |
|
247 } |
|
248 |
|
249 return ETrue; |
|
250 } |
|
251 |
|
252 /**************************************************************************** |
|
253 * CMessageRelay |
|
254 ***************************************************************************** |
|
255 * |
|
256 * |
|
257 * |
|
258 ****************************************************************************/ |
|
259 EXPORT_C CMessageRelay::CMessageRelay() : CServer2(EPriorityNormal) |
|
260 { |
|
261 |
|
262 } |
|
263 |
|
264 EXPORT_C void CMessageRelay::ConstructL(CMessageWriter *aWriter) |
|
265 { |
|
266 iSessions = new (ELeave) CArrayFixFlat<CRelaySession *>(1); |
|
267 |
|
268 SetWriter(aWriter); |
|
269 |
|
270 } |
|
271 |
|
272 EXPORT_C CMessageRelay *CMessageRelay::NewL(CMessageWriter *aWriter /*= NULL*/) |
|
273 { |
|
274 CMessageRelay *self = CMessageRelay::NewLC(aWriter); |
|
275 CleanupStack::Pop(); |
|
276 return self; |
|
277 } |
|
278 |
|
279 EXPORT_C CMessageRelay *CMessageRelay::NewLC(CMessageWriter *aWriter /*= NULL*/) |
|
280 { |
|
281 CMessageRelay *self = new (ELeave) CMessageRelay(); |
|
282 CleanupStack::PushL(self); |
|
283 self->ConstructL(aWriter); |
|
284 return self; |
|
285 } |
|
286 |
|
287 EXPORT_C CMessageRelay::~CMessageRelay() |
|
288 { |
|
289 delete iSessions; |
|
290 } |
|
291 |
|
292 /* Goes through all sessions and returns ETrue, is someone |
|
293 is listening the given port. */ |
|
294 TBool CMessageRelay::IsAnyBodyListening(TUint aPort, TMessageType aType) |
|
295 { |
|
296 TInt i = 0; |
|
297 |
|
298 for (i = 0; i < iSessions->Count(); i++) |
|
299 { |
|
300 if (iSessions->At(i)->IsListening(aPort, aType) != EFalse) |
|
301 return ETrue; |
|
302 } |
|
303 |
|
304 return EFalse; |
|
305 } |
|
306 |
|
307 CSession2* CMessageRelay::NewSessionL(const TVersion& aVersion) const |
|
308 { |
|
309 if (!User::QueryVersionSupported(MessageRelayVersion, |
|
310 aVersion)) |
|
311 { |
|
312 /* Wrong version. */ |
|
313 User::Leave(KErrNotSupported); |
|
314 } |
|
315 |
|
316 CRelaySession *session = CRelaySession::NewL( (CMessageRelay *)this ); |
|
317 |
|
318 iSessions->AppendL(session); |
|
319 |
|
320 return session; |
|
321 } |
|
322 |
|
323 CSession2* CMessageRelay::NewSessionL(const TVersion& aVersion, const RMessage2&) const |
|
324 { |
|
325 return NewSessionL( aVersion ); |
|
326 } |
|
327 |
|
328 /* Starts the server. */ |
|
329 void CMessageRelay::StartRelayL() |
|
330 { |
|
331 CServer2::StartL(KRelayServiceName); |
|
332 } |
|
333 |
|
334 /* Call this method when a new message is received to relay it |
|
335 to possible listeners. Returns ETrue, if the message was |
|
336 accepted. If the message was not accepted, it must not be |
|
337 destroyed, but it must be offered again, as soon as there |
|
338 is a listener for it. */ |
|
339 EXPORT_C TBool CMessageRelay::NewMessageL(TPtr8 &aMessage, TMessageType aType) |
|
340 { |
|
341 TInt i = 0; |
|
342 |
|
343 if (aType != ESmsMessage) |
|
344 User::Leave(KErrNotSupported); |
|
345 |
|
346 |
|
347 /* Extract the port and check if it's listened to. */ |
|
348 RFs fs; |
|
349 fs.Connect(); |
|
350 |
|
351 CSmsBuffer *smsBuf = CSmsBuffer::NewL(); |
|
352 CSmsMessage *smsMsg = CSmsMessage::NewL(fs, CSmsPDU::ESmsSubmit, smsBuf); |
|
353 |
|
354 RDesReadStream rs(aMessage); |
|
355 smsMsg->InternalizeL(rs); |
|
356 |
|
357 rs.Close(); |
|
358 fs.Close(); |
|
359 |
|
360 CSmsPDU &pdu = smsMsg->SmsPDU(); |
|
361 |
|
362 TInt src, dst; |
|
363 |
|
364 TBool isPorts = pdu.ApplicationPortAddressing(dst, src); |
|
365 |
|
366 if (isPorts == EFalse) |
|
367 { |
|
368 /* Copy to inbox. */ |
|
369 CopyMessageToSmsInboxL(aMessage); |
|
370 return ETrue; |
|
371 } |
|
372 |
|
373 for (i = 0; i < iSessions->Count(); i++) |
|
374 { |
|
375 if (iSessions->At(i)->AcceptL(aMessage, dst, aType) != EFalse) |
|
376 return ETrue; |
|
377 } |
|
378 |
|
379 /* No listeners. Cache the message to Inbox. Inbox is traversed, |
|
380 when new listener are created. */ |
|
381 TPtr8 &aMessage2 = aMessage; |
|
382 CopyMessageToSmsInboxL(aMessage2); |
|
383 return ETrue; |
|
384 } |
|
385 |
|
386 /* Sets the message writer. Writers WriteMessageL(...) method |
|
387 is called when a client wants to send a message. */ |
|
388 EXPORT_C void CMessageRelay::SetWriter(CMessageWriter *aWriter) |
|
389 { |
|
390 iWriter = aWriter; |
|
391 } |
|
392 |
|
393 /* Copies the message to inbox. */ |
|
394 void CMessageRelay::CopyMessageToSmsInboxL(TPtr8 &aMessage) |
|
395 { |
|
396 // Get the idle statuses from P&S |
|
397 TInt aiStatus(0); |
|
398 TInt aiGetErr = RProperty::Get( KPSUidAiInformation, |
|
399 KActiveIdleState, |
|
400 aiStatus ); |
|
401 TInt tiStatus(0); |
|
402 TInt tiGetErr = RProperty::Get( KPSUidIdleInformation, |
|
403 KTelephonyIdleStatus, |
|
404 tiStatus ); |
|
405 |
|
406 _LIT(KIdleStatus,"MSGRelay -- aiState:%d aiGetErr:%d tiState:%d tiGetErr:%d"); |
|
407 RDebug::Print(KIdleStatus, aiStatus, aiGetErr, tiStatus, tiGetErr); |
|
408 |
|
409 // Update telephony idle status to idle and active idle status |
|
410 // to foreground if needed. Without these "New message" notifications |
|
411 // might not be visible in some cases. |
|
412 if( aiStatus != EPSAiForeground ) |
|
413 { |
|
414 TInt setAiErr = RProperty::Set( KPSUidAiInformation, |
|
415 KActiveIdleState, |
|
416 EPSAiForeground ); |
|
417 _LIT( KAISetErr,"MSGRelay -- setAiErr:%d" ); |
|
418 RDebug::Print( KAISetErr, setAiErr ); |
|
419 } |
|
420 |
|
421 if( tiStatus != EPSTelephonyIdle ) |
|
422 { |
|
423 TInt setTiErr = RProperty::Set( KPSUidIdleInformation, |
|
424 KTelephonyIdleStatus, |
|
425 EPSTelephonyIdle ); |
|
426 _LIT( KTISetErr,"MSGRelay -- setTiErr:%d" ); |
|
427 RDebug::Print( KTISetErr, setTiErr ); |
|
428 } |
|
429 |
|
430 RFs fs; |
|
431 |
|
432 User::LeaveIfError(fs.Connect()); |
|
433 |
|
434 CSmsBuffer *smsBuf = CSmsBuffer::NewL(); |
|
435 CSmsMessage *smsMessage = CSmsMessage::NewL(fs, CSmsPDU::ESmsSubmit, smsBuf); |
|
436 CMsvSession *iMsvSession = CMsvSession::OpenSyncL(*this); |
|
437 CClientMtmRegistry *registry = CClientMtmRegistry::NewL(*iMsvSession); |
|
438 |
|
439 RDesReadStream rs(aMessage); |
|
440 rs >> *smsMessage; |
|
441 rs.Close(); |
|
442 |
|
443 TMsvEntry index; |
|
444 |
|
445 index.iMtm = KUidMsgTypeSMS; |
|
446 index.iType = KUidMsvMessageEntry; |
|
447 index.iServiceId = KMsvLocalServiceIndexEntryId; |
|
448 index.iDate.HomeTime(); |
|
449 index.SetInPreparation(ETrue); |
|
450 |
|
451 TMsvSelectionOrdering ordering; |
|
452 CMsvEntry *entry = CMsvEntry::NewL(*iMsvSession, KMsvGlobalInBoxIndexEntryIdValue, |
|
453 ordering); |
|
454 |
|
455 entry->CreateL(index); |
|
456 |
|
457 entry->SetEntryL(index.Id()); |
|
458 |
|
459 CSmsClientMtm* mtm = (CSmsClientMtm*)registry->NewMtmL(KUidMsgTypeSMS); |
|
460 |
|
461 mtm->SetCurrentEntryL(entry); |
|
462 |
|
463 index = mtm->Entry().Entry(); |
|
464 |
|
465 index.iDetails.Set(smsMessage->ToFromAddress()); |
|
466 |
|
467 index.SetInPreparation(EFalse); |
|
468 |
|
469 index.SetSendingState(KMsvSendStateNotApplicable); |
|
470 index.iDate = smsMessage->Time(); |
|
471 |
|
472 // Set the new and unread flags. Enables "New message" notifications. |
|
473 index.SetNew( ETrue ); |
|
474 index.SetUnread( ETrue ); |
|
475 |
|
476 CRichText &mtmBody = mtm->Body(); |
|
477 mtmBody.Reset(); |
|
478 |
|
479 HBufC *data = HBufC::NewLC(smsBuf->Length()); |
|
480 TPtr ptr(data->Des()); |
|
481 |
|
482 smsBuf->Extract(ptr, 0, smsBuf->Length()); |
|
483 |
|
484 mtmBody.InsertL(0, ptr); |
|
485 |
|
486 if (ptr.Length() > KMaxSubjectLength) |
|
487 index.iDescription.Set(ptr.Left(KMaxSubjectLength)); |
|
488 else |
|
489 index.iDescription.Set(ptr); |
|
490 |
|
491 mtm->RestoreServiceAndSettingsL(); |
|
492 |
|
493 CSmsHeader &hdr = mtm->SmsHeader(); |
|
494 |
|
495 CSmsSettings *sendOpt = CSmsSettings::NewL(); |
|
496 CleanupStack::PushL(sendOpt); |
|
497 |
|
498 sendOpt->CopyL(mtm->ServiceSettings()); |
|
499 sendOpt->SetDelivery(ESmsDeliveryImmediately); |
|
500 |
|
501 hdr.SetSmsSettingsL(*sendOpt); |
|
502 hdr.SetFromAddressL(smsMessage->ToFromAddress()); |
|
503 |
|
504 CleanupStack::PopAndDestroy(sendOpt); |
|
505 |
|
506 CSmsMessage &newMsg = hdr.Message(); |
|
507 |
|
508 newMsg.SetServiceCenterAddressL(smsMessage->ServiceCenterAddress()); |
|
509 |
|
510 CSmsPDU &pdu = newMsg.SmsPDU(); |
|
511 CSmsPDU &oldPdu = smsMessage->SmsPDU(); |
|
512 |
|
513 pdu.SetAlphabet(oldPdu.Alphabet()); |
|
514 |
|
515 TSmsDataCodingScheme::TSmsClass coding; |
|
516 TBool b = oldPdu.Class(coding); |
|
517 pdu.SetClass(b, coding); |
|
518 |
|
519 TInt dst = -1; |
|
520 TInt src = -1; |
|
521 TBool is16; |
|
522 |
|
523 b = oldPdu.ApplicationPortAddressing(dst, src, &is16); |
|
524 |
|
525 if(b != EFalse) |
|
526 { |
|
527 pdu.SetApplicationPortAddressingL(b, dst, src, is16); |
|
528 } |
|
529 |
|
530 mtm->AddAddresseeL(smsMessage->ToFromAddress(), index.iDetails); |
|
531 |
|
532 CMsvEntry &newEntry = mtm->Entry(); |
|
533 newEntry.ChangeL(index); |
|
534 |
|
535 mtm->SaveMessageL(); |
|
536 |
|
537 CleanupStack::PopAndDestroy(1); |
|
538 |
|
539 } |
|
540 |
|
541 static CSmsMessage *ConvertEntryToMessageL(TMsvEntry &aIndex, CMsvSession *aSession) |
|
542 { |
|
543 CClientMtmRegistry *registry = CClientMtmRegistry::NewL(*aSession); |
|
544 CleanupStack::PushL(registry); |
|
545 |
|
546 CSmsClientMtm* mtm = (CSmsClientMtm*)registry->NewMtmL(aIndex.iMtm); |
|
547 CleanupStack::PushL(mtm); |
|
548 |
|
549 mtm->SwitchCurrentEntryL(aIndex.Id()); |
|
550 mtm->LoadMessageL(); |
|
551 |
|
552 CSmsHeader &hdr = mtm->SmsHeader(); |
|
553 |
|
554 CSmsMessage &msg = hdr.Message(); |
|
555 |
|
556 HBufC8 *buf = HBufC8::NewLC(KMaxSmsBufferSize); |
|
557 TPtr8 ptr(buf->Des()); |
|
558 RDesWriteStream ws(ptr); |
|
559 |
|
560 ws << msg; |
|
561 |
|
562 ws.Close(); |
|
563 |
|
564 RFs fs; |
|
565 |
|
566 User::LeaveIfError(fs.Connect()); |
|
567 |
|
568 CSmsBuffer *smsBuf = CSmsBuffer::NewL(); |
|
569 CSmsMessage *newMsg = CSmsMessage::NewL(fs, CSmsPDU::ESmsSubmit, smsBuf); |
|
570 |
|
571 RDesReadStream rs(ptr); |
|
572 rs >> *newMsg; |
|
573 |
|
574 rs.Close(); |
|
575 fs.Close(); |
|
576 |
|
577 CleanupStack::PopAndDestroy(3); |
|
578 |
|
579 return newMsg; |
|
580 } |
|
581 |
|
582 static void DeleteEntryFromInboxL(CMsvEntry *aEntry, CMsvSession *aSession) |
|
583 { |
|
584 TMsvEntry index = aEntry->Entry(); |
|
585 TMsvSelectionOrdering sort = aEntry->SortType(); |
|
586 sort.SetShowInvisibleEntries(ETrue); |
|
587 CMsvEntry* parentEntry = CMsvEntry::NewL(*aSession, index.Parent(), sort); |
|
588 CleanupStack::PushL(parentEntry); |
|
589 |
|
590 TRAPD(err, parentEntry->DeleteL(index.Id())); |
|
591 |
|
592 if(err != KErrNone) |
|
593 { |
|
594 aSession->RemoveEntry(index.Id()); |
|
595 } |
|
596 |
|
597 CleanupStack::PopAndDestroy(parentEntry); |
|
598 } |
|
599 |
|
600 /* Traverses the inbox and sends messages to listeners. */ |
|
601 void CMessageRelay::TraverseInboxL() |
|
602 { |
|
603 TInt count = 0; |
|
604 CMsvEntrySelection* childrenEntrySelection; |
|
605 CMsvEntry* rootEntry; |
|
606 CMsvEntry* child; |
|
607 |
|
608 CMsvSession *iMsvSession = CMsvSession::OpenSyncL(*this); |
|
609 CleanupStack::PushL(iMsvSession); |
|
610 |
|
611 rootEntry = iMsvSession->GetEntryL(KMsvGlobalInBoxIndexEntryId); |
|
612 count = rootEntry->Count(); |
|
613 |
|
614 childrenEntrySelection = rootEntry->ChildrenL(); |
|
615 |
|
616 for(TInt i = 0; i < count; i++) |
|
617 { |
|
618 child = iMsvSession->GetEntryL((*childrenEntrySelection)[i]); |
|
619 TMsvEntry msvEntry = child->Entry(); |
|
620 |
|
621 if (msvEntry.iMtm != KUidMsgTypeSMS) |
|
622 /* Not to us. */ |
|
623 continue; |
|
624 |
|
625 CSmsMessage *smsMsg = ConvertEntryToMessageL(msvEntry, iMsvSession); |
|
626 |
|
627 HBufC8 *buf = HBufC8::NewLC(KMaxSmsBufferSize); |
|
628 TPtr8 ptr(buf->Des()); |
|
629 RDesWriteStream ws(ptr); |
|
630 |
|
631 ws << *smsMsg; |
|
632 |
|
633 ws.Close(); |
|
634 |
|
635 CSmsPDU &pdu = smsMsg->SmsPDU(); |
|
636 |
|
637 TInt src, dst; |
|
638 |
|
639 TBool isPorts = pdu.ApplicationPortAddressing(dst, src); |
|
640 |
|
641 if (isPorts == EFalse) |
|
642 { |
|
643 /* No ports, no listeners, leave to inbox. */ |
|
644 CleanupStack::PopAndDestroy(1); //buf |
|
645 continue; |
|
646 |
|
647 } |
|
648 |
|
649 for (i = 0; i < iSessions->Count(); i++) |
|
650 { |
|
651 if (iSessions->At(i)->AcceptL(ptr, dst, ESmsMessage) != EFalse) |
|
652 { |
|
653 /* Remove from inbox */ |
|
654 DeleteEntryFromInboxL(child, iMsvSession); |
|
655 |
|
656 /* Inbox has changed, start traversing again. */ |
|
657 rootEntry = iMsvSession->GetEntryL(KMsvGlobalInBoxIndexEntryId); |
|
658 count = rootEntry->Count(); |
|
659 childrenEntrySelection = rootEntry->ChildrenL(); |
|
660 |
|
661 i = -1; /* Will be incremented before testing... */ |
|
662 break; |
|
663 } |
|
664 } |
|
665 |
|
666 CleanupStack::PopAndDestroy(1); //buf |
|
667 |
|
668 } |
|
669 CleanupStack::PopAndDestroy(1); // iMsvSesssion |
|
670 } |
|
671 |
|
672 void CMessageRelay::HandleSessionEventL(TMsvSessionEvent, TAny*, |
|
673 TAny*, TAny*) |
|
674 { |
|
675 } |
|
676 /**************************************************************************** |
|
677 * CMessageWriter |
|
678 ***************************************************************************** |
|
679 * |
|
680 * |
|
681 * |
|
682 ****************************************************************************/ |
|
683 EXPORT_C void CMessageWriter::ConstructL() |
|
684 { |
|
685 |
|
686 } |
|
687 |
|
688 EXPORT_C CMessageWriter *CMessageWriter::NewL() |
|
689 { |
|
690 CMessageWriter *self = CMessageWriter::NewLC(); |
|
691 CleanupStack::Pop(); |
|
692 return self; |
|
693 } |
|
694 |
|
695 EXPORT_C CMessageWriter *CMessageWriter::NewLC() |
|
696 { |
|
697 CMessageWriter *self = new (ELeave) CMessageWriter; |
|
698 CleanupStack::PushL(self); |
|
699 self->ConstructL(); |
|
700 return self; |
|
701 } |
|
702 |
|
703 EXPORT_C CMessageWriter::~CMessageWriter() |
|
704 { |
|
705 |
|
706 } |
|
707 |
|
708 /* Called when a message is received from client for sending. */ |
|
709 EXPORT_C void CMessageWriter::WriteMessageL(TPtr8 & /*aMessage*/, TMessageType /*aType*/) |
|
710 { |
|
711 /* Nothing to do, inherited class will override. */ |
|
712 } |
|
713 |
|
714 // End of file |