diff -r 000000000000 -r 3553901f7fa8 smsprotocols/smsstack/smsprot/Src/smspbear.cpp --- /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 +#include +#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 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(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 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* smsBearerField = NULL; + + smsBearerField = new(ELeave) CMDBField(KCDTIdSMSBearer); + CleanupStack::PushL(smsBearerField); + + smsBearerField->SetRecordId(1); + smsBearerField->LoadL(*sess); + + aBearer = static_cast(static_cast(*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