--- a/smsprotocols/smsstack/smsprot/Src/smspfacadestor.cpp Mon May 03 13:37:20 2010 +0300
+++ b/smsprotocols/smsstack/smsprot/Src/smspfacadestor.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,1075 +1,1075 @@
-// 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 "gsmubuf.h"
-#include "smspfacadestor.h"
-
-/**
-Static factory constructor. Uses two phase
-construction and leaves nothing on the CleanupStack.
-
-@internalComponent
-
-@return A pointer to the newly created CFacadeSmsReassemblyStore object.
-@param aFs File Server handle.
-@param aSmsComm Notification Event Reference.
-@leave KErrNoMemory
-
-@pre A connected file server session must be passed as parameter.
-@post CFacadeSmsReassemblyStore object is now fully initialised
-*/
-CFacadeSmsReassemblyStore* CFacadeSmsReassemblyStore::NewL(RFs& aFs, MSmsComm& aSmsComm)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::NewL()");
-
- CFacadeSmsReassemblyStore* self = new (ELeave) CFacadeSmsReassemblyStore(aFs, aSmsComm);
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop(self);
-
- return self;
- }
-
-/**
- * Constructor.
-*/
-CFacadeSmsReassemblyStore::CFacadeSmsReassemblyStore(RFs& aFs, MSmsComm& aSmsComm)
- :iFs(aFs), iSmsComm(aSmsComm), iReassemblyStore(NULL), iClass0ReassemblyStore(NULL)
- {
- // NOP
- }
-
-/**
- * Destructor. It destroys all the member variables.
-*/
-CFacadeSmsReassemblyStore::~CFacadeSmsReassemblyStore()
- {
- LOGSMSPROT1("~CFacadeSmsReassemblyStore()");
- iReassemblyStore->Close();
- delete iReassemblyStore;
-
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->Close();
- delete iClass0ReassemblyStore;
- }
- }
-
-/**
-Second Phase construction. It creates re-assembly stores. If SMS stack is configured
-for handling class 0 messages in out-of-disk condition. It creates class 0
-& non-class 0 re-assembly store. Otherwise it creates only one re-assembly store
-which will be used to store all type of SMS messages.
-
-@internalComponent
-
-@leave KErrNoMemory
-
-@pre A connected file server session must be passed as parameter.
-@post CFacadeSmsReassemblyStore object is now fully constructed.
-*/
-void CFacadeSmsReassemblyStore::ConstructL()
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::ConstructL()");
-
- iReassemblyStore = CSmsReassemblyStore::NewL(iFs);
- /*
- Read [ReassemblyStore] section from smswap.sms.esk file. If section is absent then there is
- no need to create class 0 re-assembly store. This sms stack is configured to work
- as before (class 0 message will be -vely ack in out-of-disk condition).
- If ReassemblyStore section is present then read the value of Class0.
- If the value of Class0 is 1. Then create class 0 re-assembly store object.
- For example:
- [ReassemblyStore]
- Class0= 1
- MaxClass0Messages=10
- NumberOfPDUSegements=20
- GuardTimeOut=12
- */
- CESockIniData* ini = NULL;
- ini=CESockIniData::NewL(_L("smswap.sms.esk"));
- CleanupStack::PushL(ini);
- TBool status(EFalse);
- if (ini->FindVar(_L("ReassemblyStore"), _L("Class0"), status))
- {
- if (status)
- {
- iClass0ReassemblyStore = CClass0SmsReassemblyStore::NewL(iFs, iSmsComm);
- }
- }
-
- // Set the default value for iMaxmumNumberOfCompleteMessagesInReassemblyStore.
- iMaxmumNumberOfCompleteMessagesInReassemblyStore = KDefaultMaxmumNumberOfCompleteMessagesInReassemblyStore;
- // Load up the user configurable setting for the maximum number of complete messages in
- // the reassembly store.
- TPtrC value;
- if((ini->FindVar(_L("ReasmemblyStoreOptions"),_L("MaxNumOfComMessInReStore"),value)))
- {
- TLex16 valueconv(value);
- valueconv.Val(iMaxmumNumberOfCompleteMessagesInReassemblyStore);
- }
-
- CleanupStack::PopAndDestroy(ini);
- }
-
-/**
-It open the re-assembly stores.
-This function needs to be called before doing any operations (add/delete/update) in the
-re-assembly stores.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::OpenStoreL()
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::OpenStoreL()");
- iReassemblyStore->OpenStoreL();
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->OpenStoreL();
- }
- }
-
-/**
-It closes the re-assembly stores.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::Close()
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::Close()");
- // Close general Re-assembly store.
- iReassemblyStore->Close();
- // Close Class0 re-assembly store.
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->Close();
- }
- }
-
-/**
-It returns the file session.
-
-@internalComponent
-
-@return returns the file session.
-*/
-RFs& CFacadeSmsReassemblyStore::FileSession() const
- {
- return iFs;
- }
-
-/**
-It initializes the re-assembly store.
-It goes through all the entries in re-assembly store. It updates its header information.
-If any sms message is either SIM based or combined storage based then it is deleted from re-assembly store.
-For other type of SMS messages, its header info is updated to indicate that it is not passed to client.
-
-This initialization process is required because SMS stack might have been re-started.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::InitL()
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::InitL()");
- // Initialize Non-class 0 Re-assembly store.
- InitializeNonClass0StoreL();
- // Initialize Class0 re-assembly store.
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->InitializeL();
- }
- }
-
-/**
-Purges the reassembly file stores.
-
-@param aTimeIntervalMinutes Purge time
-@param aPurgeIncompleteOnly Purge complete messages flag
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::PurgeL(const TTimeIntervalMinutes& aTimeIntervalMinutes,TBool aPurgeIncompleteOnly)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::PurgeL()");
- iReassemblyStore->PurgeL(aTimeIntervalMinutes, aPurgeIncompleteOnly);
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->PurgeL(aTimeIntervalMinutes, aPurgeIncompleteOnly);
- }
- }
-
-/**
-It returns a boolean value indicating whether re-assembly store is full or not.
-If number of complete sms messages exceed the configured value (KMaxmumNumberOfCompleteMessagesInReassemblyStore),
-it return TRUE. Otherwise it returns FALSE.
-
-@internalComponent
-*/
-TBool CFacadeSmsReassemblyStore::IsFull()
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::IsFull()");
-
- //local variable for complete entries
- TInt count( 0 );
- count = NumberOfCompleteNonClass0Messages();
- if (iClass0ReassemblyStore)
- {
- count += iClass0ReassemblyStore->NumberOfCompleteMessages();
- }
- if (count > iMaxmumNumberOfCompleteMessagesInReassemblyStore)
- {
- return ETrue;
- }
- else
- {
- return EFalse;
- }
- }
-
-/**
-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 CFacadeSmsReassemblyStore::DeleteEnumeratedSIMEntries()
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::DeleteEnumeratedSIMEntries()");
- DeleteNonClass0EnumeratedSIMEntries();
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->DeleteEnumeratedSIMEntries();
- }
- }
-
-/**
-It externalizes all the enumerated messages.
-It goes through the re-assembly store and sends all those SMS messages
-(which is SIM/Combined storage based) to client (aSmsProvider).
-
-@param aSmsProvider a reference to a service access point.
-@param aCount number of sms messages enumerated.
-@return number of new segments.
-
-@internalComponent
-*/
-TInt CFacadeSmsReassemblyStore::ExternalizeEnumeratedMessagesL(CSmsProvider& aProvider,TInt& aCount)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::ExternalizeEnumeratedMessagesL()");
- TInt numNewSegments(0);
- numNewSegments = ExternalizeEnumeratedNonClass0SmsMessagesL(aProvider, aCount);
- if (iClass0ReassemblyStore)
- {
- numNewSegments += ExternalizeEnumeratedClass0SmsMessagesL(aProvider, aCount);
- }
- return numNewSegments;
- }
-
-/**
-It searches the reassembly store for complete messages and then it sends that
-message for further processing. It is called when a new observer is added or
-a PDU has been received and successfully processed.
-
-@param aSmsComm a reference to the protocol.
-@param aCurrentSmsMessage a pointer to current SMS message.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::ProcessCompleteSmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage* aCurrentSmsMessage)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::ProcessCompleteSmsMessagesL");
-
- ProcessCompleteNonClass0SmsMessagesL(aSmsComm, aCurrentSmsMessage);
- if (iClass0ReassemblyStore)
- {
- ProcessCompleteClass0SmsMessagesL(aSmsComm, aCurrentSmsMessage);
- }
- }
-
-/**
-It adds the message segment to the reassembly store.
-This function first checks on which re-assembly store the message should be stored and then add
-the message to appropriate re-assembly store.
-
-@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. At the time of function call it contains the message.
- When the function returns it contains full decoded message if it is complete.
- But in case of class 0 messages it might not contain complete class 0 messages.
-
-@param aGsmSms a reference to GsmSms object which contain actual PDU.
- It acts as pure input.
-
-@param aIsComplete boolean value indicating whether the message is complete or not.
- It acts both as input & output.
- In case of multi-segment message, the value of aIsComplete will be true when function returns
- if the added segment makes the messsage complete.
-
-@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 for the given sms message.
- It acts as only output.
-
-@internalComponent
-
-NOTE:
- When function returns, if the value of aIsComplete is True, then aSmsMesssage will contain the
- complete decoded SMS message.
- But the above statement might not be always true:
- In case of class 0 messages, it is possible to forward the incomplete messages. So after forwarding
- the incomplete message, if we receive other constituent PDU of that message then in that case we
- might receive all the constituent PDU of that message but aSmsMesssage will contain partial complete message.
- To find out complete/incompletness of the message, CSmsMessage::IsComplete() message function has to be called.
-*/
-void CFacadeSmsReassemblyStore::AddSegmentToReassemblyStoreL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms, TInt& aIndex, TBool& aIsComplete, TBool aIsEnumeration, TInt& aCount, TInt& aTotal)
- {
- LOGSMSPROT2("CFacadeSmsReassemblyStore::AddSegmentToReassemblyStoreL(): isComplete Message=%d",
- aSmsMessage.IsComplete());
-
- TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
-
- if (toBeStoredInClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->AddSegmentToReassemblyStoreL(aSmsMessage, aGsmSms, aIndex, aIsComplete, aIsEnumeration, aCount, aTotal);
- }
- else
- {
- AddSegmentToNonClass0ReassemblyStoreL(aSmsMessage, aGsmSms, aIndex, aIsComplete, aIsEnumeration, aCount, aTotal);
- }
- }
-
-/**
-It forwards the complete class 0 messages to client.
-NOTE:
- This function needs to be called only in case of class 0 messages.
-
-@param aSmsComm a reference to aSmsComm object which implemented the events.
-
-@param aSmsMessage a reference to sms message object. This sms message must be class 0 messages.
-
-@param aOriginalSmsAddr pointer to the address of the sender of a previously sent
-
-@param aOriginalSmsMessage pointer to a message previously sent matched to the received
- one (e.g. status report). Null if not matched.
-
-@param aDes user data for the deliver report acknowledging this message to the SC.
- Filled in by the observer.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::ForwardCompleteClass0SmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage& aSmsMessage,const TSmsAddr* aOriginalSmsAddr,const CSmsMessage* aOriginalSmsMessage,TDes& aDes)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::ForwardCompleteClass0SmsMessagesL");
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->ForwardCompleteClass0SmsMessagesL(aSmsComm, aSmsMessage, aOriginalSmsAddr, aOriginalSmsMessage, aDes);
- }
- }
-
-/**
-It frees the space by forwarding the class 0 message if class 0 re-assembly store
-exceeds limitation (max class 0 message, max reserved pdu segment).
-NOTE:
- This function needs to be called only in case of class 0 messages.
-
-@param aSmsComm a reference to aSmsComm object which implemented the events.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::ProcessMessageIfExceedLimitationL(MSmsComm& aSmsComm)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::ProcessMessageIfExceedLimitationL");
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->ProcessMessageIfExceedLimitationL(aSmsComm);
- }
- }
-
-/**
-It sets the incomplete messsage forwarded to client.
-Internally it frees up the memory by removing the forwarded PDUs and also it stores forwarded PDU index.
-
-NOTE:
- This function needs to be called only in case of class 0 messages.
-
-@param aSmsMessage a reference to sms message object. This sms message must be class 0 messages.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::SetIncompleteMessageForwardedToClientL(const CSmsMessage& aSmsMessage)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::SetIncompleteMessageForwardedToClientL()");
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->SetIncompleteMessageForwardedToClientL(aSmsMessage);
- }
- }
-
-/**
-It sets the disk space status.
-If disk space is full, then class 0 re-assembly store stores the incoming message in
-pre-allocated file. Otherwise it stores the message in permanent store file.
-*/
-void CFacadeSmsReassemblyStore::SetDiskSpaceState(TSmsDiskSpaceMonitorStatus aDiskSpaceStatus)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::SetDiskSpaceState()");
- if (iClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->SetDiskSpaceState(aDiskSpaceStatus);
- }
- }
-
-/**
-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 CFacadeSmsReassemblyStore::DeleteMessageL(const CSmsMessage& aSmsMessage, TBool aPassed)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::DeleteEntryL()");
-
- TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
-
- if (toBeStoredInClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->DeleteMessageL(aSmsMessage, aPassed);
- }
- else
- {
- DeleteNonClass0MessageL(aSmsMessage, aPassed);
- }
- }
-
-/**
-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 CFacadeSmsReassemblyStore::UpdateLogServerIdL(const CSmsMessage& aSmsMessage, TInt aIndex)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::UpdateLogServerIdL()");
-
- TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
-
- if (toBeStoredInClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->UpdateLogServerIdOfMessageL(aSmsMessage, aIndex);
- }
- else
- {
- UpdateLogServerIdOfNonClass0MessageL(aSmsMessage, aIndex);
- }
- }
-
-/**
-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 CFacadeSmsReassemblyStore::SetMessagePassedToClientL(const CSmsMessage& aSmsMessage, TBool aPassed)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::SetMessagePassedToClientL()");
-
- TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
-
- if (toBeStoredInClass0ReassemblyStore)
- {
- iClass0ReassemblyStore->SetMessagePassedToClientL(aSmsMessage, aPassed);
- }
- else
- {
- SetNonClass0MessagePassedToClientL(aSmsMessage, aPassed);
- }
- }
-
-/**
-Returns a boolean value indicating whether this class contains separate
-re-assembly store for class 0 message or not.
-
-@internalComponent
-*/
-TBool CFacadeSmsReassemblyStore::IsSeparateClass0StoreSupported()
- {
- if (iClass0ReassemblyStore)
- {
- return ETrue;
- }
- else
- {
- return EFalse;
- }
- }
-
-/**
-Returns a boolean value indicating where this SMS message will be stored.
-If it rerurns EFalse, message will be stored in normal re-assembly store,
-otherwise it will be stored in class 0 re-assembly store.
-
-@internalComponent
-*/
-TBool CFacadeSmsReassemblyStore::IsForClass0ReassemblyStore(const CSmsMessage& aSmsMessage)
- {
- if (iClass0ReassemblyStore == NULL)
- {
- return EFalse;
- }
-
- TSmsDataCodingScheme::TSmsClass msgClass;
-
- if (aSmsMessage.SmsPDU().DataCodingSchemePresent() && aSmsMessage.SmsPDU().Class(msgClass))
- {
- if (msgClass == TSmsDataCodingScheme::ESmsClass0)
- {
- //Check also whether it is a WAP Datagram
- // In that case return EFalse otherwise ETrue (REQ7012)
- if (!IsWapSMS(aSmsMessage))
- {
- return ETrue;
- }
- }
- }
- return EFalse;
- }
-
-/**
-It initializes the re-assembly store.
-It goes through all the entries in re-assembly store. It updates its header information.
-If any sms message is either SIM based or combined storage based then it is deleted from re-assembly store.
-For other type of SMS messages, its header info is updated to indicate that it is not passed to client.
-
-This initialization process is required because SMS stack might have been re-started.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::InitializeNonClass0StoreL()
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::InitializeNonClass0StoreL()");
- // Initialize Re-assembly store.
- iReassemblyStore->OpenStoreL();
- iReassemblyStore->BeginTransactionLC();
- TInt count = iReassemblyStore->Entries().Count();
- while (count--)
- {
- TSmsReassemblyEntry entry= (TSmsReassemblyEntry&) iReassemblyStore->Entries()[count];
- CSmsPDU::TSmsPDUType pdu = entry.PduType();
- CSmsBuffer* buffer = CSmsBuffer::NewL();
- CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, pdu, buffer );
- CleanupStack::PushL(smsMessage);
- iReassemblyStore->GetMessageL(count,*smsMessage);
- if ((smsMessage->Storage() == CSmsMessage::ESmsSIMStorage) || (smsMessage->Storage() == CSmsMessage::ESmsCombinedStorage))
- {
- iReassemblyStore->DeleteEntryL(count);
- }
- else
- {
- iReassemblyStore->SetPassedToClientL(count, EFalse);
- }
- CleanupStack::PopAndDestroy(smsMessage);
- }
- iReassemblyStore->CommitTransactionL();
- iReassemblyStore->Close();
- }
-
-/**
-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 CFacadeSmsReassemblyStore::DeleteNonClass0EnumeratedSIMEntries()
- {
- const TInt count = iReassemblyStore->Entries().Count();
-
- LOGSMSPROT2("CFacadeSmsReassemblyStore::DeleteNonClass0EnumeratedSIMEntries(): %d messages in RAS", count);
-
- TInt index;
-
- for (index = count-1; index >= 0; --index)
- {
- TSmsReassemblyEntry entry = (TSmsReassemblyEntry&) iReassemblyStore->Entries()[index];
-
- if (entry.Storage()==CSmsMessage::ESmsSIMStorage)
- {
- TRAP_IGNORE(iReassemblyStore->BeginTransactionLC();
- iReassemblyStore->DeleteEntryL(index);
- iReassemblyStore->CommitTransactionL());
- }
- }
- }
-
-/**
-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 CFacadeSmsReassemblyStore::DeleteNonClass0MessageL(const CSmsMessage& aSmsMessage, TBool aPassed)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::DeleteNonClass0MessageL()");
- TInt index(0);
-
- if(!iReassemblyStore->InTransaction())
- {
- iReassemblyStore->BeginTransactionLC();
- if (iReassemblyStore->FindMessageL(aSmsMessage, aPassed, index))
- {
- iReassemblyStore->DeleteEntryL(index);
- }
- iReassemblyStore->CommitTransactionL();
- }
- else if (iReassemblyStore->FindMessageL(aSmsMessage, aPassed, index))
- {
- iReassemblyStore->DeleteEntryL(index);
- }
- }
-
-/**
-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 CFacadeSmsReassemblyStore::SetNonClass0MessagePassedToClientL(const CSmsMessage& aSmsMessage, TBool aPassed)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::SetNonClass0MessagePassedToClientL()");
- TInt index(0);
-
- iReassemblyStore->BeginTransactionLC();
- if (iReassemblyStore->FindMessageL(aSmsMessage , !aPassed, index))
- {
- iReassemblyStore->SetPassedToClientL(index, aPassed);
- }
- iReassemblyStore->CommitTransactionL();
- }
-
-/**
-It returns the number of complete messages stored in general re-assembly store.
-*/
-TInt CFacadeSmsReassemblyStore::NumberOfCompleteNonClass0Messages()
- {
- LOGSMSPROT2("CFacadeSmsReassemblyStore::NumberOfCompleteMessages(): Entries().Count()=%d",
- iReassemblyStore->Entries().Count());
-
- //local variable for complete entries
- TInt count( 0 );
- // checks all entrys in the reassembly store
- for ( TInt i = iReassemblyStore->Entries().Count()-1; i >= 0; i-- )
- {
- // checks if entry is completed
- if ( iReassemblyStore->Entries()[i].IsComplete() )
- {
- ++count;
- }
- }
- return count;
- }
-
-/**
-It searches the non class 0 reassembly store for complete messages and then
-it sends that message for further processing. It is called when a new
-observer is added or a PDU has been received and successfully processed.
-
-@param aSmsComm a reference to the protocol.
-@param aCurrentSmsMessage a pointer to current SMS message.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::ProcessCompleteNonClass0SmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage* aCurrentSmsMessage)
- {
- LOGSMSPROT2("CFacadeSmsReassemblyStore::ProcessCompleteNonClass0SmsMessagesL [from %d to 0]", iReassemblyStore->Entries().Count()-1);
-
- iReassemblyStore->BeginTransactionLC();
- TInt count = iReassemblyStore->Entries().Count();
-
- CSmsBuffer* buffer = CSmsBuffer::NewL();
- CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, CSmsPDU::ESmsDeliver, buffer );
- CleanupStack::PushL( smsMessage );
-
- while (count--)
- {
- TSAREntry entry(iReassemblyStore->Entries()[count]);
- if ( entry.IsComplete() )
- {
- TRAPD( ret, iReassemblyStore->GetMessageL( count , *smsMessage ) );
- if ( ret == KErrNone )
- {
- if( !iReassemblyStore->PassedToClient( count ) )
- {
- if(!(aCurrentSmsMessage && aCurrentSmsMessage->Time()==smsMessage->Time()))
- {
- TBuf16<CSmsPDUProcessor::ESmsMaxDeliverReportBufferSize> buffer;
- ret = aSmsComm.ProcessMessageL( *smsMessage, NULL, NULL, buffer );
- if ( ret == KErrNone )
- iReassemblyStore->SetPassedToClientL( count , ETrue);
- }
- }
- }
- }
- }
- CleanupStack::PopAndDestroy( smsMessage );
- iReassemblyStore->CommitTransactionL();
- }
-
-/**
-It searches the class 0 reassembly store for complete messages and then
-it sends that message for further processing. It is called when a new
-observer is added or a PDU has been received and successfully processed.
-
-@param aSmsComm a reference to the protocol.
-@param aCurrentSmsMessage a pointer to current SMS message.
-
-@internalComponent
-*/
-void CFacadeSmsReassemblyStore::ProcessCompleteClass0SmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage* aCurrentSmsMessage)
- {
- LOGSMSPROT2("CFacadeSmsReassemblyStore::ProcessCompleteClass0SmsMessagesL [from %d to 0]", iClass0ReassemblyStore->Entries().Count()-1);
-
- iClass0ReassemblyStore->BeginTransactionLC();
- TInt count = iClass0ReassemblyStore->Entries().Count();
-
- CSmsBuffer* buffer = CSmsBuffer::NewL();
- CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, CSmsPDU::ESmsDeliver, buffer );
- CleanupStack::PushL( smsMessage );
-
- while (count--)
- {
- TReassemblyEntry entry(iClass0ReassemblyStore->Entries()[count]);
- if ( entry.IsComplete() )
- {
- TRAPD( ret, iClass0ReassemblyStore->GetMessageL( count , *smsMessage ) );
- if ( ret == KErrNone )
- {
- if( !entry.PassedToClient() )
- {
- if(!(aCurrentSmsMessage && aCurrentSmsMessage->Time()==smsMessage->Time()))
- {
- TBuf16<CSmsPDUProcessor::ESmsMaxDeliverReportBufferSize> buffer;
- ret = aSmsComm.ProcessMessageL( *smsMessage, NULL, NULL, buffer );
- if ( ret == KErrNone )
- iClass0ReassemblyStore->SetPassedToClientL(entry, ETrue);
- }
- }
- }
- }
- }
- CleanupStack::PopAndDestroy( smsMessage );
- iClass0ReassemblyStore->CommitTransactionL();
- //Call this function to process those messages whose time has expired.
- iClass0ReassemblyStore->ProcessTimeoutMessageL();
- iClass0ReassemblyStore->CleanReassemblyEntries();
- }
-
-/**
-It externalizes all the enumerated messages.
-It goes through the re-assembly store and sends all those SMS messages
-(which is SIM/Combined storage based) to client (aSmsProvider).
-
-@param aSmsProvider a reference to a service access point.
-@param aCount number of sms messages enumerated.
-@return number of new segments.
-
-@internalComponent
-*/
-TInt CFacadeSmsReassemblyStore::ExternalizeEnumeratedNonClass0SmsMessagesL(CSmsProvider& aProvider,TInt& aCount)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::ExternalizeEnumeratedNonClass0SmsMessagesL()");
- TInt count = iReassemblyStore->Entries().Count();
- TInt index,numNewSegments(0);
- for(index = count-1; index >=0; --index)
- {
- TSmsReassemblyEntry entry= (TSmsReassemblyEntry&) iReassemblyStore->Entries()[index];
- if( entry.PassedToClient() == EFalse)
- {
- CSmsPDU::TSmsPDUType pdu = entry.PduType();
- CSmsBuffer* buffer = CSmsBuffer::NewL();
- CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, pdu, buffer );
- CleanupStack::PushL(smsMessage);
- iReassemblyStore->GetMessageL(index,*smsMessage);
- if (((smsMessage->Storage() == CSmsMessage::ESmsSIMStorage) || (smsMessage->Storage() == CSmsMessage::ESmsCombinedStorage)) ||
- ( (smsMessage->DecodedOnSim()) && (smsMessage->ForwardToClient()) ) )
- {
- numNewSegments+=aProvider.ExternalizeMessageL(*smsMessage,EFalse);
- for(TInt i=0; i< smsMessage->iSlotArray.Count() ;i++)
- {
- LOGSMSPROT2("CFacadeSmsReassemblyStore::ExternalizeEnumeratedNonClass0SmsMessagesL %d", smsMessage->iSlotArray[i].iIndex);
- }
- ++aCount;
- iReassemblyStore->BeginTransactionLC();
- iReassemblyStore->SetPassedToClientL(index,ETrue);
- iReassemblyStore->CommitTransactionL();
- }
- CleanupStack::PopAndDestroy(smsMessage);
- }
- }
- return numNewSegments;
- }
-
-/**
-It externalizes all the class 0 enumerated messages.
-It goes through the class 0 re-assembly store and sends all those SMS messages
-(which is SIM/Combined storage based) to client (aSmsProvider).
-
-@param aSmsProvider a reference to a service access point.
-@param aCount number of sms messages enumerated.
-@return number of new segments.
-
-@internalComponent
-*/
-TInt CFacadeSmsReassemblyStore::ExternalizeEnumeratedClass0SmsMessagesL(CSmsProvider& aProvider,TInt& aCount)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::ExternalizeEnumeratedClass0SmsMessagesL()");
- TInt count = iClass0ReassemblyStore->Entries().Count();
- TInt index,numNewSegments(0);
- for(index = count-1; index >=0; --index)
- {
- TReassemblyEntry entry= (TReassemblyEntry&) iClass0ReassemblyStore->Entries()[index];
- if( entry.PassedToClient() == EFalse)
- {
- CSmsPDU::TSmsPDUType pdu = entry.PduType();
- CSmsBuffer* buffer = CSmsBuffer::NewL();
- CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, pdu, buffer );
- CleanupStack::PushL(smsMessage);
- iClass0ReassemblyStore->GetMessageL(index,*smsMessage);
- if (((smsMessage->Storage() == CSmsMessage::ESmsSIMStorage) || (smsMessage->Storage() == CSmsMessage::ESmsCombinedStorage)) ||
- ( (smsMessage->DecodedOnSim()) && (smsMessage->ForwardToClient()) ) )
- {
- numNewSegments+=aProvider.ExternalizeMessageL(*smsMessage,EFalse);
- for(TInt i=0; i< smsMessage->iSlotArray.Count() ;i++)
- {
- LOGSMSPROT2("CFacadeSmsReassemblyStore::ExternalizeEnumeratedClass0SmsMessagesL() %d", smsMessage->iSlotArray[i].iIndex);
- }
- ++aCount;
- iClass0ReassemblyStore->BeginTransactionLC();
- iClass0ReassemblyStore->SetPassedToClientL(entry, ETrue);
- iClass0ReassemblyStore->CommitTransactionL();
- }
- CleanupStack::PopAndDestroy(smsMessage);
- }
- }
- return numNewSegments;
- }
-
-/**
-It adds the message segment to the general reassembly store.
-
-@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. At the time of function call it contains the message.
- When the function returns it contains full decoded message.
-
-@param aGsmSms a reference to GsmSms object which contain actual PDU.
- It acts as pure input.
-
-@param aIsComplete boolean value indicating whether the message is complete or not.
- It acts both as input & output.
- In case of multi-segment message, the value of aIsComplete will be true when function returns
- if the added segment makes the messsage complete.
-
-@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 for the given sms message.
- It acts as only output.
-
-@internalComponent
-
-NOTE:
- When function returns, if the value of aIsComplete is True, then aSmsMesssage will contain the
- complete decoded SMS message.
-*/
-void CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms, TInt& aIndex, TBool& aIsComplete, TBool aIsEnumeration, TInt& aCount, TInt& aTotal)
- {
- LOGSMSPROT2("CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(): isComplete Message=%d",
- aSmsMessage.IsComplete());
-
- 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...
- //
- iReassemblyStore->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);
-
- iReassemblyStore->MatchPDUToExistingMessage(aSmsMessage, segStoreIndex);
- LOGSMSPROT2("CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(): "
- "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;
- TBool isDuplicateMsgRef;
- //
- // So we found a related part of the message, add this message to the
- // store...
- //
- aIndex = segStoreIndex;
- iReassemblyStore->UpdateExistingMessageL(aSmsMessage, aGsmSms, aIndex,
- aIsComplete, isDuplicateMsgRef,
- isDuplicateSlot);
- LOGSMSPROT5("CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(): "
- "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)
- {
- iReassemblyStore->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.
- //
- iReassemblyStore->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(FileSession(),
- CSmsPDU::ESmsDeliver, buffer);
- CleanupStack::PushL(firstMessagePdu);
- iReassemblyStore->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.
- //
- iReassemblyStore->NewMessagePDUL(aIndex, aSmsMessage, aGsmSms);
- }
- }
-
- //
- // Update the Log Server ID and time data from the other segments.
- //
- const TSAREntry& entry = iReassemblyStore->Entries()[aIndex];
-
- aSmsMessage.SetLogServerId(entry.LogServerId());
- aSmsMessage.SetTime(entry.Time());
-
- aCount = entry.Count();
- aTotal = entry.Total();
- }
-
-/**
-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 CFacadeSmsReassemblyStore::UpdateLogServerIdOfNonClass0MessageL(const CSmsMessage& aSmsMessage, TInt aIndex)
- {
- //
- // Find the message in the reassembly store...
- //
- TInt foundIndex(KErrNotFound);
- TBool found(EFalse);
-
- if (iReassemblyStore->InTransaction())
- {
- found = iReassemblyStore->FindMessageL(aSmsMessage, EFalse, foundIndex);
- }
- else
- {
- iReassemblyStore->BeginTransactionLC();
- found = iReassemblyStore->FindMessageL(aSmsMessage, EFalse, foundIndex);
- iReassemblyStore->CommitTransactionL();
- }
-
- LOGSMSPROT3("CFacadeSmsReassemblyStore::UpdateLogServerIdOfNonClass0MessageL(): found=%d, foundIndex=%d",
- found, foundIndex);
-
- //
- // If found and the index is valid, then update the Log Server ID...
- //
- if (found && aIndex == foundIndex)
- {
- iReassemblyStore->UpdateLogServerIdL(aIndex,
- aSmsMessage.LogServerId());
- }
- }
-
-/**
- * Checks whether a message is a WAP message.
- *
- */
-TBool CFacadeSmsReassemblyStore::IsWapSMS(const CSmsMessage& aSmsMessage)
- {
- LOGSMSPROT1("CFacadeSmsReassemblyStore::IsWapSMS()");
-
- return CSmsProtocol::IsAppPortSMS(aSmsMessage);
- }
+// 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 "gsmubuf.h"
+#include "smspfacadestor.h"
+
+/**
+Static factory constructor. Uses two phase
+construction and leaves nothing on the CleanupStack.
+
+@internalComponent
+
+@return A pointer to the newly created CFacadeSmsReassemblyStore object.
+@param aFs File Server handle.
+@param aSmsComm Notification Event Reference.
+@leave KErrNoMemory
+
+@pre A connected file server session must be passed as parameter.
+@post CFacadeSmsReassemblyStore object is now fully initialised
+*/
+CFacadeSmsReassemblyStore* CFacadeSmsReassemblyStore::NewL(RFs& aFs, MSmsComm& aSmsComm)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::NewL()");
+
+ CFacadeSmsReassemblyStore* self = new (ELeave) CFacadeSmsReassemblyStore(aFs, aSmsComm);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+
+ return self;
+ }
+
+/**
+ * Constructor.
+*/
+CFacadeSmsReassemblyStore::CFacadeSmsReassemblyStore(RFs& aFs, MSmsComm& aSmsComm)
+ :iFs(aFs), iSmsComm(aSmsComm), iReassemblyStore(NULL), iClass0ReassemblyStore(NULL)
+ {
+ // NOP
+ }
+
+/**
+ * Destructor. It destroys all the member variables.
+*/
+CFacadeSmsReassemblyStore::~CFacadeSmsReassemblyStore()
+ {
+ LOGSMSPROT1("~CFacadeSmsReassemblyStore()");
+ iReassemblyStore->Close();
+ delete iReassemblyStore;
+
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->Close();
+ delete iClass0ReassemblyStore;
+ }
+ }
+
+/**
+Second Phase construction. It creates re-assembly stores. If SMS stack is configured
+for handling class 0 messages in out-of-disk condition. It creates class 0
+& non-class 0 re-assembly store. Otherwise it creates only one re-assembly store
+which will be used to store all type of SMS messages.
+
+@internalComponent
+
+@leave KErrNoMemory
+
+@pre A connected file server session must be passed as parameter.
+@post CFacadeSmsReassemblyStore object is now fully constructed.
+*/
+void CFacadeSmsReassemblyStore::ConstructL()
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::ConstructL()");
+
+ iReassemblyStore = CSmsReassemblyStore::NewL(iFs);
+ /*
+ Read [ReassemblyStore] section from smswap.sms.esk file. If section is absent then there is
+ no need to create class 0 re-assembly store. This sms stack is configured to work
+ as before (class 0 message will be -vely ack in out-of-disk condition).
+ If ReassemblyStore section is present then read the value of Class0.
+ If the value of Class0 is 1. Then create class 0 re-assembly store object.
+ For example:
+ [ReassemblyStore]
+ Class0= 1
+ MaxClass0Messages=10
+ NumberOfPDUSegements=20
+ GuardTimeOut=12
+ */
+ CESockIniData* ini = NULL;
+ ini=CESockIniData::NewL(_L("smswap.sms.esk"));
+ CleanupStack::PushL(ini);
+ TBool status(EFalse);
+ if (ini->FindVar(_L("ReassemblyStore"), _L("Class0"), status))
+ {
+ if (status)
+ {
+ iClass0ReassemblyStore = CClass0SmsReassemblyStore::NewL(iFs, iSmsComm);
+ }
+ }
+
+ // Set the default value for iMaxmumNumberOfCompleteMessagesInReassemblyStore.
+ iMaxmumNumberOfCompleteMessagesInReassemblyStore = KDefaultMaxmumNumberOfCompleteMessagesInReassemblyStore;
+ // Load up the user configurable setting for the maximum number of complete messages in
+ // the reassembly store.
+ TPtrC value;
+ if((ini->FindVar(_L("ReasmemblyStoreOptions"),_L("MaxNumOfComMessInReStore"),value)))
+ {
+ TLex16 valueconv(value);
+ valueconv.Val(iMaxmumNumberOfCompleteMessagesInReassemblyStore);
+ }
+
+ CleanupStack::PopAndDestroy(ini);
+ }
+
+/**
+It open the re-assembly stores.
+This function needs to be called before doing any operations (add/delete/update) in the
+re-assembly stores.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::OpenStoreL()
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::OpenStoreL()");
+ iReassemblyStore->OpenStoreL();
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->OpenStoreL();
+ }
+ }
+
+/**
+It closes the re-assembly stores.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::Close()
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::Close()");
+ // Close general Re-assembly store.
+ iReassemblyStore->Close();
+ // Close Class0 re-assembly store.
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->Close();
+ }
+ }
+
+/**
+It returns the file session.
+
+@internalComponent
+
+@return returns the file session.
+*/
+RFs& CFacadeSmsReassemblyStore::FileSession() const
+ {
+ return iFs;
+ }
+
+/**
+It initializes the re-assembly store.
+It goes through all the entries in re-assembly store. It updates its header information.
+If any sms message is either SIM based or combined storage based then it is deleted from re-assembly store.
+For other type of SMS messages, its header info is updated to indicate that it is not passed to client.
+
+This initialization process is required because SMS stack might have been re-started.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::InitL()
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::InitL()");
+ // Initialize Non-class 0 Re-assembly store.
+ InitializeNonClass0StoreL();
+ // Initialize Class0 re-assembly store.
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->InitializeL();
+ }
+ }
+
+/**
+Purges the reassembly file stores.
+
+@param aTimeIntervalMinutes Purge time
+@param aPurgeIncompleteOnly Purge complete messages flag
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::PurgeL(const TTimeIntervalMinutes& aTimeIntervalMinutes,TBool aPurgeIncompleteOnly)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::PurgeL()");
+ iReassemblyStore->PurgeL(aTimeIntervalMinutes, aPurgeIncompleteOnly);
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->PurgeL(aTimeIntervalMinutes, aPurgeIncompleteOnly);
+ }
+ }
+
+/**
+It returns a boolean value indicating whether re-assembly store is full or not.
+If number of complete sms messages exceed the configured value (KMaxmumNumberOfCompleteMessagesInReassemblyStore),
+it return TRUE. Otherwise it returns FALSE.
+
+@internalComponent
+*/
+TBool CFacadeSmsReassemblyStore::IsFull()
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::IsFull()");
+
+ //local variable for complete entries
+ TInt count( 0 );
+ count = NumberOfCompleteNonClass0Messages();
+ if (iClass0ReassemblyStore)
+ {
+ count += iClass0ReassemblyStore->NumberOfCompleteMessages();
+ }
+ if (count > iMaxmumNumberOfCompleteMessagesInReassemblyStore)
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+/**
+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 CFacadeSmsReassemblyStore::DeleteEnumeratedSIMEntries()
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::DeleteEnumeratedSIMEntries()");
+ DeleteNonClass0EnumeratedSIMEntries();
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->DeleteEnumeratedSIMEntries();
+ }
+ }
+
+/**
+It externalizes all the enumerated messages.
+It goes through the re-assembly store and sends all those SMS messages
+(which is SIM/Combined storage based) to client (aSmsProvider).
+
+@param aSmsProvider a reference to a service access point.
+@param aCount number of sms messages enumerated.
+@return number of new segments.
+
+@internalComponent
+*/
+TInt CFacadeSmsReassemblyStore::ExternalizeEnumeratedMessagesL(CSmsProvider& aProvider,TInt& aCount)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::ExternalizeEnumeratedMessagesL()");
+ TInt numNewSegments(0);
+ numNewSegments = ExternalizeEnumeratedNonClass0SmsMessagesL(aProvider, aCount);
+ if (iClass0ReassemblyStore)
+ {
+ numNewSegments += ExternalizeEnumeratedClass0SmsMessagesL(aProvider, aCount);
+ }
+ return numNewSegments;
+ }
+
+/**
+It searches the reassembly store for complete messages and then it sends that
+message for further processing. It is called when a new observer is added or
+a PDU has been received and successfully processed.
+
+@param aSmsComm a reference to the protocol.
+@param aCurrentSmsMessage a pointer to current SMS message.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::ProcessCompleteSmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage* aCurrentSmsMessage)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::ProcessCompleteSmsMessagesL");
+
+ ProcessCompleteNonClass0SmsMessagesL(aSmsComm, aCurrentSmsMessage);
+ if (iClass0ReassemblyStore)
+ {
+ ProcessCompleteClass0SmsMessagesL(aSmsComm, aCurrentSmsMessage);
+ }
+ }
+
+/**
+It adds the message segment to the reassembly store.
+This function first checks on which re-assembly store the message should be stored and then add
+the message to appropriate re-assembly store.
+
+@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. At the time of function call it contains the message.
+ When the function returns it contains full decoded message if it is complete.
+ But in case of class 0 messages it might not contain complete class 0 messages.
+
+@param aGsmSms a reference to GsmSms object which contain actual PDU.
+ It acts as pure input.
+
+@param aIsComplete boolean value indicating whether the message is complete or not.
+ It acts both as input & output.
+ In case of multi-segment message, the value of aIsComplete will be true when function returns
+ if the added segment makes the messsage complete.
+
+@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 for the given sms message.
+ It acts as only output.
+
+@internalComponent
+
+NOTE:
+ When function returns, if the value of aIsComplete is True, then aSmsMesssage will contain the
+ complete decoded SMS message.
+ But the above statement might not be always true:
+ In case of class 0 messages, it is possible to forward the incomplete messages. So after forwarding
+ the incomplete message, if we receive other constituent PDU of that message then in that case we
+ might receive all the constituent PDU of that message but aSmsMesssage will contain partial complete message.
+ To find out complete/incompletness of the message, CSmsMessage::IsComplete() message function has to be called.
+*/
+void CFacadeSmsReassemblyStore::AddSegmentToReassemblyStoreL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms, TInt& aIndex, TBool& aIsComplete, TBool aIsEnumeration, TInt& aCount, TInt& aTotal)
+ {
+ LOGSMSPROT2("CFacadeSmsReassemblyStore::AddSegmentToReassemblyStoreL(): isComplete Message=%d",
+ aSmsMessage.IsComplete());
+
+ TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
+
+ if (toBeStoredInClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->AddSegmentToReassemblyStoreL(aSmsMessage, aGsmSms, aIndex, aIsComplete, aIsEnumeration, aCount, aTotal);
+ }
+ else
+ {
+ AddSegmentToNonClass0ReassemblyStoreL(aSmsMessage, aGsmSms, aIndex, aIsComplete, aIsEnumeration, aCount, aTotal);
+ }
+ }
+
+/**
+It forwards the complete class 0 messages to client.
+NOTE:
+ This function needs to be called only in case of class 0 messages.
+
+@param aSmsComm a reference to aSmsComm object which implemented the events.
+
+@param aSmsMessage a reference to sms message object. This sms message must be class 0 messages.
+
+@param aOriginalSmsAddr pointer to the address of the sender of a previously sent
+
+@param aOriginalSmsMessage pointer to a message previously sent matched to the received
+ one (e.g. status report). Null if not matched.
+
+@param aDes user data for the deliver report acknowledging this message to the SC.
+ Filled in by the observer.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::ForwardCompleteClass0SmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage& aSmsMessage,const TSmsAddr* aOriginalSmsAddr,const CSmsMessage* aOriginalSmsMessage,TDes& aDes)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::ForwardCompleteClass0SmsMessagesL");
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->ForwardCompleteClass0SmsMessagesL(aSmsComm, aSmsMessage, aOriginalSmsAddr, aOriginalSmsMessage, aDes);
+ }
+ }
+
+/**
+It frees the space by forwarding the class 0 message if class 0 re-assembly store
+exceeds limitation (max class 0 message, max reserved pdu segment).
+NOTE:
+ This function needs to be called only in case of class 0 messages.
+
+@param aSmsComm a reference to aSmsComm object which implemented the events.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::ProcessMessageIfExceedLimitationL(MSmsComm& aSmsComm)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::ProcessMessageIfExceedLimitationL");
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->ProcessMessageIfExceedLimitationL(aSmsComm);
+ }
+ }
+
+/**
+It sets the incomplete messsage forwarded to client.
+Internally it frees up the memory by removing the forwarded PDUs and also it stores forwarded PDU index.
+
+NOTE:
+ This function needs to be called only in case of class 0 messages.
+
+@param aSmsMessage a reference to sms message object. This sms message must be class 0 messages.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::SetIncompleteMessageForwardedToClientL(const CSmsMessage& aSmsMessage)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::SetIncompleteMessageForwardedToClientL()");
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->SetIncompleteMessageForwardedToClientL(aSmsMessage);
+ }
+ }
+
+/**
+It sets the disk space status.
+If disk space is full, then class 0 re-assembly store stores the incoming message in
+pre-allocated file. Otherwise it stores the message in permanent store file.
+*/
+void CFacadeSmsReassemblyStore::SetDiskSpaceState(TSmsDiskSpaceMonitorStatus aDiskSpaceStatus)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::SetDiskSpaceState()");
+ if (iClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->SetDiskSpaceState(aDiskSpaceStatus);
+ }
+ }
+
+/**
+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 CFacadeSmsReassemblyStore::DeleteMessageL(const CSmsMessage& aSmsMessage, TBool aPassed)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::DeleteEntryL()");
+
+ TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
+
+ if (toBeStoredInClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->DeleteMessageL(aSmsMessage, aPassed);
+ }
+ else
+ {
+ DeleteNonClass0MessageL(aSmsMessage, aPassed);
+ }
+ }
+
+/**
+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 CFacadeSmsReassemblyStore::UpdateLogServerIdL(const CSmsMessage& aSmsMessage, TInt aIndex)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::UpdateLogServerIdL()");
+
+ TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
+
+ if (toBeStoredInClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->UpdateLogServerIdOfMessageL(aSmsMessage, aIndex);
+ }
+ else
+ {
+ UpdateLogServerIdOfNonClass0MessageL(aSmsMessage, aIndex);
+ }
+ }
+
+/**
+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 CFacadeSmsReassemblyStore::SetMessagePassedToClientL(const CSmsMessage& aSmsMessage, TBool aPassed)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::SetMessagePassedToClientL()");
+
+ TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
+
+ if (toBeStoredInClass0ReassemblyStore)
+ {
+ iClass0ReassemblyStore->SetMessagePassedToClientL(aSmsMessage, aPassed);
+ }
+ else
+ {
+ SetNonClass0MessagePassedToClientL(aSmsMessage, aPassed);
+ }
+ }
+
+/**
+Returns a boolean value indicating whether this class contains separate
+re-assembly store for class 0 message or not.
+
+@internalComponent
+*/
+TBool CFacadeSmsReassemblyStore::IsSeparateClass0StoreSupported()
+ {
+ if (iClass0ReassemblyStore)
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+/**
+Returns a boolean value indicating where this SMS message will be stored.
+If it rerurns EFalse, message will be stored in normal re-assembly store,
+otherwise it will be stored in class 0 re-assembly store.
+
+@internalComponent
+*/
+TBool CFacadeSmsReassemblyStore::IsForClass0ReassemblyStore(const CSmsMessage& aSmsMessage)
+ {
+ if (iClass0ReassemblyStore == NULL)
+ {
+ return EFalse;
+ }
+
+ TSmsDataCodingScheme::TSmsClass msgClass;
+
+ if (aSmsMessage.SmsPDU().DataCodingSchemePresent() && aSmsMessage.SmsPDU().Class(msgClass))
+ {
+ if (msgClass == TSmsDataCodingScheme::ESmsClass0)
+ {
+ //Check also whether it is a WAP Datagram
+ // In that case return EFalse otherwise ETrue (REQ7012)
+ if (!IsWapSMS(aSmsMessage))
+ {
+ return ETrue;
+ }
+ }
+ }
+ return EFalse;
+ }
+
+/**
+It initializes the re-assembly store.
+It goes through all the entries in re-assembly store. It updates its header information.
+If any sms message is either SIM based or combined storage based then it is deleted from re-assembly store.
+For other type of SMS messages, its header info is updated to indicate that it is not passed to client.
+
+This initialization process is required because SMS stack might have been re-started.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::InitializeNonClass0StoreL()
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::InitializeNonClass0StoreL()");
+ // Initialize Re-assembly store.
+ iReassemblyStore->OpenStoreL();
+ iReassemblyStore->BeginTransactionLC();
+ TInt count = iReassemblyStore->Entries().Count();
+ while (count--)
+ {
+ TSmsReassemblyEntry entry= (TSmsReassemblyEntry&) iReassemblyStore->Entries()[count];
+ CSmsPDU::TSmsPDUType pdu = entry.PduType();
+ CSmsBuffer* buffer = CSmsBuffer::NewL();
+ CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, pdu, buffer );
+ CleanupStack::PushL(smsMessage);
+ iReassemblyStore->GetMessageL(count,*smsMessage);
+ if ((smsMessage->Storage() == CSmsMessage::ESmsSIMStorage) || (smsMessage->Storage() == CSmsMessage::ESmsCombinedStorage))
+ {
+ iReassemblyStore->DeleteEntryL(count);
+ }
+ else
+ {
+ iReassemblyStore->SetPassedToClientL(count, EFalse);
+ }
+ CleanupStack::PopAndDestroy(smsMessage);
+ }
+ iReassemblyStore->CommitTransactionL();
+ iReassemblyStore->Close();
+ }
+
+/**
+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 CFacadeSmsReassemblyStore::DeleteNonClass0EnumeratedSIMEntries()
+ {
+ const TInt count = iReassemblyStore->Entries().Count();
+
+ LOGSMSPROT2("CFacadeSmsReassemblyStore::DeleteNonClass0EnumeratedSIMEntries(): %d messages in RAS", count);
+
+ TInt index;
+
+ for (index = count-1; index >= 0; --index)
+ {
+ TSmsReassemblyEntry entry = (TSmsReassemblyEntry&) iReassemblyStore->Entries()[index];
+
+ if (entry.Storage()==CSmsMessage::ESmsSIMStorage)
+ {
+ TRAP_IGNORE(iReassemblyStore->BeginTransactionLC();
+ iReassemblyStore->DeleteEntryL(index);
+ iReassemblyStore->CommitTransactionL());
+ }
+ }
+ }
+
+/**
+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 CFacadeSmsReassemblyStore::DeleteNonClass0MessageL(const CSmsMessage& aSmsMessage, TBool aPassed)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::DeleteNonClass0MessageL()");
+ TInt index(0);
+
+ if(!iReassemblyStore->InTransaction())
+ {
+ iReassemblyStore->BeginTransactionLC();
+ if (iReassemblyStore->FindMessageL(aSmsMessage, aPassed, index))
+ {
+ iReassemblyStore->DeleteEntryL(index);
+ }
+ iReassemblyStore->CommitTransactionL();
+ }
+ else if (iReassemblyStore->FindMessageL(aSmsMessage, aPassed, index))
+ {
+ iReassemblyStore->DeleteEntryL(index);
+ }
+ }
+
+/**
+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 CFacadeSmsReassemblyStore::SetNonClass0MessagePassedToClientL(const CSmsMessage& aSmsMessage, TBool aPassed)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::SetNonClass0MessagePassedToClientL()");
+ TInt index(0);
+
+ iReassemblyStore->BeginTransactionLC();
+ if (iReassemblyStore->FindMessageL(aSmsMessage , !aPassed, index))
+ {
+ iReassemblyStore->SetPassedToClientL(index, aPassed);
+ }
+ iReassemblyStore->CommitTransactionL();
+ }
+
+/**
+It returns the number of complete messages stored in general re-assembly store.
+*/
+TInt CFacadeSmsReassemblyStore::NumberOfCompleteNonClass0Messages()
+ {
+ LOGSMSPROT2("CFacadeSmsReassemblyStore::NumberOfCompleteMessages(): Entries().Count()=%d",
+ iReassemblyStore->Entries().Count());
+
+ //local variable for complete entries
+ TInt count( 0 );
+ // checks all entrys in the reassembly store
+ for ( TInt i = iReassemblyStore->Entries().Count()-1; i >= 0; i-- )
+ {
+ // checks if entry is completed
+ if ( iReassemblyStore->Entries()[i].IsComplete() )
+ {
+ ++count;
+ }
+ }
+ return count;
+ }
+
+/**
+It searches the non class 0 reassembly store for complete messages and then
+it sends that message for further processing. It is called when a new
+observer is added or a PDU has been received and successfully processed.
+
+@param aSmsComm a reference to the protocol.
+@param aCurrentSmsMessage a pointer to current SMS message.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::ProcessCompleteNonClass0SmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage* aCurrentSmsMessage)
+ {
+ LOGSMSPROT2("CFacadeSmsReassemblyStore::ProcessCompleteNonClass0SmsMessagesL [from %d to 0]", iReassemblyStore->Entries().Count()-1);
+
+ iReassemblyStore->BeginTransactionLC();
+ TInt count = iReassemblyStore->Entries().Count();
+
+ CSmsBuffer* buffer = CSmsBuffer::NewL();
+ CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, CSmsPDU::ESmsDeliver, buffer );
+ CleanupStack::PushL( smsMessage );
+
+ while (count--)
+ {
+ TSAREntry entry(iReassemblyStore->Entries()[count]);
+ if ( entry.IsComplete() )
+ {
+ TRAPD( ret, iReassemblyStore->GetMessageL( count , *smsMessage ) );
+ if ( ret == KErrNone )
+ {
+ if( !iReassemblyStore->PassedToClient( count ) )
+ {
+ if(!(aCurrentSmsMessage && aCurrentSmsMessage->Time()==smsMessage->Time()))
+ {
+ TBuf16<CSmsPDUProcessor::ESmsMaxDeliverReportBufferSize> buffer;
+ ret = aSmsComm.ProcessMessageL( *smsMessage, NULL, NULL, buffer );
+ if ( ret == KErrNone )
+ iReassemblyStore->SetPassedToClientL( count , ETrue);
+ }
+ }
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( smsMessage );
+ iReassemblyStore->CommitTransactionL();
+ }
+
+/**
+It searches the class 0 reassembly store for complete messages and then
+it sends that message for further processing. It is called when a new
+observer is added or a PDU has been received and successfully processed.
+
+@param aSmsComm a reference to the protocol.
+@param aCurrentSmsMessage a pointer to current SMS message.
+
+@internalComponent
+*/
+void CFacadeSmsReassemblyStore::ProcessCompleteClass0SmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage* aCurrentSmsMessage)
+ {
+ LOGSMSPROT2("CFacadeSmsReassemblyStore::ProcessCompleteClass0SmsMessagesL [from %d to 0]", iClass0ReassemblyStore->Entries().Count()-1);
+
+ iClass0ReassemblyStore->BeginTransactionLC();
+ TInt count = iClass0ReassemblyStore->Entries().Count();
+
+ CSmsBuffer* buffer = CSmsBuffer::NewL();
+ CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, CSmsPDU::ESmsDeliver, buffer );
+ CleanupStack::PushL( smsMessage );
+
+ while (count--)
+ {
+ TReassemblyEntry entry(iClass0ReassemblyStore->Entries()[count]);
+ if ( entry.IsComplete() )
+ {
+ TRAPD( ret, iClass0ReassemblyStore->GetMessageL( count , *smsMessage ) );
+ if ( ret == KErrNone )
+ {
+ if( !entry.PassedToClient() )
+ {
+ if(!(aCurrentSmsMessage && aCurrentSmsMessage->Time()==smsMessage->Time()))
+ {
+ TBuf16<CSmsPDUProcessor::ESmsMaxDeliverReportBufferSize> buffer;
+ ret = aSmsComm.ProcessMessageL( *smsMessage, NULL, NULL, buffer );
+ if ( ret == KErrNone )
+ iClass0ReassemblyStore->SetPassedToClientL(entry, ETrue);
+ }
+ }
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( smsMessage );
+ iClass0ReassemblyStore->CommitTransactionL();
+ //Call this function to process those messages whose time has expired.
+ iClass0ReassemblyStore->ProcessTimeoutMessageL();
+ iClass0ReassemblyStore->CleanReassemblyEntries();
+ }
+
+/**
+It externalizes all the enumerated messages.
+It goes through the re-assembly store and sends all those SMS messages
+(which is SIM/Combined storage based) to client (aSmsProvider).
+
+@param aSmsProvider a reference to a service access point.
+@param aCount number of sms messages enumerated.
+@return number of new segments.
+
+@internalComponent
+*/
+TInt CFacadeSmsReassemblyStore::ExternalizeEnumeratedNonClass0SmsMessagesL(CSmsProvider& aProvider,TInt& aCount)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::ExternalizeEnumeratedNonClass0SmsMessagesL()");
+ TInt count = iReassemblyStore->Entries().Count();
+ TInt index,numNewSegments(0);
+ for(index = count-1; index >=0; --index)
+ {
+ TSmsReassemblyEntry entry= (TSmsReassemblyEntry&) iReassemblyStore->Entries()[index];
+ if( entry.PassedToClient() == EFalse)
+ {
+ CSmsPDU::TSmsPDUType pdu = entry.PduType();
+ CSmsBuffer* buffer = CSmsBuffer::NewL();
+ CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, pdu, buffer );
+ CleanupStack::PushL(smsMessage);
+ iReassemblyStore->GetMessageL(index,*smsMessage);
+ if (((smsMessage->Storage() == CSmsMessage::ESmsSIMStorage) || (smsMessage->Storage() == CSmsMessage::ESmsCombinedStorage)) ||
+ ( (smsMessage->DecodedOnSim()) && (smsMessage->ForwardToClient()) ) )
+ {
+ numNewSegments+=aProvider.ExternalizeMessageL(*smsMessage,EFalse);
+ for(TInt i=0; i< smsMessage->iSlotArray.Count() ;i++)
+ {
+ LOGSMSPROT2("CFacadeSmsReassemblyStore::ExternalizeEnumeratedNonClass0SmsMessagesL %d", smsMessage->iSlotArray[i].iIndex);
+ }
+ ++aCount;
+ iReassemblyStore->BeginTransactionLC();
+ iReassemblyStore->SetPassedToClientL(index,ETrue);
+ iReassemblyStore->CommitTransactionL();
+ }
+ CleanupStack::PopAndDestroy(smsMessage);
+ }
+ }
+ return numNewSegments;
+ }
+
+/**
+It externalizes all the class 0 enumerated messages.
+It goes through the class 0 re-assembly store and sends all those SMS messages
+(which is SIM/Combined storage based) to client (aSmsProvider).
+
+@param aSmsProvider a reference to a service access point.
+@param aCount number of sms messages enumerated.
+@return number of new segments.
+
+@internalComponent
+*/
+TInt CFacadeSmsReassemblyStore::ExternalizeEnumeratedClass0SmsMessagesL(CSmsProvider& aProvider,TInt& aCount)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::ExternalizeEnumeratedClass0SmsMessagesL()");
+ TInt count = iClass0ReassemblyStore->Entries().Count();
+ TInt index,numNewSegments(0);
+ for(index = count-1; index >=0; --index)
+ {
+ TReassemblyEntry entry= (TReassemblyEntry&) iClass0ReassemblyStore->Entries()[index];
+ if( entry.PassedToClient() == EFalse)
+ {
+ CSmsPDU::TSmsPDUType pdu = entry.PduType();
+ CSmsBuffer* buffer = CSmsBuffer::NewL();
+ CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, pdu, buffer );
+ CleanupStack::PushL(smsMessage);
+ iClass0ReassemblyStore->GetMessageL(index,*smsMessage);
+ if (((smsMessage->Storage() == CSmsMessage::ESmsSIMStorage) || (smsMessage->Storage() == CSmsMessage::ESmsCombinedStorage)) ||
+ ( (smsMessage->DecodedOnSim()) && (smsMessage->ForwardToClient()) ) )
+ {
+ numNewSegments+=aProvider.ExternalizeMessageL(*smsMessage,EFalse);
+ for(TInt i=0; i< smsMessage->iSlotArray.Count() ;i++)
+ {
+ LOGSMSPROT2("CFacadeSmsReassemblyStore::ExternalizeEnumeratedClass0SmsMessagesL() %d", smsMessage->iSlotArray[i].iIndex);
+ }
+ ++aCount;
+ iClass0ReassemblyStore->BeginTransactionLC();
+ iClass0ReassemblyStore->SetPassedToClientL(entry, ETrue);
+ iClass0ReassemblyStore->CommitTransactionL();
+ }
+ CleanupStack::PopAndDestroy(smsMessage);
+ }
+ }
+ return numNewSegments;
+ }
+
+/**
+It adds the message segment to the general reassembly store.
+
+@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. At the time of function call it contains the message.
+ When the function returns it contains full decoded message.
+
+@param aGsmSms a reference to GsmSms object which contain actual PDU.
+ It acts as pure input.
+
+@param aIsComplete boolean value indicating whether the message is complete or not.
+ It acts both as input & output.
+ In case of multi-segment message, the value of aIsComplete will be true when function returns
+ if the added segment makes the messsage complete.
+
+@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 for the given sms message.
+ It acts as only output.
+
+@internalComponent
+
+NOTE:
+ When function returns, if the value of aIsComplete is True, then aSmsMesssage will contain the
+ complete decoded SMS message.
+*/
+void CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms, TInt& aIndex, TBool& aIsComplete, TBool aIsEnumeration, TInt& aCount, TInt& aTotal)
+ {
+ LOGSMSPROT2("CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(): isComplete Message=%d",
+ aSmsMessage.IsComplete());
+
+ 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...
+ //
+ iReassemblyStore->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);
+
+ iReassemblyStore->MatchPDUToExistingMessage(aSmsMessage, segStoreIndex);
+ LOGSMSPROT2("CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(): "
+ "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;
+ TBool isDuplicateMsgRef;
+ //
+ // So we found a related part of the message, add this message to the
+ // store...
+ //
+ aIndex = segStoreIndex;
+ iReassemblyStore->UpdateExistingMessageL(aSmsMessage, aGsmSms, aIndex,
+ aIsComplete, isDuplicateMsgRef,
+ isDuplicateSlot);
+ LOGSMSPROT5("CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(): "
+ "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)
+ {
+ iReassemblyStore->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.
+ //
+ iReassemblyStore->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(FileSession(),
+ CSmsPDU::ESmsDeliver, buffer);
+ CleanupStack::PushL(firstMessagePdu);
+ iReassemblyStore->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.
+ //
+ iReassemblyStore->NewMessagePDUL(aIndex, aSmsMessage, aGsmSms);
+ }
+ }
+
+ //
+ // Update the Log Server ID and time data from the other segments.
+ //
+ const TSAREntry& entry = iReassemblyStore->Entries()[aIndex];
+
+ aSmsMessage.SetLogServerId(entry.LogServerId());
+ aSmsMessage.SetTime(entry.Time());
+
+ aCount = entry.Count();
+ aTotal = entry.Total();
+ }
+
+/**
+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 CFacadeSmsReassemblyStore::UpdateLogServerIdOfNonClass0MessageL(const CSmsMessage& aSmsMessage, TInt aIndex)
+ {
+ //
+ // Find the message in the reassembly store...
+ //
+ TInt foundIndex(KErrNotFound);
+ TBool found(EFalse);
+
+ if (iReassemblyStore->InTransaction())
+ {
+ found = iReassemblyStore->FindMessageL(aSmsMessage, EFalse, foundIndex);
+ }
+ else
+ {
+ iReassemblyStore->BeginTransactionLC();
+ found = iReassemblyStore->FindMessageL(aSmsMessage, EFalse, foundIndex);
+ iReassemblyStore->CommitTransactionL();
+ }
+
+ LOGSMSPROT3("CFacadeSmsReassemblyStore::UpdateLogServerIdOfNonClass0MessageL(): found=%d, foundIndex=%d",
+ found, foundIndex);
+
+ //
+ // If found and the index is valid, then update the Log Server ID...
+ //
+ if (found && aIndex == foundIndex)
+ {
+ iReassemblyStore->UpdateLogServerIdL(aIndex,
+ aSmsMessage.LogServerId());
+ }
+ }
+
+/**
+ * Checks whether a message is a WAP message.
+ *
+ */
+TBool CFacadeSmsReassemblyStore::IsWapSMS(const CSmsMessage& aSmsMessage)
+ {
+ LOGSMSPROT1("CFacadeSmsReassemblyStore::IsWapSMS()");
+
+ return CSmsProtocol::IsAppPortSMS(aSmsMessage);
+ }