Esempio n. 1
0
void CMsgImOutboxSend::CleanUpOnDestructL()
    {
	if(!iSetDisconnected)
		{
		DisconnectUnsentMessagesL();
		}

	if (iStatus.Int() != KErrNone)
		{
		if ((iCurrentMessageNo != -1) && (iCurrentMessageNo<iTotalMessages))
			{
			TInt err=iServerEntry.SetEntry(iEntrySelection.At(iCurrentMessageNo));
			if(err == KErrNotFound)
				{
				User::Leave(KErrNotFound);
				}
			__ASSERT_DEBUG(err == KErrNone, gPanic(EImsmServerError));
			TMsvEntry entry = iServerEntry.Entry();

			RestoreBccRecipientsToHeaderL();

			//	Set date info and completion data..update the iServerEntry with this data..
			TInt errorCode = (TSmtpSessionError)iStatus.Int();
			entry.iDate.UniversalTime();
			if(errorCode!=KErrCancel)
				{
				entry.SetFailed(errorCode != KErrNone);
				entry.SetSendingState(errorCode==KErrNone? KMsvSendStateSent: KMsvSendStateWaiting);  //set it to send agian.
				if (errorCode)
					entry.iError=CalculateError(errorCode);
				}
			else
				{
				entry.SetFailed(EFalse);
				entry.SetSendingState(KMsvSendStateSuspended);
				entry.iError=KErrNone;
				}
			entry.SetConnected(EFalse);
		#ifdef _DEBUG
			err = 
		#endif
			iServerEntry.ChangeEntry(entry);
			__ASSERT_DEBUG(err == KErrNone, gPanic(EImsmServerError));
			}
		}
	}
void CSmsReplyToStep::CreateMessageL()
	{
	INFO_PRINTF1(_L("Creating message..."));
	
	TMsvEntry entry;
	entry.SetVisible(ETrue); 
	entry.SetInPreparation(ETrue); 
	entry.iServiceId = iTestUtils->iSmsServiceId; 
	entry.iType = KUidMsvMessageEntry; 
	entry.iMtm = KUidMsgTypeSMS; 
	entry.iDate.HomeTime(); 
	entry.iSize = 0; 
	entry.iDescription.Set(KNullDesC); 
	entry.iDetails.Set(KNullDesC); 
	entry.SetSendingState(KMsvSendStateScheduled);

	// Create the SMS header object...
	CSmsHeader* header = CSmsHeader::NewL(CSmsPDU::ESmsSubmit, *iTestUtils->iRichText);
	CleanupStack::PushL(header);
	
	// Set the body text...
	iTestUtils->iRichText->Reset();
	iTestUtils->iRichText->InsertL(0, KMessageData);
	
	// Copy the message settings...
	header->SetSmsSettingsL(*iTestUtils->iServiceSettings); 
	
	// Set the service centre
	TInt defaultIndex = iTestUtils->iServiceSettings->DefaultServiceCenter();
	header->SetServiceCenterAddressL(iTestUtils->iServiceSettings->GetServiceCenter(defaultIndex).Address());

	// Set recipient - ask derived class
	SetRecipientsL(*header);
	
	// Update entry description and details...
	CArrayPtrFlat<CSmsNumber>& recipient = header->Recipients();
	entry.iDetails.Set(recipient[0]->Address());
	entry.iDescription.Set(iTestUtils->iRichText->Read(0, iTestUtils->iServiceSettings->DescriptionLength()));
	entry.SetInPreparation(EFalse);
	
	// Create the entry - set context to the global outbox.
	iTestUtils->iMsvEntry->SetEntryL(KMsvGlobalOutBoxIndexEntryId);
	iTestUtils->iMsvEntry->CreateL(entry);

	// Create new store and save header information 
	iTestUtils->iMsvEntry->SetEntryL(entry.Id()); 
	CMsvStore* store = iTestUtils->iMsvEntry->EditStoreL(); 
	CleanupStack::PushL(store); 
	header->StoreL(*store);
	store->StoreBodyTextL(*iTestUtils->iRichText);
	store->CommitL(); 
	CleanupStack::PopAndDestroy(2, header); 
	
	iMessageId = entry.Id();

	}
