telephonyutils/telephonywatchers/src/watcherbase.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "watcherbase.h"
       
    17 #include "watcherlog.h"
       
    18 
       
    19 // System includes
       
    20  #include <commsdattypesv1_1.h>
       
    21  #include <commsdat_partner.h>
       
    22 
       
    23  #include <sacls.h>
       
    24 
       
    25  using namespace CommsDat;
       
    26 
       
    27 // User includes
       
    28 #include "phoneonoff.h"
       
    29 
       
    30 // Constants
       
    31 const TInt KOneSecond = 1000000;
       
    32 
       
    33 
       
    34 
       
    35 //
       
    36 // ------> Global exports
       
    37 //
       
    38 
       
    39 
       
    40 //
       
    41 // ------> CWatcherBase (source)
       
    42 //
       
    43 
       
    44 EXPORT_C CWatcherBase::CWatcherBase(TInt aPriority)
       
    45 :	CActive(aPriority)
       
    46 	{
       
    47 	CActiveScheduler::Add(this);
       
    48 
       
    49 #ifdef WATCHER_TESTING    
       
    50     //-- this section of code is used by TE_TelWatchers(Unit) test 
       
    51 	TTime now;
       
    52 	now.UniversalTime();
       
    53 	TheSeed = now.Int64();
       
    54 
       
    55     //-- define properties for test purposes
       
    56     LOGCOMMON1("CTelWatcherBase : defining properties for testing");
       
    57    
       
    58     //-- For debugging purposes only, used by TE_TelWatchers(Unit).
       
    59 
       
    60     //- this property change (to any value) informs that CTelPhoneWatcher has re-read modem table from commdb in
       
    61     //- CTelPhoneWatcher::DoRetrieveTSYNameL(). 
       
    62     RProperty::Define(KUidSystemCategory, KUidTestProp_ModemTableRefreshed.iUid, RProperty::EInt);  
       
    63   
       
    64     //- this property changes in CTelPhoneWatcher::HandleModemChangedL()
       
    65     //- when the commsdb modem record has changed
       
    66     RProperty::Define(KUidSystemCategory, KUidTestProp_ModemRecordChanged.iUid, RProperty::EInt);
       
    67     
       
    68     //-- this property is used in CIndicatorWatcher::HandleIndicatorUpdateL()
       
    69     //-- to simulate call state change by t_watchers test
       
    70     RProperty::Define(KUidSystemCategory, KUidTestProp_CallStateChange.iUid, RProperty::EInt);
       
    71 
       
    72     //-- this property is used to disable and reset phone watchers
       
    73     RProperty::Define(KUidSystemCategory, KUidTestProp_WatchersDisable.iUid, RProperty::EInt);    
       
    74 #endif
       
    75 	}
       
    76 
       
    77 EXPORT_C CWatcherBase::~CWatcherBase()
       
    78 	{
       
    79 	Cancel();
       
    80 	iTimer.Close();
       
    81 	iPhonePowerProperty.Close();
       
    82 	}
       
    83 
       
    84 EXPORT_C void CWatcherBase::ConstructL()
       
    85 	{
       
    86 	LOGCOMMON1("WatcherBase : Creating timer");
       
    87 	User::LeaveIfError(iTimer.CreateLocal());
       
    88 
       
    89 	User::LeaveIfError(iPhonePowerProperty.Attach(KUidSystemCategory, KUidPhonePwr.iUid));    
       
    90 	
       
    91 	// This starts the whole ball rolling
       
    92 	RequestNextState();
       
    93 	}
       
    94 
       
    95 //
       
    96 //
       
    97 //
       
    98 
       
    99 EXPORT_C void CWatcherBase::SuspendFor(TInt aTimeInSeconds)
       
   100 	{
       
   101 	LOGCOMMON1("WatcherBase : Pausing after error");
       
   102 	TTimeIntervalMicroSeconds32 timeToSuspendFor = aTimeInSeconds * KOneSecond;
       
   103 	iTimer.After(iStatus, timeToSuspendFor);
       
   104 	State() = EBaseStateSuspending;
       
   105 	SetActive();
       
   106 	}
       
   107 
       
   108 EXPORT_C void CWatcherBase::SetDisabled(const TDesC& aLogEntry, TInt aError)
       
   109 	{
       
   110 #ifdef _WATCHER_LOGGING_ENABLED
       
   111 	TBuf8<256>  tmpBuf;
       
   112 	tmpBuf.Copy(aLogEntry);
       
   113 	LOGCOMMON3("Log Entry \"%S\" error %d", &tmpBuf, aError);
       
   114 #else
       
   115 	(void) aLogEntry;
       
   116 	(void) aError;
       
   117 #endif
       
   118 	LOGCOMMON1("WatcherBase : Watcher is now disabled");
       
   119 	State() = EBaseStateDisabled;
       
   120 	}
       
   121 
       
   122 EXPORT_C void CWatcherBase::RequestNextState()
       
   123 	{
       
   124 	LOGCOMMON1("WatcherBase : Requesting State Change");
       
   125 
       
   126 	if	(State() != EBaseStateDisabled)
       
   127 		{
       
   128 		TRequestStatus* status = &iStatus;
       
   129 		User::RequestComplete(status, KErrNone);
       
   130 		SetActive();
       
   131 		}
       
   132 	}
       
   133 
       
   134 EXPORT_C void CWatcherBase::WaitForPhoneToPowerUpL()
       
   135 //
       
   136 //	The phone is currently turned off. We must wait for it to be turned back on
       
   137 //	again before the watchers can continue.
       
   138 //
       
   139 	{
       
   140 	TInt val;	
       
   141 	
       
   142 	LOGCOMMON1("WatcherBase : Waiting for phone to be turned on");
       
   143 	__ASSERT_DEBUG(!IsActive(), WatcherBasePanic(EUnexpectedActiveState));
       
   144 	Cancel();
       
   145 
       
   146 	//-- Subscribe to phone power state change property and wait until it changes
       
   147 	iPhonePowerProperty.Subscribe(iStatus);
       
   148 
       
   149 	// Update our state
       
   150 	State() = EBaseStateWaitingForPhoneToPowerUp;
       
   151 
       
   152 	// Set us ready to go again
       
   153 	SetActive();    
       
   154 
       
   155 	User::LeaveIfError(iPhonePowerProperty.Get(val));
       
   156 
       
   157 	if (val != ESAPhoneOff)
       
   158 		{//-- phone is already ON, complete request so that we go to RunL without waiting
       
   159 		iPhonePowerProperty.Cancel();        
       
   160 		LOGCOMMON1("CTelWatcherBase::WaitForPhoneToPowerUpL ??? phone is already turned ON");
       
   161 		}
       
   162 	}
       
   163 
       
   164 //
       
   165 //
       
   166 //
       
   167 
       
   168 EXPORT_C void CWatcherBase::RunL()
       
   169 	{
       
   170 	LOGCOMMON2("WatcherBase : RunL(%d)", iStatus.Int());
       
   171 
       
   172 	switch(State())
       
   173 		{
       
   174 	case EBaseStateConnectingToPropertyNotifier:		
       
   175 		LOGCOMMON1("WatcherBase : Attaching to Property");
       
   176 
       
   177 		// Virtual function call back, for any subclasses that need to implement
       
   178 		// any special stuff.
       
   179 		HandleConnectionToChangeNotifierEstablishedL();
       
   180 
       
   181 		// Move to next state
       
   182 		State() = EBaseStatePassive;
       
   183 		RequestNextState();
       
   184 		break;
       
   185 
       
   186 	case EBaseStateWaitingForPhoneToPowerUp:
       
   187 		// We were waiting for the phone to become available again. We now must restart
       
   188 		// this watcher from scratch.
       
   189 		LOGCOMMON1("WatcherBase : Phone available again. Restarting watcher framework");
       
   190 		
       
   191         //--  phone power state has changed (it must be turned ON)
       
   192         //--  retrieve its state and check.
       
   193         TInt val;
       
   194 	    
       
   195         User::LeaveIfError(iPhonePowerProperty.Get(val));
       
   196 
       
   197         if (val == ESAPhoneOn)
       
   198         {   //-- everything OK, the phone has been turned ON, restart this watcher from scratch.
       
   199 		    LOGCOMMON1("CTelWatcherBase : Phone has been turned ON. Restarting watcher framework");
       
   200             State() = EBaseStateConnectingToPropertyNotifier;
       
   201             RequestNextState();
       
   202         }
       
   203         else
       
   204         {   //-- strange situation, we were waiting for phone On and it now Off, try to wait again
       
   205             LOGCOMMON1("CTelWatcherBase : ??? Phone has been turned OFF. Continue waiting...");
       
   206             WaitForPhoneToPowerUpL();
       
   207         } 		
       
   208 		break;
       
   209 
       
   210 	case EBaseStateSuspending:
       
   211 		LOGCOMMON1("WatcherBase : Completed suspension. Resuming passive state");
       
   212 		
       
   213 		State() = EBaseStatePassive; // Fall through
       
   214 
       
   215 	case EBaseStatePassive: // In passive mode, so just call framework function
       
   216 		HandleStateEventL(iStatus.Int());
       
   217 		break;
       
   218 	
       
   219 	default:
       
   220 	case EBaseStateDisabled:
       
   221 		LOGCOMMON1("WatcherBase : RunL called in Disabled state. Ooops");
       
   222 		__ASSERT_DEBUG(0, WatcherBasePanic(EUnexpectedState));
       
   223 		}
       
   224 	}
       
   225 
       
   226 EXPORT_C void CWatcherBase::DoCancel()
       
   227 	{
       
   228 	switch(State())
       
   229 		{	
       
   230 	case EBaseStateSuspending:
       
   231 		// Cancel outstanding timer
       
   232 		iTimer.Cancel();
       
   233 		break;
       
   234 
       
   235 	case EBaseStateWaitingForPhoneToPowerUp:
       
   236 		// Cancel outstanding asynchronous request
       
   237 		iPhonePowerProperty.Cancel();
       
   238 		break;
       
   239 
       
   240 	default:
       
   241 	case EBaseStatePassive:
       
   242 	case EBaseStateConnectingToPropertyNotifier:
       
   243 	case EBaseStateDisabled:
       
   244 		break;
       
   245 		}
       
   246 
       
   247 	// Let other sub classes cancel their requests
       
   248 	HandleCancel();
       
   249 	}
       
   250 
       
   251 EXPORT_C TInt CWatcherBase::RunError(TInt aError)
       
   252 //
       
   253 //	Called when RunL (or a sub-function there-of) leaves.
       
   254 //
       
   255 	{
       
   256 #ifdef _WATCHER_LOGGING_ENABLED
       
   257 	LOGCOMMON2("WatcherBase : RunError called with error of %d", aError);
       
   258 #else
       
   259 	(void) aError;
       
   260 #endif
       
   261 
       
   262 	// Should never be called from outside the framework
       
   263 	__ASSERT_DEBUG(!IsActive(), WatcherBasePanic(EUnexpectedActiveState));
       
   264 	Cancel();
       
   265 
       
   266 	// Reset all resources in this, and the derrived class so that
       
   267 	// we can start up again (from scratch) (virtual function).
       
   268 	if	(State() == EBaseStatePassive)
       
   269 		Reset();
       
   270 
       
   271 	// Close our resources
       
   272 	iPhonePowerProperty.Close();
       
   273 
       
   274 	// NOTE: we don't close the timer. This was opened in ConstructL so
       
   275 	// we can't close that here.
       
   276 
       
   277 	// Have we already tried this too many times?
       
   278 	if	(ErrorCountIncrement() >= KErrorRetryCount)
       
   279 		{
       
   280 		// We've tried to resume 3 times already and we've still not managed. Give up
       
   281 		// now until a reboot.
       
   282 		SetDisabled(_L("WatcherBase : RunError called too many times in succession"), KErrNone);
       
   283 		}
       
   284 	else
       
   285 		{
       
   286 		// Put us in the start up state again
       
   287 		LOGCOMMON1("WatcherBase : Phone available again. Restarting watcher framework");
       
   288 		State() = EBaseStateConnectingToPropertyNotifier;
       
   289 		RequestNextState();
       
   290 		}
       
   291 
       
   292 	return KErrNone;
       
   293 	}
       
   294 
       
   295 //
       
   296 // Panic Function
       
   297 //
       
   298 void CWatcherBase::WatcherBasePanic(TWatcherPanic aPanicNumber)
       
   299 	{
       
   300 	_LIT(panicText,"Watcher Base");
       
   301 	User::Panic(panicText,aPanicNumber);
       
   302 	}
       
   303 
       
   304 
       
   305 
       
   306 //
       
   307 // ------> CPhoneWatcher (source)
       
   308 //
       
   309 
       
   310 
       
   311 EXPORT_C CPhoneWatcher::CPhoneWatcher(TInt aPriority)
       
   312 :	CWatcherBase(aPriority)
       
   313 	{
       
   314 	}
       
   315 
       
   316 EXPORT_C CPhoneWatcher::~CPhoneWatcher()
       
   317 	{
       
   318 	delete iModemChangeObserver;
       
   319 	delete iPhoneWait;
       
   320 	Phone().Close();
       
   321 	ETel().Close();
       
   322 	}
       
   323 
       
   324 EXPORT_C void CPhoneWatcher::ConstructL()
       
   325 	{
       
   326 	CWatcherBase::ConstructL();
       
   327 	}
       
   328 
       
   329 //
       
   330 //
       
   331 //
       
   332 
       
   333 EXPORT_C void CPhoneWatcher::HandleStateEventL(TInt aCompletionCode)
       
   334 	{
       
   335 	switch(PhoneState())
       
   336 		{
       
   337 	case EPhoneStateRetrievingTsyName:
       
   338 		// Cconstruct observers
       
   339 		if	(!iPhoneWait)
       
   340 			{
       
   341 			iPhoneWait = new(ELeave) CPhoneOnOff(*this);
       
   342 			iPhoneWait->ConstructL();
       
   343 			}
       
   344 		if	(!iModemChangeObserver)
       
   345 			{
       
   346 			iModemChangeObserver = new(ELeave) CModemChangeObserver(*this);
       
   347 			iModemChangeObserver->ConstructL();
       
   348 			}
       
   349 
       
   350 		User::LeaveIfError(RetrieveTSYName());
       
   351 		PhoneState() = EPhoneStateConnectingToETel;
       
   352 		RequestNextState();
       
   353 		break;
       
   354 
       
   355 	case EPhoneStateConnectingToETel:
       
   356 		User::LeaveIfError(ConnectToETelServer());
       
   357 		PhoneState() = EPhoneStateLoadingPhoneModule;
       
   358 		RequestNextState();
       
   359 		break;
       
   360 
       
   361 	case EPhoneStateLoadingPhoneModule:
       
   362 		User::LeaveIfError(LoadPhoneModule());
       
   363 		PhoneState() = EPhoneStateConnectingToPhone;
       
   364 		RequestNextState();
       
   365 		break;
       
   366 
       
   367 	case EPhoneStateConnectingToPhone:
       
   368 		User::LeaveIfError(ConnectToPhone());
       
   369 		PhoneState() = EPhoneStatePassive;
       
   370 		RequestNextState();
       
   371 		break;
       
   372 	
       
   373 	case EPhoneStatePassive:
       
   374 		HandlePhoneStateEventL(aCompletionCode);
       
   375 		break;
       
   376 
       
   377 	default:
       
   378 		__ASSERT_DEBUG(0, WatcherBasePanic(EUnexpectedState));
       
   379 		}
       
   380 	}
       
   381 
       
   382 EXPORT_C void CPhoneWatcher::Reset()
       
   383 	{
       
   384 	// Ensures CModemChangeObserver object stops running
       
   385 	if (iModemChangeObserver)
       
   386 		{
       
   387 		iModemChangeObserver->Cancel();
       
   388 		}
       
   389 
       
   390 	if	(PhoneState() == EPhoneStatePassive)
       
   391 		{
       
   392 		// Get children to release any resources they have
       
   393 		ReleasePhoneResources();
       
   394 		}
       
   395 	
       
   396 	// Close our connections to the phone & ETel
       
   397 	Phone().Close();
       
   398 	ETel().Close();
       
   399 
       
   400 	// Reset state
       
   401 	PhoneState() = EPhoneStateRetrievingTsyName;
       
   402 	}
       
   403 
       
   404 //
       
   405 //
       
   406 //
       
   407 
       
   408 TInt CPhoneWatcher::RetrieveTSYName()
       
   409 	{
       
   410 	LOGCOMMON1("PhoneWatcher : RetrieveTSYName()");
       
   411 	TRAPD(error, DoRetrieveTSYNameL());
       
   412 	return error;
       
   413 	}
       
   414 
       
   415 TInt CPhoneWatcher::ConnectToETelServer()
       
   416 	{
       
   417 	LOGCOMMON1("PhoneWatcher : ConnectToETelServer()");
       
   418 	return ETel().Connect();
       
   419 	}
       
   420 
       
   421 TInt CPhoneWatcher::LoadPhoneModule()
       
   422 	{
       
   423 #ifdef _WATCHER_LOGGING_ENABLED
       
   424 	TBuf8<256>  tmpBuf;
       
   425 	tmpBuf.Copy(iTSYName);
       
   426 	LOGCOMMON1("PhoneWatcher : LoadPhoneModule()");
       
   427 	LOGCOMMON2("TSY Name to load is %S",&tmpBuf);
       
   428 #endif
       
   429 
       
   430 	return ETel().LoadPhoneModule(iTSYName);
       
   431 	}
       
   432 
       
   433 TInt CPhoneWatcher::ConnectToPhone()
       
   434 	{
       
   435 	LOGCOMMON1("PhoneWatcher : ConnectToPhone()");
       
   436 	TInt error;
       
   437 
       
   438 	RTelServer::TPhoneInfo phoneInfo;
       
   439 
       
   440 	// Get the number of phones
       
   441 	TInt phoneCount = 0;
       
   442 	error = ETel().EnumeratePhones(phoneCount);
       
   443 	if	(error < KErrNone)
       
   444 		{
       
   445 		LOGCOMMON2("PhoneWatcher : Failed to enumerate phones (%d)", error);
       
   446 		return error;
       
   447 		}
       
   448 
       
   449 	LOGCOMMON2("PhoneWatcher : Counted %d 'phones'", phoneCount);
       
   450 
       
   451 	// Iterate through all the phones
       
   452 	for(TInt i=0; i<phoneCount; i++)
       
   453 		{
       
   454 		// Get the TSY name for the phone
       
   455 		TName matchTsyName;
       
   456 		
       
   457 		error = ETel().GetTsyName(i, matchTsyName);
       
   458 		if	(error < KErrNone)
       
   459 			{
       
   460 			LOGCOMMON2("PhoneWatcher : Getting TSY name failed (%d)", error);
       
   461 			return error;
       
   462 			}
       
   463 
       
   464 #ifdef _WATCHER_LOGGING_ENABLED
       
   465 		TBuf8<256>  tmpMatchTsyName;
       
   466 		tmpMatchTsyName.Copy(matchTsyName);
       
   467 		LOGCOMMON3("PhoneWatcher : TSY for phone %d is '%S'", i, &tmpMatchTsyName);
       
   468 #endif
       
   469 
       
   470 		// See if the phone belongs to the TSY
       
   471 		if	(matchTsyName.CompareF(iTSYName) == 0)
       
   472 			{
       
   473 #ifdef _WATCHER_LOGGING_ENABLED
       
   474 			TBuf8<256>  tsyNameBuf;
       
   475 			tsyNameBuf.Copy(iTSYName);
       
   476 			LOGCOMMON3("PhoneWatcher : %S is a match for CommDb TSY: %S", &tmpMatchTsyName, &tsyNameBuf);
       
   477 #endif
       
   478 
       
   479 			error = ETel().GetPhoneInfo(i, phoneInfo);
       
   480 			if	(error < KErrNone)
       
   481 				{
       
   482 				LOGCOMMON2("PhoneWatcher : Getting phone info failed (%d)", error);
       
   483 				return error;
       
   484 				}
       
   485 			break;
       
   486 			}
       
   487 		}
       
   488 
       
   489 	// Connect to the specified phone
       
   490 	error = Phone().Open(ETel(), phoneInfo.iName);
       
   491 	if	(error < KErrNone)
       
   492 		{
       
   493 #ifdef _WATCHER_LOGGING_ENABLED
       
   494 		TBuf8<256>  tmpBuf;
       
   495 		tmpBuf.Copy(phoneInfo.iName);
       
   496 		LOGCOMMON3("PhoneWatcher : Open phone %S failed (%d)", &tmpBuf, error);
       
   497 #endif
       
   498 		return error;
       
   499 		}
       
   500 
       
   501 #ifdef _WATCHER_LOGGING_ENABLED
       
   502 	TBuf8<256>  tmpBuf;
       
   503 	tmpBuf.Copy(phoneInfo.iName);
       
   504 	LOGCOMMON2("PhoneWatcher : Opened 'phone' %S", &tmpBuf);
       
   505 #endif
       
   506 
       
   507 	// Indicate we're connected and to move to next state.
       
   508 	return error;
       
   509 	}
       
   510 
       
   511 //
       
   512 //
       
   513 //
       
   514 
       
   515 void CPhoneWatcher::DoRetrieveTSYNameL()
       
   516 	{
       
   517 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   518 	CMDBSession* db = CMDBSession::NewL(KCDVersion1_2);
       
   519 #else
       
   520 	CMDBSession* db = CMDBSession::NewL(KCDVersion1_1);
       
   521 #endif
       
   522 	CleanupStack::PushL(db);
       
   523 
       
   524 	CMDBField<TUint32>* globalSettingsField = new(ELeave) CMDBField<TUint32>(KCDTIdModemPhoneServicesSMS);
       
   525 	CleanupStack::PushL(globalSettingsField);
       
   526 	globalSettingsField->SetRecordId(1);
       
   527 	globalSettingsField->LoadL(*db);
       
   528 	TUint32 modemId = *globalSettingsField;
       
   529 	CleanupStack::PopAndDestroy(globalSettingsField);
       
   530 	
       
   531 	CMDBField<TDesC>* tsyField = new(ELeave) CMDBField<TDesC>(KCDTIdTsyName);
       
   532 	CleanupStack::PushL(tsyField);
       
   533 	tsyField->SetRecordId(modemId);
       
   534 	tsyField->SetMaxLengthL(KMaxTextLength);
       
   535 	tsyField->LoadL(*db);
       
   536 	iTSYName = *tsyField;
       
   537 	CleanupStack::PopAndDestroy(tsyField);
       
   538 	
       
   539 	
       
   540 	// Strip any file extension
       
   541 	TInt pos = iTSYName.LocateReverse('.');
       
   542 	if	(pos >= 0)
       
   543 		iTSYName = iTSYName.Left(pos);
       
   544 
       
   545 #ifdef WATCHER_TESTING
       
   546 	{
       
   547 	TTime now;
       
   548 	now.UniversalTime();
       
   549 	User::LeaveIfError(RProperty::Set(KUidSystemCategory, KUidTestProp_ModemTableRefreshed.iUid, I64LOW(now.Int64())));
       
   550 	}
       
   551 #endif
       
   552 
       
   553 	CleanupStack::PopAndDestroy(); // db or commsDatabase 
       
   554 	}
       
   555 
       
   556 EXPORT_C void CPhoneWatcher::PhoneIsOff()
       
   557 	{
       
   558 	Cancel();
       
   559 	Reset(); // Kill phone resources
       
   560 #ifdef	_DEBUG
       
   561 	TRAPD(err, WaitForPhoneToPowerUpL());
       
   562 	__ASSERT_DEBUG(err == KErrNone, WatcherBasePanic(EGeneral));
       
   563 #else
       
   564 	TRAP_IGNORE(WaitForPhoneToPowerUpL());
       
   565 #endif
       
   566 	}
       
   567 
       
   568 EXPORT_C void CPhoneWatcher::HandleModemChangedL()
       
   569 //
       
   570 //	Called when the commsdb modem record has changed. Must
       
   571 //	re-read the current modem and attempt to reinitialise the watcher
       
   572 //	using this new modem.
       
   573 //
       
   574 	{
       
   575 #ifdef WATCHER_TESTING
       
   576 	{
       
   577 	TTime now;
       
   578 	now.UniversalTime();
       
   579 	// State set to ETrue/EFalse
       
   580 	User::LeaveIfError(RProperty::Set(KUidSystemCategory, KUidTestProp_ModemRecordChanged.iUid, I64LOW(now.Int64())));
       
   581 	}
       
   582 #endif
       
   583 
       
   584 	Cancel();
       
   585 
       
   586 	// Kill phone resources
       
   587 	Reset();
       
   588 
       
   589 	// Start us going again. This will (in turn) 
       
   590 	// re-read the comms database. NOTE: Our state has been set to
       
   591 	// 'EPhoneStateRetrievingTsyName' by Reset()
       
   592 	RequestNextState();
       
   593 	}
       
   594