--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/smsprotocols/smsstack/smsprot/Src/smspsend.cpp Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,767 @@
+// Copyright (c) 1997-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:
+// Implementation for the CSmsuActiveBase based class CSmsMessageSend.
+//
+//
+
+/**
+ @file
+ @internalAll
+*/
+
+#include "smspsend.h"
+#include "smspstor.h"
+#include "smspmain.h"
+#include "smsuset.h"
+#include "smsulog.h"
+#include "exterror.h"
+#include "gsmubuf.h"
+#include "SmsuTimer.h"
+#include <logwraplimits.h>
+
+
+/**
+ * Static object constructor for CSmsMessageSend.
+ *
+ * @param aSegmentationStore Segmentation Store.
+ * @param aSmsMessaging ETel SMS messaging subsession.
+ * @param aSmsSettings The global SMS settings.
+ * @param aMobileSmsCaps SMS messaging capabilities of TSY/phone.
+ * @param aPriority Priority to use for the Active Object.
+ * @param aSmspSetBearer Set bearer object.
+ */
+CSmsMessageSend* CSmsMessageSend::NewL(CSmsSegmentationStore& aSegmentationStore,
+ const TSmsSettings& aSmsSettings,
+ const RMobileSmsMessaging::TMobileSmsCapsV1& aMobileSmsCaps,
+ RMobileSmsMessaging& aSmsMessaging,
+ TInt aPriority,
+ CSmspSetBearer& aSmspSetBearer)
+ {
+ LOGSMSPROT1("CSmsMessageSend::NewL()");
+
+ CSmsMessageSend* self = new (ELeave) CSmsMessageSend(aSegmentationStore,
+ aSmsSettings,
+ aMobileSmsCaps,
+ aSmsMessaging,
+ aPriority,
+ aSmspSetBearer);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+
+ return self;
+ } // CSmsMessageSend::NewL
+
+
+/**
+ * 2nd Phase of construction.
+ *
+ * Creates CSmsTimeout object and the SMS event logger.
+ */
+void CSmsMessageSend::ConstructL()
+ {
+ LOGSMSPROT1("CSmsMessageSend::ConstructL()");
+
+ iSmsEventLogger = CSmsEventLogger::NewL(iSegmentationStore.FileSession(),
+ Priority());
+
+ ConstructTimeoutL();
+ } // CSmsMessageSend::ConstructL
+
+
+/**
+ * Default constructor.
+ *
+ * @param aSegmentationStore Segmentation Store.
+ * @param aSmsSettings The global SMS settings.
+ * @param aMobileSmsCaps SMS messaging capabilities of TSY/phone.
+ * @param aSmsMessaging ETel SMS messaging subsession.
+ * @param aPriority Priority to use for the Active Object.
+ * @param aSmspSetBearer Set bearer object.
+ */
+CSmsMessageSend::CSmsMessageSend(CSmsSegmentationStore& aSegmentationStore,
+ const TSmsSettings& aSmsSettings,
+ const RMobileSmsMessaging::TMobileSmsCapsV1& aMobileSmsCaps,
+ RMobileSmsMessaging& aSmsMessaging,
+ TInt aPriority,
+ CSmspSetBearer& aSmspSetBearer)
+ : CSmsuActiveBase(aPriority),
+ iState(ESmsMessageSendIdle),
+ iSegmentationStore(aSegmentationStore),
+ iSmspSetBearer(aSmspSetBearer),
+ iSmsSettings(aSmsSettings),
+ iMobileSmsCaps(aMobileSmsCaps),
+ iSmsMessaging(aSmsMessaging),
+ iMobileSmsSendAttributesV1Pckg(iMobileSmsSendAttributesV1),
+ iSmsArray(8),
+ iSegmentSequenceNumber(-1)
+ {
+ // NOP
+ } // CSmsMessageSend::CSmsMessageSend
+
+
+/**
+ * Standard destructor.
+ */
+CSmsMessageSend::~CSmsMessageSend()
+ {
+ Cancel();
+ delete iSmsEventLogger;
+ } // CSmsMessageSend::~CSmsMessageSend
+
+
+void CSmsMessageSend::Start(CSmsMessage& aSmsMessage, TInt aOptions,
+ const TSmsAddr& aSmsAddr, TRequestStatus& aStatus)
+ {
+ LOGSMSPROT1("CSmsMessageSend::Start()");
+
+ __ASSERT_DEBUG(iState == ESmsMessageSendIdle,SmspPanic(KSmspPanicUnexpectedState));
+
+ //
+ // Store the request status that we will complete when finished...
+ //
+ Queue(aStatus);
+
+ //
+ // Initialise member data...
+ //
+ iSmsMessage=&aSmsMessage;
+ iSmsMessage->ParsedToFromAddress(iToFromTelNumber);
+ iOptions = aOptions;
+ iSmsAddr = aSmsAddr;
+
+ iSmsPDUData.iType = aSmsMessage.Type();
+ iSmsPDUData.iTotal = 0;
+ iSmsPDUData.iSent = 0;
+ iSmsPDUData.iDelivered = 0;
+
+ iSendError = KErrNone;
+ iSmsEventLogger->Event().SetId(KLogNullId);
+
+ //
+ // Begin by setting the bearer...
+ //
+ iState = ESmsMessageSendSetBearer;
+ iSmspSetBearer.NotifyBearerSet(iStatus);
+ SetActive();
+ } // CSmsMessageSend::Start
+
+
+void CSmsMessageSend::DoRunL()
+ {
+ LOGSMSPROT3("CSmsMessageSend::RunL(): iStatus=%d, iState=%d", iStatus.Int(), iState);
+
+ switch (iState)
+ {
+ case ESmsMessageSendSetBearer:
+ {
+ //
+ // If setting of bearer was successful then send the message.
+ //
+ // The TSY will complete with KErrNotSupported if it doesn't
+ // support setting the send bearer.
+ //
+ if (iStatus.Int() == KErrNone ||
+ iStatus.Int() == KErrNotSupported)
+ {
+ if (iSmsEventLogger->ClientAvailable())
+ {
+ CreateLogServerEvent();
+ }
+ else
+ {
+ SegmentMessage();
+ }
+ }
+ }
+ break;
+
+ case ESmsMessageSendCreatingLogServerEvent:
+ {
+ //
+ // If a log event was created ok, then store the id...
+ //
+ if (iStatus.Int() == KErrNone)
+ {
+ iSmsMessage->SetLogServerId(iSmsEventLogger->Event().Id());
+ }
+ else
+ {
+ iSmsEventLogger->Event().SetId(KLogNullId);
+ }
+
+ //
+ // Segment the message. This will send the first PDU as well...
+ //
+ SegmentMessage();
+ }
+ break;
+
+ case ESmsMessageSendSegmentingMessage:
+ {
+ //
+ // If the previous PDU was sent ok, then send the next one...
+ //
+ if (iStatus.Int() == KErrNone)
+ {
+ SendNextPDU();
+ }
+ else
+ {
+ //
+ // An error occured. Save the error for later and either
+ // update the log event, or drop to the end of RunL() so
+ // that Complete() is called...
+ //
+ iSendError = iStatus.Int();
+
+ if (iSmsEventLogger->Event().Id() != KLogNullId)
+ {
+ UpdateLogServerEvent();
+ }
+ }
+ }
+ break;
+
+ case ESmsMessageSendPDU:
+ {
+ //
+ // If the PDU is sent with an acknowledgement, then decode the
+ // submit report...
+ //
+ if (iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsSendWithAck &&
+ iMobileSmsSendAttributesV1.iFlags & RMobileSmsMessaging::KGsmSubmitReport)
+ {
+ DecodeSubmitReportL();
+ }
+
+ if (iStatus.Int() == KErrNone && !IsRPError())
+ {
+ LOGSMSIF2("CSmsMessageSend::RunL(): Submit ACK'd MsgRef=%d",
+ iMobileSmsSendAttributesV1.iMsgRef);
+ }
+ else if (IsRPError())
+ {
+ LOGSMSIF2("CSmsMessageSend::RunL(): Submit N'ACK'D MsgRef=%d",
+ iMobileSmsSendAttributesV1.iMsgRef);
+ }
+ else
+ {
+ LOGSMSIF2("CSmsMessageSend::RunL(): MsgRef=%d",
+ iMobileSmsSendAttributesV1.iMsgRef);
+ }
+
+ //
+ // If the PDU was sent okay, then update the segmentation store...
+ //
+ if (iStatus.Int() ==KErrNone)
+ {
+ iSegmentSequenceNumber++;
+ UpdateSegmentationStore();
+ }
+ else
+ {
+ //
+ // An error occured. Save the error for later and either
+ // update the log event, or drop to the end of RunL() so
+ // that Complete() is called...
+ //
+ iSendError = iStatus.Int();
+
+ if (iSmsEventLogger->Event().Id() != KLogNullId)
+ {
+ UpdateLogServerEvent();
+ }
+ }
+ }
+ break;
+
+ case ESmsMessageSendUpdatingSegmentationStore:
+ {
+ if (iStatus.Int() == KErrNone)
+ {
+ //
+ // The update has been successful, so update the log event or
+ // send the next PDU. If the log event is updated, then it
+ // will then send the next PDU...
+ //
+ if (iSmsEventLogger->Event().Id() != KLogNullId)
+ {
+ UpdateLogServerEvent();
+ }
+ else
+ {
+ SendNextPDU();
+ }
+ }
+ else
+ {
+ //
+ // An error occured. Save the error for later and either
+ // update the log event, or drop to the end of RunL() so
+ // that Complete() is called...
+ //
+ iSendError = iStatus.Int();
+
+ if (iSmsEventLogger->Event().Id() != KLogNullId)
+ {
+ UpdateLogServerEvent();
+ }
+ }
+ }
+ break;
+
+ case ESmsMessageSendUpdatingLogEvent:
+ {
+ //
+ // Ignore log server error and continue with the next PDU if
+ // the last send was okay, otherwise drop to the bottom of the
+ // RunL() and Complete().
+ //
+ if (iSendError == KErrNone)
+ {
+ SendNextPDU();
+ }
+ }
+ break;
+
+ default:
+ {
+ SmspPanic(KSmspPanicUnexpectedState);
+ }
+ break;
+ };
+
+ //
+ // DoRunL() will now return to CSmsuActiveBase which if the object
+ // is not active, will call Complete().
+ //
+ } // CSmsMessageSend::DoRunL
+
+
+void CSmsMessageSend::DoCancel()
+ {
+ LOGSMSPROT2("CSmsMessageSend::DoCancel(): iState=%d", iState);
+
+ TimedSetActiveCancel();
+
+ switch (iState)
+ {
+ case ESmsMessageSendSetBearer:
+ {
+ iSmspSetBearer.Cancel();
+ }
+ break;
+
+ case ESmsMessageSendSegmentingMessage:
+ {
+ // NOP
+ }
+ break;
+
+ case ESmsMessageSendCreatingLogServerEvent:
+ case ESmsMessageSendUpdatingLogEvent:
+ {
+ iSmsEventLogger->Cancel();
+ }
+ break;
+
+ case ESmsMessageSendPDU:
+ {
+ iSmsMessaging.CancelAsyncRequest(EMobileSmsMessagingSendMessage);
+ }
+ break;
+
+ case ESmsMessageSendUpdatingSegmentationStore:
+ {
+ // NOP
+ }
+ break;
+
+ default:
+ {
+ SmspPanic(KSmspPanicUnexpectedState);
+ }
+ break;
+ };
+
+ iSendError = KErrCancel;
+
+ //
+ // Handle completion of this Active Object. Note that the object
+ // may well still be active at this point...
+ //
+ if (TimedOut())
+ {
+ Complete(KErrTimedOut);
+ }
+ else
+ {
+ Complete(KErrCancel);
+ }
+ } // CSmsMessageSend::DoCancel
+
+
+/**
+ * Decodes SMS-SUBMIT-REPORT PDU and checks if it is SMS-SUBMIT-REPORT for
+ * RP-ERROR.
+ *
+ * @leave Leaves if CSmsBuffer::NewL or CSmsMessage::NewL leaves.
+ *
+ */
+void CSmsMessageSend::DecodeSubmitReportL()
+ {
+ LOGSMSPROT1("CSmsMessageSend::DecodeSubmitReportL()");
+
+ //
+ // Only try to decode the submit report if error is a RP-error, in which case there should be a valid PDU
+ //
+ if (IsRPError())
+ {
+ TGsmSms sms;
+ sms.SetPdu(iMobileSmsSendAttributesV1.iSubmitReport);
+ CSmsBuffer* buffer=CSmsBuffer::NewL();
+
+ // try to create a sms message from the submit report PDU (smsMessage takes ownership of the buffer)
+ CSmsMessage* smsMessage = CSmsMessage::NewL(iSegmentationStore.FileSession(),
+ sms,buffer,IsRPError(),ETrue);
+ CleanupStack::PushL(smsMessage);
+
+ if (smsMessage->SmsPDU().Type() == CSmsPDU::ESmsSubmitReport)
+ {
+ CSmsSubmitReport& submitReport =(CSmsSubmitReport&) smsMessage->SmsPDU();
+ TInt failureCause = submitReport.FailureCause();
+
+ if (failureCause != TSmsFailureCause::ESmsErrorFree)
+ {
+ iStatus = FailureCauseToError(failureCause);
+ }
+ }
+ else
+ {
+ LOGSMSPROT3("Invalid PDU Type = %d with iStatus = %d", smsMessage->SmsPDU().Type(), iStatus.Int() );
+ }
+
+ CleanupStack::PopAndDestroy(smsMessage);
+ }
+ } // CSmsMessageSend::DecodeSubmitReportL
+
+
+/**
+ * Checks if TSY completed send message request with RP-error.
+ *
+ * @return boolean.
+ */
+TBool CSmsMessageSend::IsRPError() const
+ {
+ LOGSMSPROT1("CSmsMessageSend::IsRPError()");
+
+ TBool isRPError = EFalse;
+
+ switch (iStatus.Int())
+ {
+ case KErrGsmSMSUnassignedNumber:
+ case KErrGsmSMSOperatorDeterminedBarring:
+ case KErrGsmSMSCallBarred:
+ case KErrGsmSMSReserved:
+ case KErrGsmSMSNetworkFailure:
+ case KErrGsmSMSShortMessageTransferRejected:
+ case KErrGsmSMSMemoryCapacityExceeded:
+ case KErrGsmSMSDestinationOutOfOrder:
+ case KErrGsmSMSUnidentifiedSubscriber:
+ case KErrGsmSMSFacilityRejected:
+ case KErrGsmSMSUnknownSubscriber:
+ case KErrGsmSMSNetworkOutOfOrder:
+ case KErrGsmSMSTemporaryFailure:
+ case KErrGsmSMSCongestion:
+ case KErrGsmSMSResourcesUnavailable:
+ case KErrGsmSMSRequestedFacilityNotSubscribed:
+ case KErrGsmSMSRequestedFacilityNotImplemented:
+ case KErrGsmSMSInvalidShortMessageTransferReferenceValue:
+ case KErrGsmSMSUnspecifiedInvalidMessage:
+ case KErrGsmSMSInvalidMandatoryInformation:
+ case KErrGsmSMSNonExistentMessageType:
+ case KErrGsmSMSIncompatibleMessageWithSmsProtocolState:
+ case KErrGsmSMSInformationElementNotImplemented:
+ case KErrGsmSMSUnspecifiedProtocolError:
+ case KErrGsmSMSUnspecifiedInterworkingError:
+ {
+ isRPError = ETrue;
+ }
+ break;
+
+ default:
+ {
+ // NOP
+ }
+ break;
+ }
+
+ return isRPError;
+ } // CSmsMessageSend::IsRPError
+
+
+void CSmsMessageSend::SegmentMessage()
+ {
+ LOGSMSPROT1("CSmsMessageSend::SegmentMessage()");
+
+ iState = ESmsMessageSendSegmentingMessage;
+
+ TRAPD(ret,DoSegmentMessageL());
+
+ CompleteMyself(ret);
+ } // CSmsMessageSend::SegmentMessage
+
+
+void CSmsMessageSend::DoSegmentMessageL()
+ {
+ LOGSMSPROT1("CSmsMessageSend::DoSegmentMessageL()");
+
+ TInt reference=0;
+ if (iSmsMessage->Type()==CSmsPDU::ESmsCommand)
+ {
+ CSmsCommand& command=(CSmsCommand&) iSmsMessage->SmsPDU();
+
+ CSmsSegmentationStore::RSmsSegmentationStoreRefStatusArray referencearray;
+ CleanupClosePushL(referencearray);
+
+ if (!iSegmentationStore.AddCommandL(iSmsAddr,*iSmsMessage, referencearray))
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ const TInt count=referencearray.Count();
+ CArrayFix<TGsmSms>* smsarray=new(ELeave) CArrayFixFlat<TGsmSms>(8);
+ CleanupStack::PushL(smsarray);
+
+ for (TInt i=0; i<count; i++)
+ {
+ command.SetMessageNumber(referencearray[i].Reference());
+ //TODO should reference be set to referencearray[i].iReference here?
+ iSmsMessage->EncodeMessagePDUsL(*smsarray, reference);
+ iSmsArray.AppendL(smsarray->At(0));
+ smsarray->Reset();
+ }
+ CleanupStack::PopAndDestroy(2); // smsarray, referencearray
+ }
+ else
+ {
+ TBool iSentBefore=EFalse;
+ TBool is16bit = EFalse;
+ TBool concatenationIEPresent= iSmsMessage->SmsPDU().TextConcatenated( &is16bit );
+ iSmsMessage->SmsPDU().SetTextConcatenatedL(EFalse,EFalse);
+
+ // Fix for INC039985;
+ // The cause was that resending a SMS message(single PDU, same LogId),
+ // caused an assertion fault; This did not happen with an SMS with multiple PDUs.
+ // The reason for that is that for the multiple PDU case the stack employes a caching mechanism
+ // built in - it checks which PDUs from an SMS message have already been sent and
+ // then sends only the ones which have not been sent. This is performed by using the LodId,
+ // which is used to uniquely identify an SMS message and the PDUs it consists of.
+ // If an SMS message consisting of multiple PDUs is resend by an application and it has been already
+ // sent sucessfully, the stack deletes the previous entry corresponding to the old LogId
+ // segmentation store and replaces it with the new one with a new logid.
+ // This mechanism has been extended for SMS messages consisting of single PDU.
+ if(!iSmsMessage->EncodeIntoSinglePDUL(iSmsArray))
+ {
+ if (concatenationIEPresent && is16bit)
+ {
+ iSmsMessage->Set16BitConcatenation(ETrue);
+ }
+
+ if(iSegmentationStore.HasEntryWithLogIdL(iSmsMessage->LogServerId(),reference,iSmsPDUData.iSent))
+ {
+ iSentBefore=ETrue;
+ }
+ else
+ {
+ reference=is16bit? iSegmentationStore.Next16BitReferenceL(): iSegmentationStore.Next8BitReferenceL();
+ }
+ iSmsMessage->EncodeMessagePDUsL(iSmsArray, reference);
+ }
+ else
+ {
+ if( iSegmentationStore.HasEntryWithLogIdL(iSmsMessage->LogServerId(),reference,iSmsPDUData.iSent))
+ {
+ iSentBefore=ETrue;
+ }
+ }
+
+ LOGSMSPROT3("CSmsMesageSend::DoSegmentMessageL [LogServerId=%d][iSentBefore=%d]",iSmsMessage->LogServerId(),iSentBefore);
+ LOGSMSPROT3("CSmsMesageSend::DoSegmentMessageL [referenceNo=%d] [iCountOfSentBefore=%d ]",reference,iSmsPDUData.iSent);
+ if(!iSentBefore)
+ {
+ iSegmentationStore.AddSubmitL(iSmsAddr,*iSmsMessage);
+ }
+ }
+ } // CSmsMessageSend::DoSegmentMessageL
+
+
+void CSmsMessageSend::CreateLogServerEvent()
+ {
+ LOGSMSPROT1("CSmsMessageSend::CreateLogServerEvent()");
+
+ iState=ESmsMessageSendCreatingLogServerEvent;
+ TLogId logid=(TLogId) iSmsMessage->LogServerId();
+
+ if (logid == KLogNullId)
+ {
+ iSmsPDUData.iTotal=iSmsArray.Count();
+ iSmsEventLogger->AddEvent(iStatus,*iSmsMessage,iSmsPDUData);
+ }
+ else
+ {
+ iSmsEventLogger->GetEvent(iStatus,logid);
+ }
+ SetActive();
+ } // CSmsMessageSend::CreateLogServerEvent
+
+
+void CSmsMessageSend::SendNextPDU()
+ {
+ LOGSMSPROT3("CSmsMessageSend::SendNextPDU [sending pdu %d of count=%d]",iSmsPDUData.iSent, iSmsArray.Count() );
+
+ if (iSmsPDUData.iSent<iSmsArray.Count())
+ {
+ NMobilePhone::TMobileTON ton;
+ NMobilePhone::TMobileNPI npi;
+
+ TGsmSmsTelNumber parsedAddress(iSmsArray[iSmsPDUData.iSent].Sca());
+
+ iMobileSmsSendAttributesV1.iFlags = RMobileSmsMessaging::KGsmServiceCentre |
+ RMobileSmsMessaging::KRemotePartyInfo |
+ RMobileSmsMessaging::KSmsDataFormat |
+ RMobileSmsMessaging::KMoreToSend;
+
+ //
+ // Set service centre address...
+ //
+ parsedAddress.iTypeOfAddress.ConvertToETelMM(ton, npi);
+ iMobileSmsSendAttributesV1.iGsmServiceCentre.iTelNumber = parsedAddress.iTelNumber;
+ iMobileSmsSendAttributesV1.iGsmServiceCentre.iTypeOfNumber = static_cast<RMobilePhone::TMobileTON>(static_cast<TInt>(ton));
+ iMobileSmsSendAttributesV1.iGsmServiceCentre.iNumberPlan = static_cast<RMobilePhone::TMobileNPI>(static_cast<TInt>(npi));
+
+ //
+ // Set destination address...
+ //
+ iToFromTelNumber.iTypeOfAddress.ConvertToETelMM(ton, npi);
+ iMobileSmsSendAttributesV1.iDestination.iTelNumber = iToFromTelNumber.iTelNumber;
+ iMobileSmsSendAttributesV1.iDestination.iTypeOfNumber = static_cast<RMobilePhone::TMobileTON>(static_cast<TInt>(ton));
+ iMobileSmsSendAttributesV1.iDestination.iNumberPlan = static_cast<RMobilePhone::TMobileNPI>(static_cast<TInt>(npi));
+
+ iMobileSmsSendAttributesV1.iDataFormat = RMobileSmsMessaging::EFormatGsmTpdu;
+
+ if (iSmsPDUData.iSent < iSmsArray.Count() - 1)
+ {
+ iMobileSmsSendAttributesV1.iMore = ETrue;
+ }
+ else
+ {
+ iMobileSmsSendAttributesV1.iMore = EFalse;
+ }
+
+ //
+ // Debug logging of the PDU we are sending...
+ //
+ LOGSMSIFPDU(_L8("ETEL TX PDU: "), iSmsArray[iSmsPDUData.iSent].Pdu(), ETrue);
+ LOGSMSIFSENDATTRIBUTES(_L8("SENDATTRIBS: "), iMobileSmsSendAttributesV1);
+ LOGSMSIFTIMESTAMP();
+
+ //
+ // Send the message and enter the correct state...
+ //
+ iState = ESmsMessageSendPDU;
+ iSmsMessaging.SendMessage(iStatus, iSmsArray[iSmsPDUData.iSent].Pdu(),
+ iMobileSmsSendAttributesV1Pckg);
+ TimedSetActive(iSmsSettings.SendTryTimeout());
+ }
+ } // CSmsMessageSend::SendNextPDU
+
+
+void CSmsMessageSend::UpdateSegmentationStore()
+ {
+ iState = ESmsMessageSendUpdatingSegmentationStore;
+
+ TRAPD(ret,DoUpdateSegmentationStoreL());
+
+ CompleteMyself(ret);
+ } // CSmsMessageSend::UpdateSegmentationStore
+
+
+void CSmsMessageSend::DoUpdateSegmentationStoreL()
+ {
+ LOGSMSPROT1("CSmsMessageSend::DoUpdateSegmentationStoreL()");
+
+ iSmsPDUData.iSent++; // This is the end of the sequence for sending an SMS PDU
+
+ if (iSmsMessage->Scheme() == EControlParametersScheme ||
+ iSmsMessage->Scheme() == ETPSRRScheme)
+ {
+ iSegmentationStore.AddReferenceStatusPairL(*iSmsMessage,(TInt) iMobileSmsSendAttributesV1.iMsgRef, iSegmentSequenceNumber);
+ }
+ else if (iSmsMessage->Scheme() == EDefaultScheme)
+ {
+ iSegmentationStore.AddReferenceL(*iSmsMessage,(TInt) iMobileSmsSendAttributesV1.iMsgRef);
+ }
+ else
+ {
+ User::Leave(KErrNotFound);
+ }
+ } // CSmsMessageSend::DoUpdateSegmentationStoreL
+
+
+void CSmsMessageSend::UpdateLogServerEvent()
+ {
+ LOGSMSPROT1("CSmsMessageSend::UpdateLogServerEvent()");
+
+ //
+ // Fill in log event...
+ //
+ iState = ESmsMessageSendUpdatingLogEvent;
+ iSmsPDUData.iTotal = iSmsArray.Count();
+ iSmsEventLogger->ChangeEvent(iStatus, *iSmsMessage, iSmsPDUData);
+ SetActive();
+ } // CSmsMessageSend::UpdateLogServerEvent
+
+
+void CSmsMessageSend::Complete(TInt aStatus)
+ {
+ LOGSMSPROT3("CSmsMessageSend::Complete [iStatus=%d, iState=%d]", iStatus.Int(), iState );
+
+ //
+ // For completion during log events, use the saved error code instead...
+ //
+ if (iState == ESmsMessageSendCreatingLogServerEvent ||
+ iState == ESmsMessageSendUpdatingLogEvent)
+ {
+ aStatus = iSendError;
+ }
+
+ //
+ // Clear all PDU data that was sent...
+ //
+ for (TInt i=0; i < iSmsPDUData.iSent; i++)
+ {
+ iSmsArray.Delete(0);
+ }
+
+ iSmsArray.Reset();
+
+ iState = ESmsMessageSendIdle;
+
+ //
+ // Call the base function to perform the actual complete...
+ //
+ CSmsuActiveBase::Complete(aStatus);
+ } // CSmsMessageSend::Complete