/**
Utility function that updates message index entry fields to reflect 
the message's scheduling.

@param aRef 
Scheduler item.

@param aInfo 
Scheduler task information.

@param aTime 
Schedule start time.

@param aFinalState 
Sending state flag.

@param aEntry 
On return, updated index entry.

@param aData 
On return, populated messaging scheduling data.
*/
EXPORT_C void CMsvScheduleSend::UpdateEntryAfterSchedule(const TSchedulerItemRef& aRef, const TTaskInfo& aInfo, const TTime& aTime, TInt aFinalState, TMsvEntry& aEntry, TMsvEntryScheduleData& aData)
	{
	aEntry.SetScheduled(ETrue);
	aEntry.SetFailed(EFalse);
	aEntry.SetSendingState(aFinalState);
	aEntry.SetConnected(EFalse);
	aEntry.iDate = aTime;
	aData.iRef = aRef;
	aData.iTaskId = aInfo.iTaskId;
	}
Esempio n. 4
0
void CMsvSendExe::AddTaskL(const TMsvSchedulePackage& aPackage)
	{
	CMsvEntry* cEntry = NULL;
	TRAPD(err, cEntry = iSession->GetEntryL(aPackage.iId));

	if (err != KErrNotFound)
		{
		User::LeaveIfError(err);
		CleanupStack::PushL(cEntry);

		TMsvEntry entry = cEntry->Entry();
		const TInt sendState = entry.SendingState();

		//Only send the message if sending state is Scheduled or Resend.
		if (entry.Scheduled() && (sendState == KMsvSendStateScheduled || sendState == KMsvSendStateResend))
			{
			entry.SetSendingState(KMsvSendStateWaiting);

			// Fix for DEF000924: Need to be able to send/cancel an sms while another is being sent
			if (entry.iServiceId == KMsvLocalServiceIndexEntryId && entry.iRelatedId != KMsvNullIndexEntryId)
				{
				SCHSENDLOG(  FLog(iFileName, _L("Changing service from %x to %x"), entry.iServiceId, entry.iRelatedId));
				entry.iServiceId = entry.iRelatedId;
				}
			else
				{
				SCHSENDLOG(  FLog(iFileName, _L("Not changing service from %x (related=%x)"), entry.iServiceId, entry.iRelatedId));
				}
			// End of fix

 			cEntry->ChangeL(entry);
			AddTaskL(aPackage, entry.iMtm);
			SCHSENDLOG(FLog(iFileName, _L("\t\tMsg=%d [Mtm=%d SendState=%d]"), aPackage.iId, entry.iMtm.iUid, entry.SendingState()));
			}
		else
			{
			SCHSENDLOG(FLog(iFileName, _L("\t\tIGNORING Msg=%d (Mtm=%d SendState=%d Scheduled=%d)"), aPackage.iId, entry.iMtm.iUid, sendState, entry.Scheduled()));
			}

		CleanupStack::PopAndDestroy(cEntry);
		}
	else
		{
		SCHSENDLOG(FLog(iFileName, _L("\t\tIGNORING Msg=%d: NOT FOUND"), aPackage.iId));
		}
	}
void CBulkCommitServerMtm::CreateBulkEntries(TUint aEntryCount, TMsvId aServiceId)
	{	
	TMsvEntry newEntry;
	for (TInt i = 0; i < aEntryCount; ++i)
		{
		newEntry.iType = KUidMsvMessageEntry;
		newEntry.iMtm = KUidBulkCommitTestMtm;
		newEntry.iServiceId = aServiceId;		
		newEntry.SetVisible(ETrue);
		newEntry.SetReadOnly(EFalse);
		newEntry.SetUnread(ETrue);
		newEntry.iDescription.Set(_L("Bulk Entry"));
		newEntry.SetSendingState(KMsvSendStateNotApplicable);
		
		iServerEntry->CreateEntryBulk(newEntry);	
		}
	}
