email/pop3andsmtpmtm/smtpservermtm/src/SMTS.CPP
changeset 0 72b543305e3a
child 76 60a8a215b0ec
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/email/pop3andsmtpmtm/smtpservermtm/src/SMTS.CPP	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,417 @@
+// Copyright (c) 1998-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 "SMTS.H"
+#include "SMTSUTIL.H"
+#include "IMSM.H"
+#include <smtpcmds.h>
+#include <msventry.h>
+#include <miutset.h>
+
+EXPORT_C CSmtpSrvMtm* CSmtpSrvMtm::NewL(CRegisteredMtmDll& aRegisteredMtmDll,CMsvServerEntry*  aEntry)
+	{
+	CSmtpSrvMtm* mysvrmtm = new CSmtpSrvMtm(aRegisteredMtmDll, aEntry);
+	if (mysvrmtm==NULL)
+		{
+		aRegisteredMtmDll.ReleaseLibrary();
+		User::Leave(KErrNoMemory);
+		}
+	CleanupStack::PushL(mysvrmtm);
+	mysvrmtm->ConstructL();
+	CleanupStack::Pop();
+	return mysvrmtm;
+	}
+
+CSmtpSrvMtm::CSmtpSrvMtm(CRegisteredMtmDll& aRegisteredMtmDll, CMsvServerEntry* aEntry):
+	CBaseServerMtm(aRegisteredMtmDll, aEntry)
+	{
+	__DECLARE_NAME(_S("CStmpSvrMtm"));
+	}
+		
+void CSmtpSrvMtm::ConstructL()
+	{
+	iSessionError=KErrNone;
+	iProgressBuffer().SetStatus(EMsgOutboxProgressDone);
+#if (defined SYMBIAN_USER_PROMPT_SERVICE)
+	iHasCapability = ETrue;
+#endif
+	CActiveScheduler::Add(this);
+	}
+
+CSmtpSrvMtm::~CSmtpSrvMtm()
+	{
+	Cancel();	//classes derived from CActive MUST call Cancel()
+	delete iOutboxSend;	//should already be dead
+	delete iSendSelection;
+	//  Set the Service Entry to be NOT connected
+    SetServiceToConnected(EFalse);
+   	}
+
+
+// aServiceId is ignored and the service ids of the messages in the selection
+// are used instead
+
+void CSmtpSrvMtm::CopyFromLocalL(const CMsvEntrySelection& aSelection, TMsvId aServiceId, /* Info for protocol....*/ TRequestStatus& aStatus)
+	{
+	iServiceId=aServiceId;
+	__ASSERT_DEBUG(iOutboxSend == NULL,gPanic(ESmtsBusy));
+	__ASSERT_DEBUG(iServerEntry != NULL,gPanic(EEntryNotSet));
+	if (IsActive())
+		User::Leave(KErrServerBusy);
+
+	if (iSendSelection)
+		iSendSelection->Reset();
+	else
+		iSendSelection=new (ELeave) CMsvEntrySelection;
+
+	CopyToOurSelectionL(aSelection);
+	AddWaitingInOutboxToSelectionL();
+
+	if (iSendSelection->Count())
+		DoSendMessagesL(aStatus);
+	else
+		{
+		iSessionError=KSmtpNoMsgsToSendWithActiveSettings;
+		TRequestStatus* pStatus=&aStatus;
+		User::RequestComplete(pStatus,KErrNone);//nothing to send
+		}
+	}
+
+
+
+void CSmtpSrvMtm::DoSendMessagesL(TRequestStatus& aStatus)
+	{
+	iSessionError = KErrNone;
+    
+	// Set the Service entry to be Connected
+	User::LeaveIfError(SetServiceToConnected(ETrue));
+	
+	delete iOutboxSend;
+	iOutboxSend=NULL;
+	iOutboxSend = CMsgImOutboxSend::NewL(*iSendSelection,*iServerEntry,iServiceId);
+
+#if (defined SYMBIAN_USER_PROMPT_SERVICE)
+	iOutboxSend->StartL(iStatus, iClientThreadId, iHasCapability);
+#else
+	iOutboxSend->StartL(iStatus);
+#endif
+	
+	SetActive();
+	aStatus = KRequestPending;
+	iReport = &aStatus;
+	}
+
+
+//
+//	Progress()
+//
+//	Args:			None.
+//	
+//	Return Value:	TDesC& -- reference to a TBufPckg<TImSmtpProgress>
+//					maintained by the instantiated CMsgImOutboxSend
+//					object...
+//
+//	Remarks:				
+//
+const TDesC8& CSmtpSrvMtm::Progress()
+	{
+	//	load in latest progress, otherwise use saved progress
+	if(iOutboxSend!=NULL)
+		{
+		iProgressBuffer = iOutboxSend->Progress();
+		}
+	else
+		iProgressBuffer().SetError(iSessionError);
+	return iProgressBuffer;
+	}
+
+void CSmtpSrvMtm::DoCancel()
+	{
+	if(iOutboxSend)
+		{
+		iOutboxSend->Cancel();
+		Progress();	//update iProgressBuffer
+		delete  iOutboxSend;
+		iOutboxSend = NULL;
+		}
+
+    //  Set the Service Entry to be NOT connected
+    SetServiceToConnected(EFalse);
+
+	User::RequestComplete(iReport,KErrCancel);
+	}
+
+void CSmtpSrvMtm::DoRunL()
+	{
+	iSessionError = iStatus.Int();
+	Progress();
+
+	//	Delete the CImOutboxSend object.
+	delete  iOutboxSend;
+	iOutboxSend = NULL;
+
+    //  Set the Service Entry to be NOT connected
+    SetServiceToConnected(EFalse);
+
+	User::RequestComplete(iReport,KErrNone);	// always returns KErrNone; errors are returned in Progress
+	}
+
+void CSmtpSrvMtm::DoComplete(TInt aError)
+	{
+	iSessionError=aError;	// store error away to set Progress() later
+	User::RequestComplete(iReport,KErrNone);	// always returns KErrNone; errors are returned in Progress
+	}
+
+
+TBool CSmtpSrvMtm::CommandExpected()
+	{
+	return EFalse;
+	}
+
+void CSmtpSrvMtm::StartCommandL(CMsvEntrySelection& aSelection,
+                                TInt aCommand,
+                                const TDesC8& /*aParameter*/,
+                                TRequestStatus& aStatus)
+	{
+	TInt error = KErrNone;
+
+    switch (aCommand)
+        {
+    //  Is session connected...
+    case KSMTPMTMIsConnected:
+		if (iOutboxSend)
+			iOutboxSend->SessionIsConnected();
+		else 
+            error = KErrDisconnected;    
+        break;
+    case KSMTPMTMSendOnNextConnection:
+		CopyFromLocalL(aSelection, aSelection.At(0), aStatus);
+		return;
+    default:
+        error = KErrNotSupported;
+        break;
+        }
+	iReport=&aStatus;
+	aStatus=KRequestPending;
+	User::RequestComplete(iReport, error);
+	}
+
+
+void CSmtpSrvMtm::CopyToOurSelectionL(const CMsvEntrySelection& aSourceSelection)
+	{
+  	TInt count=aSourceSelection.Count();
+  	TMsvEntry entry;
+  	while (count--)
+  		{
+  		TInt err=iServerEntry->SetEntry(aSourceSelection[count]);
+		if(err==KErrNone)
+			{
+  			entry=iServerEntry->Entry();
+  
+			// If this entry is a message using the SMTP service & it hasn't been sent, 
+			// then add it to the list of entries to send.
+  			if (entry.iMtm==KUidMsgTypeSMTP && entry.iType==KUidMsvMessageEntry &&	
+				entry.iServiceId==iServiceId && entry.SendingState() != KMsvSendStateSent)
+				{
+				iSendSelection->AppendL(aSourceSelection[count]);						
+				}
+			}
+		}
+  	}
+
+void CSmtpSrvMtm::AddWaitingInOutboxToSelectionL()
+	{
+	User::LeaveIfError(iServerEntry->SetEntry(KMsvGlobalOutBoxIndexEntryId));
+	CMsvEntrySelection *sel = new (ELeave) CMsvEntrySelection;
+	CleanupStack::PushL(sel);
+	User::LeaveIfError(iServerEntry->GetChildrenWithService(iServiceId,*sel));
+	TInt count=sel->Count();
+	TMsvEntry entry;
+	while (count--)
+		{
+		TInt err=iServerEntry->SetEntry((*sel)[count]);
+		if(err==KErrNone)
+			{
+			entry=iServerEntry->Entry();
+			if ((entry.SendingState()==KMsvSendStateWaiting ||entry.SendingState()==KMsvSendStateScheduled || entry.SendingState()==KMsvSendStateResend) && //i.e send on next connection
+				iSendSelection->Find((*sel)[count])==KErrNotFound && 
+				entry.iType==KUidMsvMessageEntry) 
+				iSendSelection->AppendL((*sel)[count]);						
+			}
+		}
+	CleanupStack::PopAndDestroy(sel);
+	}
+
+
+TInt CSmtpSrvMtm::SetServiceToConnected(TBool aConnected)
+// Set the Service Entry to be either connected or not. 
+	{
+	TInt error = iServerEntry->SetEntry( iServiceId );
+    if (error == KErrNone)
+        {
+        TMsvEntry entry = iServerEntry->Entry();
+
+		// Change the connected flag if not already set to this value
+		if (entry.Connected()!=aConnected)
+			{
+		    entry.SetConnected(aConnected);
+			error = iServerEntry->ChangeEntry(entry);
+			}
+        }
+
+	// returns any error that occured
+	return error;
+	}
+
+
+//*****************************************************************************
+//The rest of the commands are unsupported
+//*****************************************************************************
+
+void CSmtpSrvMtm::MoveFromLocalL(const CMsvEntrySelection& /*aSelection*/,
+                                 TMsvId /*aServiceId*/,
+                                 TRequestStatus& aStatus)
+	{
+	__ASSERT_DEBUG(iOutboxSend == NULL,gPanic(ESmtsBusy));
+	iReport=&aStatus;
+	User::RequestComplete(iReport,KErrNotSupported);
+	}
+
+void CSmtpSrvMtm::CopyToLocalL(const CMsvEntrySelection& /*aSelection*/,
+                               TMsvId /*aDestination*/, 
+                               TRequestStatus& aStatus)
+	{
+	__ASSERT_DEBUG(iOutboxSend == NULL,gPanic(ESmtsBusy));
+	iReport=&aStatus;
+	User::RequestComplete(iReport,KErrNotSupported);
+	}
+
+void CSmtpSrvMtm::MoveToLocalL(const CMsvEntrySelection& /*aSelection*/,
+                               TMsvId /*aDestination*/,
+                               TRequestStatus& aStatus)
+	{
+	__ASSERT_DEBUG(iOutboxSend == NULL,gPanic(ESmtsBusy));
+	iReport=&aStatus;
+	User::RequestComplete(iReport,KErrNotSupported);
+	}
+
+void CSmtpSrvMtm::CopyWithinServiceL(const CMsvEntrySelection& /*aSelection*/,
+                                     TMsvId /*aDestination*/, TRequestStatus& aStatus)
+	{
+	__ASSERT_DEBUG(iOutboxSend == NULL,gPanic(ESmtsBusy));
+	iReport=&aStatus;
+	User::RequestComplete(iReport,KErrNotSupported);
+	}
+
+void CSmtpSrvMtm::MoveWithinServiceL(const CMsvEntrySelection& /*aSelection*/,
+                                     TMsvId /*aDestination*/,
+                                     TRequestStatus& aStatus)
+	{
+	__ASSERT_DEBUG(iOutboxSend == NULL,gPanic(ESmtsBusy));
+	iReport=&aStatus;
+	User::RequestComplete(iReport,KErrNotSupported);
+	}
+
+void CSmtpSrvMtm::DeleteAllL(const CMsvEntrySelection& /*aSelection*/,
+                             TRequestStatus& aStatus)
+	{
+	__ASSERT_DEBUG(iOutboxSend == NULL,gPanic(ESmtsBusy));
+	iReport=&aStatus;
+	User::RequestComplete(iReport,KErrNotSupported);
+	}
+
+void CSmtpSrvMtm::CreateL(TMsvEntry /*aNewEntry*/,
+                          TRequestStatus& aStatus)
+	{
+	__ASSERT_DEBUG(iOutboxSend == NULL,gPanic(ESmtsBusy));
+	iReport=&aStatus;
+	User::RequestComplete(iReport,KErrNotSupported);
+	}
+
+void CSmtpSrvMtm::ChangeL(TMsvEntry /*aNewEntry*/,
+                          TRequestStatus& aStatus)
+	{
+	__ASSERT_DEBUG(iOutboxSend == NULL,gPanic(ESmtsBusy));
+	iReport=&aStatus;
+	User::RequestComplete(iReport,KErrNotSupported);
+	}
+
+/**
+The extension method provides a polymorphic behaviour to call the correct
+MTM.
+@param aExtensionId The Uid passed in as KUIDMsgClientThreadInfo to copy the
+					Client Thread Info.
+@return KErrNone.
+*/
+TInt CSmtpSrvMtm::Extension_(TUint aExtensionId, TAny *&a0, TAny *a1)	
+	{
+	switch(aExtensionId)
+		{
+#if (defined SYMBIAN_USER_PROMPT_SERVICE)		
+		case KUIDMsgClientThreadInfo:
+			{
+			iClientThreadId = *(TThreadId*) (a1);
+	    	iHasCapability = (TBool)*(TInt*)(a0);
+	    	return KErrNone;
+			}
+#endif
+
+		case KUidMsgNonOperationMtmData:
+			{
+			TNonOperationMtmDataType* mtmDataType = reinterpret_cast<TNonOperationMtmDataType*>(a0);
+			TPtrC8* mtmDataBuffer = reinterpret_cast<TPtrC8*>(a1);
+			return GetNonOperationMtmData(*mtmDataType, *mtmDataBuffer);
+			}
+
+		default:
+			{
+			// Chain to base class
+			return CBaseServerMtm::Extension_(aExtensionId, a0, a1);
+			}
+		}
+	}
+
+/**
+Gets MTM information that is not related to the current operation
+
+@param aMtmDataType Type of data to fetch
+@param aMtmDataBuffer On return this points to a descriptor holding the data
+
+@return KErrNone if successful, or a system wide error code
+*/
+TInt CSmtpSrvMtm::GetNonOperationMtmData(TNonOperationMtmDataType aMtmDataType, TPtrC8& aMtmDataBuffer)
+	{
+	if (aMtmDataType == EMtmDataAccessPointId)
+		{
+		if (iOutboxSend)
+			{
+			TNonOperationMtmDataAccessPointId mtmDataAccessPointId;
+
+			TInt err = iOutboxSend->GetAccessPointIdForConnection(mtmDataAccessPointId.iAccessPointId);
+
+			if (err == KErrNone)
+				{
+				iMtmDataAccessPointIdBuffer = TNonOperationMtmDataAccessPointIdBuffer(mtmDataAccessPointId);
+				aMtmDataBuffer.Set(iMtmDataAccessPointIdBuffer);
+				return KErrNone;
+				}
+			}
+
+		return KErrNotFound;
+		}
+
+	return KErrNotSupported;
+	}
+