--- a/messagingappbase/smsmtm/servermtm/src/SmssSimUtils.cpp Fri Apr 16 14:56:15 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1169 +0,0 @@
-// Copyright (c) 2000-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:
-//
-
-#ifdef _DEBUG
-#undef _MSG_NO_LOGGING
-#endif
-
-#include <smutset.h>
-#include <txtrich.h>
-#include <smuthdr.h>
-#include <msventry.h>
-#include <msvuids.h>
-#include <mmlist.h>
-#include <smutsimparam.h>
-#include <biodb.h>
-#include <biouids.h>
-#include <csmsaccount.h>
-
-#include "SmssSimUtils.h"
-#include "SMSSPAN.H"
-
-//Logging constants
-
-#ifndef _MSG_NO_LOGGING
-_LIT(KDeleteFromSimLog, "DeleteFromSim.txt");
-_LIT(KEnumerateSimLog, "EnumerateSim.txt");
-_LIT(KCopyToSimLog, "CopyToSim.txt");
-#endif
-
-//CopyToSim constants
-
-
-CSmsSimUtils* CSmsSimUtils::NewL(CMsvServerEntry& aServerEntry, RFs& aFs, TMsvId aSmsServiceId)
- {
- CSmsSimUtils* self = new (ELeave) CSmsSimUtils(aServerEntry, aFs, aSmsServiceId);
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop(self);
- return self;
- }
-
-void CSmsSimUtils::ConstructL()
- {
- iSettings = CSmsSettings::NewL();
-
- // load ECOM interface used to create SMS details and description values.
- iGetDetDesc = CSmsGetDetDescInterface::NewL();
- }
-
-CSmsSimUtils::~CSmsSimUtils()
- {
- Cancel();
-
- iWriteStream.Close();
- iReadStream.Close();
-
- iSocket.Close();
- iSocketServ.Close();
-
- delete iSelection;
- delete iCompletedSelection;
-
- delete iHeader;
- delete iBody;
- delete iCharFormat;
- delete iParaFormat;
-
- delete iBioDb;
- delete iSettings;
-
- delete iGetDetDesc;
- REComSession::FinalClose();
- }
-
-void CSmsSimUtils::ReadSimParamsL(TRequestStatus& aStatus)
-/**
- Reads the SMS parameters from the SIM
-
- @since 7.0
- @param aStatus Indicates the completion status of a request made to
- a service provider.
- @pre None
- @post Starts the reading async operation.
- */
- {
- SMSSLOG(FLogFormat(_L8("Reading SMS SIM Parameters")));
-
- Queue(aStatus);
-
- iProgress = TSmsProgress();
- iProgress.iType = TSmsProgress::ESmsProgressTypeReadSimParams;
-
- ConnectL();
-
- iSocket.Ioctl(KIoctlReadSmsParams, iStatus, NULL, KSolSmsProv);
-
- SetActive();
- iReadingSimParams = ETrue;
- }
-
-void CSmsSimUtils::WriteSimParamsL(TRequestStatus& aStatus)
-/**
- Writes the SMS parameters to the SIM
-
- @since 7.0
- @param aStatus
- @pre The parameters are stored in the message store.
- @post The parameters are retrived form the message store and the writing
- async operation is started.
- */
- {
- SMSSLOG(FLogFormat(_L8("Writing SMS SIM Parameters")));
-
- Queue(aStatus);
-
- iProgress = TSmsProgress();
- iProgress.iType = TSmsProgress::ESmsProgressTypeWriteSimParams;
-
- CMobilePhoneSmspList* smspList = CMobilePhoneSmspList::NewL();
- CleanupStack::PushL(smspList);
-
- User::LeaveIfError(iServerEntry.SetEntry(iSmsServiceId));
-
- CMsvStore* store = iServerEntry.ReadStoreL();
- CleanupStack::PushL(store);
-
- CSmsSimParamOperation::RestoreSimParamsL(*store, *smspList);
-
- TInt count = 0;
- count = smspList->Enumerate();
-
- if (!count)
- User::Leave(KErrNotFound);
-
- ConnectL();
-
- iWriteStream << *smspList;
- iWriteStream.CommitL();
-
- CleanupStack::PopAndDestroy(2); //smspList, store
- User::LeaveIfError(iServerEntry.SetEntry(KMsvNullIndexEntryId));
-
- iSocket.Ioctl(KIoctlWriteSmsParams, iStatus, NULL, KSolSmsProv);
-
- SetActive();
- }
-
-void CSmsSimUtils::EnumerateL(const TDesC8& aParameter, TRequestStatus& aStatus)
- {
- SMSSLOG(FLogFormat(_L8("Enumerate messages in SIM [param=%d]"), aParameter.Length()));
-
- //Enumerate messages on the SIM.
- //First obtains a count of messages on the SIM.
-
- Queue(aStatus);
- iProgress = TSmsProgress();
- iProgress.iType = TSmsProgress::ESmsProgressTypeEnumeratingPhoneStores;
-
- ConstructHeaderAndBodyL();
- SetAndCleanEnumerateFolderL(aParameter);
- SMSSLOG(FLogFormat(_L8("\tUsing folder %d"), iProgress.iEnumerateFolder, aParameter.Length()));
-
- //Obtain a count of the messages on the SIM
- CountMessagesInPhoneStoresL();
- }
-
-void CSmsSimUtils::SetAndCleanEnumerateFolderL(const TDesC8& aParameter)
-/**
- *
- *
- * @param aParameter Optionally contains the ID of the folder to store the phone store messages
- */
- {
- iProgress.iEnumerateFolder = KErrNotFound;
-
- //Restore the iSimUtilsData.
- //This should be moved to a more general ContructL() if other functions other than EnumerateL() need to use this data
- RestoreSimUtilsDataL();
-
- //Delete messages under the last folder used to store phone-side messages
- const TInt err = iServerEntry.SetEntry(iSimUtilsData.iLastEnumerateFolder);
- if (err == KErrNotFound)
- {
- iSimUtilsData.iLastEnumerateFolder = KErrNotFound;
- }
- else
- {
- //Clean the last folder used to store phone-side messages
- User::LeaveIfError(err);
- DeleteChildrenL(iSimUtilsData.iLastEnumerateFolder);
- }
-
- if (aParameter.Length() != 0)
- {
- //Use the TMsvId packaged in aParameter as the folder in which to store phone-side messages
- TPckgC<TMsvId> enumFolder(KErrNotFound);
- enumFolder.Set(aParameter);
- iProgress.iEnumerateFolder = enumFolder();
- SMSSLOG(FLogFormat(_L8("\tAsked to use folder %d [last=%d]"), iProgress.iEnumerateFolder, iSimUtilsData.iLastEnumerateFolder));
-
- switch (iProgress.iEnumerateFolder)
- {
- case KMsvRootIndexEntryId:
- case KMsvLocalServiceIndexEntryId:
- case KMsvGlobalInBoxIndexEntryId:
- case KMsvGlobalOutBoxIndexEntryId:
- case KMsvDraftEntryId:
- case KMsvSentEntryId:
- User::Leave(KErrArgument); //cannot store phone-side messages under a standard folder
- break;
- default:
- break;
- }
-
- //Check the folder exists and delete all its children
- User::LeaveIfError(iServerEntry.SetEntry(iProgress.iEnumerateFolder));
- DeleteChildrenL(iProgress.iEnumerateFolder);
- }
- else
- {
- //else use the last folder used to store phone-side messages
- iProgress.iEnumerateFolder = iSimUtilsData.iLastEnumerateFolder;
- }
-
- if (iProgress.iEnumerateFolder == KErrNotFound)
- {
- //Create a new folder if last is not found AND aParameter,Length() == 0
- //Note: CreateNewEnumerateFolderL() sets iSimUtilsData.iLastEnumerateFolder
- iProgress.iEnumerateFolder = CreateNewEnumerateFolderL();
- }
-
- if (iProgress.iEnumerateFolder != iSimUtilsData.iLastEnumerateFolder)
- {
- //Delete the last enumerate folder if it is under the SMS service
- DeleteEnumerateFolderL(iSimUtilsData.iLastEnumerateFolder);
-
- //Store the enumerate folder for next time
- iSimUtilsData.iLastEnumerateFolder = iProgress.iEnumerateFolder;
- StoreSimUtilsDataL();
- }
- }
-
-void CSmsSimUtils::DeleteEnumerateFolderL(TMsvId aId)
-/**
- * Deletes entry aId if its parent is iSmsServiceId
- */
- {
- SMSSLOG(FLogFormat(_L8("\tAttempting to delete enumerate folder %d"), aId));
- const TInt err = iServerEntry.SetEntry(aId);
-
- if (err != KErrNotFound)
- {
- User::LeaveIfError(aId);
-
- if (iServerEntry.Entry().Parent() == iSmsServiceId)
- {
- SMSSLOG(FLogFormat(_L8("\tDeleting enumerate folder %d"), aId));
- User::LeaveIfError(iServerEntry.SetEntry(iSmsServiceId));
- User::LeaveIfError(iServerEntry.DeleteEntry(aId));
- }
- }
- }
-
-void CSmsSimUtils::DeleteChildrenL(TMsvId aId)
-/**
- * Deletes all messages under parent aId
- */
- {
- SMSSLOG(FLogFormat(_L8("\tDeleting children from %d"), aId));
-
- User::LeaveIfError(iServerEntry.SetEntry(aId));
-
- TMsvSelectionOrdering order;
- order.SetShowInvisibleEntries(ETrue);
- iServerEntry.SetSort(order);
-
- CMsvEntrySelection* sel = new (ELeave) CMsvEntrySelection();
- CleanupStack::PushL(sel);
- User::LeaveIfError(iServerEntry.GetChildren(*sel));
-
- if (sel->Count() != 0)
- {
- User::LeaveIfError(iServerEntry.DeleteEntries(*sel));
- }
-
- CleanupStack::PopAndDestroy(sel);
- }
-
-TMsvId CSmsSimUtils::CreateNewEnumerateFolderL()
-/**
- * Creates a new folder under the SMS service where phone-side messages will be stored
- * iSimUtilsData.iLastEnumerateFolder is set to the new folder's ID then stored against the SMS service
- *
- * @return the new folder's ID
- */
- {
- SMSSLOG(FLogFormat(_L8("\tCreating new folder...")));
- User::LeaveIfError(iServerEntry.SetEntry(iSmsServiceId));
-
- TMsvEntry entry;
-
- //Create a new invisible folder under the local service
- entry.SetVisible(EFalse);
- entry.iType = KUidMsvFolderEntry;
- entry.iMtm = KUidMsgTypeSMS;
- entry.iServiceId = iSmsServiceId;
- User::LeaveIfError(iServerEntry.CreateEntry(entry));
- iSimUtilsData.iLastEnumerateFolder = entry.Id();
-
- TRAPD(err, StoreSimUtilsDataL());
-
- if (err != KErrNone)
- {
- iServerEntry.DeleteEntry(entry.Id()); //remove the folder if StoreSimUtilsDataL() leaves
- User::Leave(err);
- }
-
- return iSimUtilsData.iLastEnumerateFolder;
- }
-
-void CSmsSimUtils::CountMessagesInPhoneStoresL()
- {
- SMSSLOG(FLogFormat(_L8("\tCounting Messages on SIM. Calling Ioctl KIoctlEnumerateSmsMessages")));
-
- User::LeaveIfError(iServerEntry.SetEntry(KMsvNullIndexEntryId));
- ConnectL();
- CreateBioDbL();
- iSocket.Ioctl(KIoctlEnumerateSmsMessages, iStatus, &iEnumerateCountBuf, KSolSmsProv);
- SetActive();
- }
-
-void CSmsSimUtils::CreateBioDbL()
- {
- if (iBioDb == NULL)
- iBioDb = CBIODatabase::NewL(iFs);
- }
-
-TBool CSmsSimUtils::GetDefaultSendBearerL(TInt aBioType, TBioMsgIdType aBearer, TBioMsgId& rBioMsgId) const
- {
- TInt index = 0;
- TUid uid;
- uid.iUid = aBioType;
- TBool found = EFalse;
- TRAPD(ret,iBioDb->GetBioIndexWithMsgIDL(uid, index)); //leaves with KErrNotFound if aBioType does not exist in bdb
- if (ret==KErrNone)
- {
- const CArrayFix<TBioMsgId>* bioIDs = iBioDb->BIOEntryLC(index);
- const TInt count = bioIDs->Count();
-
- for (TInt i = 0; !found && i < count; i++) //order important
- {
- rBioMsgId = bioIDs->At(i);
- found = (rBioMsgId.iType == aBearer);
- }
-
- CleanupStack::PopAndDestroy(); // bioIDs
- }
- else if (ret!=KErrNotFound)
- User::LeaveIfError(ret);
- return found;
- }
-
-TUid CSmsSimUtils::DecodeBioMessageL(TBioMsgId& rId)
- {
- TUid biomsguid=KNullUid;
- rId.iType=EBioMsgIdNbs;
- // Take text off front of message
- CSmsMessage& smsmessage=iHeader->Message();
- const TInt length=smsmessage.Buffer().Length();
- smsmessage.Buffer().Extract(rId.iText,0,length<KMaxBioIdText? length: KMaxBioIdText);
- TInt originator;
- TInt destination;
- // Has the message got application port addressing?
- if (smsmessage.SmsPDU().ApplicationPortAddressing(destination,originator))
- {
- rId.iPort=STATIC_CAST(TUint16,destination);
- rId.iType=EBioMsgIdWap;
- // Is it WAP?
- if (iBioDb->IsBioMessageL(rId,biomsguid)==KErrNotFound)
- {
- rId.iType=EBioMsgIdWapSecure;
- // Is it WAP secure?
- if (iBioDb->IsBioMessageL(rId,biomsguid)==KErrNotFound)
- {
- rId.iType=EBioMsgIdWsp;
- // Is it WSP?
- if(iBioDb->IsBioMessageL(rId,biomsguid)==KErrNotFound)
- {
- rId.iType=EBioMsgIdWspSecure;
- // Is it WSP secure?
- iBioDb->IsBioMessageL(rId,biomsguid);
- }
- }
- }
- }
- else
- {
- // Is it an NBS style text message?
- TInt index=rId.iText.Locate('\r');
- if (index==KErrNotFound)
- index=rId.iText.Locate('\n');
- // Look for text match in BIO database
- if ((index>0) && (iBioDb->IsBioMessageL(EBioMsgIdNbs,rId.iText.Left(index),0,biomsguid) != KErrNotFound))
- smsmessage.Buffer().DeleteL(0,index+1); // Remove BIO text
- }
- iHeader->SetBioMsgIdType(rId.iType);
- return biomsguid;
- }
-
-void CSmsSimUtils::EncodeBioMessageL()
- {
- CSmsMessage& smsmessage=iHeader->Message();
- TBioMsgId bioMsgId;
- // Is it a BIO message?
- if (GetDefaultSendBearerL(iServerEntry.Entry().iBioType, iHeader->BioMsgIdType(), bioMsgId))
- {
- switch (bioMsgId.iType)
- {
- case EBioMsgIdNbs:
- {
- // Put text on NBS message
- TBioMsgIdText text;
- CSmsBufferBase& buffer=smsmessage.Buffer();
- TInt textlength=bioMsgId.iText.Length();
- buffer.Extract(text,0,textlength<buffer.Length()? textlength: 0);
- if (bioMsgId.iText.CompareF(text))
- {
- _LIT(KSmsNewLine,"\n");
- buffer.InsertL(0,KSmsNewLine);
- buffer.InsertL(0,bioMsgId.iText);
- }
- break;
- }
- case EBioMsgIdWap:
- case EBioMsgIdWapSecure:
- case EBioMsgIdWsp:
- case EBioMsgIdWspSecure:
- {
- // Put port addressing on binary messages
- smsmessage.SmsPDU().SetApplicationPortAddressingL(ETrue,bioMsgId.iPort,bioMsgId.iPort,bioMsgId.iPort>255);
- smsmessage.SmsPDU().SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet8Bit);
- }
- default:
- break;
- }
- }
- }
-
-void CSmsSimUtils::SetupMoveDeleteL(const CMsvEntrySelection& aSelection, TRequestStatus& aStatus)
- {
- __ASSERT_DEBUG(aSelection.Count(), Panic(KSmssPanicNoMessagesInSelection));
-
- Queue(aStatus);
- iProgress = TSmsProgress();
-
- if (iSelection != &aSelection)
- {
- delete iSelection;
- iSelection = NULL;
- iSelection = aSelection.CopyL();
- iSelection->Delete(0); // Remove the SMS service entry id
- }
-
- iProgress.iMsgCount = iSelection->Count();
- }
-
-void CSmsSimUtils::DeleteEachMessageFromPhoneStoreL()
- {
- iState = ESimUtilsStateOther;
-
- if (iProgress.iMsgDone < iProgress.iMsgCount)
- {
- ConstructHeaderAndBodyL();
-
- const TMsvId id = iSelection->At(iProgress.iMsgDone);
- const TInt err = iServerEntry.SetEntry(id);
-
- if (err == KErrNone)
- {
- CMsvStore* store = iServerEntry.ReadStoreL();
- CleanupStack::PushL(store);
-
- store->RestoreBodyTextL(*iBody);
- iHeader->RestoreL(*store);
- CleanupStack::PopAndDestroy(); //store
-
- iProgress.iError = KErrNone;
-
- SMSSLOG(FLogMessage(iServerEntry.Entry(), iHeader->Message(), iHeader->BioMsgIdType(), KDeleteFromSimLog));
- SMSSLOG(FLogFormat(_L8("\tDeleting %d from SIM (%d/%d)"), id, iProgress.iMsgDone+1, iProgress.iMsgCount));
-
- iWriteStream << iHeader->Message();
- iWriteStream.CommitL();
- iSocket.Ioctl(KIoctlDeleteSmsMessage, iStatus, NULL, KSolSmsProv);
- iState = ESimUtilsDeleteEachMessage;
- }
- else
- {
- SMSSLOG(FLogFormat(_L8("\tIgnoring %d, Error=%d"), id, err));
- RequestComplete(&iStatus, KErrNone);
- }
-
- SetActive();
- iProgress.iMsgDone++;
- User::LeaveIfError(iServerEntry.SetEntry(KMsvNullIndexEntryId));
- }
- else
- {
- iState = ESimUtilsDeletedLastMessage;
- }
- }
-
-void CSmsSimUtils::ConstructHeaderAndBodyL()
- {
- if (!iParaFormat)
- iParaFormat = CParaFormatLayer::NewL();
-
- if (!iCharFormat)
- iCharFormat = CCharFormatLayer::NewL();
-
- if (!iBody)
- iBody = CRichText::NewL(iParaFormat, iCharFormat);
-
- if (!iHeader)
- iHeader = CSmsHeader::NewL(CSmsPDU::ESmsDeliver, *iBody);
- }
-
-void CSmsSimUtils::RestoreSimUtilsDataL()
-/**
- * Restore iSimUtilsData from the SMS service entry
- * Does not attempt to restore if the stream is not present
- */
- {
- User::LeaveIfError(iServerEntry.SetEntry(iSmsServiceId));
- CMsvStore* store = iServerEntry.ReadStoreL();
- CleanupStack::PushL(store);
-
- if (iSimUtilsData.IsPresentL(*store))
- {
- iSimUtilsData.RestoreL(*store);
- }
-
- CleanupStack::PopAndDestroy(store);
- }
-
-void CSmsSimUtils::StoreSimUtilsDataL()
-/**
- * Store iSimUtilsData against the SMS service entry
- */
- {
- User::LeaveIfError(iServerEntry.SetEntry(iSmsServiceId));
- CMsvStore* store = iServerEntry.EditStoreL();
- CleanupStack::PushL(store);
- iSimUtilsData.StoreL(*store);
- store->CommitL();
- CleanupStack::PopAndDestroy(store);
- }
-
-void CSmsSimUtils::DeleteFromPhoneStoreL(const CMsvEntrySelection& aSelection, TRequestStatus& aStatus)
- {
- SMSSLOG(FLogFormat(_L8("Deleting %d messages from SIM"), aSelection.Count()));
-
- SetupMoveDeleteL(aSelection, aStatus);
- DoDeleteFromPhoneStoreL();
- }
-
-void CSmsSimUtils::DoDeleteFromPhoneStoreL()
- {
- iProgress.iType = TSmsProgress::ESmsProgressTypeDeleteFromPhoneStore;
-
- ConnectL();
- RequestComplete(&iStatus, KErrNone, ETrue);
- }
-
-void CSmsSimUtils::DoDeleteThenMoveFromPhoneStoreL()
- {
- iProgress.iType = TSmsProgress::ESmsProgressTypeMoveFromPhoneStore;
-
- ConnectL();
- RequestComplete(&iStatus, KErrNone, ETrue);
- }
-
-void CSmsSimUtils::LoadClass2FolderIdL()
- {
- RestoreSmsSettingsL();
- iClass2Folder = iSettings->Class2Folder();
- }
-
-void CSmsSimUtils::RestoreSmsSettingsL()
- {
- CSmsAccount* account = CSmsAccount::NewLC();
- // just v2
- account->LoadSettingsL(*iSettings);
- CleanupStack::PopAndDestroy(account);
- }
-
-void CSmsSimUtils::CopyToPhoneStoreL(const CMsvEntrySelection& aSelection, const TDesC8& /*aParameter*/, TRequestStatus& aStatus)
- {
- SMSSLOG(FLogFormat(_L8("Copying messages to SIM")));
-
- __ASSERT_DEBUG(aSelection.Count(), Panic(KSmssPanicNoMessagesInSelection));
-
- SetupMoveDeleteL(aSelection,aStatus);
- iProgress.iType = TSmsProgress::ESmsProgressTypeCopyToPhoneStore;
- iProgress.iMsgCount = iSelection->Count();
- iProgress.iMsgDone = -1;
- iState=EWritingToSIM;
- iRecipientCount = 0;
- iRecipientIndex = 0;
-
- LoadClass2FolderIdL();
-
- ConnectL();
- ConstructHeaderAndBodyL();
- CreateBioDbL();
-
- DoCopyToPhoneStoreL();
- }
-
-void CSmsSimUtils::MoveToPhoneStoreL(const CMsvEntrySelection& aSelection, const TDesC8& /*aParameter*/, TRequestStatus& aStatus)
- {
- SMSSLOG(FLogFormat(_L8("Moving messages to SIM")));
-
- __ASSERT_DEBUG(aSelection.Count(), Panic(KSmssPanicNoMessagesInSelection));
-
- SetupMoveDeleteL(aSelection,aStatus);
- iProgress.iType = TSmsProgress::ESmsProgressTypeMoveToPhoneStore;
- iProgress.iMsgCount = iSelection->Count();
- iProgress.iMsgDone = -1;
- iState=EWritingToSIM;
- iRecipientCount = 0;
- iRecipientIndex = 0;
-
- LoadClass2FolderIdL();
-
- ConnectL();
- ConstructHeaderAndBodyL();
- CreateBioDbL();
-
- DoCopyToPhoneStoreL();
- }
-
-
-void CSmsSimUtils::DoCopyToPhoneStoreL()
- {
- User::LeaveIfError(iServerEntry.SetEntry(KMsvNullIndexEntryId));
- if(iState==EWritingToSIM)
- {
- if (iRecipientCount == 0)
- ++iProgress.iMsgDone;
-
- if (iProgress.iMsgDone < iProgress.iMsgCount)
- {
- User::LeaveIfError(iServerEntry.SetEntry(iSelection->At(iProgress.iMsgDone)));
-
- CMsvStore* store = iServerEntry.ReadStoreL();
- CleanupStack::PushL(store);
-
- iHeader->RestoreL(*store);
- iBody->Reset();
- store->RestoreBodyTextL(*iBody);
-
- CleanupStack::PopAndDestroy(); //store
-
- // Set correct address on the CSmsMessage if it out going
- CSmsMessage& smsmessage=iHeader->Message();
- if (smsmessage.Type()==CSmsPDU::ESmsSubmit || (smsmessage.Type()==CSmsPDU::ESmsCommand))
- {
- // Get the count of recipients for the current message
- if (iRecipientCount == 0)
- {
- iRecipientCount = iHeader->Recipients().Count();
- iRecipientIndex = 0;
- }
- // Create separate copy of message for each recipient
- if (iRecipientCount > 0)
- {
- CSmsNumber& rcpt = *iHeader->Recipients().At(iRecipientIndex);
- iHeader->Message().SetToFromAddressL(rcpt.Address());
- }
- ++iRecipientIndex;
- // Check if all the recipients are processed
- if (iRecipientIndex >= iRecipientCount)
- {
- // Yes all are done
- iRecipientIndex = 0;
- iRecipientCount = 0;
- }
- }
- SMSSLOG(FLogMessage(iServerEntry.Entry(), iHeader->Message(), iHeader->BioMsgIdType(), KCopyToSimLog));
-
- smsmessage.SetStorage(CSmsMessage::ESmsSIMStorage); //Set to store on SIM
-
- if (iServerEntry.Entry().Unread())
- {
- smsmessage.SetStatus(NMobileSmsStore::EStoredMessageUnread);
- }
- else
- {
- smsmessage.SetStatus(NMobileSmsStore::EStoredMessageRead);
- }
-
- // This may be a BIO message, so test and set up SMS message correctly!
- if ((smsmessage.Type()==CSmsPDU::ESmsSubmit) || (smsmessage.Type()==CSmsPDU::ESmsDeliver))
- EncodeBioMessageL();
-
- iWriteStream << iHeader->Message();
- iWriteStream.CommitL();
- iSocket.Ioctl(KIoctlWriteSmsMessage, iStatus, &iSlotBuffer, KSolSmsProv);
- SetActive();
-
- // if we have a class 2 folder, and its not the current parent
- // then update the class 2 folder with the new message one the sim
- if(iClass2Folder!=KMsvNullIndexEntryId &&
- iClass2Folder != iServerEntry.Entry().Parent())
- iState=EUpdatingClass2;
- else
- iState=EWritingToSIM;
- }
- }
- else
- {
- __ASSERT_DEBUG(iState==EUpdatingClass2,Panic(ESmssBadState));
- __ASSERT_DEBUG(iClass2Folder!=KMsvNullIndexEntryId,Panic(ESmssNoClass2Folder));
- TMsvId toCopy=iSelection->At(iProgress.iMsgDone);
- User::LeaveIfError(iServerEntry.SetEntry(toCopy));
-
- // Update the slot array of the CSmsMessage so that
- // it can be deleted at a later time without the need for a re-enumeration
- TMsvEntry entry = iServerEntry.Entry();
- TBool wasReadOnly = entry.ReadOnly();
-
- if (wasReadOnly)
- {
- entry.SetReadOnly(EFalse);
- iServerEntry.ChangeEntry(entry);
- }
-
- CMsvStore* store = iServerEntry.EditStoreL();
- CleanupStack::PushL(store);
- iHeader->RestoreL(*store);
- CSmsMessage& smsmessage=iHeader->Message();
-
- smsmessage.UpdateSlotsL(iSlotBuffer);
- smsmessage.SetStorage(CSmsMessage::ESmsSIMStorage);
- iHeader->StoreL(*store);
- store->CommitL();
-
- if (wasReadOnly)
- {
- entry.SetReadOnly(ETrue);
- iServerEntry.ChangeEntry(entry);
- }
-
- CleanupStack::PopAndDestroy(store);
- User::LeaveIfError(iServerEntry.SetEntry(iServerEntry.Entry().Parent()));
-
- if(iProgress.iType == TSmsProgress::ESmsProgressTypeMoveToPhoneStore)
- iServerEntry.MoveEntryL(toCopy,iClass2Folder,iStatus);
- else
- iServerEntry.CopyEntryL(toCopy,iClass2Folder,iStatus);
-
- SetActive();
- iState=EWritingToSIM;
- }
- }
-
-void CSmsSimUtils::CopyFromPhoneStoreL(const CMsvEntrySelection& aSelection, const TDesC8& aParameter, TRequestStatus& aStatus)
- {
- SMSSLOG(FLogFormat(_L8("Copying messages from phone store")));
- __ASSERT_DEBUG(aSelection.Count(), Panic(KSmssPanicNoMessagesInSelection));
-
- SetupMoveDeleteL(aSelection, aStatus);
- iProgress.iType = TSmsProgress::ESmsProgressTypeCopyFromPhoneStore;
- SetDestination(aParameter);
- MoveEntriesL(*iSelection, ETrue);
- }
-
-void CSmsSimUtils::MoveEntriesL(const CMsvEntrySelection& aSelection, TBool aCopy)
- {
- // Uses the enumeration folder under the service to copy from
- User::LeaveIfError(iServerEntry.SetEntry(aSelection[0]));
- User::LeaveIfError(iServerEntry.SetEntry(iServerEntry.Entry().Parent()));
- if (aCopy)
- {
- if (iCompletedSelection)
- iCompletedSelection->Reset();
- else
- iCompletedSelection = new(ELeave) CMsvEntrySelection;
-
- iServerEntry.CopyEntriesL(aSelection, iDestination, *iCompletedSelection, iStatus);
- }
- else
- iServerEntry.MoveEntriesL(aSelection, iDestination, iStatus);
- SetActive();
- }
-
-void CSmsSimUtils::MoveFromPhoneStoreL(const CMsvEntrySelection& aSelection, const TDesC8& aParameter, TRequestStatus& aStatus)
- {
- SMSSLOG(FLogFormat(_L8("Moving messages from phone store")));
- __ASSERT_DEBUG(aSelection.Count(), Panic(KSmssPanicNoMessagesInSelection));
-
- SetupMoveDeleteL(aSelection, aStatus);
- iProgress.iType = TSmsProgress::ESmsProgressTypeMoveFromPhoneStore;
- SetDestination(aParameter);
-
- DoDeleteThenMoveFromPhoneStoreL();
- }
-
-void CSmsSimUtils::SetDestination(const TDesC8& aParameter)
- {
- TPckgBuf<TMsvId> pkg;
- pkg.Copy(aParameter);
- iDestination = pkg();
- __ASSERT_DEBUG(iDestination, Panic(KSmssPanicDestinationFolderNotSet));
- }
-
-void CSmsSimUtils::SetLocalStorageInfoL(const CMsvEntrySelection& aSelection)
- {
- // After a copy/move from phone store the iSlotArray and Storage members
- // need to be reset to reflect the local storage.
- __ASSERT_DEBUG(aSelection.Count(), Panic(KSmssPanicNoMessagesInSelection));
- TInt count = aSelection.Count();
- ConstructHeaderAndBodyL();
- TBool wasReadOnly = EFalse;
-
- while (count--)
- {
- // RetrieveMessageFromPhoneStoreL() may have set the TMsvEntry
- // to read only if the message is a CSmsPDU::ESmsSubmit
- iServerEntry.SetEntry(aSelection.At(count));
- TMsvEntry entry = iServerEntry.Entry();
- wasReadOnly = entry.ReadOnly();
-
- if (wasReadOnly)
- {
- entry.SetReadOnly(EFalse);
- iServerEntry.ChangeEntry(entry);
- }
-
- CMsvStore* store = iServerEntry.EditStoreL();
- CleanupStack::PushL(store);
- iHeader->RestoreL(*store);
- CSmsMessage& smsmessage = iHeader->Message();
-
- // Set the destination attributes
- smsmessage.SetStorage(CSmsMessage::ESmsPhoneStorage);
- smsmessage.iSlotArray.Reset();
-
- iHeader->StoreL(*store);
- store->CommitL();
- CleanupStack::PopAndDestroy(store);
-
- if (wasReadOnly)
- {
- entry.SetReadOnly(ETrue);
- iServerEntry.ChangeEntry(entry);
- }
- }
- }
-
-void CSmsSimUtils::ConnectL()
- {
- ConnectL(iSocketServ, iSocket, ESmsAddrLocalOperation);
- }
-
-void CSmsSimUtils::ConnectL(RSocketServ& arSocketServ, RSocket& arSocket, TSmsAddrFamily aSmsAddrFamily)
- {
- if (!arSocketServ.Handle())
- {
- User::LeaveIfError(arSocketServ.Connect());
- }
-
- TProtocolDesc protoinfo;
- TProtocolName protocolname(KSmsDatagram);
- User::LeaveIfError(arSocketServ.FindProtocol(protocolname,protoinfo));
-
- if (!arSocket.SubSessionHandle())
- {
- User::LeaveIfError(arSocket.Open(arSocketServ,protoinfo.iAddrFamily,protoinfo.iSockType,protoinfo.iProtocol));
- }
-
- TSmsAddr smsaddr;
- smsaddr.SetSmsAddrFamily(aSmsAddrFamily);
- User::LeaveIfError(arSocket.Bind(smsaddr));
- }
-
-
-CSmsSimUtils::CSmsSimUtils(CMsvServerEntry& aServerEntry, RFs& aFs, TMsvId aSmsServiceId)
- : CSmssActive(aFs, aServerEntry),
- iState(ESimUtilsStateOther),
- iReadStream(iSocket),
- iSmsServiceId(aSmsServiceId),
- iWriteStream(iSocket)
- {
- CActiveScheduler::Add(this);
- }
-
-void CSmsSimUtils::DoRunReadSimParamsL()
-/**
- Retrive and store the parameters to the message store.
-
- @since 7.0
- @leave KErrNotFound
- @pre The reading async operation is complete.
- @post The parameters are retrived and stored in the message store.
- */
- {
- iProgress.iMsgDone = iSmsServiceId;
-
- CMobilePhoneSmspList* smspList = CMobilePhoneSmspList::NewL();
- CleanupStack::PushL(smspList);
-
- iReadStream >> *smspList;
-
- iProgress.iMsgCount = smspList->Enumerate();
-
- if (!iProgress.iMsgCount)
- User::Leave(KErrNotFound);
-
- User::LeaveIfError(iServerEntry.SetEntry(iSmsServiceId));
-
- CMsvStore* store = iServerEntry.EditStoreL();
- CleanupStack::PushL(store);
-
- CSmsSimParamOperation::StoreSimParamsL(*store, *smspList);
-
- CleanupStack::PopAndDestroy(2); //smspList, store
- User::LeaveIfError(iServerEntry.SetEntry(KMsvNullIndexEntryId));
- }
-
-void CSmsSimUtils::DoRunL()
-/**
- Handles completed async operations
-
- @since 7.0
- @leave ESmscPanicUnexpectedCommand, KErrNone
- @pre The async operation is complete
- @post The operation is complete
- */
- {
- switch (iProgress.iType)
- {
- case TSmsProgress::ESmsProgressTypeCopyFromPhoneStore:
- {
- __ASSERT_DEBUG(iCompletedSelection, Panic(KSmssPanicNoMessagesInSelection));
- SetLocalStorageInfoL(*iCompletedSelection);
- break;
- }
- case TSmsProgress::ESmsProgressTypeWriteSimParams:
- {
- break;
- }
- case TSmsProgress::ESmsProgressTypeReadSimParams:
- {
- if (iReadingSimParams)
- {
- iReadingSimParams = EFalse;
- TRAP(iProgress.iError, DoRunReadSimParamsL());
- iSocket.Ioctl(KIoctlCompleteReadSmsParams, iStatus, NULL, KSolSmsProv);
- SetActive();
- }
- break;
- }
- case TSmsProgress::ESmsProgressTypeEnumeratingPhoneStores:
- {
- iProgress.iMsgCount = iEnumerateCountBuf();
- RetrieveMessageFromPhoneStoreL();
- break;
- }
- case TSmsProgress::ESmsProgressTypeDeleteFromPhoneStore:
- {
- DeleteEachMessageFromPhoneStoreL();
- break;
- }
- case TSmsProgress::ESmsProgressTypeMoveFromPhoneStore:
- {
- DeleteEachMessageFromPhoneStoreL();
-
- if (iState == ESimUtilsDeletedLastMessage)
- {
- // We have finished deleting the messages from the SIM so set
- // the Storage & iSlotArray then move the entries
- SetLocalStorageInfoL(*iSelection);
- iState = ESimUtilsStateOther;
- iProgress.iType = TSmsProgress::ESmsProgressTypeMovingEntries;
- MoveEntriesL(*iSelection, EFalse);
- }
- break;
- }
- case TSmsProgress::ESmsProgressTypeCopyToPhoneStore:
- case TSmsProgress::ESmsProgressTypeMoveToPhoneStore:
- {
- DoCopyToPhoneStoreL();
- break;
- }
- case TSmsProgress::ESmsProgressTypeMovingEntries:
- break;
- default:
- {
- Panic(KSmssPanicUnexpectedState);
- }
- }
- }
-
-void CSmsSimUtils::RetrieveMessageFromPhoneStoreL()
- {
- // If one message fails to be restored the rest fail
- if (iProgress.iMsgDone < iProgress.iMsgCount)
- {
- CSmsMessage& smsmessage=iHeader->Message();
- iReadStream >> smsmessage;
-
- TUid biomsguid=KNullUid;
- TBioMsgId id;
- if ((smsmessage.Type()==CSmsPDU::ESmsSubmit) || (smsmessage.Type()==CSmsPDU::ESmsDeliver))
- biomsguid=DecodeBioMessageL(id);
-
- TMsvEntry entry;
- RestoreSmsSettingsL();
- TInt length = iSettings->DescriptionLength();
- HBufC* buf = HBufC::NewLC(length);
- TPtr description = buf->Des();
-
- if (biomsguid != KNullUid)
- {
- TSmsUtilities::PopulateMsgEntry(entry, smsmessage, iSmsServiceId, *iSettings, KUidBIOMessageTypeMtm);
-
- // BioficateEntry!!!
- // Set up all the needed ids
- entry.iBioType = biomsguid.iUid;
- entry.iServiceId = KMsvLocalServiceIndexEntryId;
- entry.iMtm = KUidBIOMessageTypeMtm;
-
- // Look up and set the description
- TInt index;
- iBioDb->GetBioIndexWithMsgIDL(biomsguid, index);
- description.Copy(iBioDb->BifReader(index).Description().Left(length));
- }
- else
- {
- // Set the details
- TSmsUtilities::PopulateMsgEntry(entry, smsmessage, iSmsServiceId, *iSettings);
-
- iGetDetDesc->GetDescription(smsmessage, description, length);
- }
-
- entry.iDescription.Set(description);
-
- if (smsmessage.Status() == NMobileSmsStore::EStoredMessageUnread)
- entry.SetUnread(ETrue);
- else
- entry.SetUnread(EFalse);
-
- TBuf<KSmsDetailsLength> details;
- if (iGetDetDesc->GetDetails(iFs, smsmessage, details) == KErrNone)
- entry.iDetails.Set(details);
-
- User::LeaveIfError(iServerEntry.SetEntry(iProgress.iEnumerateFolder));
- User::LeaveIfError(iServerEntry.CreateEntry(entry));
- User::LeaveIfError(iServerEntry.SetEntry(entry.Id()));
- CMsvStore* store = iServerEntry.EditStoreL();
- CleanupStack::PushL(store);
- store->StoreBodyTextL(*iBody);
- iHeader->StoreL(*store);
- store->CommitL();
-
- if (iHeader->Type() != CSmsPDU::ESmsSubmit)
- {
- entry.SetReadOnly(ETrue);
- }
-
- entry.iSize = store->SizeL();
- CleanupStack::PopAndDestroy(store);
- User::LeaveIfError(iServerEntry.ChangeEntry(entry));
-
- SMSSLOG(FLogMessage(entry, iHeader->Message(), iHeader->BioMsgIdType(), KEnumerateSimLog));
-
- User::LeaveIfError(iServerEntry.SetEntry(KMsvNullIndexEntryId));
-
- iSocket.Ioctl(KIoctlReadMessageSucceeded, iStatus, NULL, KSolSmsProv);
- SetActive();
-
- iProgress.iMsgDone++;
-
- SMSSLOG(FLogFormat(_L8("\tRead %d from SIM (%d/%d)"), entry.Id(), iProgress.iMsgDone, iProgress.iMsgCount));
-
- CleanupStack::PopAndDestroy(buf);
- }
- }
-
-void CSmsSimUtils::DoComplete(TInt& aStatus)
- {
- if (iState == ESimUtilsDeleteEachMessage && aStatus == KErrNotFound)
- {
-#ifndef _MSG_NO_LOGGING
- const TMsvId id = iServerEntry.Entry().Id();
- _LIT(KLogTxt, "\tERROR: %d NOT deleted from the SIM. Error=KErrNotFound");
- SMSSLOG(FLogFormat(KDeleteFromSimLog, KLogTxt, id));
- SMSSLOG(FLogFormat(KLogTxt, id));
-#endif
-
- TRAP(iProgress.iError, DeleteEachMessageFromPhoneStoreL());
- }
- else if (aStatus != KErrNone)
- {
- iServerEntry.SetEntry(KMsvNullIndexEntryId);
- iProgress.iError = aStatus;
- }
-
-#ifndef _MSG_NO_LOGGING
- if (!IsActive())
- SMSSLOG(FLogFormat(_L8("SmsSimUtils completed. Error %d, MsgCount %d, MsgDone %d"), iProgress.iError, iProgress.iMsgCount, iProgress.iMsgDone));
-#endif
-
- aStatus = KErrNone;
- }
-
-void CSmsSimUtils::DoSmssCancel()
- {
- if (iSocket.SubSessionHandle())
- iSocket.CancelIoctl();
- }
-
-
-/**
- * TSmsSimUtilsData
- */
-
-void TSmsSimUtilsData::StoreL(CMsvStore& aStore) const
- {
- RMsvWriteStream writeStream;
- writeStream.AssignLC(aStore, KSmsSimUtilsDataUid);
- ExternalizeL(writeStream);
- writeStream.CommitL();
- CleanupStack::PopAndDestroy(&writeStream);
- }
-
-void TSmsSimUtilsData::RestoreL(const CMsvStore& aStore)
- {
- RMsvReadStream readStream;
- readStream.OpenLC(aStore, KSmsSimUtilsDataUid);
- InternalizeL(readStream);
- CleanupStack::PopAndDestroy(&readStream);
- }
-
-void TSmsSimUtilsData::ExternalizeL(RWriteStream& aStream) const
- {
- aStream.WriteInt16L(KSmsSimUtilsDataVersion);
- aStream.WriteInt32L(iLastEnumerateFolder);
- }
-
-void TSmsSimUtilsData::InternalizeL(RReadStream& aStream)
- {
- aStream.ReadInt16L(); // version, not used until version > 1
- iLastEnumerateFolder = aStream.ReadInt32L();
- }