/*
Creates two folders and then creates bulk entries under each folder.
After bulk commit, creates an entry to let the client know about 
bulk commit is done.
@param aEntryCount - Bulk entries to be created under each root entry
*/
void CBulkCommitServerMtm::CreateBulkEntryWithMultipleParentsL(TUint aEntryCount)
	{	
	iServerEntry->SetEntry(iServiceId);
	
	TMsvEntry folderEntry1, folderEntry2;
	//create the first folder
	folderEntry1.iType=KUidMsvFolderEntry;
	folderEntry1.iMtm = KUidBulkCommitTestMtm;
	folderEntry1.iServiceId = iServiceId;	
	iServerEntry->CreateEntry(folderEntry1);
	
	//create the second folder entry
	folderEntry2.iType=KUidMsvFolderEntry;
	folderEntry2.iMtm = KUidBulkCommitTestMtm;
	folderEntry2.iServiceId = iServiceId;	
	iServerEntry->CreateEntry(folderEntry2);
	
	iServerEntry->SetEntry(folderEntry1.Id());
	//Create a series of entries using the bulk API under the first folder
	CreateBulkEntries(aEntryCount, folderEntry1.Id());
	
	iServerEntry->SetEntry(folderEntry2.Id());
	//Create a series of entries using the bulk API under the second folder
	CreateBulkEntries(aEntryCount, folderEntry2.Id());
	
	//commit the bulk entries
	iServerEntry->CompleteBulk();
	
	iServerEntry->SetEntry(iServiceId);
	//Let the client know that the bulk commit is done
	TMsvEntry childEntry;	
	childEntry.iType = KUidMsvMessageEntry;
	childEntry.iMtm = KUidBulkCommitTestMtm;
	childEntry.iServiceId = iServiceId;		
	childEntry.SetVisible(ETrue);
	childEntry.SetReadOnly(EFalse);
	childEntry.SetUnread(ETrue);
	childEntry.iDescription.Set(_L("Bulk Commit Done"));
	childEntry.SetSendingState(KMsvSendStateNotApplicable);	
	iServerEntry->CreateEntry(childEntry);
	
	//Set entry to NULL entry to avoid locking	
	iServerEntry->SetEntry(KMsvNullIndexEntryId);		
	}
Esempio n. 7
0
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
void CSMSSender::PopulateMessageL(TMsvEntry& aMsvEntry,TDes& aDescription,TDes& aDetails)
    {
    ASSERT(iMtm);

	// We get the message body from Mtm and insert a bodytext
	CRichText& mtmBody = iMtm->Body();
	mtmBody.Reset();
	mtmBody.InsertL(0, iMessage);   // insert our msg tag as the body text

	if(iDescription)
	{	
		if(iDescription->Des().Length() > 30)
			aDescription.Copy(iDescription->Des().Left(30));
		else
			aDescription.Copy(iDescription->Des());
	}
	else
	{	
		if(iMessage.Length() > 30)
			aDescription.Copy(iMessage.Left(30));
		else
			aDescription.Copy(iMessage);
	}	    	    	
	
    if(iDetails)
    {
    	if(iDetails->Des().Length() > 30)
			aDetails.Copy(iDetails->Des().Left(30));
		else
			aDetails.Copy(iDetails->Des());
    }
    else
	{ 
		if(iRecipients.Length() > 30)
			aDetails.Copy(iRecipients.Left(30));
		else
			aDetails.Copy(iRecipients);	
	}
	
	aMsvEntry.SetInPreparation(EFalse);            
	aMsvEntry.SetScheduled(EFalse);
	aMsvEntry.iDate.UniversalTime();
	aMsvEntry.SetSendingState(KMsvSendStateWaiting); 
}
void CPigeonServerMtm::SendScheduledL(CMsvEntrySelection& aSelection, const TBool /*aMove*/, const TDesC8& /*aParameter*/, TRequestStatus& /*aStatus*/)
{
    TBool leave = EFalse;
    for ( TInt i = 0; i < aSelection.Count(); ++i )
    {
        // Move message to the sent folder, and update sending state to Sent.
        TInt err = iServerEntry->SetEntry(aSelection[i]);
        TMsvEntry entry = iServerEntry->Entry();

        // Check each message to see if it should be sent...
        if( entry.iError == KPigeonErrFailFirstSend )
        {
            leave = ETrue;
        }
        else
        {
            entry.SetSendingState(KMsvSendStateSent);
            entry.iDetails.Set(KSchSendTestDetails);
            err = iServerEntry->ChangeEntry(entry);
            TMsvId id = entry.Id();
            err = iServerEntry->SetEntry(KMsvSentEntryId);
            if(KErrNone == err)
            {
                err = iServerEntry->SetEntry(KMsvGlobalOutBoxIndexEntryId);
                if(KErrNone == err)
                {
                    // Move it...
                    err = iServerEntry->MoveEntryWithinService(id, KMsvSentEntryId);
                }
            }
        }
    }
    iServerEntry->SetEntry(KMsvNullIndexEntryId);

    if( leave )
        User::Leave(KErrDisconnected);
}
void CSmsCancelTest::CancelIfSendingL(const CMsvEntrySelection& aSelection)
	{
	const TInt count = aSelection.Count();

	for (TInt i = 0; i < count; i++)
		{
		TRAPD(err, iSmsTest.SetEntryL(aSelection[i]));

		if (!err)
			{
			TMsvEntry entry = iSmsTest.Entry();

			if (entry.SendingState() == KMsvSendStateSending)
				{
				if (iOperation)
					{
					iOperation->Cancel();
					return;
					}
				else
					{
					entry.SetSendingState(KMsvSendStateSuspended);
					TRAP(err, iSmsTest.ChangeEntryL(entry)); //ignore error

					if (err)
						{
						iSmsTest.Printf(_L("Error Cancelling Entry %d: On ChangeEntryL()\n"), aSelection[i]);
						} //end if
					} //end if
				} //end if
			}
		else
			{
			iSmsTest.Printf(_L("Error Cancelling Entry %d: On SetEntryL()\n"), aSelection[i]);
			}
		}
	}
