smsprotocols/smsstack/smsprot/Src/smspmondsk.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 0 3553901f7fa8
--- a/smsprotocols/smsstack/smsprot/Src/smspmondsk.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/smsprotocols/smsstack/smsprot/Src/smspmondsk.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,593 +1,593 @@
-// 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:
-// Implementation for a CActive based class that monitors for low disk space
-// and is informed when a PDU is being received. Should memory be too low,
-// an error code is returned causing a NAck. The class will then monitor
-// for the point at which PDUs can be received again, and a Resume Reception
-// will be sent to the network.
-// The are two limits - a high limit for general SMSs and a low limit for
-// class 0 SMSs. However there is only one way to resume reception of SMSs. So
-// once a resume reception is sent, it resumes hoth types of SMSs. The algorithm
-// is a bit simiplier because of this:
-// IF sending non-Class 0 AND we are below the high limit THEN
-// N'Ack SMS
-// IF not waiting for free diskspace THEN
-// Wait for free diskspace to rise above the high limit
-// Resume SMS Reception.
-// ELSE
-// Continue waiting for either high limit or low limit
-// Resume SMS Reception as previously intended
-// END_IF
-// ELSE IF sending Class 0 AND we are below the low limit THEN
-// Wait for free diskspace to rise above the low limit
-// Resume SMS Reception.
-// END_IF
-// Note that in the second and last case, SMS reception may be resumed before
-// we are above the high limit, but in that case montioring will repeat when
-// the next non-class 0 SMS is attempted to be delivered. This is necessary as
-// there is no way to resume just class 0 SMSs.
-// 
-//
-
-/**
- @file
- @internalComponent 
-*/
-
-#include <barsc.h>
-#include <bautils.h>
-
-#include "smspcomm.h"
-#include "smspmondsk.h"
-#include "smsstacklog.h"
-#include "smspmain.h"
-#include "smspver.h"
-#include <smsu.rsg>
-
-
-_LIT(KSmsResourceFile, "sms\\smsu.rsc");
-
-
-/**
- *  2 phase constructor.
- *  
- *  @leave Leaves if not enough memory is available.
- *  
- *  @return a newly created CSmsMonitorDiskSpace object.
- */
-CSmsMonitorDiskSpace* CSmsMonitorDiskSpace::NewL(MSmsComm& aSmsComm, RMobileSmsMessaging& aSmsMessaging,RFs& aFs)
-	{
-	LOGSMSPROT1("CSmsMonitorDiskSpace::NewL()");
-
-	CSmsMonitorDiskSpace*  self = new(ELeave) CSmsMonitorDiskSpace(aSmsComm, aSmsMessaging, aFs);
-	CleanupStack::PushL(self);
-	self->ConstructL();
-	CleanupStack::Pop();
-
-	return self;
-	} // CSmsMonitorDiskSpace::NewL
-
-
-/**
- *  Private constructor used in the first phase of construction.
- */
-CSmsMonitorDiskSpace::CSmsMonitorDiskSpace(MSmsComm& aSmsComm, RMobileSmsMessaging& aSmsMessaging,RFs& aFs)
-  : CActive(KSmsSessionPriority),
-	iState(ESmsMonitorDiskSpaceIdle),
-	iSmsMessaging(aSmsMessaging),
-	iFs(aFs),
-	iSmsComm(aSmsComm),
-	iLowLimit(8*1024),
-	iHighLimit(16*1024)
-	{
-	CActiveScheduler::Add(this);
-	} // CSmsMonitorDiskSpace::CSmsMonitorDiskSpace
-
-
-/**
- *  Destructor.  Ensures any outstanding operation is cancelled.
- */
-CSmsMonitorDiskSpace::~CSmsMonitorDiskSpace()
-	{
-    Cancel();
-
-#ifdef _DEBUG    
-    iFreeDiskSpaceProperty.Close();
-#endif
-    
-	} // CSmsMonitorDiskSpace::~CSmsMonitorDiskSpace
-
-
-/**
- *  Initialize values for LowLimitDiskSpace and HighLimitDiskSpace
- *  from resource file
- */
-void CSmsMonitorDiskSpace::ConstructL()
-	{
-	RResourceFile  resourceFile;
-	TFileName  fileName;
-	Dll::FileName(fileName);
-	TParse  parse;
-	TFileName  resourceFileName;
-
-	//
-	// Create the path to the resource file...
-	//
-	iFs.PrivatePath(resourceFileName);
-	resourceFileName.Append(KSmsResourceFile);
-	parse.Set(resourceFileName, &fileName, 0);
-	fileName = parse.FullName();
-	BaflUtils::NearestLanguageFile(iFs, fileName);
-
-	//
-	// To enable adequate CSmsMonitorDiskSpace testing we allow the SMSU.RSC
-	// file to be loaded from the C: drive if it exists. This is only for a
-	// DEBUG version of course! Later WINSCW is also added to allow the testing
-	// on WINSCW UREL version.
-	//
-#if (defined __WINSCW__) || (defined _DEBUG)
-	TUint  attValue;
-	TChar  oldDriveLetter = fileName[0];
-
-	//
-	// Change the filename to look on C: and then see if it exists...
-	//	
-	fileName[0] = 'C';
-
-	if (iFs.Att(fileName, attValue) != KErrNone)
-		{
-		//
-		// The file does not exist on C: so revert the change...
-		//
-		fileName[0] = oldDriveLetter;
-		}
-#endif
-
-	//
-	// Log the filename in use and whether it is ROM based...
-	//
-#ifdef _SMS_LOGGING_ENABLED
-	TBuf8<KMaxFileName>  buf8;
-	buf8.Copy(fileName);
-	LOGSMSPROT2("CSmsMonitorDiskSpace::ConstructL(): fileName=\"%S\"", &buf8);
-#endif
-
-    if (iFs.IsFileInRom(fileName) == NULL)
-    	{
-     	LOGSMSPROT1("CSmsMonitorDiskSpace::ConstructL(): Smsu.rsc not in ROM");
-     	}
-
-	//
-	// Read the low and high limits...
-	//
-	TResourceReader  reader;
-	HBufC8*  buf;
-
-	resourceFile.OpenL(iFs, fileName);
-	CleanupClosePushL(resourceFile);
-
-	buf = resourceFile.AllocReadLC(R_LOWLIMIT_DISKSPACE_HOLDER);
-	reader.SetBuffer(buf);
-	iLowLimit = reader.ReadInt32();
-	CleanupStack::PopAndDestroy(buf);
-
-	buf = resourceFile.AllocReadLC(R_HIGHLIMIT_DISKSPACE_HOLDER);
-	reader.SetBuffer(buf);
-	iHighLimit=reader.ReadInt32();
-	CleanupStack::PopAndDestroy(buf);
-	
-	CleanupStack::PopAndDestroy(&resourceFile);
-
-#ifdef _DEBUG    
-    TInt  freeSpace;
-    TInt err = RProperty::Get(KUidPSSMSStackCategory, KUidPSSMSStackFreeDiskSpaceKey, freeSpace);
-    if (err == KErrNone)
-        {
-        iInOODTesting = ETrue;
-        
-        TInt ret = iFreeDiskSpaceProperty.Attach(KUidPSSMSStackCategory, KUidPSSMSStackFreeDiskSpaceKey);
-        if (ret != KErrNone)
-            {
-            LOGSMSPROT2("iFreeDiskSpaceProperty.Attach(): error=%d", ret);
-            User::Leave(ret);
-            }                        
-        }   
-#endif        
-    
-	LOGSMSPROT3("CSmsMonitorDiskSpace::ConstructL(): iLowLimit=%d, iHighLimit=%d",
-			    iLowLimit, iHighLimit);
-	} // CSmsMonitorDiskSpace::ConstructL
-
-
-/**
- *  Handles a completed disk monitor or resume request.
- */
-void CSmsMonitorDiskSpace::RunL()
-	{
-	LOGSMSPROT3("CSmsMonitorDiskSpace:RunL(): iStatus=%d, iState=%d",
-	            iStatus.Int(), iState );
-
-	switch (iState)
-		{
-		case ESmsMonitorDiskSpaceMonitorLowLimit:
-			{
-		 	iState = ESmsMonitorDiskSpaceIdle;
-			
-			//
-			// If the disk space has gone above the low limit, then
-			// resume reception. Otherwise (assuming the notify was
-			// successful) then start monitoring the low limit again...
-			//
-		 	TInt  freeDiskSpace = GetFreeDiskSpace();
-
-			if (freeDiskSpace >= iLowLimit)
-				{
-				ResumeSmsReception();
-				}
-			else if (iStatus.Int() == KErrNone)
-				{
-				NotifyDiskSpace(iLowLimit, ESmsMonitorDiskSpaceMonitorLowLimit);
-				}
-		 	}
-		 	break;
-
-		case ESmsMonitorDiskSpaceMonitorHighLimit:
-			{
-		 	iState = ESmsMonitorDiskSpaceIdle;
-			
-			//
-			// If the disk space has gone above the high limit, then
-			// resume reception. Otherwise (assuming the notify was
-			// successful) then start monitoring the high limit again...
-			//
-		 	TInt  freeDiskSpace = GetFreeDiskSpace();
-
-			if (freeDiskSpace >= iHighLimit)
-				{
-				ResumeSmsReception();
-				}
-			else if (iStatus.Int() == KErrNone)
-				{
-				NotifyDiskSpace(iHighLimit, ESmsMonitorDiskSpaceMonitorHighLimit);
-				}
-		 	}
-		 	break;
-
-		case ESmsMonitorDiskSpaceResumeReception:
-			{
-			//
-			// We are finished. However, check if any N'Acks were sent between
-			// the time we began the resume and now incase we need to restart
-			// the monitoring.
-			//
-			if (iNAckdClassZero)
-				{
-				NotifyDiskSpace(iLowLimit, ESmsMonitorDiskSpaceMonitorLowLimit);
-				}
-			else if (iNAckdClassOther)
-				{
-				NotifyDiskSpace(iHighLimit, ESmsMonitorDiskSpaceMonitorHighLimit);
-				}
-			else
-				{
-				iState = ESmsMonitorDiskSpaceIdle;
-				}
-			}
-			break;
-
-		default:
-			{
-		 	SmspPanic(KSmspPanicUnexpectedState);
-		 	}
-			break;
-		}
-	} // CSmsMonitorDiskSpace::RunL
-
-
-/**
- *  Handles a request to cancel the current state machine operation.
- */
-void CSmsMonitorDiskSpace::DoCancel()
-	{
-	LOGSMSPROT2("CSmsMonitorDiskSpace::DoCancel(): iState=%d", iState);
-
-    switch (iState)
-		{
-		case ESmsMonitorDiskSpaceIdle:
-			{
-			// NOP
-			}
-	 		break;
-
-		case ESmsMonitorDiskSpaceMonitorLowLimit:
-		case ESmsMonitorDiskSpaceMonitorHighLimit:
-			{
-#ifdef _DEBUG			
-			if (iInOODTesting)
-			    {
-			    iFreeDiskSpaceProperty.Cancel();			    
-			    }
-			else
-#endif			    
-                {
-                iFs.NotifyDiskSpaceCancel();
-                }
-			    			    			    			    
-		 	}
-		 	break;
-
-		case ESmsMonitorDiskSpaceResumeReception:
-			{
-		   	iSmsMessaging.CancelAsyncRequest(EMobileSmsMessagingResumeSmsReception);
-			}
-			break;
-
-		default:
-			{
-		 	SmspPanic(KSmspPanicUnexpectedState);
-		 	}
-		}
-
-	iState = ESmsMonitorDiskSpaceIdle;
-	} // CSmsMonitorDiskSpace::DoCancel
-
-
-/**
- *  Checks for enough disk space, and starts monitoring disk space if needed.
- */
-void CSmsMonitorDiskSpace::CheckDiskSpaceForPDUL(TBool aPDUIsClass0)
-	{
-	LOGSMSPROT2("CSmsMonitorDiskSpace::CheckDiskSpaceForPDUL(): aPDUIsClass0=%d",
-				aPDUIsClass0);
-
-	//
-	// First check the actual disk space before working out what to do.
-	// 
-	// If enough space exists, then we don't need to do anything else (even if
-	// we where previously monitoring, because that will be handled later as
-	// it would without this function call).
-	//
-	TInt  freeDiskSpace = GetFreeDiskSpace();
-	
-	if (freeDiskSpace >= iHighLimit  ||
-		(freeDiskSpace >= iLowLimit  &&  aPDUIsClass0))
-		{
-		//
-		// There is enough space for the PDU, so nothing more to do.
-		//
-		return;
-		}
-	
-	//
-	// There is not enough diskspace so record that a PDU will be N'Ack'd.
-	//
-	if (aPDUIsClass0)
-		{
-		iNAckdClassZero = ETrue;
-		}
-	else
-		{
-		iNAckdClassOther = ETrue;
-		}
-	
-	//
-	// Ensure we are monitoring the disk space. This will then cause a
-	// ResumeReception() to be sent when the disk space increases above the
-	// appropriate limit.
-	//
-    if (freeDiskSpace < iLowLimit)
-    	{
-    	//
-    	// Start montioring the low limit, if not already monitoring or if
-    	// we are currently monitoring the high limit.
-    	//
-		if (iState == ESmsMonitorDiskSpaceIdle  ||
-			iState == ESmsMonitorDiskSpaceMonitorHighLimit)
-			{
-	    	NotifyDiskSpace(iLowLimit, ESmsMonitorDiskSpaceMonitorLowLimit);
-	    	}
-		}
-    else // (freeDiskSpace < iHighLimit)
-    	{
-    	//
-    	// Start monitoring the high limit if not already monitoring...
-    	//
-		if (iState == ESmsMonitorDiskSpaceIdle)
-			{
-	    	NotifyDiskSpace(iHighLimit, ESmsMonitorDiskSpaceMonitorHighLimit);
-	    	}
-    	}
-
-	//
-	// Imform the caller that the SMS should be N'Ack'd...
-	//
-	User::Leave(KErrDiskFull);
-	} // CSmsMonitorDiskSpace::CheckDiskSpaceForPDUL
-
-
-/**
- *  Starts monitoring the free disk space to spot when it rises above the
- *  requested limit.
- *
- *  Unfortunately the File System API does not distiguish between going below
- *  or above a limit, so some checking is needed to ensure that the correct
- *  behaviour is requested, since it is possible in theory for the disk space
- *  to change between the calls.
- *
- *  In theory this is unlikely since the priority of the SMS Stack is higher
- *  but not impossible to happen. We guard against it anyway since the mere
- *  fact it could happen poses questions when the defects come in from handsets.
- *
- *  @note The current disk space is assumed to be below the limit requested.
- *        If it is found to be above, this will cause an imediate completion.
- *
- *  @param aLimit  Limit to monitor.
- *  @param aState  State to transition to when this request is made.
- */
-void CSmsMonitorDiskSpace::NotifyDiskSpace(TInt aLimit,
-										   TSmsMonitorDiskSpaceState aState)
-	{
-	LOGSMSPROT3("CSmsMonitorDiskSpace::NotifyDiskSpace(): aLimit=%d, aState=%d",
-				aLimit, aState);
-
-	//
-	// Cancel any previously outstanding requests...
-	//
-	if (iState != ESmsMonitorDiskSpaceIdle)
-		{
-		Cancel();
-		}
-		
-	//
-	// Start the notification...
-	//
-	iState = aState;
-
-#ifdef _DEBUG	
-	if (iInOODTesting)
-        {
-        iFreeDiskSpaceProperty.Subscribe(iStatus);
-        }
-    else
-#endif                
-        {
-        iFs.NotifyDiskSpace(aLimit, EDriveC, iStatus);
-        }	
-	
-	iSmsComm.DiskSpaceMonitorStateChange(ESmsDiskSpaceFull);
-	SetActive();
-	
-	//
-	// Now, as a sanity check, check the diskspace again. If the disk space
-	// has advanced above the limit in the time between the request and now,
-	// or since the last call to GetFreeDiskSpace() then the request will
-	// either be invalid, or have completed. If either of these are the case
-	// we need to control the situation and ensure a completion occurs...
-	//
-	TInt  freeDiskSpace = GetFreeDiskSpace();
-	
-	if (freeDiskSpace > aLimit)
-		{
-		//
-		// Cancel the request...
-		//
-		Cancel();
-		
-		//
-		// Force a fake completion for this state...
-		//
-		TRequestStatus*  status = &iStatus;
-
-		iState = aState;
-		iStatus = KRequestPending;
-		SetActive();
-		User::RequestComplete(status, KErrNone);
-		}
-	} // CSmsMonitorDiskSpace::NotifyDiskSpace
-
-
-/**
- *  Performs the required actions for the case when leaving either the low
- *  limit or the high limit. It doesn't really matter which limit you are
- *  leaving since the resume applies for all SMSs. This gives three scenarios:
- *
- *      1) You leave the high limit. This is not a problem as all SMSs can
- *         now be received.
- *      2) You leave the low limit and go above the high limit. This is also
- *         not a problem as all SMSs can be received.
- *      3) You leave the low limit but stay below the high limit. In this case
- *         the N'Ack'd SMS was class 0 and you can now receive it. A non-class 0
- *         SMS may attempt to be delivered, but monitoring will restart as
- *         before. So again no problem.
- */
-void CSmsMonitorDiskSpace::ResumeSmsReception()
-	{
-	LOGSMSPROT1("CSmsMonitorDiskSpace::ResumeSmsReception");
-
-	//
-	// Cancel any previously outstanding requests...
-	//
-	if (iState != ESmsMonitorDiskSpaceIdle)
-		{
-		Cancel();
-		}
-
-	//
-	// Clear the N'Ackd flags...
-	//
-	iNAckdClassZero = EFalse;
-	iNAckdClassOther = EFalse;
-
-	//
-	// Start the resume request...
-	//
-	iState = ESmsMonitorDiskSpaceResumeReception;
-	iSmsMessaging.ResumeSmsReception(iStatus);
-	iSmsComm.DiskSpaceMonitorStateChange(ESmsDiskSpaceAvailable);
- 	SetActive();
-	} // CSmsMonitorDiskSpace::ResumeSmsReception
-
-
-/**
- *  Utilility function to determine amount of free disk space. The actual
- *  free space is limited at 2GB.
- */
-TInt CSmsMonitorDiskSpace::GetFreeDiskSpace()
-	{
-	TVolumeInfo  volumeInfo;
-	TInt  ret;
-	
-#ifdef _DEBUG
-    if( iInOODTesting )
-        {
-        TInt value = 0;
-        ret = iFreeDiskSpaceProperty.Get(value);
-        
-        // update volumeInfo with value regardless of error as error handled later
-        volumeInfo.iFree = value;
-        }
-    else    
-#endif                
-        {
-        ret = iFs.Volume(volumeInfo, EDriveC);
-        }
-    
-	//
-	// Get the volume info for drive C:...
-	//
-    
-	if (ret != KErrNone) 
-		{
-		LOGSMSPROT2("CSmsMonitorDiskSpace::GetFreeDiskSpace(): error=%d", ret);
-		return KErrGeneral;
-		}
-
-	//
-	// Convert the disk space value to a TInt (allowing 2GB limits)...
-	//	
-	TInt  freeSpace;
-	
-	if (volumeInfo.iFree >= 0x7fffffff)
-		{
-		freeSpace = 0x7fffffff;
-		}
-	else
-		{
-		freeSpace = (TInt) volumeInfo.iFree;
-		}
-
-	LOGSMSPROT2("CSmsMonitorDiskSpace::GetFreeDiskSpace(): freeSpace=%d", freeSpace);
-
-	return freeSpace;
-	} // CSmsMonitorDiskSpace::GetFreeDiskSpace
+// 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:
+// Implementation for a CActive based class that monitors for low disk space
+// and is informed when a PDU is being received. Should memory be too low,
+// an error code is returned causing a NAck. The class will then monitor
+// for the point at which PDUs can be received again, and a Resume Reception
+// will be sent to the network.
+// The are two limits - a high limit for general SMSs and a low limit for
+// class 0 SMSs. However there is only one way to resume reception of SMSs. So
+// once a resume reception is sent, it resumes hoth types of SMSs. The algorithm
+// is a bit simiplier because of this:
+// IF sending non-Class 0 AND we are below the high limit THEN
+// N'Ack SMS
+// IF not waiting for free diskspace THEN
+// Wait for free diskspace to rise above the high limit
+// Resume SMS Reception.
+// ELSE
+// Continue waiting for either high limit or low limit
+// Resume SMS Reception as previously intended
+// END_IF
+// ELSE IF sending Class 0 AND we are below the low limit THEN
+// Wait for free diskspace to rise above the low limit
+// Resume SMS Reception.
+// END_IF
+// Note that in the second and last case, SMS reception may be resumed before
+// we are above the high limit, but in that case montioring will repeat when
+// the next non-class 0 SMS is attempted to be delivered. This is necessary as
+// there is no way to resume just class 0 SMSs.
+// 
+//
+
+/**
+ @file
+ @internalComponent 
+*/
+
+#include <barsc.h>
+#include <bautils.h>
+
+#include "smspcomm.h"
+#include "smspmondsk.h"
+#include "smsstacklog.h"
+#include "smspmain.h"
+#include "smspver.h"
+#include <smsu.rsg>
+
+
+_LIT(KSmsResourceFile, "sms\\smsu.rsc");
+
+
+/**
+ *  2 phase constructor.
+ *  
+ *  @leave Leaves if not enough memory is available.
+ *  
+ *  @return a newly created CSmsMonitorDiskSpace object.
+ */
+CSmsMonitorDiskSpace* CSmsMonitorDiskSpace::NewL(MSmsComm& aSmsComm, RMobileSmsMessaging& aSmsMessaging,RFs& aFs)
+	{
+	LOGSMSPROT1("CSmsMonitorDiskSpace::NewL()");
+
+	CSmsMonitorDiskSpace*  self = new(ELeave) CSmsMonitorDiskSpace(aSmsComm, aSmsMessaging, aFs);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+
+	return self;
+	} // CSmsMonitorDiskSpace::NewL
+
+
+/**
+ *  Private constructor used in the first phase of construction.
+ */
+CSmsMonitorDiskSpace::CSmsMonitorDiskSpace(MSmsComm& aSmsComm, RMobileSmsMessaging& aSmsMessaging,RFs& aFs)
+  : CActive(KSmsSessionPriority),
+	iState(ESmsMonitorDiskSpaceIdle),
+	iSmsMessaging(aSmsMessaging),
+	iFs(aFs),
+	iSmsComm(aSmsComm),
+	iLowLimit(8*1024),
+	iHighLimit(16*1024)
+	{
+	CActiveScheduler::Add(this);
+	} // CSmsMonitorDiskSpace::CSmsMonitorDiskSpace
+
+
+/**
+ *  Destructor.  Ensures any outstanding operation is cancelled.
+ */
+CSmsMonitorDiskSpace::~CSmsMonitorDiskSpace()
+	{
+    Cancel();
+
+#ifdef _DEBUG    
+    iFreeDiskSpaceProperty.Close();
+#endif
+    
+	} // CSmsMonitorDiskSpace::~CSmsMonitorDiskSpace
+
+
+/**
+ *  Initialize values for LowLimitDiskSpace and HighLimitDiskSpace
+ *  from resource file
+ */
+void CSmsMonitorDiskSpace::ConstructL()
+	{
+	RResourceFile  resourceFile;
+	TFileName  fileName;
+	Dll::FileName(fileName);
+	TParse  parse;
+	TFileName  resourceFileName;
+
+	//
+	// Create the path to the resource file...
+	//
+	iFs.PrivatePath(resourceFileName);
+	resourceFileName.Append(KSmsResourceFile);
+	parse.Set(resourceFileName, &fileName, 0);
+	fileName = parse.FullName();
+	BaflUtils::NearestLanguageFile(iFs, fileName);
+
+	//
+	// To enable adequate CSmsMonitorDiskSpace testing we allow the SMSU.RSC
+	// file to be loaded from the C: drive if it exists. This is only for a
+	// DEBUG version of course! Later WINSCW is also added to allow the testing
+	// on WINSCW UREL version.
+	//
+#if (defined __WINSCW__) || (defined _DEBUG)
+	TUint  attValue;
+	TChar  oldDriveLetter = fileName[0];
+
+	//
+	// Change the filename to look on C: and then see if it exists...
+	//	
+	fileName[0] = 'C';
+
+	if (iFs.Att(fileName, attValue) != KErrNone)
+		{
+		//
+		// The file does not exist on C: so revert the change...
+		//
+		fileName[0] = oldDriveLetter;
+		}
+#endif
+
+	//
+	// Log the filename in use and whether it is ROM based...
+	//
+#ifdef _SMS_LOGGING_ENABLED
+	TBuf8<KMaxFileName>  buf8;
+	buf8.Copy(fileName);
+	LOGSMSPROT2("CSmsMonitorDiskSpace::ConstructL(): fileName=\"%S\"", &buf8);
+#endif
+
+    if (iFs.IsFileInRom(fileName) == NULL)
+    	{
+     	LOGSMSPROT1("CSmsMonitorDiskSpace::ConstructL(): Smsu.rsc not in ROM");
+     	}
+
+	//
+	// Read the low and high limits...
+	//
+	TResourceReader  reader;
+	HBufC8*  buf;
+
+	resourceFile.OpenL(iFs, fileName);
+	CleanupClosePushL(resourceFile);
+
+	buf = resourceFile.AllocReadLC(R_LOWLIMIT_DISKSPACE_HOLDER);
+	reader.SetBuffer(buf);
+	iLowLimit = reader.ReadInt32();
+	CleanupStack::PopAndDestroy(buf);
+
+	buf = resourceFile.AllocReadLC(R_HIGHLIMIT_DISKSPACE_HOLDER);
+	reader.SetBuffer(buf);
+	iHighLimit=reader.ReadInt32();
+	CleanupStack::PopAndDestroy(buf);
+	
+	CleanupStack::PopAndDestroy(&resourceFile);
+
+#ifdef _DEBUG    
+    TInt  freeSpace;
+    TInt err = RProperty::Get(KUidPSSMSStackCategory, KUidPSSMSStackFreeDiskSpaceKey, freeSpace);
+    if (err == KErrNone)
+        {
+        iInOODTesting = ETrue;
+        
+        TInt ret = iFreeDiskSpaceProperty.Attach(KUidPSSMSStackCategory, KUidPSSMSStackFreeDiskSpaceKey);
+        if (ret != KErrNone)
+            {
+            LOGSMSPROT2("iFreeDiskSpaceProperty.Attach(): error=%d", ret);
+            User::Leave(ret);
+            }                        
+        }   
+#endif        
+    
+	LOGSMSPROT3("CSmsMonitorDiskSpace::ConstructL(): iLowLimit=%d, iHighLimit=%d",
+			    iLowLimit, iHighLimit);
+	} // CSmsMonitorDiskSpace::ConstructL
+
+
+/**
+ *  Handles a completed disk monitor or resume request.
+ */
+void CSmsMonitorDiskSpace::RunL()
+	{
+	LOGSMSPROT3("CSmsMonitorDiskSpace:RunL(): iStatus=%d, iState=%d",
+	            iStatus.Int(), iState );
+
+	switch (iState)
+		{
+		case ESmsMonitorDiskSpaceMonitorLowLimit:
+			{
+		 	iState = ESmsMonitorDiskSpaceIdle;
+			
+			//
+			// If the disk space has gone above the low limit, then
+			// resume reception. Otherwise (assuming the notify was
+			// successful) then start monitoring the low limit again...
+			//
+		 	TInt  freeDiskSpace = GetFreeDiskSpace();
+
+			if (freeDiskSpace >= iLowLimit)
+				{
+				ResumeSmsReception();
+				}
+			else if (iStatus.Int() == KErrNone)
+				{
+				NotifyDiskSpace(iLowLimit, ESmsMonitorDiskSpaceMonitorLowLimit);
+				}
+		 	}
+		 	break;
+
+		case ESmsMonitorDiskSpaceMonitorHighLimit:
+			{
+		 	iState = ESmsMonitorDiskSpaceIdle;
+			
+			//
+			// If the disk space has gone above the high limit, then
+			// resume reception. Otherwise (assuming the notify was
+			// successful) then start monitoring the high limit again...
+			//
+		 	TInt  freeDiskSpace = GetFreeDiskSpace();
+
+			if (freeDiskSpace >= iHighLimit)
+				{
+				ResumeSmsReception();
+				}
+			else if (iStatus.Int() == KErrNone)
+				{
+				NotifyDiskSpace(iHighLimit, ESmsMonitorDiskSpaceMonitorHighLimit);
+				}
+		 	}
+		 	break;
+
+		case ESmsMonitorDiskSpaceResumeReception:
+			{
+			//
+			// We are finished. However, check if any N'Acks were sent between
+			// the time we began the resume and now incase we need to restart
+			// the monitoring.
+			//
+			if (iNAckdClassZero)
+				{
+				NotifyDiskSpace(iLowLimit, ESmsMonitorDiskSpaceMonitorLowLimit);
+				}
+			else if (iNAckdClassOther)
+				{
+				NotifyDiskSpace(iHighLimit, ESmsMonitorDiskSpaceMonitorHighLimit);
+				}
+			else
+				{
+				iState = ESmsMonitorDiskSpaceIdle;
+				}
+			}
+			break;
+
+		default:
+			{
+		 	SmspPanic(KSmspPanicUnexpectedState);
+		 	}
+			break;
+		}
+	} // CSmsMonitorDiskSpace::RunL
+
+
+/**
+ *  Handles a request to cancel the current state machine operation.
+ */
+void CSmsMonitorDiskSpace::DoCancel()
+	{
+	LOGSMSPROT2("CSmsMonitorDiskSpace::DoCancel(): iState=%d", iState);
+
+    switch (iState)
+		{
+		case ESmsMonitorDiskSpaceIdle:
+			{
+			// NOP
+			}
+	 		break;
+
+		case ESmsMonitorDiskSpaceMonitorLowLimit:
+		case ESmsMonitorDiskSpaceMonitorHighLimit:
+			{
+#ifdef _DEBUG			
+			if (iInOODTesting)
+			    {
+			    iFreeDiskSpaceProperty.Cancel();			    
+			    }
+			else
+#endif			    
+                {
+                iFs.NotifyDiskSpaceCancel();
+                }
+			    			    			    			    
+		 	}
+		 	break;
+
+		case ESmsMonitorDiskSpaceResumeReception:
+			{
+		   	iSmsMessaging.CancelAsyncRequest(EMobileSmsMessagingResumeSmsReception);
+			}
+			break;
+
+		default:
+			{
+		 	SmspPanic(KSmspPanicUnexpectedState);
+		 	}
+		}
+
+	iState = ESmsMonitorDiskSpaceIdle;
+	} // CSmsMonitorDiskSpace::DoCancel
+
+
+/**
+ *  Checks for enough disk space, and starts monitoring disk space if needed.
+ */
+void CSmsMonitorDiskSpace::CheckDiskSpaceForPDUL(TBool aPDUIsClass0)
+	{
+	LOGSMSPROT2("CSmsMonitorDiskSpace::CheckDiskSpaceForPDUL(): aPDUIsClass0=%d",
+				aPDUIsClass0);
+
+	//
+	// First check the actual disk space before working out what to do.
+	// 
+	// If enough space exists, then we don't need to do anything else (even if
+	// we where previously monitoring, because that will be handled later as
+	// it would without this function call).
+	//
+	TInt  freeDiskSpace = GetFreeDiskSpace();
+	
+	if (freeDiskSpace >= iHighLimit  ||
+		(freeDiskSpace >= iLowLimit  &&  aPDUIsClass0))
+		{
+		//
+		// There is enough space for the PDU, so nothing more to do.
+		//
+		return;
+		}
+	
+	//
+	// There is not enough diskspace so record that a PDU will be N'Ack'd.
+	//
+	if (aPDUIsClass0)
+		{
+		iNAckdClassZero = ETrue;
+		}
+	else
+		{
+		iNAckdClassOther = ETrue;
+		}
+	
+	//
+	// Ensure we are monitoring the disk space. This will then cause a
+	// ResumeReception() to be sent when the disk space increases above the
+	// appropriate limit.
+	//
+    if (freeDiskSpace < iLowLimit)
+    	{
+    	//
+    	// Start montioring the low limit, if not already monitoring or if
+    	// we are currently monitoring the high limit.
+    	//
+		if (iState == ESmsMonitorDiskSpaceIdle  ||
+			iState == ESmsMonitorDiskSpaceMonitorHighLimit)
+			{
+	    	NotifyDiskSpace(iLowLimit, ESmsMonitorDiskSpaceMonitorLowLimit);
+	    	}
+		}
+    else // (freeDiskSpace < iHighLimit)
+    	{
+    	//
+    	// Start monitoring the high limit if not already monitoring...
+    	//
+		if (iState == ESmsMonitorDiskSpaceIdle)
+			{
+	    	NotifyDiskSpace(iHighLimit, ESmsMonitorDiskSpaceMonitorHighLimit);
+	    	}
+    	}
+
+	//
+	// Imform the caller that the SMS should be N'Ack'd...
+	//
+	User::Leave(KErrDiskFull);
+	} // CSmsMonitorDiskSpace::CheckDiskSpaceForPDUL
+
+
+/**
+ *  Starts monitoring the free disk space to spot when it rises above the
+ *  requested limit.
+ *
+ *  Unfortunately the File System API does not distiguish between going below
+ *  or above a limit, so some checking is needed to ensure that the correct
+ *  behaviour is requested, since it is possible in theory for the disk space
+ *  to change between the calls.
+ *
+ *  In theory this is unlikely since the priority of the SMS Stack is higher
+ *  but not impossible to happen. We guard against it anyway since the mere
+ *  fact it could happen poses questions when the defects come in from handsets.
+ *
+ *  @note The current disk space is assumed to be below the limit requested.
+ *        If it is found to be above, this will cause an imediate completion.
+ *
+ *  @param aLimit  Limit to monitor.
+ *  @param aState  State to transition to when this request is made.
+ */
+void CSmsMonitorDiskSpace::NotifyDiskSpace(TInt aLimit,
+										   TSmsMonitorDiskSpaceState aState)
+	{
+	LOGSMSPROT3("CSmsMonitorDiskSpace::NotifyDiskSpace(): aLimit=%d, aState=%d",
+				aLimit, aState);
+
+	//
+	// Cancel any previously outstanding requests...
+	//
+	if (iState != ESmsMonitorDiskSpaceIdle)
+		{
+		Cancel();
+		}
+		
+	//
+	// Start the notification...
+	//
+	iState = aState;
+
+#ifdef _DEBUG	
+	if (iInOODTesting)
+        {
+        iFreeDiskSpaceProperty.Subscribe(iStatus);
+        }
+    else
+#endif                
+        {
+        iFs.NotifyDiskSpace(aLimit, EDriveC, iStatus);
+        }	
+	
+	iSmsComm.DiskSpaceMonitorStateChange(ESmsDiskSpaceFull);
+	SetActive();
+	
+	//
+	// Now, as a sanity check, check the diskspace again. If the disk space
+	// has advanced above the limit in the time between the request and now,
+	// or since the last call to GetFreeDiskSpace() then the request will
+	// either be invalid, or have completed. If either of these are the case
+	// we need to control the situation and ensure a completion occurs...
+	//
+	TInt  freeDiskSpace = GetFreeDiskSpace();
+	
+	if (freeDiskSpace > aLimit)
+		{
+		//
+		// Cancel the request...
+		//
+		Cancel();
+		
+		//
+		// Force a fake completion for this state...
+		//
+		TRequestStatus*  status = &iStatus;
+
+		iState = aState;
+		iStatus = KRequestPending;
+		SetActive();
+		User::RequestComplete(status, KErrNone);
+		}
+	} // CSmsMonitorDiskSpace::NotifyDiskSpace
+
+
+/**
+ *  Performs the required actions for the case when leaving either the low
+ *  limit or the high limit. It doesn't really matter which limit you are
+ *  leaving since the resume applies for all SMSs. This gives three scenarios:
+ *
+ *      1) You leave the high limit. This is not a problem as all SMSs can
+ *         now be received.
+ *      2) You leave the low limit and go above the high limit. This is also
+ *         not a problem as all SMSs can be received.
+ *      3) You leave the low limit but stay below the high limit. In this case
+ *         the N'Ack'd SMS was class 0 and you can now receive it. A non-class 0
+ *         SMS may attempt to be delivered, but monitoring will restart as
+ *         before. So again no problem.
+ */
+void CSmsMonitorDiskSpace::ResumeSmsReception()
+	{
+	LOGSMSPROT1("CSmsMonitorDiskSpace::ResumeSmsReception");
+
+	//
+	// Cancel any previously outstanding requests...
+	//
+	if (iState != ESmsMonitorDiskSpaceIdle)
+		{
+		Cancel();
+		}
+
+	//
+	// Clear the N'Ackd flags...
+	//
+	iNAckdClassZero = EFalse;
+	iNAckdClassOther = EFalse;
+
+	//
+	// Start the resume request...
+	//
+	iState = ESmsMonitorDiskSpaceResumeReception;
+	iSmsMessaging.ResumeSmsReception(iStatus);
+	iSmsComm.DiskSpaceMonitorStateChange(ESmsDiskSpaceAvailable);
+ 	SetActive();
+	} // CSmsMonitorDiskSpace::ResumeSmsReception
+
+
+/**
+ *  Utilility function to determine amount of free disk space. The actual
+ *  free space is limited at 2GB.
+ */
+TInt CSmsMonitorDiskSpace::GetFreeDiskSpace()
+	{
+	TVolumeInfo  volumeInfo;
+	TInt  ret;
+	
+#ifdef _DEBUG
+    if( iInOODTesting )
+        {
+        TInt value = 0;
+        ret = iFreeDiskSpaceProperty.Get(value);
+        
+        // update volumeInfo with value regardless of error as error handled later
+        volumeInfo.iFree = value;
+        }
+    else    
+#endif                
+        {
+        ret = iFs.Volume(volumeInfo, EDriveC);
+        }
+    
+	//
+	// Get the volume info for drive C:...
+	//
+    
+	if (ret != KErrNone) 
+		{
+		LOGSMSPROT2("CSmsMonitorDiskSpace::GetFreeDiskSpace(): error=%d", ret);
+		return KErrGeneral;
+		}
+
+	//
+	// Convert the disk space value to a TInt (allowing 2GB limits)...
+	//	
+	TInt  freeSpace;
+	
+	if (volumeInfo.iFree >= 0x7fffffff)
+		{
+		freeSpace = 0x7fffffff;
+		}
+	else
+		{
+		freeSpace = (TInt) volumeInfo.iFree;
+		}
+
+	LOGSMSPROT2("CSmsMonitorDiskSpace::GetFreeDiskSpace(): freeSpace=%d", freeSpace);
+
+	return freeSpace;
+	} // CSmsMonitorDiskSpace::GetFreeDiskSpace