--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/smsprotocols/smsstack/smsprot/Src/smspreassemblystore.cpp Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,690 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "smsstacklog.h"
+#include "gsmubuf.h"
+#include "smspreassemblystore.h"
+
+/**
+ * Populate entry information from sms message.
+ * @param aEntry fills up re-assembly entry information from aSmsMessage.
+ * @param aSmsMessage refernce to sms message.
+ * @param aNumSmss number of sms.
+ */
+void CReassemblyStoreUtility::PopulateEntry(TSmsReassemblyEntry& aEntry,const CSmsMessage& aSmsMessage,TInt aNumSmss)
+ {
+ LOGSMSPROT1("CReassemblyStoreUtility::PopulateEntry");
+ aEntry.SetReference(0);
+ aEntry.SetTotal(1);
+ aEntry.SetCount(1);
+
+ if (aSmsMessage.TextPresent())
+ {
+ if (aSmsMessage.SmsPDU().TextConcatenated())
+ {
+ aEntry.SetReference(aSmsMessage.SmsPDU().ConcatenatedMessageReference());
+ aEntry.SetTotal(aSmsMessage.SmsPDU().NumConcatenatedMessagePDUs());
+ aEntry.SetCount(aSmsMessage.IsComplete()? aEntry.Total(): aNumSmss);
+ }
+ TInt bits7to4=aSmsMessage.SmsPDU().Bits7To4();
+ TInt count=aSmsMessage.SmsPDU().UserData().NumInformationElements();
+ TInt identifier1=0xFF;
+ TInt identifier2=0x00;
+ for (TInt i=0; i<count; i++)
+ {
+ TInt identifier=aSmsMessage.SmsPDU().UserData().InformationElement(i).Identifier();
+ if ((identifier!=CSmsInformationElement::ESmsIEIConcatenatedShortMessages8BitReference) && (identifier!=CSmsInformationElement::ESmsIEIConcatenatedShortMessages16BitReference))
+ {
+ if (identifier<identifier1)
+ identifier1=identifier;
+ if (identifier>identifier2)
+ identifier2=identifier;
+ }
+ }
+
+ if ((bits7to4>=TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage) && (bits7to4<=TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationUCS2))
+ aEntry.SetBits7to4andIdentifiers(bits7to4, identifier1, identifier2);
+ else
+ aEntry.SetBits7to4andIdentifiers(0, identifier1, identifier2);
+ }
+
+ //Set the logServerId to aSmsMessage.LogServerId()
+
+ aEntry.SetLogServerId(aSmsMessage.LogServerId());
+
+ const CSmsPDU::TSmsPDUType type(aSmsMessage.Type());
+ aEntry.SetPduType(type);
+ aEntry.SetPassedToClient(EFalse);
+
+ aEntry.SetStorage(aSmsMessage.Storage());
+ if ((type!=CSmsPDU::ESmsSubmitReport) && (type!=CSmsPDU::ESmsDeliverReport))
+ {
+ // Strip out spaces etc from address
+ TGsmSmsTelNumber parsedaddress;
+ aSmsMessage.ParsedToFromAddress(parsedaddress);
+ aEntry.SetDescription2(parsedaddress.iTelNumber);
+ }
+
+ aEntry.SetTime(aSmsMessage.Time());
+ }
+
+/**
+ * Returns the private path of the component.
+ * @param aFs File Server handle.
+ * @param aPath (retrurns) private path of the component.
+ */
+void CReassemblyStoreUtility::PrivatePath(RFs& aFs, TDes& aPath)
+ {
+ LOGSMSPROT1("CReassemblyStoreUtility::PrivatePath()");
+
+ TDriveUnit driveUnit(KStoreDrive);
+ TDriveName drive=driveUnit.Name();
+ aPath.Insert(0, drive);
+ //append private path
+ TPath privatePath;
+ aFs.PrivatePath(privatePath);
+ aPath.Append(privatePath);
+ aPath.Append(KStoreSubDir);
+ } // CReassemblyStoreUtility::PrivatePath
+
+/**
+ * Constructor.
+*/
+CReassemblyStore::CReassemblyStore(RFs& aFs) : iFs(aFs), iEntryArray(KFlatArrayGranularity)
+ {
+ iLastReceivedTime.UniversalTime();
+ iLastRealTime = iLastReceivedTime;
+ }
+
+/**
+ * Destructor.
+*/
+CReassemblyStore::~CReassemblyStore()
+ {
+ iEntryArray.Reset();
+ }
+
+/**
+It cleans up the re-assembly store.
+This function will be called to allow re-assembly store to initialize/clean-up
+
+@internalComponent
+*/
+void CReassemblyStore::InitializeL()
+ {
+ LOGSMSPROT1("CClass0SmsReassemblyStore::InitializeL()");
+ // Initialize Re-assembly store.
+ OpenStoreL();
+ BeginTransactionLC();
+ TInt count = iEntryArray.Count();
+ while (count--)
+ {
+ TReassemblyEntry entry= iEntryArray[count];
+ if ((entry.Storage() == CSmsMessage::ESmsSIMStorage) || (entry.Storage() == CSmsMessage::ESmsCombinedStorage))
+ {
+ DeleteEntryL(entry);
+ }
+ else
+ {
+ SetPassedToClientL(entry, EFalse);
+ }
+ }
+ CommitTransactionL();
+ Close();
+ }
+
+/**
+ * Purges the reassembly file store.
+ *
+ * After a multipart message, it delete all the old entries.
+ *
+ * Entries will be purged when: 1) The complete message is received; 2) After
+ * aTimerintervalMinutes, if aPurgeIncompletely is false.
+ *
+ * PurgeL() will be called after the booting of the device or when a message
+ * has been received.
+ *
+ * This function opens and closes the file automatically.
+ *
+ *
+ * @param aTimeIntervalMinutes Purge time
+ * @param aPurgeIncompleteOnly Purge complete messages flag
+ */
+void CReassemblyStore::PurgeL(const TTimeIntervalMinutes& aTimeIntervalMinutes,TBool aPurgeIncompleteOnly)
+ {
+ //Call purging function
+ LOGSMSPROT3("CReassemblyStore::PurgeL(): aTimeIntervalMinutes=%d, aPurgeIncompleteOnly=%d",
+ aTimeIntervalMinutes.Int(), aPurgeIncompleteOnly);
+
+ // TODO - flag
+ // we could also save the call of the method from the consruction of the smsprot
+ if( aPurgeIncompleteOnly )
+ return;
+
+ TInt count=iEntryArray.Count();
+ LOGSMSPROT2("CClass0SmsReassemblyStore::PurgeL(): count=%d", count);
+
+ TTime time;
+ time.UniversalTime();
+
+ // we open the file outside the loop
+ // to save some CPU
+ BeginTransactionLC();
+ for (TInt i=count-1; i>=0; i--)
+ {
+ //TReassemblyEntry entry=iEntryArray[i];
+ if (time > (iEntryArray[i].Time()+aTimeIntervalMinutes))
+ // TODO - flag
+ // check the logic o the aPurgeIncompleteOnly flg
+ // don't purge the store if the entry is complete
+ // entry.IsComplete() )
+ {
+ DeleteEntryL(iEntryArray[i]);
+ }
+ }
+ CommitTransactionL();
+
+ PopulateEntryArrayL(iEntryArray);
+ }
+
+/**
+It deletes all the enumerated SIM messages stored in re-assembly store.
+This function will be called if user choses to cancel the enumeration.
+
+@internalComponent
+*/
+void CReassemblyStore::DeleteEnumeratedSIMEntries()
+ {
+ const TInt count = iEntryArray.Count();
+
+ LOGSMSPROT2("CReassemblyStore::DeleteEnumeratedSIMEntries(): %d messages in RAS", count);
+
+ TInt index;
+
+ for (index = count-1; index >= 0; --index)
+ {
+ TReassemblyEntry entry = iEntryArray[index];
+
+ if (entry.Storage()==CSmsMessage::ESmsSIMStorage)
+ {
+ TRAP_IGNORE(BeginTransactionLC();
+ DeleteEntryL(entry);
+ CommitTransactionL();
+ iEntryArray.Delete(index));
+ }
+ }
+ }
+
+/**
+It returns the number of complete messages in reassembly store.
+
+@internalComponent
+*/
+TInt CReassemblyStore::NumberOfCompleteMessages()
+ {
+ LOGSMSPROT2("CReassemblyStore::NumberOfCompleteMessages(): iEntryArray.Count()=%d",
+ iEntryArray.Count());
+
+ //local variable for complete entries
+ TInt count( 0 );
+ // checks all entrys in the reassembly store
+ for ( TInt i = iEntryArray.Count()-1; i >= 0; i-- )
+ {
+ // checks if entry is completed
+ if ( iEntryArray[i].IsComplete() )
+ {
+ ++count;
+ }
+ }
+ return count;
+ }
+
+/**
+It adds the message segment to the reassembly store. There are 5 possiblities:
+
+1) This is the single segment message.
+We therefore have all the segments.
+2) This is a duplicate message segment.
+We will ignore it.
+3) This is the last segment in the message required to complete it.
+The other segments are already stored.
+4) This is another PDU to an existing message in the store, but it is
+not yet complete.
+5) This is the first PDU in the message, and therefore the message is
+not yet complete and no segments are stored.
+
+@note Only SUBMIT or DELIVER PDUs can be added to the reassembly store.
+
+@param aSmsMessage a reference to the SMS message.
+ It acts both as input & output. If the message is complete, it contains the decoded message.
+ Otherwise it contains the received message with few properties set (LogServerId, Time).
+
+@param aGsmSms a reference to GsmSms object which contain actual PDU.
+ It acts as input.
+
+@param aIsComplete Boolean value indicating whether the message is complete or not.
+ It acts both as input & output.
+
+@param aIsEnumeration Boolean value indicating whether the function is called at the time of enumeration.
+ It acts as only input.
+
+@param aCount value indicating the number of current PDUs in the re-assembly store for the given SMS message.
+ It acts as only output.
+
+@param aTotal value indicating the total number of PDUs in the re-assembly store for the given SMS message.
+ It acts as only output.
+
+@internalComponent
+*/
+void CReassemblyStore::AddSegmentToReassemblyStoreL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms, TInt& aIndex, TBool& aIsComplete, TBool aIsEnumeration, TInt& aCount, TInt& aTotal)
+ {
+ LOGSMSPROT2("CReassemblyStore::AddSegmentToReassemblyStoreL(): isComplete Message=%d",
+ aSmsMessage.IsComplete());
+
+ /*
+ (1) If it is a single segment message create a new message
+ (2) If it is part of concatenated message find whether this is the first PDU
+ or it is the part of existing message.
+ If it is a new message then create new one.
+ If it is part of existing message, then check duplication (CheckDuplication()).
+ If it is a duplicate, return. Otherwise update the reassembly store.
+ */
+
+ if (aIsComplete || aSmsMessage.Type() == CSmsPDU::ESmsStatusReport)
+ {
+ //
+ // 1) This is the complete message (e.g. a single-segment message).
+ // We therefore have all the segments.
+ //
+ // Create the new message in the reassembly store. This is incase the
+ // power fails before the client gets it (note that it will be ack'd
+ // before passed to the client) so keeping it in memory is not
+ // acceptable...
+ //
+ NewMessagePDUL(aIndex, aSmsMessage, aGsmSms);
+ }
+ else
+ {
+ //
+ // If not yet complete, then we must be part of a multiple PDU message.
+ // Search the reassembly store for existing parts of the message.
+ //
+ TInt segStoreIndex(KErrNotFound);
+
+ MatchPDUToExistingMessage(aSmsMessage, segStoreIndex);
+ LOGSMSPROT2("CSmsReassemblyStore::AddSegmentToReassemblyStoreL(): "
+ "segStoreIndex=%d", segStoreIndex);
+
+ //
+ // If not yet complete, then we must be part of a multiple PDU message.
+ // Search the reassembly store for existing parts of the message. This
+ // may set iIsComplete to true if all segments are then found.
+ //
+ if (segStoreIndex != KErrNotFound)
+ {
+ TBool isDuplicateSlot(EFalse);
+ TBool isDuplicateMsgRef(EFalse);
+ //
+ // So we found a related part of the message, add this message to the
+ // store...
+ //
+ aIndex = segStoreIndex;
+ UpdateExistingMessageL(aSmsMessage, aGsmSms, aIndex,
+ aIsComplete, isDuplicateMsgRef,
+ isDuplicateSlot);
+ LOGSMSPROT5("CSmsReassemblyStore::AddSegmentToReassemblyStoreL(): "
+ "aIndex=%d, isComplete=%d, isDuplicateMsgRef=%d, isDuplicateSlot=%d",
+ aIndex, aIsComplete, isDuplicateMsgRef, isDuplicateSlot);
+
+ if (isDuplicateMsgRef)
+ {
+ //
+ // In most cases discard it, unless we are doing an enumeration???
+ //
+ if (aIsEnumeration)
+ {
+ NewMessagePDUL(aIndex, aSmsMessage, aGsmSms);
+ }
+ }
+ else if (aIsComplete)
+ {
+ //
+ // 3) This is the last segment in the message required to complete it.
+ // The other segments are already stored.
+ //
+ // Load the complete message into memory for futher processing.
+ //
+ GetMessageL(aIndex, aSmsMessage);
+ }
+ else
+ {
+ //
+ // 4) This is another PDU to an existing message in the store, but it is
+ // not yet complete.
+ //
+ // Update the this segment with the timestamp of the original message.
+ //
+ CSmsBuffer* buffer = CSmsBuffer::NewL();
+ CSmsMessage* firstMessagePdu = CSmsMessage::NewL(iFs,
+ CSmsPDU::ESmsDeliver, buffer);
+ CleanupStack::PushL(firstMessagePdu);
+ GetMessageL(aIndex, *firstMessagePdu);
+ aSmsMessage.SetUTCOffset(firstMessagePdu->UTCOffset());
+ CleanupStack::PopAndDestroy(firstMessagePdu);
+ }
+ }
+ else
+ {
+ //
+ // 5) This is the first PDU in the message, and therefore the message is
+ // not yet complete and no segments are stored.
+ //
+ // The entry needs to be added to the reassembly store as a new entry.
+ //
+ NewMessagePDUL(aIndex, aSmsMessage, aGsmSms);
+ }
+ }
+
+ const TReassemblyEntry& entry = iEntryArray[aIndex];
+ aCount = entry.Count();
+ aTotal = entry.Total();
+ }
+
+/**
+It deletes the given SMS message from re-assembly store.
+
+@param aSmsMessage Message to delete.
+@param aPassed Determines if we are searching for a message already
+ passed to the client.
+
+@internalComponent
+*/
+void CReassemblyStore::DeleteMessageL(const CSmsMessage& aSmsMessage, TBool aPassed)
+ {
+ LOGSMSPROT1("CReassemblyStore::DeleteMessageL()");
+ TInt index(0);
+ BeginTransactionLC();
+ if (FindMessageL(aSmsMessage, aPassed, index))
+ {
+ const TReassemblyEntry& entry = iEntryArray[index];
+ DeleteEntryL(entry);
+ iEntryArray.Delete(index);
+ }
+ CommitTransactionL();
+ }
+
+/**
+It updates log server id of the passed message in re-assembly store.
+
+@param aSmsMessage a reference to a message.
+@param aIndex index number of sms message to be updated.
+
+@internalComponent
+*/
+void CReassemblyStore::UpdateLogServerIdOfMessageL(const CSmsMessage& aSmsMessage, TInt aIndex)
+ {
+ LOGSMSPROT1("CReassemblyStore::UpdateLogServerIdOfMessageL()");
+ TInt foundIndex(KErrNotFound);
+ TBool found(EFalse);
+
+ BeginTransactionLC();
+
+ found = FindMessageL(aSmsMessage , EFalse, foundIndex);
+ if (found && (aIndex == foundIndex))
+ {
+ const TReassemblyEntry& entry = iEntryArray[foundIndex];
+ UpdateLogServerIdL(entry, aSmsMessage.LogServerId());
+ iEntryArray[foundIndex].SetLogServerId(aSmsMessage.LogServerId());
+ }
+ CommitTransactionL();
+ }
+
+/**
+It updates that the given SMS message in re-assembly store is passed to client.
+
+@param aSmsMessage Message which is passed to client.
+
+@internalComponent
+*/
+void CReassemblyStore::SetMessagePassedToClientL(const CSmsMessage& aSmsMessage, TBool aPassed)
+ {
+ LOGSMSPROT1("CReassemblyStore::SetMessagePassedToClientL()");
+ TInt index(0);
+
+ BeginTransactionLC();
+
+ if (FindMessageL(aSmsMessage , !aPassed, index))
+ {
+ const TReassemblyEntry& entry = iEntryArray[index];
+ SetPassedToClientL(entry, aPassed);
+ iEntryArray[index].SetPassedToClient(aPassed);
+ }
+ CommitTransactionL();
+ }
+
+/**
+It adds a new message segment to the reassembly store and it returns an index to the message.
+
+@param aIndex value indicating the index of the message added to re-assembly store.
+ It acts as output.
+
+@param aSmsMessage a reference to the SMS message.
+ It acts as input.
+
+@param aGsmSms a reference to GsmSms object which contain actual PDU.
+ It acts as input.
+
+@internalComponent
+*/
+void CReassemblyStore::NewMessagePDUL(TInt& aIndex,CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms)
+ {
+ LOGSMSPROT1("CReassemblyStore::NewMessagePDUL");
+
+ if (aSmsMessage.Time() >= iLastRealTime)
+ {
+ iLastRealTime=aSmsMessage.Time();
+ if(iLastReceivedTime >= aSmsMessage.Time())
+ {
+ aSmsMessage.SetTime(iLastReceivedTime+(TTimeIntervalMicroSeconds32)1);
+ }
+ iLastReceivedTime=aSmsMessage.Time(); //provide uniqueness of time
+ }
+ else // clock turned back
+ {
+ iLastReceivedTime=aSmsMessage.Time();
+ }
+
+ TReassemblyEntry entry;
+ CReassemblyStoreUtility::PopulateEntry(entry,aSmsMessage,1);
+ BeginTransactionLC();
+ AddNewMessageL(aSmsMessage, aGsmSms);
+ CommitTransactionL();
+ //Successfully added so add the entry in entry array.
+ aIndex = iEntryArray.Count();
+ iEntryArray.AppendL(entry);
+ }
+
+/**
+It adds a new message segment to the existing message in reassembly store & returns
+whether this segment makes this message complete or not. It also returns whether this
+segment is the duplicate one or not.
+
+@param aSmsMessage a reference to the SMS message.
+ It acts as input.
+
+@param aGsmSms a reference to GsmSms object which contain actual PDU.
+ It acts as input.
+
+@param aIndex value indicating the index of the message added to re-assembly store.
+ It acts as output.
+
+@param aIsComplete Boolean value indicating whether the message is complete or not.
+ It acts as output.
+
+@param aDuplicateMsgRef Boolean value indicating whether the added segment is a duplicate one or not.
+ It acts as output.
+
+@param aDuplicateSlot Boolean value indicating whether the added segment is from duplicate slot or not.
+ It acts as output.
+
+@internalComponent
+*/
+void CReassemblyStore::UpdateExistingMessageL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms,
+ TInt aIndex, TBool& aIsComplete,
+ TBool& aDuplicateMsgRef, TBool& aDuplicateSlot)
+ {
+ LOGSMSPROT1("CReassemblyStore::UpdateExistingMessageL");
+ aIsComplete = EFalse;
+ BeginTransactionLC();
+ UpdateExistingMessageL(aSmsMessage, aGsmSms, aDuplicateMsgRef, aDuplicateSlot);
+ CommitTransactionL();
+ if ((aDuplicateMsgRef == EFalse) && (aDuplicateSlot==EFalse))
+ {
+ iEntryArray[aIndex].SetCount(iEntryArray[aIndex].Count() + 1);
+ if (iEntryArray[aIndex].IsComplete())
+ {
+ aIsComplete = ETrue;
+ }
+ }
+ }
+
+/**
+It matches the passed message in re-assembly store & returns the index.
+
+@param aSmsMessage a reference to the SMS message.
+ It acts as input.
+
+@param aIndex index number of message in re-assembly store.
+ It acts as input.
+
+@internalComponent
+*/
+void CReassemblyStore::MatchPDUToExistingMessage(const CSmsMessage& aSmsMessage,
+ TInt& aIndex)
+ {
+ LOGSMSPROT1("CReassemblyStore::MatchPDUToExistingMessage()");
+
+ aIndex = KErrNotFound;
+
+ TGsmSmsTelNumber parsedAddress;
+ aSmsMessage.ParsedToFromAddress(parsedAddress);
+
+ //
+ // Search the reassembly store for a matching entry (start from the
+ // end as the most recent PDUs appear at the end)...
+ //
+ TInt reassemblyCount = iEntryArray.Count();
+
+ for (TInt index = 0; index < reassemblyCount; index++)
+ {
+ TReassemblyEntry& entry = iEntryArray[index];
+ // Always check the fields in order of the quickest to check...
+ if (entry.IsComplete() == EFalse &&
+ entry.PduType() == aSmsMessage.Type() &&
+ entry.Storage() == aSmsMessage.Storage())
+ {
+ TInt telLen = Min(entry.Description2().Length(),
+ parsedAddress.iTelNumber.Length());
+
+ if (entry.Description2().Right(telLen) == parsedAddress.iTelNumber.Right(telLen) &&
+ entry.Total() == aSmsMessage.SmsPDU().NumConcatenatedMessagePDUs() &&
+ entry.Reference() == aSmsMessage.SmsPDU().ConcatenatedMessageReference())
+ {
+ //
+ // Found it!
+ //
+ aIndex = index;
+ break;
+ }
+ }
+ }
+
+ LOGSMSPROT3("CReassemblyStore::MatchPDUToExistingMessage(): reassemblyCount=%d, aIndex=%d", reassemblyCount, aIndex);
+ } // CReassemblyStore::MatchPDUToExistingMessage
+
+/**
+It retrieves the message from re-assembly store.
+
+@param aIndex index number of message in re-assembly store.
+ It acts as input.
+
+@param aSmsMessage a reference to the SMS message.
+ It acts as output.
+
+@internalComponent
+*/
+void CReassemblyStore::GetMessageL(TInt aIndex, CSmsMessage& aSmsMessage)
+ {
+ LOGSMSPROT1("CReassemblyStore::GetMessageL()");
+ const TReassemblyEntry& entry = iEntryArray[aIndex];
+ RetrieveMessageL(entry, aSmsMessage);
+ }
+
+/**
+ * Searches the reassembly store for a CSmsMessage with aPassed value (indicates if we
+ * are searching for a message already passed to client) and returns its index.
+ *
+ * @param aSmsMessage Message to search for.
+ * @param aPassed Determines if we are searching for a message already
+ * passed to the client.
+ * @param aIndex Return index value.
+ *
+ * @return True and an index if aSmsMessage is found in this reassembly store
+ */
+TBool CReassemblyStore::FindMessageL(const CSmsMessage& aSmsMessage,
+ TBool aPassed,
+ TInt& aIndex)
+ {
+ LOGSMSPROT1("CReassemblyStore::FindMessageL()");
+
+ //
+ // Parse the GSM data from the SMS message...
+ //
+ TGsmSmsTelNumber parsedAddress;
+
+ aSmsMessage.ParsedToFromAddress(parsedAddress);
+
+ //
+ // Search the store for a matching message...
+ //
+ for (TInt index = iEntryArray.Count() - 1; index >= 0; index--)
+ {
+ const TReassemblyEntry& entry = iEntryArray[index];
+
+ // Always search the basic types first and strings last!
+ if (entry.PduType() == aSmsMessage.Type() &&
+ entry.PassedToClient() == aPassed &&
+ entry.Storage() == aSmsMessage.Storage() &&
+ entry.Time() == aSmsMessage.Time() &&
+ entry.Description2().Right(8) == parsedAddress.iTelNumber.Right(8))
+ {
+ //
+ // Found!
+ //
+ LOGSMSPROT2("CReassemblyStore::FindMessage(): Found! index=%d", index);
+
+ aIndex = index;
+
+ return ETrue;
+ }
+ }
+
+ //
+ // Not found...
+ //
+ LOGSMSPROT1("CReassemblyStore::FindMessage(): Not found!");
+
+ return EFalse;
+ } // CReassemblyStore::FindMessageL