TVerdict CCreateSmsMessageTestStep::doTestStepL()
	{

	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
	CActiveScheduler::Install(scheduler);
	CleanupStack::PushL(scheduler);

	CSessionObserver* sessionObserver = new (ELeave) CSessionObserver;
	CleanupStack::PushL(sessionObserver);
	CMsvSession* session = CMsvSession::OpenSyncL(*sessionObserver);
	CleanupStack::PushL(session);
	
	_LIT(KFileName,"FileName");
	TPtrC tag;
	if ( !GetStringFromConfig(ConfigSection(),KFileName,tag))
		{
		ERR_PRINTF1(_L("No Input for FileName in CreateSmsMessage"));
		User::Leave(KErrNotReady);
		}
	
	HBufC* fileName = tag.AllocLC();
	

	// Create a Rich Text object
	CPlainText::TTextOrganisation ttOrg = {CPlainText::EOrganiseByLine};

	CParaFormatLayer* paraFormatLayer = CParaFormatLayer::NewL();
	CleanupStack::PushL(paraFormatLayer);
	CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL();
	CleanupStack::PushL(charFormatLayer);
	CRichText* bodyRichText = CRichText::NewL(paraFormatLayer, charFormatLayer);
	CleanupStack::PushL(bodyRichText);
	
	// Store the file contents into the CRichText object
	bodyRichText->ImportTextFileL(0, fileName->Des(), ttOrg);
	
	
	// Create the SMS header object...
	CSmsHeader* header = CSmsHeader::NewL(CSmsPDU::ESmsSubmit, *bodyRichText);
	CleanupStack::PushL(header);
	
	// Set the body text...
	CSmsSettings* smsSettings = CSmsSettings::NewL();
	CleanupStack::PushL(smsSettings);

	CSmsAccount* account = CSmsAccount::NewLC();
	account->LoadSettingsL(*smsSettings);
	// Copy the message settings...
	header->SetSmsSettingsL(*smsSettings); 
	
	// Set the service centre
	TInt defaultIndex = smsSettings->DefaultServiceCenter();
	header->SetServiceCenterAddressL(smsSettings->GetServiceCenter(defaultIndex).Address());

	// Set recipient - ask derived class
	SetRecipientsL(*header);
	CArrayPtrFlat<CSmsNumber>& recipient = header->Recipients();

	INFO_PRINTF1(_L("Creating message..."));
	
	TMsvEntry entry;
	entry.SetVisible(ETrue); 
	entry.SetInPreparation(ETrue);
	TMsvId srvcId=0;
	TSmsUtilities::ServiceIdL(*session, srvcId);
	entry.iServiceId = srvcId;
	entry.iType = KUidMsvMessageEntry; 
	entry.iMtm = KUidMsgTypeSMS; 
	entry.iDate.UniversalTime();
	entry.iSize = 0; 
	entry.iDescription.Set(KNullDesC); 
	entry.iDetails.Set(KNullDesC); 
	entry.SetSendingState(KMsvSendStateWaiting);

	// Update entry description and details...
	entry.iDetails.Set(recipient[0]->Address());
	entry.iDescription.Set(recipient[0]->Address());
	entry.SetInPreparation(EFalse);

	//TPtrC tag;
	_LIT(KParent,"Parent");
	TPtrC parentTag;
	if ( !GetStringFromConfig(ConfigSection(),KParent,parentTag))
		{
		ERR_PRINTF1(_L("No Input for Outbox"));
		User::Leave(KErrNotReady);
		}
	// Create the entry - set context to the global outbox.
	TMsvId paramParentId =	MsgingUtils::GetLocalFolderId(parentTag);//KMsvGlobalOutBoxIndexEntryId;

	CMsvEntry* newEntry = CMsvEntry::NewL(*session,paramParentId,TMsvSelectionOrdering());
	CleanupStack::PushL(newEntry);
	newEntry->SetEntryL(paramParentId);
	
	newEntry->CreateL(entry);

	// Create new store and save header information
	newEntry->SetEntryL(entry.Id());
	CMsvStore* store = newEntry->EditStoreL();
	CleanupStack::PushL(store);
	header->StoreL(*store);
	store->StoreBodyTextL(*bodyRichText);
	store->CommitL();

//store,newEntry,account, smsSettings, header, bodyRichText,charFormatLayer, paraFormatLayer,fileName
	CleanupStack::PopAndDestroy(9,fileName); 
	
	CleanupStack::PopAndDestroy(3, scheduler);
	
	SetTestStepResult(EPass);
	
	return TestStepResult();
	}
