smsprotocols/smsstack/smsprot/Src/smspbear.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smsprotocols/smsstack/smsprot/Src/smspbear.cpp	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,366 @@
+// 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:
+//
+
+/**
+ @file
+*/
+
+#include <commsdattypesv1_1.h>
+#include <cdbcols.h>
+#include "smspmain.h"
+#include "smsuset.h"
+#include "smspcdb.h"
+#include "SmsuTimer.h"
+
+using namespace CommsDat;
+
+
+/**
+ *  2 phase constructor.
+ *  
+ *  @param aSmsSettings a reference to the global SMS settings.
+ *  @param aSmsMessaging a reference to the ETEL SMS messaging subsession.
+ *  @param aPriority of the request.
+ *  @leave Leaves if ContructL() leaves, or not enough memory is available.
+ *  @return a new CSmspSetBearer object
+ */
+CSmspSetBearer* CSmspSetBearer::NewL(const TSmsSettings& aSmsSettings,RMobileSmsMessaging& aSmsMessaging, TInt aPriority)
+	{
+	LOGSMSPROT2("CSmspSetBearer::NewL aPriority = %d", aPriority);
+
+	CSmspSetBearer* smsSetBearer=new(ELeave) CSmspSetBearer(aSmsSettings,aSmsMessaging, aPriority);
+	CleanupStack::PushL(smsSetBearer);
+	smsSetBearer->ConstructL();
+	CleanupStack::Pop();
+
+	return smsSetBearer;
+	} // CSmspSetBearer::NewL
+
+
+/**
+ *  2-phase constructor, perform construction that can leave
+ */
+void CSmspSetBearer::ConstructL()
+	{
+	LOGSMSPROT1("CSmspSetBearer::ConstructL()");
+
+	CSmspCommDbEvent::ConstructL();
+
+	User::LeaveIfError(iProperty.Attach(KUidSystemCategory, KUidCommDbSMSBearerChange.iUid));
+	} // CSmspSetBearer::ConstructL
+
+
+/**
+ *  Private constructor used in the first phase of construction.
+ *  
+ *  @param aSmsSettings a reference to the global SMS settings.
+ *  @param aSmsMessaging a reference to the ETEL SMS messaging subsession.
+ *  @param aPriority of the request.
+ *  
+ */
+CSmspSetBearer::CSmspSetBearer(const TSmsSettings& aSmsSettings, RMobileSmsMessaging& aSmsMessaging, TInt aPriority)
+	:CSmspCommDbEvent(aSmsSettings, aSmsMessaging, aPriority)
+	,iState(ESmsSetBearerStateInit)
+	{
+	} // CSmspSetBearer::CSmspSetBearer
+
+
+/**
+ *  CSmspSetBearer destructor
+ */
+CSmspSetBearer::~CSmspSetBearer()
+	{
+	Cancel();
+	} // CSmspSetBearer::~CSmspSetBearer
+
+
+/**
+ *  Notifies if SMS bearer is set to the TSY. Start setting bearer
+ *  process if bearer is not set.
+ */
+void CSmspSetBearer::NotifyBearerSet(TRequestStatus& aStatus)
+	{
+	LOGSMSPROT2("CSmspSetBearer::NotifyBearerSet, aStatus = %d", aStatus.Int());
+	if (!iBearerSet && IsActive())
+		{
+		Cancel();
+		}
+
+	Queue(aStatus);
+
+	if (iBearerSet)
+		{
+		LOGSMSPROT1("CSmspSetBearer::NotifyBearerSet RequestComplete called");
+		CSmsuActiveBase::Complete(KErrNone);
+		}
+	else
+		{
+		LOGSMSPROT1("CSmspSetBearer::NotifyBearerSet started");
+		Start();
+		}
+	} // CSmspSetBearer::NotifyBearerSet
+
+
+/**
+ *  Starts the sequence for configuring the current SMS bearer on the phone/TSY.
+ */
+void CSmspSetBearer::Start()
+	{
+	LOGSMSPROT1("CSmspSetBearer::Start");
+	// Cancel any outstanding request
+	TRAPD(err, GetSmsBearerL(iBearer));
+
+	iBearerSet = EFalse;
+
+	if (err == KErrNone)
+		{
+		LOGSMSPROT2("CSmspSetBearer::GetSmsBearerL() left with %d", err);
+
+		// Set the previous bearer to the one that has been read
+		// from CommDB so that iPreviousBearer has an initial value
+		// when the smsstack is first started.
+		iPreviousBearer = iBearer;
+		SetSmsBearer();
+		}
+	else
+		{
+		LOGSMSPROT2("CSmspSetBearer::Start failed to get SMS bearer, error = %d", err);
+		Complete(err);
+		}
+	} // CSmspSetBearer::Start
+
+
+/**
+ *  Handles a completed request.
+ *  
+ *  Makes a state transition based on the result of the request and current state.
+ *  
+ *  @leave Panic if RunL is called while object is in idle state.
+ */
+void CSmspSetBearer::DoRunL()
+	{
+	LOGSMSPROT3("CSmspSetBearer::DoRunL(): iState=%d iStatus=%d", iState, iStatus.Int());
+
+	switch (iState)
+		{
+		case ESmsSetBearerNotifyOnEvent:
+			{
+			if (iStatus.Int() == KErrNone)
+				{
+				TInt tempBearer;
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+				CMDBSession *dbSession = CMDBSession::NewL(KCDVersion1_2);
+#else
+				CMDBSession *dbSession = CMDBSession::NewL(KCDVersion1_1);
+#endif
+				CleanupStack::PushL(dbSession);
+				CMDBRecordSet<CCDGlobalSettingsRecord> globalSettingsRecord(KCDTIdGlobalSettingsRecord);
+				TRAPD(err, globalSettingsRecord.LoadL(*dbSession));
+				if (err != KErrNone)
+					{
+					LOGSMSPROT2("CSmspSetBearer::DoRunL, could not load global settings, leave error code = %d", err);
+					User::Leave(err);
+					}
+
+				iPreviousBearer = iBearer;
+
+				LOGSMSPROT2("CSmspSetBearer::DoRunL Storing previous bearer setting. Previous bearer now = %d", iBearer);
+
+				tempBearer = ((CCDGlobalSettingsRecord*)globalSettingsRecord.iRecords[0])->iSMSBearer;
+				iBearer = static_cast<RMobileSmsMessaging::TMobileSmsBearer>(tempBearer);
+
+				CleanupStack::PopAndDestroy(dbSession);
+
+				SetSmsBearer();
+				}
+			else
+				{
+				NotifyOnEvent();
+				}
+			}
+			break;
+
+		case ESmsSetBearerStateSettingBearer:
+			{
+			if (iStatus.Int() == KErrNone)
+				{
+				iBearerSet = ETrue;
+				}
+			else
+				{
+				// Set bearer to previous value, if status!=KErrNone
+				// (e.g. KErrNotSupported)
+				// Set global setting to previous value,
+				// then complete.
+				LOGSMSPROT3("CSmspSetBearer::DoRunL TSY failed to set MO SMS bearer. status = %d. Bearer = %d", iStatus.Int(), iBearer);
+
+				iBearer = iPreviousBearer;
+				LOGSMSPROT2("CSmspSetBearer::DoRunL Setting bearer back to previous setting. Bearer = %d", iBearer);
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+				CMDBSession *dbSession = CMDBSession::NewL(KCDVersion1_2);
+#else
+				CMDBSession *dbSession = CMDBSession::NewL(KCDVersion1_1);
+#endif
+				CleanupStack::PushL(dbSession);
+				CMDBRecordSet<CCDGlobalSettingsRecord> globalSettingsRecord(KCDTIdGlobalSettingsRecord);
+				TRAPD(err, globalSettingsRecord.LoadL(*dbSession));
+				if (err != KErrNone)
+					{
+					LOGSMSPROT2("CSmspSetBearer::DoRunL could not load global settings, error = %d", err);
+					User::Leave(err);
+					}
+
+				((CCDGlobalSettingsRecord*)globalSettingsRecord.iRecords[0])->iSMSBearer = iPreviousBearer;
+				TRAP(err, globalSettingsRecord.ModifyL(*dbSession));
+				if (err != KErrNone)
+					{
+					LOGSMSPROT2("CSmspSetBearer::DoRunL could not modify global settings, error = %d", err);
+					User::Leave(err);
+					}
+
+				CleanupStack::PopAndDestroy(dbSession);
+				}
+			}
+			break;
+
+		default:
+			{
+			SmspPanic(KSmspPanicUnexpectedState);
+			}
+			break;
+		}
+
+	//
+	// DoRunL() will now return to CSmsuActiveBase which if the object
+	// is not active, will call Complete().
+	//
+	} // CSmspSetBearer::DoRunL
+
+
+/**
+ *  Handles a request to cancel the state machine.
+ *  Cancels any outstanding request and calls Complete().
+ */
+void CSmspSetBearer::DoCancel()
+	{
+	LOGSMSPROT1("CSmspSetBearer::DoCancel");
+
+	TimedSetActiveCancel();
+
+	// Explicitly set iBearerSet to false to ensure new bearer is set on each execution
+	iBearerSet = EFalse;
+
+	switch (iState)
+		{
+		case ESmsSetBearerStateInit:
+			{
+			// NOP
+			}
+			break;
+			
+		case ESmsSetBearerStateSettingBearer:
+			{
+			iSmsMessaging.CancelAsyncRequest(EMobileSmsMessagingSetMoSmsBearer);
+			}
+			break;
+
+		case ESmsSetBearerNotifyOnEvent:
+			{
+			iProperty.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);
+		}
+	} // CSmspSetBearer::DoCancel
+
+
+/**
+ *  Performs the state transition to CSmspSetBearer::ESmsSetBearerStateQueryingCommDb by
+ *  querying CommDB for the current value.
+ *  
+ *  @param aBearer a reference to the TMobileSmsBearer.
+ */
+void CSmspSetBearer::GetSmsBearerL(RMobileSmsMessaging::TMobileSmsBearer& aBearer)
+	{
+	LOGSMSPROT1("CSmspSetBearer::GetSmsBearerL()");
+	
+#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>* smsBearerField = NULL;
+
+	smsBearerField = new(ELeave) CMDBField<TUint32>(KCDTIdSMSBearer);
+	CleanupStack::PushL(smsBearerField);
+
+	smsBearerField->SetRecordId(1);
+	smsBearerField->LoadL(*sess);
+
+	aBearer = static_cast<RMobileSmsMessaging::TMobileSmsBearer>(static_cast<TUint32>(*smsBearerField));
+	LOGSMSPROT2("CSmspSetBearer::GetSmsBearerL(): aBearer=%d", aBearer);
+
+	CleanupStack::PopAndDestroy(smsBearerField);
+	CleanupStack::PopAndDestroy(sess);
+	} // CSmspSetBearer::GetSmsBearerL
+
+
+/**
+ *  Performs the state transition to CSmspSetBearer::ESmsSetBearerStateSettingBearer
+ *  by trying to set the sms bearer on the phone/TSY.
+ */
+void CSmspSetBearer::SetSmsBearer()
+	{
+	LOGSMSPROT2("CSmspSetBearer::SetSmsBearer, iBearer = %d", iBearer);
+
+	iBearerSet = EFalse;
+	iState = ESmsSetBearerStateSettingBearer;
+
+	iSmsMessaging.SetMoSmsBearer(iStatus, iBearer);
+	TimedSetActive(iSmsSettings.Timeout());
+	} // CSmspSetBearer::SetSmsBearer
+
+
+/**
+ *  Wait for notification from property for when the CommDB global setting SMS_BEARER changes
+ */
+void CSmspSetBearer::NotifyOnEvent()
+	{
+	LOGSMSPROT1("CSmspSetBearer::NotifyOnEvent");
+
+	iState = ESmsSetBearerNotifyOnEvent;
+	CSmspCommDbEvent::NotifyOnEvent();
+	} // CSmspSetBearer::NotifyOnEvent