diff -r 000000000000 -r 72b543305e3a mobilemessaging/smsmtm/servermtm/src/SMSSendSession.cpp --- /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 +#include +#include + +#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(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(); + }