diff -r 6b1d113cdff3 -r 6638e7f4bd8f smsprotocols/smsstack/smsprot/Src/smspfacadestor.cpp --- 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 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 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 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 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); + }