datacommsserver/networkcontroller/src/CTelBearer.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2003-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 /**
       
    17  @file CTelBearer.cpp
       
    18 */
       
    19 
       
    20 #include "CTelBearer.h"
       
    21 #include "NetConLog.h"
       
    22 #include "NetConError.h"
       
    23 #include "NetConPanic.h"
       
    24 #include <comms-infras/dbaccess.h>
       
    25 #include <agentdialog.h>  // for TConnectionPrefs
       
    26 #include "CNetworkController.h"
       
    27 
       
    28 CTelBearer::~CTelBearer()
       
    29 /**
       
    30 Destructor
       
    31 */
       
    32 	{
       
    33 	
       
    34 
       
    35 	CloseTelephony();
       
    36 
       
    37 	if(iStartCheckingCb)
       
    38 		{
       
    39 		iStartCheckingCb->Cancel();
       
    40 		}
       
    41 
       
    42 	// Note:  iBearerCompleteCb is declared in the base class CBearerBase.
       
    43 	if(iBearerCompleteCb)
       
    44 		{
       
    45 		iBearerCompleteCb->Cancel();
       
    46 		}
       
    47 
       
    48 	delete iStartCheckingCb;
       
    49 	iStartCheckingCb = NULL;
       
    50 
       
    51 	delete iBearerCompleteCb;
       
    52 	iBearerCompleteCb = NULL;
       
    53 	
       
    54 	delete iTsyName;
       
    55 	iTsyName = NULL;
       
    56 	}
       
    57 
       
    58 CTelBearer* CTelBearer::NewLC(MBearerObserver* aObserver)
       
    59 /**
       
    60 Factory function - creates a new CTelBearer
       
    61 On return the new object is left on the cleanup stack
       
    62 
       
    63 @param aObserver, checks for bearer availability 
       
    64 @param aDatabase,allow the requests and bearers access to the database..
       
    65 @return the new CTelBearer object
       
    66 @exception leaves if construction fails
       
    67 */
       
    68 	{
       
    69 
       
    70 	CTelBearer* self = new(ELeave) CTelBearer(aObserver);
       
    71 	CleanupStack::PushL(self);
       
    72 	self->ConstructL();
       
    73 	return self;
       
    74 	}
       
    75 
       
    76 CTelBearer* CTelBearer::NewL(MBearerObserver* aObserver)
       
    77 /**
       
    78 Factory function - creates a new CTelBearer
       
    79 
       
    80 @param aObserver, checks for bearer availability 
       
    81 @param aDatabase,allow the requests and bearers access to the database..
       
    82 @return the new CTelBearer object
       
    83 @exception leaves if construction fails
       
    84 */
       
    85 	{
       
    86 
       
    87 	CTelBearer* self = CTelBearer::NewLC(aObserver);
       
    88 	CleanupStack::Pop(); // self
       
    89 	return self;
       
    90 	}
       
    91 
       
    92 CTelBearer::CTelBearer(MBearerObserver* aObserver)
       
    93 : CBearerBase(aObserver)
       
    94 /**
       
    95 Constructor
       
    96 */
       
    97 	{ }
       
    98 
       
    99 void CTelBearer::ConstructL()
       
   100 /**
       
   101 2nd phase of construction
       
   102 
       
   103 @exception leaves if 2nd phase construction fails 
       
   104 */
       
   105 	{
       
   106 
       
   107 	// call base class ConstructL()
       
   108 	CBearerBase::ConstructL();
       
   109 
       
   110 	// Set up start checking callback
       
   111 	TCallBack callback(StartCheckingCb, this);
       
   112 	iStartCheckingCb = new (ELeave) CAsyncCallBack(callback, CActive::EPriorityStandard);
       
   113 	}
       
   114 
       
   115 void CTelBearer::AssignSupportedBearerSet()
       
   116 /**
       
   117 Assign the supported telephony bearer set.
       
   118 */
       
   119 	{
       
   120 	
       
   121 	// identify bearer type of this object
       
   122 	iSupportedBearerSet = (KCommDbBearerCSD | KCommDbBearerPSD);
       
   123 	}
       
   124 
       
   125 void CTelBearer::Disconnect()
       
   126 /**
       
   127 Trigger all agents on this bearer to disconnect
       
   128 */
       
   129 	{
       
   130 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tDisconnect()")); )
       
   131 
       
   132 	}
       
   133 
       
   134 TBool CTelBearer::StartChecking()
       
   135 /**
       
   136 Start checking for availability
       
   137 
       
   138 @return ETrue if available else EFalse
       
   139 */
       
   140 	{
       
   141 	return StartChecking(EFalse);
       
   142 	}
       
   143 
       
   144 TBool CTelBearer::StartChecking(TBool aIsReconnect)
       
   145 /**
       
   146 Start checking for availability
       
   147 
       
   148 @param aIsReconnect, if this is a reconnection then any asynchronous requests are skipped in order to speed things up.
       
   149 @return ETrue if available else EFalse
       
   150 */
       
   151 	{
       
   152 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tStartChecking()")); )
       
   153 
       
   154 	if (iChecking)
       
   155 		return EFalse;
       
   156 
       
   157 	iChecking = ETrue;
       
   158 	iIsReconnect = aIsReconnect;
       
   159 	iStartCheckingCb->CallBack();
       
   160 	return ETrue;
       
   161 	}
       
   162 
       
   163 TInt CTelBearer::StartCheckingCb(TAny* aThisPtr)
       
   164 /**
       
   165 Callback initiated from StartChecking()
       
   166   
       
   167 @param aThisPtr a pointer to the instance of this class that initiated the callback
       
   168 @return KErrNone always
       
   169 */
       
   170 	{
       
   171 	CTelBearer* self = (CTelBearer*) aThisPtr;
       
   172 	self->CheckBearerSupport();
       
   173 	return KErrNone;
       
   174 	}
       
   175 
       
   176 TBool CTelBearer::StopChecking()
       
   177 /**
       
   178 Stop checking for availability
       
   179 
       
   180 @return ETrue if stopped else EFalse
       
   181 */
       
   182 	{
       
   183 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tStopChecking()")); )
       
   184 
       
   185 	if (!iChecking)
       
   186 		return EFalse;
       
   187 
       
   188 	iStartCheckingCb->Cancel();
       
   189 	// Note:  iBearerCompleteCb is declared in the base class CBearerBase.
       
   190 	iBearerCompleteCb->Cancel();
       
   191 	iChecking = EFalse;
       
   192 
       
   193 	// free telephony resources
       
   194 	CloseTelephony();
       
   195 
       
   196 	return ETrue;
       
   197 	}
       
   198 
       
   199 void CTelBearer::CheckBearerSupport()
       
   200 /**
       
   201 Find out which bearers are available
       
   202 */
       
   203 	{
       
   204 
       
   205 	LOG( NetConLog::Printf(_L("TelBearer:\tStarting to check for bearer availability")); )
       
   206 
       
   207 	TRAPD(err, GetBearerSupportL());
       
   208 	if(err!=KErrNone)
       
   209 		{
       
   210 		LOG( NetConLog::Printf(_L("TelBearer:\tError %d during bearer availability check"), err); )
       
   211 
       
   212 		// something has gone wrong when trying to check availability
       
   213 		// so stop checking availability and tell the observer that
       
   214 		// no bearers are available
       
   215 		StopChecking();
       
   216 		iAvailableBearerSet = KCommDbBearerUnknown;
       
   217 		UpdateObserver();
       
   218 		}
       
   219 	}
       
   220 
       
   221 void CTelBearer::GetBearerSupportL()
       
   222 /**
       
   223 Retrieve required telephony information and work out which bearers are available
       
   224 
       
   225 @exception leaves with one of the system-wide error codes
       
   226 */
       
   227 	{
       
   228 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tGetBearerSupportL()")); )
       
   229 
       
   230 	OpenTelephonyL();
       
   231 	RetrievePhoneCapsL();
       
   232 	RetrieveNetworkModeL();
       
   233 	RetrievePacketSupportL();
       
   234 	}
       
   235 
       
   236 void CTelBearer::OpenTelephonyL()
       
   237 /**
       
   238 Initialise telephony resources
       
   239 
       
   240 @exception leaves with one of the system-wide error codes
       
   241 */
       
   242 	{
       
   243 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tOpenTelephonyL()")); )
       
   244 
       
   245 	__ASSERT_DEBUG(iTelServerState == ENotConnected, NetConPanic(NetworkController::ETelBearerBadState));
       
   246 
       
   247 	// Request pointer to CommDB's access class
       
   248 	CCommsDbAccess* dbAccess = iObserver->DbAccess();
       
   249 
       
   250 	// retrieve the TSY name from the database
       
   251 	// and remove the .tsy extension if necessary
       
   252 	TFileName tsyName;
       
   253 	dbAccess->GetBearerAvailabilityTsyNameL(tsyName);
       
   254 
       
   255 	if (tsyName.Right(4).CompareF(KTsyNameExtension())==0)
       
   256 		{
       
   257 		tsyName = tsyName.Left(tsyName.Length() - 4);
       
   258 		}
       
   259 
       
   260 	// Remember the tsy name so it can be unloaded
       
   261 	if(iTsyName)
       
   262 		{
       
   263 		delete iTsyName;
       
   264 		iTsyName = NULL;
       
   265 		}
       
   266 	iTsyName = tsyName.AllocL();
       
   267 
       
   268 	// connect to ETEL
       
   269 	User::LeaveIfError(iTelServer.Connect());
       
   270 	iTelServerState = EServerConnected;
       
   271 
       
   272 	// load the TSY
       
   273 	User::LeaveIfError(iTelServer.LoadPhoneModule(tsyName));
       
   274 	iTelServerState = EPhoneModuleLoaded;
       
   275 
       
   276 	// open the phone module
       
   277 	OpenPhoneL(iTelServer, tsyName, iMmPhone);
       
   278 	iTelServerState = EPhoneOpen;
       
   279 	
       
   280 	// start watching signal strength
       
   281 	iSigStrengthWatcher = CAgentSignalStrengthWatcher::NewL(iMmPhone);
       
   282 	}
       
   283 
       
   284 void CTelBearer::CloseTelephony()
       
   285 /**
       
   286 Free any telephony resources used
       
   287 */
       
   288 	{
       
   289 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tCloseTelephony()")); )
       
   290 
       
   291 	if(iETelServerRequestsWrapper)
       
   292 		{
       
   293 		delete iETelServerRequestsWrapper;
       
   294 		iETelServerRequestsWrapper = NULL;
       
   295 		}
       
   296 
       
   297 	if(iSigStrengthWatcher)
       
   298 		{
       
   299 		delete iSigStrengthWatcher;
       
   300 		iSigStrengthWatcher = NULL;
       
   301 		}
       
   302 
       
   303 	switch(iTelServerState)
       
   304 		{
       
   305 		case EPacketOpen:
       
   306 			iPacket.Close();
       
   307 			// ... fall through ...
       
   308 		case EPhoneOpen:
       
   309 			iMmPhone.Close();
       
   310 			// ... fall through ...
       
   311 		case EPhoneModuleLoaded:
       
   312 			__ASSERT_ALWAYS(iTsyName, NetConPanic(NetworkController::ETelBearerTsyNameMissing));
       
   313 			// can't do anything if UnloadPhoneModule fails so ignore return value
       
   314 			(void)iTelServer.UnloadPhoneModule(*iTsyName);
       
   315 			// ... fall through ...
       
   316 		case EServerConnected:
       
   317 			iTelServer.Close();
       
   318 			iTelServerState = ENotConnected;
       
   319 			break;
       
   320 		case ENotConnected:
       
   321 			if (iTsyName)
       
   322 				{
       
   323 				delete iTsyName;
       
   324 				iTsyName = NULL;
       
   325 				}
       
   326 			break;
       
   327 		default:
       
   328 			break;
       
   329 		}
       
   330 	}
       
   331 
       
   332 void CTelBearer::OpenPhoneL(RTelServer& aTelServer, const TDesC& aTsyName, RMobilePhone& aMmPhone)
       
   333 /**
       
   334 Open the phone module (ie the TSY)
       
   335 
       
   336 @param aTelServer the telephony server session
       
   337 @param aTsyName the name of the phone module to load
       
   338 @param aMmPhone the phone session in which to load the TSY
       
   339 @exception leaves with one of the system-wide error codes
       
   340 */
       
   341 	{
       
   342 	__ASSERT_DEBUG(iTelServerState == EPhoneModuleLoaded, NetConPanic(NetworkController::ETelBearerBadState));
       
   343 	
       
   344 	// find out how many phones are supported (i.e. how many TSYs)
       
   345 	TInt count = 0;
       
   346 	User::LeaveIfError(aTelServer.EnumeratePhones(count));
       
   347 	if (count <= 0)
       
   348 		User::Leave(KErrNotFound);
       
   349 
       
   350 	RTelServer::TPhoneInfo info;
       
   351 	TBool found(EFalse);
       
   352 
       
   353 	// loop through all the phones and find correct TSY
       
   354 	for (TInt i = 0; i < count; ++i)
       
   355 		{
       
   356 		TBuf<KCommsDbSvrMaxFieldLength> currentTsyName;
       
   357 		User::LeaveIfError(aTelServer.GetTsyName(i, currentTsyName));
       
   358 
       
   359 		// remove .TSY extension if necessary
       
   360 		if (currentTsyName.Right(4).CompareF(KTsyNameExtension())==0)
       
   361 			{
       
   362 			currentTsyName = currentTsyName.Left(currentTsyName.Length() - 4);
       
   363 			}
       
   364 
       
   365 		// compare current TSY name with the one we're looking for
       
   366 		if (currentTsyName.CompareF(aTsyName)==0)
       
   367 			{
       
   368 			// get phone info from the TSY
       
   369 			User::LeaveIfError(aTelServer.GetPhoneInfo(i, info));
       
   370 			found = ETrue;
       
   371 			break;
       
   372 			}	
       
   373 		}
       
   374 
       
   375 	if (!found)
       
   376 		User::Leave(KErrNotFound);
       
   377 
       
   378 	// open multimode phone object
       
   379 	User::LeaveIfError(aMmPhone.Open(aTelServer, info.iName));
       
   380 	}
       
   381 
       
   382 void CTelBearer::RetrievePhoneCapsL()
       
   383 /**
       
   384 Query the phone for basic and multimode capabilities
       
   385 
       
   386 @exception leaves with one of the system-wide error codes
       
   387 */
       
   388 	{
       
   389 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tRetrievePhoneCapsL()")); )
       
   390 
       
   391 	__ASSERT_DEBUG(iTelServerState == EPhoneOpen, NetConPanic(NetworkController::ETelBearerBadState));
       
   392 
       
   393 	// retrieve the basic phone capabilities
       
   394 	// (ie. whether it supports data calls)
       
   395 	iPhoneCaps.iFlags = RPhone::KCapsUnknown;
       
   396 	User::LeaveIfError(iMmPhone.GetCaps(iPhoneCaps));
       
   397 
       
   398 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tiPhoneCaps.iFlags = %d"), iPhoneCaps.iFlags); )
       
   399 
       
   400 	// retrieve multimode phone capabilities
       
   401 	User::LeaveIfError(iMmPhone.GetMultimodeCaps(iPhoneMultimodeCaps));
       
   402 
       
   403 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tiPhoneMultimodeCaps = %d"), iPhoneMultimodeCaps); )
       
   404 	}
       
   405 
       
   406 void CTelBearer::RetrieveNetworkModeL()
       
   407 /**
       
   408 Query the phone for the network mode (e.g. GSM, WCDMA, cdma95 or cdma2000)
       
   409 Stores the network mode in the database (since it is needed for Mobile IP)
       
   410 */
       
   411 	{
       
   412 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tRetrieveNetworkModeL()")); )
       
   413 
       
   414 	__ASSERT_DEBUG(iTelServerState == EPhoneOpen, NetConPanic(NetworkController::ETelBearerBadState));
       
   415 
       
   416 	// retrieve the current network mode
       
   417 	// ignore error because the phone might not be able
       
   418 	// to report this information (eg. a normal modem)
       
   419 	iNetworkMode = RMobilePhone::ENetworkModeUnknown;
       
   420 	(void)iMmPhone.GetCurrentMode(iNetworkMode);
       
   421 
       
   422 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tiNetworkMode = %d"), iNetworkMode); )
       
   423 
       
   424 	// Request pointer to CommDB's access class
       
   425 	CCommsDbAccess* dbAccess = iObserver->DbAccess();
       
   426 
       
   427 	// set the network mode in the database
       
   428 	// this is required for Mobile IP
       
   429 	dbAccess->SetNetworkMode(iNetworkMode);
       
   430 	}
       
   431 
       
   432 void CTelBearer::RetrievePacketSupportL()
       
   433 /**
       
   434 Find out if packet switched data is available
       
   435 
       
   436 @exception leaves with one of the system-wide error codes
       
   437 */
       
   438 	{
       
   439 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tRetrievePacketSupportL()")); )
       
   440 
       
   441 	__ASSERT_DEBUG(iTelServerState == EPhoneOpen, NetConPanic(NetworkController::ETelBearerBadState));
       
   442 
       
   443 	if(iPhoneMultimodeCaps & (RMobilePhone::KCapsGprsSupported))
       
   444 		{
       
   445 		// the phone supports packet data 
       
   446 		// so try and open the packet service
       
   447 		User::LeaveIfError(iPacket.Open(iMmPhone));
       
   448 		iTelServerState = EPacketOpen;
       
   449 
       
   450 		// query the TSY for the attach mode
       
   451 		iPacketAttachMode = RPacketService::EAttachWhenNeeded;
       
   452 		TInt err = iPacket.GetAttachMode(iPacketAttachMode);
       
   453 		
       
   454 		// query packet network status (but only if the TSY is set to attach when possible)
       
   455 		iPacketDataNetworkStatus = RPacketService::EStatusUnattached;
       
   456 		if(err==KErrNone && iPacketAttachMode == RPacketService::EAttachWhenPossible)
       
   457 			{
       
   458 			User::LeaveIfError(iPacket.GetStatus(iPacketDataNetworkStatus));
       
   459 			}
       
   460 		LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tiPacketDataNetworkStatus = %d"), iPacketDataNetworkStatus); )
       
   461 
       
   462 		// close packet service as it is no-longer needed
       
   463 		iPacket.Close();
       
   464 		iTelServerState = EPhoneOpen;
       
   465 
       
   466 		if(!iIsReconnect)
       
   467 			{
       
   468 			// start asynchronous ETEL requests to retrieve
       
   469 			// the MS class and the network registration status
       
   470 			iMsClass = RPacketService::EMSClassUnknown;
       
   471 			iETelServerRequestsWrapper = CASyncEtelRequestWrapper::NewL(this);
       
   472 			iETelServerRequestsWrapper->StartAsyncRequests(iTelServer, iMmPhone);
       
   473 			return;
       
   474 			}
       
   475 		}
       
   476 		LOG_DETAILED( else NetConLog::Printf(_L("TelBearer:\tPacket data is not supported")); )
       
   477 
       
   478 	CalculateAvailableBearerSet();
       
   479 	}
       
   480 
       
   481 void CTelBearer::ETelAsyncRequestsComplete(TETelAsyncRequestData aRequestData)
       
   482 /**
       
   483 The MS Class and Network Registration status have been retrieved
       
   484 Store these values and work out which bearers are available
       
   485 
       
   486 @param aRequestData contains the information returned from ETEL
       
   487 */
       
   488 	{
       
   489 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tETelAsyncRequestsComplete()")); )
       
   490 
       
   491 	__ASSERT_DEBUG(iTelServerState == EPhoneOpen, NetConPanic(NetworkController::ETelBearerBadState));
       
   492 
       
   493 	if (aRequestData.iETelAsynError.iError==KErrNone)
       
   494 		{
       
   495 		LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tiNetworkRegStatus = %d"), iNetworkRegStatus); )
       
   496 		LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tiMsClass = %d"), iMsClass); )
       
   497 
       
   498 		// data was retrieved sucessfully
       
   499 		iNetworkRegStatus = aRequestData.iRegistrationStatus;
       
   500 		iMsClass = aRequestData.iMSClass;
       
   501 		}
       
   502 	else
       
   503 		{
       
   504 		LOG( NetConLog::Printf(_L("TelBearer:\tAsync ETEL requests completed with error %d)"), aRequestData.iETelAsynError.iError); )
       
   505 
       
   506 		iNetworkRegStatus = RPacketService::ENotRegisteredNotSearching;
       
   507 		iMsClass = RPacketService::EMSClassUnknown;
       
   508 		}
       
   509 
       
   510 	// we now have all the information we need
       
   511 	// so work out which bearers are available
       
   512 	CalculateAvailableBearerSet();
       
   513 	}
       
   514 
       
   515 void CTelBearer::CalculateAvailableBearerSet()
       
   516 /**
       
   517 Adds each available bearer to the currently available bearer set
       
   518 and updates the status of this bearer with the bearer manager
       
   519 */
       
   520 	{
       
   521 
       
   522 	iAvailableBearerSet = KCommDbBearerUnknown;
       
   523 
       
   524 	if(CsdAvailable())
       
   525 		iAvailableBearerSet |= KCommDbBearerCSD;
       
   526 	LOG( NetConLog::Printf(_L("TelBearer:\tFinished availability check - available bearer set is %d"), iAvailableBearerSet); )
       
   527 
       
   528 	// update the observer with the available bearers
       
   529 	UpdateObserver();
       
   530 	}
       
   531 
       
   532 TBool CTelBearer::CsdAvailable() const
       
   533 /**
       
   534 CSD is available as long as the phone can support data
       
   535 
       
   536 @return ETrue if CSD is available otherwise EFalse
       
   537 */
       
   538 	{
       
   539 
       
   540 	// can the phone support CSD?
       
   541 	TBool supported = (iPhoneCaps.iFlags & (RPhone::KCapsData | RPhone::KCapsUnknown));
       
   542 
       
   543 	LOG_DETAILED(
       
   544 				if(supported)
       
   545 					NetConLog::Printf(_L("TelBearer:\tPhone capabilities allow CSD"));
       
   546 				else
       
   547 					NetConLog::Printf(_L("TelBearer:\tPhone capabilities do not allow CSD"));
       
   548 				)
       
   549 
       
   550 	return supported;
       
   551 	}
       
   552 
       
   553 TBool CTelBearer::PhoneAttachedAndRegistered() const
       
   554 /**
       
   555 Check whether the phone is attached to the network and registered
       
   556 
       
   557 @return ETrue if the phone is attached and registered otherwise EFalse
       
   558 */
       
   559 	{
       
   560 
       
   561 	TBool attached(EFalse);
       
   562 	
       
   563 	// Is the phone attached to the packet network?
       
   564 	if(iPacketAttachMode == RPacketService::EAttachWhenNeeded)
       
   565 		{
       
   566 		// if the TSY is set to attach when needed then ignore the attachment status
       
   567 		attached = ETrue;
       
   568 		}
       
   569 	else if (iPacketDataNetworkStatus != RPacketService::EStatusUnattached)
       
   570 		{
       
   571 		attached = ETrue;
       
   572 		}
       
   573 
       
   574 	TBool registered(ETrue);
       
   575 
       
   576 	// Is the phone registered on the packet network?
       
   577 	if (iNetworkRegStatus == RPacketService::ENotRegisteredNotSearching ||
       
   578 			iNetworkRegStatus == RPacketService::ERegistrationDenied ||
       
   579 			iNetworkRegStatus == RPacketService::ENotRegisteredAndNotAvailable)
       
   580 		{
       
   581 		registered = EFalse;
       
   582 		}
       
   583 
       
   584 	LOG_DETAILED(
       
   585 				if(attached)
       
   586 					NetConLog::Printf(_L("TelBearer:\tPhone is attached to the packet network"));
       
   587 				else
       
   588 					NetConLog::Printf(_L("TelBearer:\tPhone is not attached to the packet network"));
       
   589 
       
   590 				if(registered)
       
   591 					NetConLog::Printf(_L("TelBearer:\tPhone is registered on the network"));
       
   592 				else
       
   593 					NetConLog::Printf(_L("TelBearer:\tPhone is not registered on the network"));
       
   594 				)
       
   595 
       
   596 	return (attached && registered);
       
   597 	}
       
   598 
       
   599 TBool CTelBearer::MsClassSupportsPsd() const
       
   600 /**
       
   601 Check whether the MS class supports Packet Switched Data
       
   602 
       
   603 As long as the MS Class is neither RPacketService::EMSClassAlternateMode or 
       
   604 RPacketService::EMSClassCircuitSwitchedOnly then PSD is supported
       
   605 
       
   606 i.e. the MS Class can be any of the following and still support PSD:
       
   607 RPacketService::EMSClassDualMode, RPacketService::EMSClassSuspensionRequired
       
   608 RPacketService::EMSClassPacketSwitchedOnly, RPacketService::EMSClassUnknown
       
   609 
       
   610 @return ETrue if PSD is supported otherwise EFalse
       
   611 */
       
   612 	{
       
   613 
       
   614 	TBool supported = (iMsClass != RPacketService::EMSClassAlternateMode && iMsClass != RPacketService::EMSClassCircuitSwitchedOnly);
       
   615 
       
   616 	LOG_DETAILED(
       
   617 				if(supported)
       
   618 					NetConLog::Printf(_L("TelBearer:\tMS class supports PSD"));
       
   619 				else
       
   620 					NetConLog::Printf(_L("TelBearer:\tMS class does not support PSD"));
       
   621 				)
       
   622 
       
   623 	return supported;
       
   624 	}
       
   625 
       
   626 TInt CTelBearer::SecondPhaseAvailability()
       
   627 /**
       
   628 Get the latest signal strength
       
   629 
       
   630 @return KErrNone if signal strength is ok, otherwise KErrNetConnInadequateSignalStrengh or one of the system-wide error codes
       
   631 */
       
   632 	{
       
   633 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tSecondPhaseAvailability()")); )
       
   634 	
       
   635 	// if the watcher is missing it may be that this function has been called before
       
   636 	// StartChecking().  In this case just return KErrNone
       
   637 	if(!iSigStrengthWatcher)
       
   638 		{
       
   639 		LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tSignal strength watcher missing")); )
       
   640 		return KErrNone;
       
   641 		}
       
   642 
       
   643 	const TInt KMinSignalStrengthOffset(10000);
       
   644 	TInt32 sigStrengthInDbm(0);
       
   645 	if(iSigStrengthWatcher->CurrentSignalStrength(sigStrengthInDbm)!=KErrNone)
       
   646 		{
       
   647 		// a value has not yet been retrieved so best to carry on with
       
   648 		// the connection and let it fail later if it is going to fail.
       
   649 
       
   650 		LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tNo signal strength value available")); )
       
   651 
       
   652 		return KErrNone;
       
   653 		}
       
   654 
       
   655 	// Request pointer to CommDB's access class
       
   656 	CCommsDbAccess* dbAccess = iObserver->DbAccess();
       
   657 
       
   658 	// retrieve signal strength from commdb
       
   659 	TUint32 minAcceptSignalStrength=0;
       
   660 	TRAPD(ret, dbAccess->GetIntL(TPtrC(MODEM_BEARER), TPtrC(MODEM_MIN_SIGNAL_LEVEL), minAcceptSignalStrength));
       
   661 	if(ret!=KErrNone)
       
   662 		{
       
   663 		LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tError %d when reading minimum signal strength from CommDb"), ret); )
       
   664 
       
   665 		return ret;
       
   666 		}
       
   667 
       
   668 	if(minAcceptSignalStrength==0)
       
   669 		{
       
   670 		// the functionality to stop a connection if the signal strength is
       
   671 		// below a certain value has been turned off in commdb so return no error
       
   672 
       
   673 		LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tSignal strength functionality disabled in CommDb")); )
       
   674 
       
   675 		return KErrNone;
       
   676 		}
       
   677 
       
   678 	// Convert to dBm's
       
   679 	TInt minSigStrengthInDbm=STATIC_CAST(TInt, minAcceptSignalStrength);
       
   680 	minSigStrengthInDbm-=KMinSignalStrengthOffset;
       
   681 	if(sigStrengthInDbm < minSigStrengthInDbm)
       
   682 		{
       
   683 		LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tSignal strength lower than minimum acceptable value")); )
       
   684 
       
   685 		// signal strength too low so fail the connection early
       
   686 		return KErrNetConInadequateSignalStrengh;
       
   687 		}
       
   688 
       
   689 	LOG_DETAILED( NetConLog::Printf(_L("TelBearer:\tSignal strength ok")); )
       
   690 	return KErrNone;
       
   691 	}
       
   692