Esempio n. 11
0
void CMsgImOutboxSend::SetLastMessageStatusL(const TTime& aTimeNow, TInt aCompletionReason)
	{
	//	If its the first message && there are messages to be sent change status..
	if (iTotalMessages>0) 
		{ 
		iProgress.SetStatus(EMsgOutboxProgressSending); 
		} 

	// Store the file progress for the last file sent. This will be used in
	// the situation where we cancel the operation to do a bearer migration
	// so that the progress information is for the last file completed as
	// opposed to the one we have just cancelled.
	if (iSession)
		{
		iProgress.iSendFileProgress = iSession->FileProgress();
		}

	//	Fill in the iServerEntry details with data from the last message
    //  IMCV may had left this inconsistent... so reset the iServerEntry
    //  explicitly....
	if (iCurrentMessageNo != -1)
		{     
		TInt err;
        err = iServerEntry.SetEntry(iEntrySelection.At(iCurrentMessageNo));
		__ASSERT_DEBUG( err == KErrNone, gPanic(EImsmServerError));
		TMsvEntry entry = iServerEntry.Entry();

		//	Set date info and completion data..update the iServerEntry with this data..
		entry.iDate=aTimeNow;
		if(aCompletionReason!=KErrCancel)
			{
			entry.SetFailed(aCompletionReason != KErrNone);
			entry.SetSendingState(aCompletionReason==KErrNone? KMsvSendStateSent: KMsvSendStateWaiting);  //set it to send agian.
			if (aCompletionReason)
				entry.iError=CalculateError(aCompletionReason);
			}
		else
			{
			entry.SetFailed(EFalse);
			entry.SetSendingState(KMsvSendStateSuspended);
			entry.iError=KErrNone;
			}

//		if (aCompletionReason<=KErrNone)
	//		{
			// ignore any +ve errors which may leak from the SMTP code
//			entry.iError=aCompletionReason;
//			entry.SetSendingState(aCompletionReason==KErrNone? KMsvSendStateSent: KMsvSendStateWaiting);  //set it to send agian.
//			}
		RestoreBccRecipientsToHeaderL();

        entry.SetConnected(EFalse);
		err = iServerEntry.ChangeEntry(entry);
		__ASSERT_DEBUG( err == KErrNone, gPanic(EImsmServerError));
		UpdateSummaryInfo(aCompletionReason);

        //  If it went move to the "Sent" folder..
        if(!entry.Failed() && aCompletionReason!=KErrCancel)
            {
            TMsvId id = entry.Id();
            err = iServerEntry.SetEntry(KMsvSentEntryIdValue);
            if(err == KErrNone)
                {
                err = iServerEntry.SetEntry(KMsvGlobalOutBoxIndexEntryId);
                if(err == KErrNone)
                    {
                    // Move it....
                    err = iServerEntry.MoveEntryWithinService(id, KMsvSentEntryIdValue);
                    }
                }
            }
		}
	}
