--- a/telephonyutils/telephonywatchers/src/watcherbase.cpp Mon May 03 13:37:20 2010 +0300
+++ b/telephonyutils/telephonywatchers/src/watcherbase.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,594 +1,594 @@
-// Copyright (c) 2000-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:
-//
-
-#include "watcherbase.h"
-#include "watcherlog.h"
-
-// System includes
- #include <commsdattypesv1_1.h>
- #include <commsdat_partner.h>
-
- #include <sacls.h>
-
- using namespace CommsDat;
-
-// User includes
-#include "phoneonoff.h"
-
-// Constants
-const TInt KOneSecond = 1000000;
-
-
-
-//
-// ------> Global exports
-//
-
-
-//
-// ------> CWatcherBase (source)
-//
-
-EXPORT_C CWatcherBase::CWatcherBase(TInt aPriority)
-: CActive(aPriority)
- {
- CActiveScheduler::Add(this);
-
-#ifdef WATCHER_TESTING
- //-- this section of code is used by TE_TelWatchers(Unit) test
- TTime now;
- now.UniversalTime();
- TheSeed = now.Int64();
-
- //-- define properties for test purposes
- LOGCOMMON1("CTelWatcherBase : defining properties for testing");
-
- //-- For debugging purposes only, used by TE_TelWatchers(Unit).
-
- //- this property change (to any value) informs that CTelPhoneWatcher has re-read modem table from commdb in
- //- CTelPhoneWatcher::DoRetrieveTSYNameL().
- RProperty::Define(KUidSystemCategory, KUidTestProp_ModemTableRefreshed.iUid, RProperty::EInt);
-
- //- this property changes in CTelPhoneWatcher::HandleModemChangedL()
- //- when the commsdb modem record has changed
- RProperty::Define(KUidSystemCategory, KUidTestProp_ModemRecordChanged.iUid, RProperty::EInt);
-
- //-- this property is used in CIndicatorWatcher::HandleIndicatorUpdateL()
- //-- to simulate call state change by t_watchers test
- RProperty::Define(KUidSystemCategory, KUidTestProp_CallStateChange.iUid, RProperty::EInt);
-
- //-- this property is used to disable and reset phone watchers
- RProperty::Define(KUidSystemCategory, KUidTestProp_WatchersDisable.iUid, RProperty::EInt);
-#endif
- }
-
-EXPORT_C CWatcherBase::~CWatcherBase()
- {
- Cancel();
- iTimer.Close();
- iPhonePowerProperty.Close();
- }
-
-EXPORT_C void CWatcherBase::ConstructL()
- {
- LOGCOMMON1("WatcherBase : Creating timer");
- User::LeaveIfError(iTimer.CreateLocal());
-
- User::LeaveIfError(iPhonePowerProperty.Attach(KUidSystemCategory, KUidPhonePwr.iUid));
-
- // This starts the whole ball rolling
- RequestNextState();
- }
-
-//
-//
-//
-
-EXPORT_C void CWatcherBase::SuspendFor(TInt aTimeInSeconds)
- {
- LOGCOMMON1("WatcherBase : Pausing after error");
- TTimeIntervalMicroSeconds32 timeToSuspendFor = aTimeInSeconds * KOneSecond;
- iTimer.After(iStatus, timeToSuspendFor);
- State() = EBaseStateSuspending;
- SetActive();
- }
-
-EXPORT_C void CWatcherBase::SetDisabled(const TDesC& aLogEntry, TInt aError)
- {
-#ifdef _WATCHER_LOGGING_ENABLED
- TBuf8<256> tmpBuf;
- tmpBuf.Copy(aLogEntry);
- LOGCOMMON3("Log Entry \"%S\" error %d", &tmpBuf, aError);
-#else
- (void) aLogEntry;
- (void) aError;
-#endif
- LOGCOMMON1("WatcherBase : Watcher is now disabled");
- State() = EBaseStateDisabled;
- }
-
-EXPORT_C void CWatcherBase::RequestNextState()
- {
- LOGCOMMON1("WatcherBase : Requesting State Change");
-
- if (State() != EBaseStateDisabled)
- {
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
- SetActive();
- }
- }
-
-EXPORT_C void CWatcherBase::WaitForPhoneToPowerUpL()
-//
-// The phone is currently turned off. We must wait for it to be turned back on
-// again before the watchers can continue.
-//
- {
- TInt val;
-
- LOGCOMMON1("WatcherBase : Waiting for phone to be turned on");
- __ASSERT_DEBUG(!IsActive(), WatcherBasePanic(EUnexpectedActiveState));
- Cancel();
-
- //-- Subscribe to phone power state change property and wait until it changes
- iPhonePowerProperty.Subscribe(iStatus);
-
- // Update our state
- State() = EBaseStateWaitingForPhoneToPowerUp;
-
- // Set us ready to go again
- SetActive();
-
- User::LeaveIfError(iPhonePowerProperty.Get(val));
-
- if (val != ESAPhoneOff)
- {//-- phone is already ON, complete request so that we go to RunL without waiting
- iPhonePowerProperty.Cancel();
- LOGCOMMON1("CTelWatcherBase::WaitForPhoneToPowerUpL ??? phone is already turned ON");
- }
- }
-
-//
-//
-//
-
-EXPORT_C void CWatcherBase::RunL()
- {
- LOGCOMMON2("WatcherBase : RunL(%d)", iStatus.Int());
-
- switch(State())
- {
- case EBaseStateConnectingToPropertyNotifier:
- LOGCOMMON1("WatcherBase : Attaching to Property");
-
- // Virtual function call back, for any subclasses that need to implement
- // any special stuff.
- HandleConnectionToChangeNotifierEstablishedL();
-
- // Move to next state
- State() = EBaseStatePassive;
- RequestNextState();
- break;
-
- case EBaseStateWaitingForPhoneToPowerUp:
- // We were waiting for the phone to become available again. We now must restart
- // this watcher from scratch.
- LOGCOMMON1("WatcherBase : Phone available again. Restarting watcher framework");
-
- //-- phone power state has changed (it must be turned ON)
- //-- retrieve its state and check.
- TInt val;
-
- User::LeaveIfError(iPhonePowerProperty.Get(val));
-
- if (val == ESAPhoneOn)
- { //-- everything OK, the phone has been turned ON, restart this watcher from scratch.
- LOGCOMMON1("CTelWatcherBase : Phone has been turned ON. Restarting watcher framework");
- State() = EBaseStateConnectingToPropertyNotifier;
- RequestNextState();
- }
- else
- { //-- strange situation, we were waiting for phone On and it now Off, try to wait again
- LOGCOMMON1("CTelWatcherBase : ??? Phone has been turned OFF. Continue waiting...");
- WaitForPhoneToPowerUpL();
- }
- break;
-
- case EBaseStateSuspending:
- LOGCOMMON1("WatcherBase : Completed suspension. Resuming passive state");
-
- State() = EBaseStatePassive; // Fall through
-
- case EBaseStatePassive: // In passive mode, so just call framework function
- HandleStateEventL(iStatus.Int());
- break;
-
- default:
- case EBaseStateDisabled:
- LOGCOMMON1("WatcherBase : RunL called in Disabled state. Ooops");
- __ASSERT_DEBUG(0, WatcherBasePanic(EUnexpectedState));
- }
- }
-
-EXPORT_C void CWatcherBase::DoCancel()
- {
- switch(State())
- {
- case EBaseStateSuspending:
- // Cancel outstanding timer
- iTimer.Cancel();
- break;
-
- case EBaseStateWaitingForPhoneToPowerUp:
- // Cancel outstanding asynchronous request
- iPhonePowerProperty.Cancel();
- break;
-
- default:
- case EBaseStatePassive:
- case EBaseStateConnectingToPropertyNotifier:
- case EBaseStateDisabled:
- break;
- }
-
- // Let other sub classes cancel their requests
- HandleCancel();
- }
-
-EXPORT_C TInt CWatcherBase::RunError(TInt aError)
-//
-// Called when RunL (or a sub-function there-of) leaves.
-//
- {
-#ifdef _WATCHER_LOGGING_ENABLED
- LOGCOMMON2("WatcherBase : RunError called with error of %d", aError);
-#else
- (void) aError;
-#endif
-
- // Should never be called from outside the framework
- __ASSERT_DEBUG(!IsActive(), WatcherBasePanic(EUnexpectedActiveState));
- Cancel();
-
- // Reset all resources in this, and the derrived class so that
- // we can start up again (from scratch) (virtual function).
- if (State() == EBaseStatePassive)
- Reset();
-
- // Close our resources
- iPhonePowerProperty.Close();
-
- // NOTE: we don't close the timer. This was opened in ConstructL so
- // we can't close that here.
-
- // Have we already tried this too many times?
- if (ErrorCountIncrement() >= KErrorRetryCount)
- {
- // We've tried to resume 3 times already and we've still not managed. Give up
- // now until a reboot.
- SetDisabled(_L("WatcherBase : RunError called too many times in succession"), KErrNone);
- }
- else
- {
- // Put us in the start up state again
- LOGCOMMON1("WatcherBase : Phone available again. Restarting watcher framework");
- State() = EBaseStateConnectingToPropertyNotifier;
- RequestNextState();
- }
-
- return KErrNone;
- }
-
-//
-// Panic Function
-//
-void CWatcherBase::WatcherBasePanic(TWatcherPanic aPanicNumber)
- {
- _LIT(panicText,"Watcher Base");
- User::Panic(panicText,aPanicNumber);
- }
-
-
-
-//
-// ------> CPhoneWatcher (source)
-//
-
-
-EXPORT_C CPhoneWatcher::CPhoneWatcher(TInt aPriority)
-: CWatcherBase(aPriority)
- {
- }
-
-EXPORT_C CPhoneWatcher::~CPhoneWatcher()
- {
- delete iModemChangeObserver;
- delete iPhoneWait;
- Phone().Close();
- ETel().Close();
- }
-
-EXPORT_C void CPhoneWatcher::ConstructL()
- {
- CWatcherBase::ConstructL();
- }
-
-//
-//
-//
-
-EXPORT_C void CPhoneWatcher::HandleStateEventL(TInt aCompletionCode)
- {
- switch(PhoneState())
- {
- case EPhoneStateRetrievingTsyName:
- // Cconstruct observers
- if (!iPhoneWait)
- {
- iPhoneWait = new(ELeave) CPhoneOnOff(*this);
- iPhoneWait->ConstructL();
- }
- if (!iModemChangeObserver)
- {
- iModemChangeObserver = new(ELeave) CModemChangeObserver(*this);
- iModemChangeObserver->ConstructL();
- }
-
- User::LeaveIfError(RetrieveTSYName());
- PhoneState() = EPhoneStateConnectingToETel;
- RequestNextState();
- break;
-
- case EPhoneStateConnectingToETel:
- User::LeaveIfError(ConnectToETelServer());
- PhoneState() = EPhoneStateLoadingPhoneModule;
- RequestNextState();
- break;
-
- case EPhoneStateLoadingPhoneModule:
- User::LeaveIfError(LoadPhoneModule());
- PhoneState() = EPhoneStateConnectingToPhone;
- RequestNextState();
- break;
-
- case EPhoneStateConnectingToPhone:
- User::LeaveIfError(ConnectToPhone());
- PhoneState() = EPhoneStatePassive;
- RequestNextState();
- break;
-
- case EPhoneStatePassive:
- HandlePhoneStateEventL(aCompletionCode);
- break;
-
- default:
- __ASSERT_DEBUG(0, WatcherBasePanic(EUnexpectedState));
- }
- }
-
-EXPORT_C void CPhoneWatcher::Reset()
- {
- // Ensures CModemChangeObserver object stops running
- if (iModemChangeObserver)
- {
- iModemChangeObserver->Cancel();
- }
-
- if (PhoneState() == EPhoneStatePassive)
- {
- // Get children to release any resources they have
- ReleasePhoneResources();
- }
-
- // Close our connections to the phone & ETel
- Phone().Close();
- ETel().Close();
-
- // Reset state
- PhoneState() = EPhoneStateRetrievingTsyName;
- }
-
-//
-//
-//
-
-TInt CPhoneWatcher::RetrieveTSYName()
- {
- LOGCOMMON1("PhoneWatcher : RetrieveTSYName()");
- TRAPD(error, DoRetrieveTSYNameL());
- return error;
- }
-
-TInt CPhoneWatcher::ConnectToETelServer()
- {
- LOGCOMMON1("PhoneWatcher : ConnectToETelServer()");
- return ETel().Connect();
- }
-
-TInt CPhoneWatcher::LoadPhoneModule()
- {
-#ifdef _WATCHER_LOGGING_ENABLED
- TBuf8<256> tmpBuf;
- tmpBuf.Copy(iTSYName);
- LOGCOMMON1("PhoneWatcher : LoadPhoneModule()");
- LOGCOMMON2("TSY Name to load is %S",&tmpBuf);
-#endif
-
- return ETel().LoadPhoneModule(iTSYName);
- }
-
-TInt CPhoneWatcher::ConnectToPhone()
- {
- LOGCOMMON1("PhoneWatcher : ConnectToPhone()");
- TInt error;
-
- RTelServer::TPhoneInfo phoneInfo;
-
- // Get the number of phones
- TInt phoneCount = 0;
- error = ETel().EnumeratePhones(phoneCount);
- if (error < KErrNone)
- {
- LOGCOMMON2("PhoneWatcher : Failed to enumerate phones (%d)", error);
- return error;
- }
-
- LOGCOMMON2("PhoneWatcher : Counted %d 'phones'", phoneCount);
-
- // Iterate through all the phones
- for(TInt i=0; i<phoneCount; i++)
- {
- // Get the TSY name for the phone
- TName matchTsyName;
-
- error = ETel().GetTsyName(i, matchTsyName);
- if (error < KErrNone)
- {
- LOGCOMMON2("PhoneWatcher : Getting TSY name failed (%d)", error);
- return error;
- }
-
-#ifdef _WATCHER_LOGGING_ENABLED
- TBuf8<256> tmpMatchTsyName;
- tmpMatchTsyName.Copy(matchTsyName);
- LOGCOMMON3("PhoneWatcher : TSY for phone %d is '%S'", i, &tmpMatchTsyName);
-#endif
-
- // See if the phone belongs to the TSY
- if (matchTsyName.CompareF(iTSYName) == 0)
- {
-#ifdef _WATCHER_LOGGING_ENABLED
- TBuf8<256> tsyNameBuf;
- tsyNameBuf.Copy(iTSYName);
- LOGCOMMON3("PhoneWatcher : %S is a match for CommDb TSY: %S", &tmpMatchTsyName, &tsyNameBuf);
-#endif
-
- error = ETel().GetPhoneInfo(i, phoneInfo);
- if (error < KErrNone)
- {
- LOGCOMMON2("PhoneWatcher : Getting phone info failed (%d)", error);
- return error;
- }
- break;
- }
- }
-
- // Connect to the specified phone
- error = Phone().Open(ETel(), phoneInfo.iName);
- if (error < KErrNone)
- {
-#ifdef _WATCHER_LOGGING_ENABLED
- TBuf8<256> tmpBuf;
- tmpBuf.Copy(phoneInfo.iName);
- LOGCOMMON3("PhoneWatcher : Open phone %S failed (%d)", &tmpBuf, error);
-#endif
- return error;
- }
-
-#ifdef _WATCHER_LOGGING_ENABLED
- TBuf8<256> tmpBuf;
- tmpBuf.Copy(phoneInfo.iName);
- LOGCOMMON2("PhoneWatcher : Opened 'phone' %S", &tmpBuf);
-#endif
-
- // Indicate we're connected and to move to next state.
- return error;
- }
-
-//
-//
-//
-
-void CPhoneWatcher::DoRetrieveTSYNameL()
- {
-#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
- CMDBSession* db = CMDBSession::NewL(KCDVersion1_2);
-#else
- CMDBSession* db = CMDBSession::NewL(KCDVersion1_1);
-#endif
- CleanupStack::PushL(db);
-
- CMDBField<TUint32>* globalSettingsField = new(ELeave) CMDBField<TUint32>(KCDTIdModemPhoneServicesSMS);
- CleanupStack::PushL(globalSettingsField);
- globalSettingsField->SetRecordId(1);
- globalSettingsField->LoadL(*db);
- TUint32 modemId = *globalSettingsField;
- CleanupStack::PopAndDestroy(globalSettingsField);
-
- CMDBField<TDesC>* tsyField = new(ELeave) CMDBField<TDesC>(KCDTIdTsyName);
- CleanupStack::PushL(tsyField);
- tsyField->SetRecordId(modemId);
- tsyField->SetMaxLengthL(KMaxTextLength);
- tsyField->LoadL(*db);
- iTSYName = *tsyField;
- CleanupStack::PopAndDestroy(tsyField);
-
-
- // Strip any file extension
- TInt pos = iTSYName.LocateReverse('.');
- if (pos >= 0)
- iTSYName = iTSYName.Left(pos);
-
-#ifdef WATCHER_TESTING
- {
- TTime now;
- now.UniversalTime();
- User::LeaveIfError(RProperty::Set(KUidSystemCategory, KUidTestProp_ModemTableRefreshed.iUid, I64LOW(now.Int64())));
- }
-#endif
-
- CleanupStack::PopAndDestroy(); // db or commsDatabase
- }
-
-EXPORT_C void CPhoneWatcher::PhoneIsOff()
- {
- Cancel();
- Reset(); // Kill phone resources
-#ifdef _DEBUG
- TRAPD(err, WaitForPhoneToPowerUpL());
- __ASSERT_DEBUG(err == KErrNone, WatcherBasePanic(EGeneral));
-#else
- TRAP_IGNORE(WaitForPhoneToPowerUpL());
-#endif
- }
-
-EXPORT_C void CPhoneWatcher::HandleModemChangedL()
-//
-// Called when the commsdb modem record has changed. Must
-// re-read the current modem and attempt to reinitialise the watcher
-// using this new modem.
-//
- {
-#ifdef WATCHER_TESTING
- {
- TTime now;
- now.UniversalTime();
- // State set to ETrue/EFalse
- User::LeaveIfError(RProperty::Set(KUidSystemCategory, KUidTestProp_ModemRecordChanged.iUid, I64LOW(now.Int64())));
- }
-#endif
-
- Cancel();
-
- // Kill phone resources
- Reset();
-
- // Start us going again. This will (in turn)
- // re-read the comms database. NOTE: Our state has been set to
- // 'EPhoneStateRetrievingTsyName' by Reset()
- RequestNextState();
- }
-
+// Copyright (c) 2000-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:
+//
+
+#include "watcherbase.h"
+#include "watcherlog.h"
+
+// System includes
+ #include <commsdattypesv1_1.h>
+ #include <commsdat_partner.h>
+
+ #include <sacls.h>
+
+ using namespace CommsDat;
+
+// User includes
+#include "phoneonoff.h"
+
+// Constants
+const TInt KOneSecond = 1000000;
+
+
+
+//
+// ------> Global exports
+//
+
+
+//
+// ------> CWatcherBase (source)
+//
+
+EXPORT_C CWatcherBase::CWatcherBase(TInt aPriority)
+: CActive(aPriority)
+ {
+ CActiveScheduler::Add(this);
+
+#ifdef WATCHER_TESTING
+ //-- this section of code is used by TE_TelWatchers(Unit) test
+ TTime now;
+ now.UniversalTime();
+ TheSeed = now.Int64();
+
+ //-- define properties for test purposes
+ LOGCOMMON1("CTelWatcherBase : defining properties for testing");
+
+ //-- For debugging purposes only, used by TE_TelWatchers(Unit).
+
+ //- this property change (to any value) informs that CTelPhoneWatcher has re-read modem table from commdb in
+ //- CTelPhoneWatcher::DoRetrieveTSYNameL().
+ RProperty::Define(KUidSystemCategory, KUidTestProp_ModemTableRefreshed.iUid, RProperty::EInt);
+
+ //- this property changes in CTelPhoneWatcher::HandleModemChangedL()
+ //- when the commsdb modem record has changed
+ RProperty::Define(KUidSystemCategory, KUidTestProp_ModemRecordChanged.iUid, RProperty::EInt);
+
+ //-- this property is used in CIndicatorWatcher::HandleIndicatorUpdateL()
+ //-- to simulate call state change by t_watchers test
+ RProperty::Define(KUidSystemCategory, KUidTestProp_CallStateChange.iUid, RProperty::EInt);
+
+ //-- this property is used to disable and reset phone watchers
+ RProperty::Define(KUidSystemCategory, KUidTestProp_WatchersDisable.iUid, RProperty::EInt);
+#endif
+ }
+
+EXPORT_C CWatcherBase::~CWatcherBase()
+ {
+ Cancel();
+ iTimer.Close();
+ iPhonePowerProperty.Close();
+ }
+
+EXPORT_C void CWatcherBase::ConstructL()
+ {
+ LOGCOMMON1("WatcherBase : Creating timer");
+ User::LeaveIfError(iTimer.CreateLocal());
+
+ User::LeaveIfError(iPhonePowerProperty.Attach(KUidSystemCategory, KUidPhonePwr.iUid));
+
+ // This starts the whole ball rolling
+ RequestNextState();
+ }
+
+//
+//
+//
+
+EXPORT_C void CWatcherBase::SuspendFor(TInt aTimeInSeconds)
+ {
+ LOGCOMMON1("WatcherBase : Pausing after error");
+ TTimeIntervalMicroSeconds32 timeToSuspendFor = aTimeInSeconds * KOneSecond;
+ iTimer.After(iStatus, timeToSuspendFor);
+ State() = EBaseStateSuspending;
+ SetActive();
+ }
+
+EXPORT_C void CWatcherBase::SetDisabled(const TDesC& aLogEntry, TInt aError)
+ {
+#ifdef _WATCHER_LOGGING_ENABLED
+ TBuf8<256> tmpBuf;
+ tmpBuf.Copy(aLogEntry);
+ LOGCOMMON3("Log Entry \"%S\" error %d", &tmpBuf, aError);
+#else
+ (void) aLogEntry;
+ (void) aError;
+#endif
+ LOGCOMMON1("WatcherBase : Watcher is now disabled");
+ State() = EBaseStateDisabled;
+ }
+
+EXPORT_C void CWatcherBase::RequestNextState()
+ {
+ LOGCOMMON1("WatcherBase : Requesting State Change");
+
+ if (State() != EBaseStateDisabled)
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ SetActive();
+ }
+ }
+
+EXPORT_C void CWatcherBase::WaitForPhoneToPowerUpL()
+//
+// The phone is currently turned off. We must wait for it to be turned back on
+// again before the watchers can continue.
+//
+ {
+ TInt val;
+
+ LOGCOMMON1("WatcherBase : Waiting for phone to be turned on");
+ __ASSERT_DEBUG(!IsActive(), WatcherBasePanic(EUnexpectedActiveState));
+ Cancel();
+
+ //-- Subscribe to phone power state change property and wait until it changes
+ iPhonePowerProperty.Subscribe(iStatus);
+
+ // Update our state
+ State() = EBaseStateWaitingForPhoneToPowerUp;
+
+ // Set us ready to go again
+ SetActive();
+
+ User::LeaveIfError(iPhonePowerProperty.Get(val));
+
+ if (val != ESAPhoneOff)
+ {//-- phone is already ON, complete request so that we go to RunL without waiting
+ iPhonePowerProperty.Cancel();
+ LOGCOMMON1("CTelWatcherBase::WaitForPhoneToPowerUpL ??? phone is already turned ON");
+ }
+ }
+
+//
+//
+//
+
+EXPORT_C void CWatcherBase::RunL()
+ {
+ LOGCOMMON2("WatcherBase : RunL(%d)", iStatus.Int());
+
+ switch(State())
+ {
+ case EBaseStateConnectingToPropertyNotifier:
+ LOGCOMMON1("WatcherBase : Attaching to Property");
+
+ // Virtual function call back, for any subclasses that need to implement
+ // any special stuff.
+ HandleConnectionToChangeNotifierEstablishedL();
+
+ // Move to next state
+ State() = EBaseStatePassive;
+ RequestNextState();
+ break;
+
+ case EBaseStateWaitingForPhoneToPowerUp:
+ // We were waiting for the phone to become available again. We now must restart
+ // this watcher from scratch.
+ LOGCOMMON1("WatcherBase : Phone available again. Restarting watcher framework");
+
+ //-- phone power state has changed (it must be turned ON)
+ //-- retrieve its state and check.
+ TInt val;
+
+ User::LeaveIfError(iPhonePowerProperty.Get(val));
+
+ if (val == ESAPhoneOn)
+ { //-- everything OK, the phone has been turned ON, restart this watcher from scratch.
+ LOGCOMMON1("CTelWatcherBase : Phone has been turned ON. Restarting watcher framework");
+ State() = EBaseStateConnectingToPropertyNotifier;
+ RequestNextState();
+ }
+ else
+ { //-- strange situation, we were waiting for phone On and it now Off, try to wait again
+ LOGCOMMON1("CTelWatcherBase : ??? Phone has been turned OFF. Continue waiting...");
+ WaitForPhoneToPowerUpL();
+ }
+ break;
+
+ case EBaseStateSuspending:
+ LOGCOMMON1("WatcherBase : Completed suspension. Resuming passive state");
+
+ State() = EBaseStatePassive; // Fall through
+
+ case EBaseStatePassive: // In passive mode, so just call framework function
+ HandleStateEventL(iStatus.Int());
+ break;
+
+ default:
+ case EBaseStateDisabled:
+ LOGCOMMON1("WatcherBase : RunL called in Disabled state. Ooops");
+ __ASSERT_DEBUG(0, WatcherBasePanic(EUnexpectedState));
+ }
+ }
+
+EXPORT_C void CWatcherBase::DoCancel()
+ {
+ switch(State())
+ {
+ case EBaseStateSuspending:
+ // Cancel outstanding timer
+ iTimer.Cancel();
+ break;
+
+ case EBaseStateWaitingForPhoneToPowerUp:
+ // Cancel outstanding asynchronous request
+ iPhonePowerProperty.Cancel();
+ break;
+
+ default:
+ case EBaseStatePassive:
+ case EBaseStateConnectingToPropertyNotifier:
+ case EBaseStateDisabled:
+ break;
+ }
+
+ // Let other sub classes cancel their requests
+ HandleCancel();
+ }
+
+EXPORT_C TInt CWatcherBase::RunError(TInt aError)
+//
+// Called when RunL (or a sub-function there-of) leaves.
+//
+ {
+#ifdef _WATCHER_LOGGING_ENABLED
+ LOGCOMMON2("WatcherBase : RunError called with error of %d", aError);
+#else
+ (void) aError;
+#endif
+
+ // Should never be called from outside the framework
+ __ASSERT_DEBUG(!IsActive(), WatcherBasePanic(EUnexpectedActiveState));
+ Cancel();
+
+ // Reset all resources in this, and the derrived class so that
+ // we can start up again (from scratch) (virtual function).
+ if (State() == EBaseStatePassive)
+ Reset();
+
+ // Close our resources
+ iPhonePowerProperty.Close();
+
+ // NOTE: we don't close the timer. This was opened in ConstructL so
+ // we can't close that here.
+
+ // Have we already tried this too many times?
+ if (ErrorCountIncrement() >= KErrorRetryCount)
+ {
+ // We've tried to resume 3 times already and we've still not managed. Give up
+ // now until a reboot.
+ SetDisabled(_L("WatcherBase : RunError called too many times in succession"), KErrNone);
+ }
+ else
+ {
+ // Put us in the start up state again
+ LOGCOMMON1("WatcherBase : Phone available again. Restarting watcher framework");
+ State() = EBaseStateConnectingToPropertyNotifier;
+ RequestNextState();
+ }
+
+ return KErrNone;
+ }
+
+//
+// Panic Function
+//
+void CWatcherBase::WatcherBasePanic(TWatcherPanic aPanicNumber)
+ {
+ _LIT(panicText,"Watcher Base");
+ User::Panic(panicText,aPanicNumber);
+ }
+
+
+
+//
+// ------> CPhoneWatcher (source)
+//
+
+
+EXPORT_C CPhoneWatcher::CPhoneWatcher(TInt aPriority)
+: CWatcherBase(aPriority)
+ {
+ }
+
+EXPORT_C CPhoneWatcher::~CPhoneWatcher()
+ {
+ delete iModemChangeObserver;
+ delete iPhoneWait;
+ Phone().Close();
+ ETel().Close();
+ }
+
+EXPORT_C void CPhoneWatcher::ConstructL()
+ {
+ CWatcherBase::ConstructL();
+ }
+
+//
+//
+//
+
+EXPORT_C void CPhoneWatcher::HandleStateEventL(TInt aCompletionCode)
+ {
+ switch(PhoneState())
+ {
+ case EPhoneStateRetrievingTsyName:
+ // Cconstruct observers
+ if (!iPhoneWait)
+ {
+ iPhoneWait = new(ELeave) CPhoneOnOff(*this);
+ iPhoneWait->ConstructL();
+ }
+ if (!iModemChangeObserver)
+ {
+ iModemChangeObserver = new(ELeave) CModemChangeObserver(*this);
+ iModemChangeObserver->ConstructL();
+ }
+
+ User::LeaveIfError(RetrieveTSYName());
+ PhoneState() = EPhoneStateConnectingToETel;
+ RequestNextState();
+ break;
+
+ case EPhoneStateConnectingToETel:
+ User::LeaveIfError(ConnectToETelServer());
+ PhoneState() = EPhoneStateLoadingPhoneModule;
+ RequestNextState();
+ break;
+
+ case EPhoneStateLoadingPhoneModule:
+ User::LeaveIfError(LoadPhoneModule());
+ PhoneState() = EPhoneStateConnectingToPhone;
+ RequestNextState();
+ break;
+
+ case EPhoneStateConnectingToPhone:
+ User::LeaveIfError(ConnectToPhone());
+ PhoneState() = EPhoneStatePassive;
+ RequestNextState();
+ break;
+
+ case EPhoneStatePassive:
+ HandlePhoneStateEventL(aCompletionCode);
+ break;
+
+ default:
+ __ASSERT_DEBUG(0, WatcherBasePanic(EUnexpectedState));
+ }
+ }
+
+EXPORT_C void CPhoneWatcher::Reset()
+ {
+ // Ensures CModemChangeObserver object stops running
+ if (iModemChangeObserver)
+ {
+ iModemChangeObserver->Cancel();
+ }
+
+ if (PhoneState() == EPhoneStatePassive)
+ {
+ // Get children to release any resources they have
+ ReleasePhoneResources();
+ }
+
+ // Close our connections to the phone & ETel
+ Phone().Close();
+ ETel().Close();
+
+ // Reset state
+ PhoneState() = EPhoneStateRetrievingTsyName;
+ }
+
+//
+//
+//
+
+TInt CPhoneWatcher::RetrieveTSYName()
+ {
+ LOGCOMMON1("PhoneWatcher : RetrieveTSYName()");
+ TRAPD(error, DoRetrieveTSYNameL());
+ return error;
+ }
+
+TInt CPhoneWatcher::ConnectToETelServer()
+ {
+ LOGCOMMON1("PhoneWatcher : ConnectToETelServer()");
+ return ETel().Connect();
+ }
+
+TInt CPhoneWatcher::LoadPhoneModule()
+ {
+#ifdef _WATCHER_LOGGING_ENABLED
+ TBuf8<256> tmpBuf;
+ tmpBuf.Copy(iTSYName);
+ LOGCOMMON1("PhoneWatcher : LoadPhoneModule()");
+ LOGCOMMON2("TSY Name to load is %S",&tmpBuf);
+#endif
+
+ return ETel().LoadPhoneModule(iTSYName);
+ }
+
+TInt CPhoneWatcher::ConnectToPhone()
+ {
+ LOGCOMMON1("PhoneWatcher : ConnectToPhone()");
+ TInt error;
+
+ RTelServer::TPhoneInfo phoneInfo;
+
+ // Get the number of phones
+ TInt phoneCount = 0;
+ error = ETel().EnumeratePhones(phoneCount);
+ if (error < KErrNone)
+ {
+ LOGCOMMON2("PhoneWatcher : Failed to enumerate phones (%d)", error);
+ return error;
+ }
+
+ LOGCOMMON2("PhoneWatcher : Counted %d 'phones'", phoneCount);
+
+ // Iterate through all the phones
+ for(TInt i=0; i<phoneCount; i++)
+ {
+ // Get the TSY name for the phone
+ TName matchTsyName;
+
+ error = ETel().GetTsyName(i, matchTsyName);
+ if (error < KErrNone)
+ {
+ LOGCOMMON2("PhoneWatcher : Getting TSY name failed (%d)", error);
+ return error;
+ }
+
+#ifdef _WATCHER_LOGGING_ENABLED
+ TBuf8<256> tmpMatchTsyName;
+ tmpMatchTsyName.Copy(matchTsyName);
+ LOGCOMMON3("PhoneWatcher : TSY for phone %d is '%S'", i, &tmpMatchTsyName);
+#endif
+
+ // See if the phone belongs to the TSY
+ if (matchTsyName.CompareF(iTSYName) == 0)
+ {
+#ifdef _WATCHER_LOGGING_ENABLED
+ TBuf8<256> tsyNameBuf;
+ tsyNameBuf.Copy(iTSYName);
+ LOGCOMMON3("PhoneWatcher : %S is a match for CommDb TSY: %S", &tmpMatchTsyName, &tsyNameBuf);
+#endif
+
+ error = ETel().GetPhoneInfo(i, phoneInfo);
+ if (error < KErrNone)
+ {
+ LOGCOMMON2("PhoneWatcher : Getting phone info failed (%d)", error);
+ return error;
+ }
+ break;
+ }
+ }
+
+ // Connect to the specified phone
+ error = Phone().Open(ETel(), phoneInfo.iName);
+ if (error < KErrNone)
+ {
+#ifdef _WATCHER_LOGGING_ENABLED
+ TBuf8<256> tmpBuf;
+ tmpBuf.Copy(phoneInfo.iName);
+ LOGCOMMON3("PhoneWatcher : Open phone %S failed (%d)", &tmpBuf, error);
+#endif
+ return error;
+ }
+
+#ifdef _WATCHER_LOGGING_ENABLED
+ TBuf8<256> tmpBuf;
+ tmpBuf.Copy(phoneInfo.iName);
+ LOGCOMMON2("PhoneWatcher : Opened 'phone' %S", &tmpBuf);
+#endif
+
+ // Indicate we're connected and to move to next state.
+ return error;
+ }
+
+//
+//
+//
+
+void CPhoneWatcher::DoRetrieveTSYNameL()
+ {
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ CMDBSession* db = CMDBSession::NewL(KCDVersion1_2);
+#else
+ CMDBSession* db = CMDBSession::NewL(KCDVersion1_1);
+#endif
+ CleanupStack::PushL(db);
+
+ CMDBField<TUint32>* globalSettingsField = new(ELeave) CMDBField<TUint32>(KCDTIdModemPhoneServicesSMS);
+ CleanupStack::PushL(globalSettingsField);
+ globalSettingsField->SetRecordId(1);
+ globalSettingsField->LoadL(*db);
+ TUint32 modemId = *globalSettingsField;
+ CleanupStack::PopAndDestroy(globalSettingsField);
+
+ CMDBField<TDesC>* tsyField = new(ELeave) CMDBField<TDesC>(KCDTIdTsyName);
+ CleanupStack::PushL(tsyField);
+ tsyField->SetRecordId(modemId);
+ tsyField->SetMaxLengthL(KMaxTextLength);
+ tsyField->LoadL(*db);
+ iTSYName = *tsyField;
+ CleanupStack::PopAndDestroy(tsyField);
+
+
+ // Strip any file extension
+ TInt pos = iTSYName.LocateReverse('.');
+ if (pos >= 0)
+ iTSYName = iTSYName.Left(pos);
+
+#ifdef WATCHER_TESTING
+ {
+ TTime now;
+ now.UniversalTime();
+ User::LeaveIfError(RProperty::Set(KUidSystemCategory, KUidTestProp_ModemTableRefreshed.iUid, I64LOW(now.Int64())));
+ }
+#endif
+
+ CleanupStack::PopAndDestroy(); // db or commsDatabase
+ }
+
+EXPORT_C void CPhoneWatcher::PhoneIsOff()
+ {
+ Cancel();
+ Reset(); // Kill phone resources
+#ifdef _DEBUG
+ TRAPD(err, WaitForPhoneToPowerUpL());
+ __ASSERT_DEBUG(err == KErrNone, WatcherBasePanic(EGeneral));
+#else
+ TRAP_IGNORE(WaitForPhoneToPowerUpL());
+#endif
+ }
+
+EXPORT_C void CPhoneWatcher::HandleModemChangedL()
+//
+// Called when the commsdb modem record has changed. Must
+// re-read the current modem and attempt to reinitialise the watcher
+// using this new modem.
+//
+ {
+#ifdef WATCHER_TESTING
+ {
+ TTime now;
+ now.UniversalTime();
+ // State set to ETrue/EFalse
+ User::LeaveIfError(RProperty::Set(KUidSystemCategory, KUidTestProp_ModemRecordChanged.iUid, I64LOW(now.Int64())));
+ }
+#endif
+
+ Cancel();
+
+ // Kill phone resources
+ Reset();
+
+ // Start us going again. This will (in turn)
+ // re-read the comms database. NOTE: Our state has been set to
+ // 'EPhoneStateRetrievingTsyName' by Reset()
+ RequestNextState();
+ }
+