--- /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