messagingappbase/smsmtm/servermtm/src/SmssSimUtils.cpp
changeset 25 84d9eb65b26f
parent 23 238255e8b033
child 27 e4592d119491
child 37 518b245aa84c
child 79 2981cb3aa489
--- 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();
-	}