Esempio n. 12
0
/**
Verifies that the schedule information stored in specified messages is the 
same as that on the task scheduler.

@param aSelection 
Array of message IDs that need to be checked against the task scheduler.

@panic ScheduleSend-DLL 0
The array of message IDs is empty.
Debug build only.
*/
EXPORT_C void CMsvScheduleSend::CheckScheduleL(const CMsvEntrySelection& aSelection)
	{
	__ASSERT_DEBUG(aSelection.Count(), gPanic(EMessageSelectionEmpty));

	GetMessagesL(aSelection);	//Leaves with KErrNotFound if there are no messages returned in iSchEntries
	TInt entryCount = iSchEntries->Count();
	SCHSENDLOG(FLog(_L8("Asked to check schedule for %d msgs"), entryCount));
	
	ConnectAndRegisterL();

	while (entryCount--)
		{
		TBool found = EFalse;
		TTsTime schTime;

		CMsvScheduledEntry& sEntry = *iSchEntries->At(entryCount);

		if (!sEntry.iData.IsReset())
			{
			TSchedulerItemRef ref;
			TInt size = 0;
			TTaskInfo info;
			
			TInt err = iScheduler.GetTaskDataSize(sEntry.iData.iTaskId, size);

			if (!err)
				{
				HBufC* buf = HBufC::NewLC(size);
				TPtr ptr = buf->Des();

				User::LeaveIfError(iScheduler.GetTaskInfoL(sEntry.iData.iTaskId, info, ptr, ref, schTime));

				CleanupStack::PopAndDestroy(buf);
				found = ETrue;
				}
			else if (err != KErrNotFound)
				{
				User::Leave(err);
				} 
			} 
			
		if (iServerEntry.SetEntry(sEntry.Id()) == KErrNone)
			{
			TMsvEntry entry = iServerEntry.Entry();
			TInt sendingState = entry.SendingState();

			if (sendingState == KMsvSendStateScheduled || sendingState == KMsvSendStateResend || entry.Scheduled())
				{
				if (found)
					{
					entry.SetScheduled(ETrue);
					entry.iDate = schTime.GetUtcTime();
					User::LeaveIfError(iServerEntry.ChangeEntry(entry));
					}
				else
					{
					entry.SetScheduled(EFalse);
					entry.SetSendingState(KMsvSendStateUnknown);
					entry.iDate.UniversalTime();
					User::LeaveIfError(iServerEntry.ChangeEntry(entry));
					SendingCompleteL(sEntry, EFalse);
					} 
				} 
			} 
		} 
	}
