smsprotocols/smsstack/smsprot/Src/smsprecvmode.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
child 42 3adadc800673
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smsprotocols/smsstack/smsprot/Src/smsprecvmode.cpp	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,379 @@
+// 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:
+// Implements the CSmspReceiveMode and CSmspReceiveModeNotifier classes
+// 
+//
+
+/**
+ @file
+*/
+
+#include <commsdattypesv1_1.h>
+#include <cdbcols.h>
+
+#include "smspcdb.h"
+#include "smspmain.h"
+#include <commdb.h>
+#include "smsuset.h"
+#include "SmsuTimer.h"
+
+using namespace CommsDat;
+
+
+/**
+ *  CSmspReceiveMode constructor
+ */
+CSmspReceiveMode::CSmspReceiveMode(const TSmsSettings& aSmsSettings,
+								   RMobileSmsMessaging& aSmsMessaging,
+								   const RMobileSmsMessaging::TMobileSmsCapsV1& aSmsCaps,
+								   TInt aPriority)
+  : CSmspCommDbEvent(aSmsSettings, aSmsMessaging, aPriority),
+	iSmsReceiveModeLastSet(RMobileSmsMessaging::EReceiveModeUnspecified),
+	iSmsCaps(aSmsCaps)
+	{
+	// NOP
+	} // CSmspReceiveMode::CSmspReceiveMode
+
+
+/**
+ *  CSmspReceiveMode destructor
+ */
+CSmspReceiveMode::~CSmspReceiveMode()
+	{
+	Cancel();
+	iCommDbRetryTimer.Close();
+	} // CSmspReceiveMode::~CSmspReceiveMode
+
+
+/**
+ *  Two-phase construction of CSmspReceiveMode
+ */
+CSmspReceiveMode* CSmspReceiveMode::NewL(const TSmsSettings& aSmsSettings, RMobileSmsMessaging& aSmsMessaging, const RMobileSmsMessaging::TMobileSmsCapsV1& aSmsCaps, TInt aPriority)
+	{
+	LOGSMSPROT1("CSmspReceiveMode::NewL()");
+
+	CSmspReceiveMode* self = new (ELeave) CSmspReceiveMode(aSmsSettings, aSmsMessaging, aSmsCaps, aPriority);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	} // CSmspReceiveMode::NewL
+
+
+void CSmspReceiveMode::ConstructL()
+	{
+	LOGSMSPROT1("CSmspReceiveMode::ConstructL()");
+
+	CSmspCommDbEvent::ConstructL();
+	User::LeaveIfError(iCommDbRetryTimer.CreateLocal());
+	User::LeaveIfError(iProperty.Attach(KUidSystemCategory, KUidCommDbSMSReceiveModeChange.iUid));
+	} // CSmspReceiveMode::ConstructL
+
+
+/**
+ *  Intially sets the SMS Receive Mode on the TSY or waits for notification of the CommDB global setting SMS_RECEIVE_MODE to change
+ */
+void CSmspReceiveMode::Start(TRequestStatus& aStatus)
+	{
+	LOGSMSPROT1("CSmspReceiveMode::Start()");
+
+	Cancel();
+	Queue(aStatus);
+
+	RMobileSmsMessaging::TMobileSmsReceiveMode recvMode(SelectReceiveMode());
+	
+	//
+	// Until we manage to read the CommDB the default choice is the best known
+	//
+	if (iSmsReceiveModeLastSet == RMobileSmsMessaging::EReceiveModeUnspecified)
+		{
+		iSmsReceiveModeLastSet = recvMode;
+		}
+
+	TRAPD(err, GetCommDbReceiveModeL(recvMode));
+	if(err == KErrNone)
+		{
+		SetReceiveMode(recvMode);
+		}
+	else
+		{
+		iState = ESmspReceiveModeRetryCommDb;
+		iCommDbRetryCount = KSmspReceiveModeCommDbRetryLimit;
+		iCommDbRetryTimer.After(iStatus, KSmspReceiveModeCommDbRetryDelay);
+		SetActive();
+		}
+	} // CSmspReceiveMode::Start
+
+
+/**
+ *  Wait for notification from property for when the CommDB global setting SMS_RECEIVE_MODE changes
+ */
+void CSmspReceiveMode::NotifyOnEvent()
+	{
+	LOGSMSPROT1("CSmspReceiveMode::NotifyOnEvent()");
+
+	iState = ESmspReceiveModeNotifyOnEvent;
+	CSmspCommDbEvent::NotifyOnEvent();
+	} // CSmspReceiveMode::NotifyOnEvent
+
+
+/**
+ *  Sets the SMS Receive Mode on the TSY
+ *  
+ *  @param aReceiveMode SMS Receive Mode to set on the TSY
+ */
+void CSmspReceiveMode::SetReceiveMode(RMobileSmsMessaging::TMobileSmsReceiveMode aReceiveMode)
+	{
+	LOGSMSPROT1("CSmspReceiveMode::SetReceiveMode()");
+
+	aReceiveMode = SelectReceiveMode(aReceiveMode);
+	iSmsReceiveModeLastSet = aReceiveMode;
+
+	iState = ESmspReceiveModeSet;
+	iSmsMessaging.SetReceiveMode(iStatus, aReceiveMode);
+	TimedSetActive(iSmsSettings.Timeout());
+	} // CSmspReceiveMode::SetReceiveMode
+
+
+void CSmspReceiveMode::DoCancel()
+	{
+	LOGSMSPROT1("CSmspReceiveMode::DoCancel()");
+
+	TimedSetActiveCancel();
+	switch (iState)
+		{
+		case ESmspReceiveModeInit:
+			{
+			// NOP
+			}
+			break;
+
+		case ESmspReceiveModeNotifyOnEvent:
+			{
+			iProperty.Cancel();
+			}
+			break;
+
+		case ESmspReceiveModeSet:
+			{
+			iSmsMessaging.CancelAsyncRequest(EMobileSmsMessagingSetReceiveMode);
+			}
+			break;
+
+		case ESmspReceiveModeRetryCommDb:
+			{
+			iCommDbRetryTimer.Cancel();
+			}
+			break;
+
+		default:
+			{
+			SmspPanic(KSmspPanicUnexpectedState);
+			}
+			break;
+		}
+
+	//
+	// 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);
+		}
+	} // CSmspReceiveMode::DoCancel
+
+
+/**
+ *  Read Comms Database global setting SMS_RECEIVE_MODE
+ *  
+ *  @param aReceiveMode Will be set to the CommsDat global setting SMS_RECEIVE_MODE
+ *  @return Error code if we cannot create the session, or load from the db
+ */
+void CSmspReceiveMode::GetCommDbReceiveModeL(RMobileSmsMessaging::TMobileSmsReceiveMode& aReceiveMode)
+	{
+	LOGSMSPROT1("CSmspReceiveMode::GetCommDbReceiveModeL()");
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+	CMDBSession* sess = CMDBSession::NewL(KCDVersion1_2);
+#else
+	CMDBSession* sess = CMDBSession::NewL(KCDVersion1_1);
+#endif
+	CleanupStack::PushL(sess);
+
+	CMDBField<TUint32>* smsReceiveModeField = new(ELeave) CMDBField<TUint32>(KCDTIdSMSReceiveMode);
+	CleanupStack::PushL(smsReceiveModeField);
+	smsReceiveModeField->SetRecordId(1);
+
+	smsReceiveModeField->LoadL(*sess);
+	aReceiveMode = static_cast<RMobileSmsMessaging::TMobileSmsReceiveMode>(static_cast<TUint32>(*smsReceiveModeField));
+
+	CleanupStack::PopAndDestroy(smsReceiveModeField);
+	CleanupStack::PopAndDestroy(sess);
+	} // CSmspReceiveMode::GetCommDbReceiveModeL
+
+
+void CSmspReceiveMode::DoRunL()
+	{
+	LOGSMSPROT1("CSmspReceiveMode::DoRunL()");
+
+	switch (iState)
+		{
+		case ESmspReceiveModeSet:
+			{
+			CSmsuActiveBase::Complete(iStatus.Int());
+
+			if (iStatus.Int() == KErrNone)
+				{
+				NotifyOnEvent();
+				}
+			}
+			break;
+
+		case ESmspReceiveModeRetryCommDb:
+			{
+			if (iStatus.Int() == KErrNone)
+				{
+				RMobileSmsMessaging::TMobileSmsReceiveMode recvMode;
+				TRAPD(err, GetCommDbReceiveModeL(recvMode));
+				if(err == KErrNone)
+					{
+					SetReceiveMode(recvMode);
+					}
+				else if(--iCommDbRetryCount > 0)
+					{
+					iCommDbRetryTimer.After(iStatus, KSmspReceiveModeCommDbRetryDelay);
+					SetActive();
+					}
+				else
+					{
+					// Failed to read CommDB even after retries. Set the receive mode to the last known setting
+					LOGSMSPROT2("CSmspReceiveMode::DoRunL in ESmspReceiveModeRetryCommDb state, failed to read CommDb, using mode #%d", iSmsReceiveModeLastSet );
+					SetReceiveMode(iSmsReceiveModeLastSet);
+					}
+				}
+			}
+			break;
+
+		case ESmspReceiveModeNotifyOnEvent:
+			{
+			if (iStatus.Int() == KErrNone)
+				{
+				TInt tempRecvMode;
+				User::LeaveIfError(iProperty.Get(tempRecvMode));
+				const RMobileSmsMessaging::TMobileSmsReceiveMode recvMode = static_cast<RMobileSmsMessaging::TMobileSmsReceiveMode>(tempRecvMode);
+
+				SetReceiveMode(recvMode);
+				}
+			else
+				{
+				NotifyOnEvent();
+				}
+			}
+			break;
+
+		default:
+			{
+			SmspPanic(KSmspPanicUnexpectedState);
+			}
+			break;
+		}
+
+	//
+	// DoRunL() will now return to CSmsuActiveBase which if the object
+	// is not active, will call Complete().
+	//
+	} // CSmspReceiveMode::DoRunL
+
+
+/**
+ *  Finds an SMS Receive Mode supported by the TSY, giving preference to EReceiveUnstoredClientAck and so forth.
+ *  
+ *  @return An SMS Receive Mode supported by the TSY.
+ */
+RMobileSmsMessaging::TMobileSmsReceiveMode CSmspReceiveMode::SelectReceiveMode() const
+	{
+	LOGSMSPROT1("CSmspReceiveMode::SelectReceiveMode()");
+
+	const TUint32 smsControl = iSmsCaps.iSmsControl;
+	RMobileSmsMessaging::TMobileSmsReceiveMode recvMode = RMobileSmsMessaging::EReceiveModeUnspecified;
+
+	if (smsControl & RMobileSmsMessaging::KCapsReceiveUnstoredClientAck)
+		{
+		recvMode = RMobileSmsMessaging::EReceiveUnstoredClientAck;
+		}
+	else if (smsControl & RMobileSmsMessaging::KCapsReceiveUnstoredPhoneAck)
+		{
+		recvMode =  RMobileSmsMessaging::EReceiveUnstoredPhoneAck;
+		}
+	else if (smsControl & RMobileSmsMessaging::KCapsReceiveStored)
+		{
+		recvMode = RMobileSmsMessaging::EReceiveStored;
+		}
+	else if (smsControl & RMobileSmsMessaging::KCapsReceiveEither)
+		{
+		recvMode =  RMobileSmsMessaging::EReceiveEither;
+		}
+
+	return recvMode;
+	} // CSmspReceiveMode::SelectReceiveMode
+
+
+/**
+ *  Finds an SMS Receive Mode supported by the TSY, giving preference to aPreferredMode.
+ *  
+ *  @param aPreferredMode SMS Receive Mode that a client would like to use.
+ *  @return aPreferredMode if it is supported by the TSY, otherwise return a receive mode that is supported by the TSY.
+ */
+RMobileSmsMessaging::TMobileSmsReceiveMode CSmspReceiveMode::SelectReceiveMode(RMobileSmsMessaging::TMobileSmsReceiveMode aPreferredMode) const
+	{
+	LOGSMSPROT1("CSmspReceiveMode::SelectReceiveMode()");
+
+	const TUint32 smsControl = iSmsCaps.iSmsControl;
+	TBool usePreferred = EFalse;
+
+	switch (aPreferredMode)
+		{
+		case RMobileSmsMessaging::EReceiveUnstoredClientAck:
+
+			usePreferred = smsControl & RMobileSmsMessaging::KCapsReceiveUnstoredClientAck;
+			break;
+
+		case RMobileSmsMessaging::EReceiveUnstoredPhoneAck:
+
+			usePreferred = smsControl & RMobileSmsMessaging::KCapsReceiveUnstoredPhoneAck;
+			break;
+
+		case RMobileSmsMessaging::EReceiveStored:
+
+			usePreferred = smsControl & RMobileSmsMessaging::KCapsReceiveStored;
+			break;
+
+		case RMobileSmsMessaging::EReceiveEither:
+
+			usePreferred = smsControl & RMobileSmsMessaging::KCapsReceiveEither;
+			break;
+
+		default:
+
+			//usePreferred = EFalse;
+			break;
+		}
+
+	return usePreferred ? aPreferredMode : SelectReceiveMode();
+	} // CSmspReceiveMode::SelectReceiveMode