|
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "smsstacklog.h" |
|
17 #include "gsmubuf.h" |
|
18 #include "smspreassemblystore.h" |
|
19 |
|
20 /** |
|
21 * Populate entry information from sms message. |
|
22 * @param aEntry fills up re-assembly entry information from aSmsMessage. |
|
23 * @param aSmsMessage refernce to sms message. |
|
24 * @param aNumSmss number of sms. |
|
25 */ |
|
26 void CReassemblyStoreUtility::PopulateEntry(TSmsReassemblyEntry& aEntry,const CSmsMessage& aSmsMessage,TInt aNumSmss) |
|
27 { |
|
28 LOGSMSPROT1("CReassemblyStoreUtility::PopulateEntry"); |
|
29 aEntry.SetReference(0); |
|
30 aEntry.SetTotal(1); |
|
31 aEntry.SetCount(1); |
|
32 |
|
33 if (aSmsMessage.TextPresent()) |
|
34 { |
|
35 if (aSmsMessage.SmsPDU().TextConcatenated()) |
|
36 { |
|
37 aEntry.SetReference(aSmsMessage.SmsPDU().ConcatenatedMessageReference()); |
|
38 aEntry.SetTotal(aSmsMessage.SmsPDU().NumConcatenatedMessagePDUs()); |
|
39 aEntry.SetCount(aSmsMessage.IsComplete()? aEntry.Total(): aNumSmss); |
|
40 } |
|
41 TInt bits7to4=aSmsMessage.SmsPDU().Bits7To4(); |
|
42 TInt count=aSmsMessage.SmsPDU().UserData().NumInformationElements(); |
|
43 TInt identifier1=0xFF; |
|
44 TInt identifier2=0x00; |
|
45 for (TInt i=0; i<count; i++) |
|
46 { |
|
47 TInt identifier=aSmsMessage.SmsPDU().UserData().InformationElement(i).Identifier(); |
|
48 if ((identifier!=CSmsInformationElement::ESmsIEIConcatenatedShortMessages8BitReference) && (identifier!=CSmsInformationElement::ESmsIEIConcatenatedShortMessages16BitReference)) |
|
49 { |
|
50 if (identifier<identifier1) |
|
51 identifier1=identifier; |
|
52 if (identifier>identifier2) |
|
53 identifier2=identifier; |
|
54 } |
|
55 } |
|
56 |
|
57 if ((bits7to4>=TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage) && (bits7to4<=TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationUCS2)) |
|
58 aEntry.SetBits7to4andIdentifiers(bits7to4, identifier1, identifier2); |
|
59 else |
|
60 aEntry.SetBits7to4andIdentifiers(0, identifier1, identifier2); |
|
61 } |
|
62 |
|
63 //Set the logServerId to aSmsMessage.LogServerId() |
|
64 |
|
65 aEntry.SetLogServerId(aSmsMessage.LogServerId()); |
|
66 |
|
67 const CSmsPDU::TSmsPDUType type(aSmsMessage.Type()); |
|
68 aEntry.SetPduType(type); |
|
69 aEntry.SetPassedToClient(EFalse); |
|
70 |
|
71 aEntry.SetStorage(aSmsMessage.Storage()); |
|
72 if ((type!=CSmsPDU::ESmsSubmitReport) && (type!=CSmsPDU::ESmsDeliverReport)) |
|
73 { |
|
74 // Strip out spaces etc from address |
|
75 TGsmSmsTelNumber parsedaddress; |
|
76 aSmsMessage.ParsedToFromAddress(parsedaddress); |
|
77 aEntry.SetDescription2(parsedaddress.iTelNumber); |
|
78 } |
|
79 |
|
80 aEntry.SetTime(aSmsMessage.Time()); |
|
81 } |
|
82 |
|
83 /** |
|
84 * Returns the private path of the component. |
|
85 * @param aFs File Server handle. |
|
86 * @param aPath (retrurns) private path of the component. |
|
87 */ |
|
88 void CReassemblyStoreUtility::PrivatePath(RFs& aFs, TDes& aPath) |
|
89 { |
|
90 LOGSMSPROT1("CReassemblyStoreUtility::PrivatePath()"); |
|
91 |
|
92 TDriveUnit driveUnit(KStoreDrive); |
|
93 TDriveName drive=driveUnit.Name(); |
|
94 aPath.Insert(0, drive); |
|
95 //append private path |
|
96 TPath privatePath; |
|
97 aFs.PrivatePath(privatePath); |
|
98 aPath.Append(privatePath); |
|
99 aPath.Append(KStoreSubDir); |
|
100 } // CReassemblyStoreUtility::PrivatePath |
|
101 |
|
102 /** |
|
103 * Constructor. |
|
104 */ |
|
105 CReassemblyStore::CReassemblyStore(RFs& aFs) : iFs(aFs), iEntryArray(KFlatArrayGranularity) |
|
106 { |
|
107 iLastReceivedTime.UniversalTime(); |
|
108 iLastRealTime = iLastReceivedTime; |
|
109 } |
|
110 |
|
111 /** |
|
112 * Destructor. |
|
113 */ |
|
114 CReassemblyStore::~CReassemblyStore() |
|
115 { |
|
116 iEntryArray.Reset(); |
|
117 } |
|
118 |
|
119 /** |
|
120 It cleans up the re-assembly store. |
|
121 This function will be called to allow re-assembly store to initialize/clean-up |
|
122 |
|
123 @internalComponent |
|
124 */ |
|
125 void CReassemblyStore::InitializeL() |
|
126 { |
|
127 LOGSMSPROT1("CClass0SmsReassemblyStore::InitializeL()"); |
|
128 // Initialize Re-assembly store. |
|
129 OpenStoreL(); |
|
130 BeginTransactionLC(); |
|
131 TInt count = iEntryArray.Count(); |
|
132 while (count--) |
|
133 { |
|
134 TReassemblyEntry entry= iEntryArray[count]; |
|
135 if ((entry.Storage() == CSmsMessage::ESmsSIMStorage) || (entry.Storage() == CSmsMessage::ESmsCombinedStorage)) |
|
136 { |
|
137 DeleteEntryL(entry); |
|
138 } |
|
139 else |
|
140 { |
|
141 SetPassedToClientL(entry, EFalse); |
|
142 } |
|
143 } |
|
144 CommitTransactionL(); |
|
145 Close(); |
|
146 } |
|
147 |
|
148 /** |
|
149 * Purges the reassembly file store. |
|
150 * |
|
151 * After a multipart message, it delete all the old entries. |
|
152 * |
|
153 * Entries will be purged when: 1) The complete message is received; 2) After |
|
154 * aTimerintervalMinutes, if aPurgeIncompletely is false. |
|
155 * |
|
156 * PurgeL() will be called after the booting of the device or when a message |
|
157 * has been received. |
|
158 * |
|
159 * This function opens and closes the file automatically. |
|
160 * |
|
161 * |
|
162 * @param aTimeIntervalMinutes Purge time |
|
163 * @param aPurgeIncompleteOnly Purge complete messages flag |
|
164 */ |
|
165 void CReassemblyStore::PurgeL(const TTimeIntervalMinutes& aTimeIntervalMinutes,TBool aPurgeIncompleteOnly) |
|
166 { |
|
167 //Call purging function |
|
168 LOGSMSPROT3("CReassemblyStore::PurgeL(): aTimeIntervalMinutes=%d, aPurgeIncompleteOnly=%d", |
|
169 aTimeIntervalMinutes.Int(), aPurgeIncompleteOnly); |
|
170 |
|
171 // TODO - flag |
|
172 // we could also save the call of the method from the consruction of the smsprot |
|
173 if( aPurgeIncompleteOnly ) |
|
174 return; |
|
175 |
|
176 TInt count=iEntryArray.Count(); |
|
177 LOGSMSPROT2("CClass0SmsReassemblyStore::PurgeL(): count=%d", count); |
|
178 |
|
179 TTime time; |
|
180 time.UniversalTime(); |
|
181 |
|
182 // we open the file outside the loop |
|
183 // to save some CPU |
|
184 BeginTransactionLC(); |
|
185 for (TInt i=count-1; i>=0; i--) |
|
186 { |
|
187 //TReassemblyEntry entry=iEntryArray[i]; |
|
188 if (time > (iEntryArray[i].Time()+aTimeIntervalMinutes)) |
|
189 // TODO - flag |
|
190 // check the logic o the aPurgeIncompleteOnly flg |
|
191 // don't purge the store if the entry is complete |
|
192 // entry.IsComplete() ) |
|
193 { |
|
194 DeleteEntryL(iEntryArray[i]); |
|
195 } |
|
196 } |
|
197 CommitTransactionL(); |
|
198 |
|
199 PopulateEntryArrayL(iEntryArray); |
|
200 } |
|
201 |
|
202 /** |
|
203 It deletes all the enumerated SIM messages stored in re-assembly store. |
|
204 This function will be called if user choses to cancel the enumeration. |
|
205 |
|
206 @internalComponent |
|
207 */ |
|
208 void CReassemblyStore::DeleteEnumeratedSIMEntries() |
|
209 { |
|
210 const TInt count = iEntryArray.Count(); |
|
211 |
|
212 LOGSMSPROT2("CReassemblyStore::DeleteEnumeratedSIMEntries(): %d messages in RAS", count); |
|
213 |
|
214 TInt index; |
|
215 |
|
216 for (index = count-1; index >= 0; --index) |
|
217 { |
|
218 TReassemblyEntry entry = iEntryArray[index]; |
|
219 |
|
220 if (entry.Storage()==CSmsMessage::ESmsSIMStorage) |
|
221 { |
|
222 TRAP_IGNORE(BeginTransactionLC(); |
|
223 DeleteEntryL(entry); |
|
224 CommitTransactionL(); |
|
225 iEntryArray.Delete(index)); |
|
226 } |
|
227 } |
|
228 } |
|
229 |
|
230 /** |
|
231 It returns the number of complete messages in reassembly store. |
|
232 |
|
233 @internalComponent |
|
234 */ |
|
235 TInt CReassemblyStore::NumberOfCompleteMessages() |
|
236 { |
|
237 LOGSMSPROT2("CReassemblyStore::NumberOfCompleteMessages(): iEntryArray.Count()=%d", |
|
238 iEntryArray.Count()); |
|
239 |
|
240 //local variable for complete entries |
|
241 TInt count( 0 ); |
|
242 // checks all entrys in the reassembly store |
|
243 for ( TInt i = iEntryArray.Count()-1; i >= 0; i-- ) |
|
244 { |
|
245 // checks if entry is completed |
|
246 if ( iEntryArray[i].IsComplete() ) |
|
247 { |
|
248 ++count; |
|
249 } |
|
250 } |
|
251 return count; |
|
252 } |
|
253 |
|
254 /** |
|
255 It adds the message segment to the reassembly store. There are 5 possiblities: |
|
256 |
|
257 1) This is the single segment message. |
|
258 We therefore have all the segments. |
|
259 2) This is a duplicate message segment. |
|
260 We will ignore it. |
|
261 3) This is the last segment in the message required to complete it. |
|
262 The other segments are already stored. |
|
263 4) This is another PDU to an existing message in the store, but it is |
|
264 not yet complete. |
|
265 5) This is the first PDU in the message, and therefore the message is |
|
266 not yet complete and no segments are stored. |
|
267 |
|
268 @note Only SUBMIT or DELIVER PDUs can be added to the reassembly store. |
|
269 |
|
270 @param aSmsMessage a reference to the SMS message. |
|
271 It acts both as input & output. If the message is complete, it contains the decoded message. |
|
272 Otherwise it contains the received message with few properties set (LogServerId, Time). |
|
273 |
|
274 @param aGsmSms a reference to GsmSms object which contain actual PDU. |
|
275 It acts as input. |
|
276 |
|
277 @param aIsComplete Boolean value indicating whether the message is complete or not. |
|
278 It acts both as input & output. |
|
279 |
|
280 @param aIsEnumeration Boolean value indicating whether the function is called at the time of enumeration. |
|
281 It acts as only input. |
|
282 |
|
283 @param aCount value indicating the number of current PDUs in the re-assembly store for the given SMS message. |
|
284 It acts as only output. |
|
285 |
|
286 @param aTotal value indicating the total number of PDUs in the re-assembly store for the given SMS message. |
|
287 It acts as only output. |
|
288 |
|
289 @internalComponent |
|
290 */ |
|
291 void CReassemblyStore::AddSegmentToReassemblyStoreL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms, TInt& aIndex, TBool& aIsComplete, TBool aIsEnumeration, TInt& aCount, TInt& aTotal) |
|
292 { |
|
293 LOGSMSPROT2("CReassemblyStore::AddSegmentToReassemblyStoreL(): isComplete Message=%d", |
|
294 aSmsMessage.IsComplete()); |
|
295 |
|
296 /* |
|
297 (1) If it is a single segment message create a new message |
|
298 (2) If it is part of concatenated message find whether this is the first PDU |
|
299 or it is the part of existing message. |
|
300 If it is a new message then create new one. |
|
301 If it is part of existing message, then check duplication (CheckDuplication()). |
|
302 If it is a duplicate, return. Otherwise update the reassembly store. |
|
303 */ |
|
304 |
|
305 if (aIsComplete || aSmsMessage.Type() == CSmsPDU::ESmsStatusReport) |
|
306 { |
|
307 // |
|
308 // 1) This is the complete message (e.g. a single-segment message). |
|
309 // We therefore have all the segments. |
|
310 // |
|
311 // Create the new message in the reassembly store. This is incase the |
|
312 // power fails before the client gets it (note that it will be ack'd |
|
313 // before passed to the client) so keeping it in memory is not |
|
314 // acceptable... |
|
315 // |
|
316 NewMessagePDUL(aIndex, aSmsMessage, aGsmSms); |
|
317 } |
|
318 else |
|
319 { |
|
320 // |
|
321 // If not yet complete, then we must be part of a multiple PDU message. |
|
322 // Search the reassembly store for existing parts of the message. |
|
323 // |
|
324 TInt segStoreIndex(KErrNotFound); |
|
325 |
|
326 MatchPDUToExistingMessage(aSmsMessage, segStoreIndex); |
|
327 LOGSMSPROT2("CSmsReassemblyStore::AddSegmentToReassemblyStoreL(): " |
|
328 "segStoreIndex=%d", segStoreIndex); |
|
329 |
|
330 // |
|
331 // If not yet complete, then we must be part of a multiple PDU message. |
|
332 // Search the reassembly store for existing parts of the message. This |
|
333 // may set iIsComplete to true if all segments are then found. |
|
334 // |
|
335 if (segStoreIndex != KErrNotFound) |
|
336 { |
|
337 TBool isDuplicateSlot(EFalse); |
|
338 TBool isDuplicateMsgRef(EFalse); |
|
339 // |
|
340 // So we found a related part of the message, add this message to the |
|
341 // store... |
|
342 // |
|
343 aIndex = segStoreIndex; |
|
344 UpdateExistingMessageL(aSmsMessage, aGsmSms, aIndex, |
|
345 aIsComplete, isDuplicateMsgRef, |
|
346 isDuplicateSlot); |
|
347 LOGSMSPROT5("CSmsReassemblyStore::AddSegmentToReassemblyStoreL(): " |
|
348 "aIndex=%d, isComplete=%d, isDuplicateMsgRef=%d, isDuplicateSlot=%d", |
|
349 aIndex, aIsComplete, isDuplicateMsgRef, isDuplicateSlot); |
|
350 |
|
351 if (isDuplicateMsgRef) |
|
352 { |
|
353 // |
|
354 // In most cases discard it, unless we are doing an enumeration??? |
|
355 // |
|
356 if (aIsEnumeration) |
|
357 { |
|
358 NewMessagePDUL(aIndex, aSmsMessage, aGsmSms); |
|
359 } |
|
360 } |
|
361 else if (aIsComplete) |
|
362 { |
|
363 // |
|
364 // 3) This is the last segment in the message required to complete it. |
|
365 // The other segments are already stored. |
|
366 // |
|
367 // Load the complete message into memory for futher processing. |
|
368 // |
|
369 GetMessageL(aIndex, aSmsMessage); |
|
370 } |
|
371 else |
|
372 { |
|
373 // |
|
374 // 4) This is another PDU to an existing message in the store, but it is |
|
375 // not yet complete. |
|
376 // |
|
377 // Update the this segment with the timestamp of the original message. |
|
378 // |
|
379 CSmsBuffer* buffer = CSmsBuffer::NewL(); |
|
380 CSmsMessage* firstMessagePdu = CSmsMessage::NewL(iFs, |
|
381 CSmsPDU::ESmsDeliver, buffer); |
|
382 CleanupStack::PushL(firstMessagePdu); |
|
383 GetMessageL(aIndex, *firstMessagePdu); |
|
384 aSmsMessage.SetUTCOffset(firstMessagePdu->UTCOffset()); |
|
385 CleanupStack::PopAndDestroy(firstMessagePdu); |
|
386 } |
|
387 } |
|
388 else |
|
389 { |
|
390 // |
|
391 // 5) This is the first PDU in the message, and therefore the message is |
|
392 // not yet complete and no segments are stored. |
|
393 // |
|
394 // The entry needs to be added to the reassembly store as a new entry. |
|
395 // |
|
396 NewMessagePDUL(aIndex, aSmsMessage, aGsmSms); |
|
397 } |
|
398 } |
|
399 |
|
400 const TReassemblyEntry& entry = iEntryArray[aIndex]; |
|
401 aCount = entry.Count(); |
|
402 aTotal = entry.Total(); |
|
403 } |
|
404 |
|
405 /** |
|
406 It deletes the given SMS message from re-assembly store. |
|
407 |
|
408 @param aSmsMessage Message to delete. |
|
409 @param aPassed Determines if we are searching for a message already |
|
410 passed to the client. |
|
411 |
|
412 @internalComponent |
|
413 */ |
|
414 void CReassemblyStore::DeleteMessageL(const CSmsMessage& aSmsMessage, TBool aPassed) |
|
415 { |
|
416 LOGSMSPROT1("CReassemblyStore::DeleteMessageL()"); |
|
417 TInt index(0); |
|
418 BeginTransactionLC(); |
|
419 if (FindMessageL(aSmsMessage, aPassed, index)) |
|
420 { |
|
421 const TReassemblyEntry& entry = iEntryArray[index]; |
|
422 DeleteEntryL(entry); |
|
423 iEntryArray.Delete(index); |
|
424 } |
|
425 CommitTransactionL(); |
|
426 } |
|
427 |
|
428 /** |
|
429 It updates log server id of the passed message in re-assembly store. |
|
430 |
|
431 @param aSmsMessage a reference to a message. |
|
432 @param aIndex index number of sms message to be updated. |
|
433 |
|
434 @internalComponent |
|
435 */ |
|
436 void CReassemblyStore::UpdateLogServerIdOfMessageL(const CSmsMessage& aSmsMessage, TInt aIndex) |
|
437 { |
|
438 LOGSMSPROT1("CReassemblyStore::UpdateLogServerIdOfMessageL()"); |
|
439 TInt foundIndex(KErrNotFound); |
|
440 TBool found(EFalse); |
|
441 |
|
442 BeginTransactionLC(); |
|
443 |
|
444 found = FindMessageL(aSmsMessage , EFalse, foundIndex); |
|
445 if (found && (aIndex == foundIndex)) |
|
446 { |
|
447 const TReassemblyEntry& entry = iEntryArray[foundIndex]; |
|
448 UpdateLogServerIdL(entry, aSmsMessage.LogServerId()); |
|
449 iEntryArray[foundIndex].SetLogServerId(aSmsMessage.LogServerId()); |
|
450 } |
|
451 CommitTransactionL(); |
|
452 } |
|
453 |
|
454 /** |
|
455 It updates that the given SMS message in re-assembly store is passed to client. |
|
456 |
|
457 @param aSmsMessage Message which is passed to client. |
|
458 |
|
459 @internalComponent |
|
460 */ |
|
461 void CReassemblyStore::SetMessagePassedToClientL(const CSmsMessage& aSmsMessage, TBool aPassed) |
|
462 { |
|
463 LOGSMSPROT1("CReassemblyStore::SetMessagePassedToClientL()"); |
|
464 TInt index(0); |
|
465 |
|
466 BeginTransactionLC(); |
|
467 |
|
468 if (FindMessageL(aSmsMessage , !aPassed, index)) |
|
469 { |
|
470 const TReassemblyEntry& entry = iEntryArray[index]; |
|
471 SetPassedToClientL(entry, aPassed); |
|
472 iEntryArray[index].SetPassedToClient(aPassed); |
|
473 } |
|
474 CommitTransactionL(); |
|
475 } |
|
476 |
|
477 /** |
|
478 It adds a new message segment to the reassembly store and it returns an index to the message. |
|
479 |
|
480 @param aIndex value indicating the index of the message added to re-assembly store. |
|
481 It acts as output. |
|
482 |
|
483 @param aSmsMessage a reference to the SMS message. |
|
484 It acts as input. |
|
485 |
|
486 @param aGsmSms a reference to GsmSms object which contain actual PDU. |
|
487 It acts as input. |
|
488 |
|
489 @internalComponent |
|
490 */ |
|
491 void CReassemblyStore::NewMessagePDUL(TInt& aIndex,CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms) |
|
492 { |
|
493 LOGSMSPROT1("CReassemblyStore::NewMessagePDUL"); |
|
494 |
|
495 if (aSmsMessage.Time() >= iLastRealTime) |
|
496 { |
|
497 iLastRealTime=aSmsMessage.Time(); |
|
498 if(iLastReceivedTime >= aSmsMessage.Time()) |
|
499 { |
|
500 aSmsMessage.SetTime(iLastReceivedTime+(TTimeIntervalMicroSeconds32)1); |
|
501 } |
|
502 iLastReceivedTime=aSmsMessage.Time(); //provide uniqueness of time |
|
503 } |
|
504 else // clock turned back |
|
505 { |
|
506 iLastReceivedTime=aSmsMessage.Time(); |
|
507 } |
|
508 |
|
509 TReassemblyEntry entry; |
|
510 CReassemblyStoreUtility::PopulateEntry(entry,aSmsMessage,1); |
|
511 BeginTransactionLC(); |
|
512 AddNewMessageL(aSmsMessage, aGsmSms); |
|
513 CommitTransactionL(); |
|
514 //Successfully added so add the entry in entry array. |
|
515 aIndex = iEntryArray.Count(); |
|
516 iEntryArray.AppendL(entry); |
|
517 } |
|
518 |
|
519 /** |
|
520 It adds a new message segment to the existing message in reassembly store & returns |
|
521 whether this segment makes this message complete or not. It also returns whether this |
|
522 segment is the duplicate one or not. |
|
523 |
|
524 @param aSmsMessage a reference to the SMS message. |
|
525 It acts as input. |
|
526 |
|
527 @param aGsmSms a reference to GsmSms object which contain actual PDU. |
|
528 It acts as input. |
|
529 |
|
530 @param aIndex value indicating the index of the message added to re-assembly store. |
|
531 It acts as output. |
|
532 |
|
533 @param aIsComplete Boolean value indicating whether the message is complete or not. |
|
534 It acts as output. |
|
535 |
|
536 @param aDuplicateMsgRef Boolean value indicating whether the added segment is a duplicate one or not. |
|
537 It acts as output. |
|
538 |
|
539 @param aDuplicateSlot Boolean value indicating whether the added segment is from duplicate slot or not. |
|
540 It acts as output. |
|
541 |
|
542 @internalComponent |
|
543 */ |
|
544 void CReassemblyStore::UpdateExistingMessageL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms, |
|
545 TInt aIndex, TBool& aIsComplete, |
|
546 TBool& aDuplicateMsgRef, TBool& aDuplicateSlot) |
|
547 { |
|
548 LOGSMSPROT1("CReassemblyStore::UpdateExistingMessageL"); |
|
549 aIsComplete = EFalse; |
|
550 BeginTransactionLC(); |
|
551 UpdateExistingMessageL(aSmsMessage, aGsmSms, aDuplicateMsgRef, aDuplicateSlot); |
|
552 CommitTransactionL(); |
|
553 if ((aDuplicateMsgRef == EFalse) && (aDuplicateSlot==EFalse)) |
|
554 { |
|
555 iEntryArray[aIndex].SetCount(iEntryArray[aIndex].Count() + 1); |
|
556 if (iEntryArray[aIndex].IsComplete()) |
|
557 { |
|
558 aIsComplete = ETrue; |
|
559 } |
|
560 } |
|
561 } |
|
562 |
|
563 /** |
|
564 It matches the passed message in re-assembly store & returns the index. |
|
565 |
|
566 @param aSmsMessage a reference to the SMS message. |
|
567 It acts as input. |
|
568 |
|
569 @param aIndex index number of message in re-assembly store. |
|
570 It acts as input. |
|
571 |
|
572 @internalComponent |
|
573 */ |
|
574 void CReassemblyStore::MatchPDUToExistingMessage(const CSmsMessage& aSmsMessage, |
|
575 TInt& aIndex) |
|
576 { |
|
577 LOGSMSPROT1("CReassemblyStore::MatchPDUToExistingMessage()"); |
|
578 |
|
579 aIndex = KErrNotFound; |
|
580 |
|
581 TGsmSmsTelNumber parsedAddress; |
|
582 aSmsMessage.ParsedToFromAddress(parsedAddress); |
|
583 |
|
584 // |
|
585 // Search the reassembly store for a matching entry (start from the |
|
586 // end as the most recent PDUs appear at the end)... |
|
587 // |
|
588 TInt reassemblyCount = iEntryArray.Count(); |
|
589 |
|
590 for (TInt index = 0; index < reassemblyCount; index++) |
|
591 { |
|
592 TReassemblyEntry& entry = iEntryArray[index]; |
|
593 // Always check the fields in order of the quickest to check... |
|
594 if (entry.IsComplete() == EFalse && |
|
595 entry.PduType() == aSmsMessage.Type() && |
|
596 entry.Storage() == aSmsMessage.Storage()) |
|
597 { |
|
598 TInt telLen = Min(entry.Description2().Length(), |
|
599 parsedAddress.iTelNumber.Length()); |
|
600 |
|
601 if (entry.Description2().Right(telLen) == parsedAddress.iTelNumber.Right(telLen) && |
|
602 entry.Total() == aSmsMessage.SmsPDU().NumConcatenatedMessagePDUs() && |
|
603 entry.Reference() == aSmsMessage.SmsPDU().ConcatenatedMessageReference()) |
|
604 { |
|
605 // |
|
606 // Found it! |
|
607 // |
|
608 aIndex = index; |
|
609 break; |
|
610 } |
|
611 } |
|
612 } |
|
613 |
|
614 LOGSMSPROT3("CReassemblyStore::MatchPDUToExistingMessage(): reassemblyCount=%d, aIndex=%d", reassemblyCount, aIndex); |
|
615 } // CReassemblyStore::MatchPDUToExistingMessage |
|
616 |
|
617 /** |
|
618 It retrieves the message from re-assembly store. |
|
619 |
|
620 @param aIndex index number of message in re-assembly store. |
|
621 It acts as input. |
|
622 |
|
623 @param aSmsMessage a reference to the SMS message. |
|
624 It acts as output. |
|
625 |
|
626 @internalComponent |
|
627 */ |
|
628 void CReassemblyStore::GetMessageL(TInt aIndex, CSmsMessage& aSmsMessage) |
|
629 { |
|
630 LOGSMSPROT1("CReassemblyStore::GetMessageL()"); |
|
631 const TReassemblyEntry& entry = iEntryArray[aIndex]; |
|
632 RetrieveMessageL(entry, aSmsMessage); |
|
633 } |
|
634 |
|
635 /** |
|
636 * Searches the reassembly store for a CSmsMessage with aPassed value (indicates if we |
|
637 * are searching for a message already passed to client) and returns its index. |
|
638 * |
|
639 * @param aSmsMessage Message to search for. |
|
640 * @param aPassed Determines if we are searching for a message already |
|
641 * passed to the client. |
|
642 * @param aIndex Return index value. |
|
643 * |
|
644 * @return True and an index if aSmsMessage is found in this reassembly store |
|
645 */ |
|
646 TBool CReassemblyStore::FindMessageL(const CSmsMessage& aSmsMessage, |
|
647 TBool aPassed, |
|
648 TInt& aIndex) |
|
649 { |
|
650 LOGSMSPROT1("CReassemblyStore::FindMessageL()"); |
|
651 |
|
652 // |
|
653 // Parse the GSM data from the SMS message... |
|
654 // |
|
655 TGsmSmsTelNumber parsedAddress; |
|
656 |
|
657 aSmsMessage.ParsedToFromAddress(parsedAddress); |
|
658 |
|
659 // |
|
660 // Search the store for a matching message... |
|
661 // |
|
662 for (TInt index = iEntryArray.Count() - 1; index >= 0; index--) |
|
663 { |
|
664 const TReassemblyEntry& entry = iEntryArray[index]; |
|
665 |
|
666 // Always search the basic types first and strings last! |
|
667 if (entry.PduType() == aSmsMessage.Type() && |
|
668 entry.PassedToClient() == aPassed && |
|
669 entry.Storage() == aSmsMessage.Storage() && |
|
670 entry.Time() == aSmsMessage.Time() && |
|
671 entry.Description2().Right(8) == parsedAddress.iTelNumber.Right(8)) |
|
672 { |
|
673 // |
|
674 // Found! |
|
675 // |
|
676 LOGSMSPROT2("CReassemblyStore::FindMessage(): Found! index=%d", index); |
|
677 |
|
678 aIndex = index; |
|
679 |
|
680 return ETrue; |
|
681 } |
|
682 } |
|
683 |
|
684 // |
|
685 // Not found... |
|
686 // |
|
687 LOGSMSPROT1("CReassemblyStore::FindMessage(): Not found!"); |
|
688 |
|
689 return EFalse; |
|
690 } // CReassemblyStore::FindMessageL |