Esempio n. 13
0
void CSmsFile::send_messageL(const TDesC& recipient, const TDesC& body)
{
    if (iStatus==KRequestPending) {
        User::Leave(KErrServerBusy);
    }

    state=_L("send_messageL");

    TMsvEntry newEntry;								 // This represents an entry in the Message Server index
    newEntry.iMtm = KUidMsgTypeSMS;                         // message type is CSmsFile
    newEntry.iType = KUidMsvMessageEntry;                   // this defines the type of the entry: message
    newEntry.iServiceId = KMsvLocalServiceIndexEntryId;     // ID of local service (containing the standard folders)
    newEntry.iDate.HomeTime();                              // set the date of the entry to home time

    newEntry.SetInPreparation(ETrue);                       // a flag that this message is in preparation


    // get ref to outbox
    state=_L("NewL");
    CMsvEntry *entry =CMsvEntry::NewL(*iSession, KMsvGlobalOutBoxIndexEntryId ,TMsvSelectionOrdering());
    CleanupStack::PushL(entry);

    // create message in outbox
    state=_L("CreateL");
    entry->CreateL(newEntry);

    state=_L("GetEntry");
    entry = iSession->GetEntryL(newEntry.Id());

    // SetCurrentEntryL takes ownership of the CMsvEntry
    state=_L("SetCurrentEntry");
    iMtm->SetCurrentEntryL(entry);

    CleanupStack::Pop(); // entry

    state=_L("Entry()");
    TMsvEntry msvEntry = (iMtm->Entry()).Entry();

    state=_L("Body()");
    CRichText& mtmBody = iMtm->Body();
    mtmBody.Reset();

    state=_L("set message");
    mtmBody.InsertL(0, body);   // insert our msg tag as the body text

    // set iRecipient into the Details of the entry
    msvEntry.iDetails.Set(recipient);  // set recipient info in details
    msvEntry.SetInPreparation(EFalse);         // set inPreparation to false

    msvEntry.SetSendingState(KMsvSendStateWaiting);   // set the sending state (immediately)
    msvEntry.iDate.HomeTime();                        // set time to Home Time

    // To handle the CSmsFile specifics we start using SmsMtm
    CSmsClientMtm* smsMtm = STATIC_CAST(CSmsClientMtm*, iMtm);

    state=_L("RestoreServiceAndSettingsL");
    smsMtm->RestoreServiceAndSettingsL();

    state=_L("set header");
    // CSmsHeader encapsulates data specific for CSmsFile messages,
    // like service center number and options for sending.
    CSmsHeader& header = smsMtm->SmsHeader();
    state=_L("get options");

    if (!sendOptions) {
        sendOptions = CSmsSettings::NewL();
        sendOptions->CopyL(smsMtm->ServiceSettings()); // restore existing settings
        state=_L("SetDelivery");
        sendOptions->SetDelivery(ESmsDeliveryImmediately);      // set to be delivered immediately
    }

    // set send options
    // ERROR HERE!
    state=_L("SetSmsSettingsL");
    header.SetSmsSettingsL(*sendOptions);

    state=_L("check sc");
    // let's check if there's sc address
    if (header.Message().ServiceCenterAddress().Length() == 0)
    {
        // no, there isn't. We assume there is at least one sc number set and use
        // the default SC number.
        CSmsSettings* serviceSettings = &(smsMtm->ServiceSettings());

        // if number of scaddresses in the list is null
        if (!serviceSettings->NumSCAddresses())
        {
            // FIXME: what to do?
            User::Leave(1);
        } else {
            // set sc address to default.
            CSmsNumber* sc = 0;
            sc = &(serviceSettings->SCAddress(serviceSettings->DefaultSC()));
            header.Message().SetServiceCenterAddressL(sc->Address());
        }
    }

    state=_L("add addresses");
    // Add our recipient to the list, takes in two TDesCs, first is real address and second is an alias
    // works also without the alias parameter.
    smsMtm->AddAddresseeL(recipient, msvEntry.iDetails);

    // if message is to be deleted after sending, mark with our UID
    msvEntry.iMtmData3 = KUidRippleVaultApp.iUid;

    state=_L("save");
    // save message
    iMtm->Entry().ChangeL(msvEntry);                // make sure that we are handling the right entry
    smsMtm->SaveMessageL();                 // closes the message

    state=_L("move");
    // This moves the message entry to outbox, we'll schedule it for sending after this.
    //    TMsvId movedId = MoveMessageEntryL( KMsvGlobalOutBoxIndexEntryId );  // move message to outbox
    TMsvId movedId = iMtm->Entry().Entry().Id();

    // We must create an entry selection for message copies (although now we only have one message in selection)
    CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
    CleanupStack::PushL(selection);

    selection->AppendL(movedId);            // add our message to the selection

    TBuf8<1> dummyParams;
    //    CCommandAbsorbingControl::NewLC();

    state=_L("InvokeAsyncFunctionL");
    // invoking async schedule copy command on our mtm
    op=iMtm->InvokeAsyncFunctionL(
           ESmsMtmCommandScheduleCopy,
           *selection,
           dummyParams,
           iStatus);

    CleanupStack::Pop(); // selection

#ifdef __LOGME__
    iAppUi.LogText.Copy(_L("SENT\n"));
    iAppUi.WriteLogFile(iAppUi.LogText);
#endif

    SetActive();

    //return KErrNone;
}