mobilemessaging/smsmtm/servermtm/src/SMSSendSession.cpp
changeset 0 72b543305e3a
child 55 5b3b2fa8c3ec
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mobilemessaging/smsmtm/servermtm/src/SMSSendSession.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,303 @@
+// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "SMSSendSession.h"
+
+#include <msventry.h>
+#include <smutset.h>
+#include <smuthdr.h>
+
+#include "SMSSPAN.H"
+#include "SMSSSEND.H"
+#include "SMSRecipientSend.h"
+
+const TInt KErrUnknownBioType = KErrNotSupported;
+
+CSmsSendSession* CSmsSendSession::NewL(TSmsProgress& aProgress, CMsvServerEntry& aServerEntry, RFs& aFs, CSmsHeader& aHeader, CRichText& aRichText, TMsvEntry& aEntry)
+	{
+	CSmsSendSession* self = new (ELeave) CSmsSendSession(aProgress, aFs, aServerEntry, aHeader);
+	CleanupStack::PushL(self);
+
+	self->ConstructL(aRichText, aEntry);
+
+	CleanupStack::Pop();
+
+	return self;
+	}
+
+CSmsSendSession::CSmsSendSession(TSmsProgress& aProgress, RFs& aFs, CMsvServerEntry& aServerEntry, CSmsHeader& aHeader)
+	: CSmssActive(aFs, aServerEntry, KSmsSessionPriority), iProgress(aProgress), iSmsHeader(aHeader)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CSmsSendSession::~CSmsSendSession()
+	{
+	if (iSendTypes)
+		iSendTypes->ResetAndDestroy();
+
+	delete iSendTypes;
+	delete iSmsSend;
+	}
+
+void CSmsSendSession::ConstructL(CRichText& aRichText, TMsvEntry& aEntry)
+	{
+	iSendTypes = new (ELeave) CArrayPtrFlat<CSmsSendType>(1);
+	iSmsSend = CSmsSend::NewL(iProgress, iServerEntry, iFs, iSmsHeader, aRichText, aEntry);
+	}
+
+void CSmsSendSession::DivideMessagesL(CMsvEntrySelection& aSelection)
+	{
+	iProgress.iMsgCount = 0;
+	TInt selCount = aSelection.Count();
+
+	if (!selCount)
+		User::Leave(KErrNotFound);
+
+	CreateRecipientsL();
+	const TInt typeCount = iSendTypes->Count();
+	TInt divideError = KErrNone; //Used later as the error code to leave with if aSelection.Count() == 0
+
+	//Order important
+	while (selCount--)
+		{
+		TMsvId id = aSelection[selCount];
+		TInt err = iServerEntry.SetEntry(id);
+    	SMSSLOG(FLogFormat(_L8("CSmsSendSession::DivideMessagesL() - switch to entry: %d, err: %d"), id, err ));
+
+		if (!err)
+			{
+			TMsvEntry entry = iServerEntry.Entry();
+
+			if(entry.InPreparation())
+				{
+		    	SMSSLOG(FLogFormat(_L8("CSmsSendSession::DivideMessagesL() - entry is in preparation - deleting it from selection array...")));
+				aSelection.Delete(selCount);
+				}
+			else
+				{   
+				//Restore the CSmsHeader
+				CMsvStore* store = NULL;
+				TInt error = KErrNone;
+				TRAP(error, store = iServerEntry.ReadStoreL());
+				if(error == KErrAccessDenied )
+					{
+		    		SMSSLOG(FLogFormat(_L8("CSmsSendSession::DivideMessagesL() - Error = -21 - deleting it from selection array...")));
+					entry.SetSendingState(KMsvSendStateWaiting);
+					iServerEntry.ChangeEntry(entry);
+					aSelection.Delete(selCount);
+					}
+				else
+					{
+					User::LeaveIfError(error);
+					CleanupStack::PushL(store);
+					iSmsHeader.RestoreL(*store);
+					CleanupStack::PopAndDestroy(); //store
+
+					TBool msgAdded = EFalse;
+
+					for(TInt curType = 0; curType < typeCount && !msgAdded; curType++)
+						{
+						CSmsSendType* smsType = iSendTypes->At(curType);
+		
+						if (smsType->iRecipientSend->AcceptMessage(entry, iSmsHeader))
+							{
+							smsType->iSelection->InsertL(0, id);
+							iProgress.iMsgCount++;
+							msgAdded = ETrue;
+							}
+						} //end for curType
+
+					if (!msgAdded)
+						{
+						SMSSLOG(FLogFormat(_L8("\tCannot send message %d - Invalid bioType (%d) and bioIdType (%d) combination"), id, entry.iBioType, iSmsHeader.BioMsgIdType()));
+
+						//Message is not going to be sent, so set failed
+						entry.SetFailed(ETrue);
+						entry.SetSendingState(KMsvSendStateFailed);
+						entry.iError = KErrUnknownBioType;
+						divideError = KErrUnknownBioType;
+						iServerEntry.ChangeEntry(entry); //ignore error?
+
+						aSelection.Delete(selCount);
+						}	
+					}
+				}
+			} 
+		else //SetEntry() failed
+			{
+			SMSSLOG(FLogFormat(_L8("\tCannot send message %d - iServerEntry.SetEntry(%d) returned error %d"), id, id, err));
+
+			if (err != KErrNotFound && err != KErrLocked)
+				User::Leave(err);
+
+			if (!divideError && divideError != KErrUnknownBioType)
+				divideError = err;
+
+			aSelection.Delete(selCount);
+			}
+		} //end for curMsg
+
+	if (!iProgress.iMsgCount)
+		{
+		SMSSLOG(FLogFormat(_L8("\tNO messages to send - CSmsSendSession::DivideMessagesL() error %d"), divideError));
+		User::Leave(divideError);
+		}
+    SMSSLOG(FLogFormat(_L8("CSmsSendSession::DivideMessagesL() - END") ));
+	}
+
+void CSmsSendSession::CreateRecipientsL()
+	{
+	SMSSLOG(FLogFormat(_L8("CSmsSendSession::CreateRecipientsL() - iServerEntry id: %d"), iServerEntry.Entry().Id() ));
+	//Create WAP and Text Recipients.
+	//Note: The order of adding rcptWap and rcptText to iSendTypes is important
+	//because rcptText->AcceptMessage() always returns ETrue, therefore rcptWap
+	//must be inserted before rcptText.
+
+	//Create a Wap Recipient
+	CWapRecipientSend* rcptWap = CWapRecipientSend::NewL(iProgress, iFs, iServerEntry);
+	CleanupStack::PushL(rcptWap);
+	CSmsSendType* smsType = CSmsSendType::NewL(rcptWap);
+	CleanupStack::PushL(smsType);
+	iSendTypes->AppendL(smsType);
+	CleanupStack::Pop(2); //rcptWap, smsType
+
+	//Create a Text Recipient
+	CTextRecipientSend* rcptText = CTextRecipientSend::NewL(iProgress, iFs, iServerEntry);
+	CleanupStack::PushL(rcptText);
+	smsType = CSmsSendType::NewL(rcptText);
+	CleanupStack::PushL(smsType);
+	iSendTypes->AppendL(smsType);
+	CleanupStack::Pop(2); //rcptText, smsType
+	}
+
+TMsvId CSmsSendSession::IncSms()
+	{
+	CSmsSendType* sendType = NULL;
+	TInt typeCount = iSendTypes->Count();
+
+	iId = 0;
+
+	if (typeCount)
+		{
+		while (iCurrentSendType < typeCount && !iId)
+			{
+			sendType = iSendTypes->At(iCurrentSendType);
+			CMsvEntrySelection& selection = *(sendType->iSelection);
+			sendType->iCurrentMessage++;
+
+			if (sendType->iCurrentMessage < selection.Count())
+				{
+				iId = selection[sendType->iCurrentMessage];
+				}
+			else
+				{
+				iCurrentSendType++;
+				}
+			}
+		}
+
+	return iId;
+	}
+
+void CSmsSendSession::SendSms(TRequestStatus& aStatus)
+	{
+	SMSSLOG(FLogFormat(_L8("CSmsSendSession::SendSms() - START - iId: %d"), iId ));
+	Queue(aStatus);
+
+	if (iId)
+		{
+		iState = ESessionSending;
+		CSmsSendType* sendType = iSendTypes->At(iCurrentSendType);
+		iSmsSend->Start(iStatus, iId, sendType->iRecipientSend);
+		}
+	else
+		{
+		iState = ESessionNoMoreMessages;
+		RequestComplete(&iStatus, KErrNotFound, EFalse);
+		}
+
+	SetActive();
+	SMSSLOG(FLogFormat(_L8("CSmsSendSession::SendSms() - END - iId: %d, iState: %d"), iId, iState ));
+	}
+
+void CSmsSendSession::DoSmssCancel()
+	{
+	SMSSLOG(FLogFormat(_L8("CSmsSendSession::DoSmssCancel() - iId: %d, iState: %d"), iId, iState ));
+	switch (iState)
+		{
+		case ESessionSending:
+			iSmsSend->Cancel();
+			break;
+		default:
+			break;
+		}
+	}
+
+void CSmsSendSession::DoRunL()
+	{
+	SMSSLOG(FLogFormat(_L8("CSmsSendSession::DoSmssCancel() - START - iId: %d, iState: %d"), iId, iState ));
+	switch (iState)
+		{
+		case ESessionSending:
+			break;
+		case ESessionNoMoreMessages:
+		case ESessionNoSendTypes:
+			iProgress.iError = KErrNotFound;
+			break;
+		default:
+			Panic(KSmssPanicUnexpectedState);
+		}
+	SMSSLOG(FLogFormat(_L8("CSmsSendSession::DoSmssCancel() - END - iId: %d, iState: %d"), iId, iState ));
+	}
+
+void CSmsSendSession::DoComplete(TInt& aStatus)
+	{
+	SMSSLOG(FLogFormat(_L8("CSmsSendSession::DoSmssCancel() - aStatus: %d, iState: %d, iProgress.iError: %d"), aStatus, iState, iProgress.iError ));
+	if (aStatus != KErrNone && iProgress.iError == KErrNone)
+		{
+		iProgress.iError = aStatus;
+		}
+
+	aStatus = KErrNone;
+	}
+
+CSmsSendSession::CSmsSendType* CSmsSendSession::CSmsSendType::NewL(CSmsRecipientSend* aRecipient)
+	{
+	CSmsSendType* self = new (ELeave) CSmsSendType(aRecipient);
+	CleanupStack::PushL(self);
+
+	self->ConstructL();
+
+	CleanupStack::Pop();
+
+	return self;
+	}
+
+CSmsSendSession::CSmsSendType::CSmsSendType(CSmsRecipientSend* aRecipient)
+: iRecipientSend(aRecipient), iCurrentMessage(-1)
+	{
+	}
+
+CSmsSendSession::CSmsSendType::~CSmsSendType()
+	{
+	delete iRecipientSend;
+	delete iSelection;
+	}
+
+void CSmsSendSession::CSmsSendType::ConstructL()
+	{
+	iSelection = new (ELeave) CMsvEntrySelection();
+	}