diff -r 238255e8b033 -r 84d9eb65b26f messagingappbase/smsmtm/servermtm/src/SmssSimUtils.cpp --- 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 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* 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,lengthIsBioMessageL(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,textlength255); - 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 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 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(); - }