telephonyprotocols/psdagt/src/MipCdma.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     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 // This file contains the implementation of the
       
    15 // handling of MIP handovers in a CDMA2000 network.
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file mipcdma.cpp
       
    21 */
       
    22 
       
    23 #include "MipCdma.h"
       
    24 #include "PSDAGTBase.h"
       
    25 #include <comms-infras/nifprvar.h>
       
    26 
       
    27 /**
       
    28 @internalComponent
       
    29 */
       
    30 const TInt K10Seconds = 10000000;
       
    31 
       
    32 /**
       
    33 @internalComponent
       
    34 */
       
    35 _LIT(KTsyNameExtension,".tsy");
       
    36 
       
    37 CMipCdmaHandoverHandler* CMipCdmaHandoverHandler::NewLC(CPSDAgent& aAgent, CCommsDbAccess& aDb)
       
    38 /**
       
    39 2 Phase constructor
       
    40 
       
    41 This function creates the whole CDMA2000 MIP Handover handler object, including the subclass
       
    42 CMIPCdmaEtelZoneChangeRequest.
       
    43 
       
    44 @param aAgent Reference to owner of this class
       
    45 @param aDb access to CommDB.
       
    46 @exception Leaves if no memory is available
       
    47 @return A newly created CMipCdmaHandoverHandler object
       
    48 */
       
    49 	{
       
    50 	CMipCdmaHandoverHandler* self = new(ELeave) CMipCdmaHandoverHandler(aAgent, aDb);
       
    51 	CleanupStack::PushL(self);
       
    52 	self->ConstructL();
       
    53 	return self;
       
    54 	}
       
    55 
       
    56 CMipCdmaHandoverHandler* CMipCdmaHandoverHandler::NewL(CPSDAgent& aAgent, CCommsDbAccess& aDb)
       
    57 /**
       
    58 2 Phase constructor
       
    59 
       
    60 This function creates the whole MIP Handover handler object, including the subclass
       
    61 CMIPCdmaEtelZoneChangeRequest.
       
    62 
       
    63 @param aAgent Reference to owner of this class
       
    64 @param aDb access to CommDB.
       
    65 @exception Leaves if no memory is available
       
    66 @return A newly created CMipCdmaHandoverHandler object
       
    67 */
       
    68 	{
       
    69 	CMipCdmaHandoverHandler* self = NewLC(aAgent, aDb);
       
    70 	CleanupStack::Pop(); //self
       
    71 	return self;
       
    72 	}
       
    73 
       
    74 CMipCdmaHandoverHandler::CMipCdmaHandoverHandler(CPSDAgent& aAgent, CCommsDbAccess& aDb) 
       
    75 	: CActive(CActive::EPriorityStandard),
       
    76 		iAgent(aAgent), iDb(aDb)
       
    77 /**
       
    78 Constructor
       
    79 
       
    80 Adds itself to the Active Sceduler. Also initalizes all member data.
       
    81 
       
    82 @param aAgent Reference to owner of this class
       
    83 @param aDb access to CommDB.
       
    84 */
       
    85 	{
       
    86 	CActiveScheduler::Add(this);
       
    87 	}
       
    88 
       
    89 void CMipCdmaHandoverHandler::ConstructL()
       
    90 /**
       
    91 2nd phase Constructor
       
    92 
       
    93 Creates an ETEL Zone change listener object.
       
    94 Resets the timer object.
       
    95 
       
    96 @exception Leaves if no memory is available
       
    97 */
       
    98 	{
       
    99 	//Create ETEL Zone Listener Object
       
   100 	iMipCdmaEtelZoneChanger = CMIPCdmaEtelZoneChangeRequest::NewL(*this, iAgent, iDb);
       
   101 	
       
   102 	//Reset the timer (initialize the timer)
       
   103 	(void)iTimer.CreateLocal();	
       
   104 	}
       
   105 
       
   106 CMipCdmaHandoverHandler::~CMipCdmaHandoverHandler()
       
   107 /**
       
   108 Destructor
       
   109 
       
   110 Calls cancel on the Active object which will cancel the timer.
       
   111 Deletes the ETEL Zone change listener object.
       
   112 */
       
   113 	{
       
   114 	Cancel();		//Cancel potential outstanding timer request.
       
   115 	iTimer.Close();	//Needed to free resources on server side.
       
   116 	delete iMipCdmaEtelZoneChanger;
       
   117 	}
       
   118 
       
   119 TInt CMipCdmaHandoverHandler::StartListening()
       
   120 /**
       
   121 This function is called when the link is brought up. It is responsible to 
       
   122 start this object and start listening to incoming events from both PPP and ETEL.
       
   123 
       
   124 @return Returns whether the starting of the object went ok or not.
       
   125 */
       
   126 	{
       
   127 	TInt err = KErrNone;
       
   128 	TBool val;
       
   129 	if(iAgent.ReadBool(TPtrC(CDMA_MIP), val)==KErrNone && val)
       
   130 		{
       
   131 		err = iMipCdmaEtelZoneChanger->StartListening();
       
   132 		}
       
   133 	return err;
       
   134 	}
       
   135 
       
   136 void CMipCdmaHandoverHandler::StopListening()
       
   137 /**
       
   138 This function is called when the link is brought down. It is responsible to 
       
   139 stop this object and its listener.
       
   140 */
       
   141 	{
       
   142 	iMipCdmaEtelZoneChanger->StopListening();
       
   143 	}
       
   144 
       
   145 TBool CMipCdmaHandoverHandler::PPPLinkDownEvent()
       
   146 /**
       
   147 This function is called from the Reconnect() method in the CPSDAgent.
       
   148 It will report back to the CPSDAgent if we are using MIP or not.
       
   149 It will also start a timer that if it expires will force a manual reconnect of the link.
       
   150 If an ETEL notification event comes in before, or has already come in, an autmatic reconnect takes place.
       
   151 
       
   152 @return ETrue if we are using MIP else EFalse.
       
   153 */
       
   154 	{
       
   155 	TBool val;
       
   156 	if(iAgent.ReadBool(TPtrC(CDMA_MIP), val)==KErrNone && val)
       
   157 		{
       
   158 		//We are using MIP
       
   159 		iPPPLinkDownEvent = ETrue;
       
   160 		if (iETELChangedZoneEvent)
       
   161 			{
       
   162 			Cancel();
       
   163 			RestartPPP();
       
   164 			}
       
   165 		else
       
   166 			{
       
   167 			//If timer is already started, cancel it and start it again.
       
   168 			Cancel();	//Will only cancel the timer if the AO is active.
       
   169 			StartTimer();
       
   170 			}		
       
   171 		return ETrue;
       
   172 		}
       
   173 	else
       
   174 		{
       
   175 		//We are NOT using MIP
       
   176 		return EFalse;
       
   177 		}
       
   178 	}
       
   179 
       
   180 void CMipCdmaHandoverHandler::ETELChangedZoneEvent()
       
   181 /**
       
   182 This function is called from the RunL() method in the CMIPCdmaEtelZoneChangeRequest.
       
   183 It will also start a timer that if it expires will force a manual reconnect of the link.
       
   184 If an PPP Link Down event comes in before, or has already come in, an autmatic reconnect takes place.
       
   185 */
       
   186 	{
       
   187 	iETELChangedZoneEvent = ETrue;
       
   188 	if (iPPPLinkDownEvent)
       
   189 		{
       
   190 		Cancel();
       
   191 		// Notify nifman of the Changed Zone Event
       
   192 		iAgent.AgentEvent(EEtelEvent,ECurrentNetworkChangeEvent,KNullDesC8);
       
   193 		// Reconnect PPP
       
   194 		RunL();
       
   195 		}
       
   196 	else
       
   197 		{
       
   198 		//If timer is already started, cancel it and start it again.
       
   199 		Cancel();	//Will only cancel the timer if the AO is active.
       
   200 		StartTimer();
       
   201 		}
       
   202 	}
       
   203 
       
   204 void CMipCdmaHandoverHandler::StartTimer()
       
   205 /**
       
   206 Help function that will start the active object. E.g. it will start the timer and activate the object.
       
   207 */
       
   208 	{
       
   209 	TUint32 time;
       
   210 	if(iAgent.ReadInt(TPtrC(CDMA_MIP_TIMEOUT), time)==KErrNone && time)
       
   211 		{
       
   212 		iTimer.After(iStatus, time);
       
   213 		}
       
   214 	else //default
       
   215 		{
       
   216 		iTimer.After(iStatus, K10Seconds); 
       
   217 		}
       
   218 
       
   219 	SetActive();
       
   220 	}
       
   221 
       
   222 void CMipCdmaHandoverHandler::RestartPPP()
       
   223 /**
       
   224 This function is responsible to do an automatic reconnect of the link. Will also "zero" the state variables
       
   225 */
       
   226 	{
       
   227 	iPPPLinkDownEvent = EFalse;
       
   228 	iETELChangedZoneEvent = EFalse;
       
   229 
       
   230 	//Notify client to restart PPP silently
       
   231 	iAgent.MDPOReconnectComplete(KErrNone);
       
   232 	}
       
   233 
       
   234 void CMipCdmaHandoverHandler::DoCancel()
       
   235 /**
       
   236 Inherited from the CActive class. Will cancel the timer request.
       
   237 */
       
   238 	{
       
   239 	// Cancel the timer request
       
   240 	iTimer.Cancel();
       
   241 	}
       
   242 
       
   243 void CMipCdmaHandoverHandler::RunL()
       
   244 /**
       
   245 Inherited from the CActive class. Will "zero" the state variables and restart the link manually.
       
   246 */
       
   247 	{
       
   248 	iPPPLinkDownEvent = EFalse;
       
   249 	iETELChangedZoneEvent = EFalse;
       
   250 	//Notify client to restart PPP as we would in a normal Simple IP scenario
       
   251 	iAgent.Reconnect();
       
   252 	}
       
   253 
       
   254 CMIPCdmaEtelZoneChangeRequest* CMIPCdmaEtelZoneChangeRequest::NewLC(CMipCdmaHandoverHandler& aHandoverHandler, CPSDAgent& aAgent, CCommsDbAccess& aDb)
       
   255 /**
       
   256 2 Phase constructor
       
   257 
       
   258 This function creates a ETEL Zone Change Listener object.
       
   259 
       
   260 @param aHandoverHandler Reference to owner of this class
       
   261 @param aAgent Reference to the Controller
       
   262 @param aDb access to CommDB.
       
   263 @exception Leaves if no memory is available
       
   264 @return A newly created CMIPCdmaEtelZoneChangeRequest object
       
   265 */
       
   266 	{
       
   267 	CMIPCdmaEtelZoneChangeRequest* self = new(ELeave) CMIPCdmaEtelZoneChangeRequest(aHandoverHandler, aAgent, aDb);
       
   268 	CleanupStack::PushL(self);
       
   269 	self->ConstructL();
       
   270 	return self;
       
   271 	}
       
   272 
       
   273 CMIPCdmaEtelZoneChangeRequest* CMIPCdmaEtelZoneChangeRequest::NewL(CMipCdmaHandoverHandler& aHandoverHandler, CPSDAgent& aAgent, CCommsDbAccess& aDb)
       
   274 /**
       
   275 2 Phase constructor
       
   276 
       
   277 This function creates a ETEL Zone Change Listener object.
       
   278 
       
   279 @param aHandoverHandler Reference to owner of this class
       
   280 @param aAgent Reference to the Agent
       
   281 @param aDb access to CommDB.
       
   282 @exception Leaves if no memory is available
       
   283 @return A newly created CMIPCdmaEtelZoneChangeRequest object
       
   284 */
       
   285 	{
       
   286 	CMIPCdmaEtelZoneChangeRequest* self = NewLC(aHandoverHandler, aAgent, aDb);
       
   287 	CleanupStack::Pop(); //self
       
   288 	return self;
       
   289 	}
       
   290 
       
   291 CMIPCdmaEtelZoneChangeRequest::CMIPCdmaEtelZoneChangeRequest(CMipCdmaHandoverHandler& aHandoverHandler, CPSDAgent& aAgent, CCommsDbAccess& aDb) 
       
   292 	: CActive(CActive::EPriorityStandard), iFirstTime(ETrue),
       
   293 	iHandoverHandler(aHandoverHandler), iAgent(aAgent), iDb(aDb),
       
   294 	iPhoneNetworkInfoPckg(iAsyncCurrentNetwork)
       
   295 /**
       
   296 Constructor
       
   297 
       
   298 Adds itself to the Active Sceduler. Also initalizes all member data.
       
   299 
       
   300 @param aHandoverHandler Reference to owner of this class
       
   301 @param aAgent Reference to the Agent
       
   302 */
       
   303 	{
       
   304 	CActiveScheduler::Add(this);
       
   305 	}
       
   306 
       
   307 void CMIPCdmaEtelZoneChangeRequest::ConstructL()
       
   308 /**
       
   309 2nd phase Constructor
       
   310 */
       
   311 	{
       
   312 	}
       
   313 
       
   314 CMIPCdmaEtelZoneChangeRequest::~CMIPCdmaEtelZoneChangeRequest()
       
   315 /**
       
   316 Destructor
       
   317 
       
   318 Calls cancel on the Active object which will cancel the outstanding request to ETEL.
       
   319 Closes the ETEL phone and server.
       
   320 */	
       
   321 	{
       
   322 	StopListening();
       
   323 	}
       
   324 
       
   325 TInt CMIPCdmaEtelZoneChangeRequest::StartListening()
       
   326 /**
       
   327 This function is called when the link is brought up.
       
   328 It is responsible to initiate and create a phone object.
       
   329 
       
   330 @return Returns whether the starting of the object and phone went ok or not.
       
   331 */
       
   332 	{
       
   333 	if (!iStarted)
       
   334 		{
       
   335 		iStarted = ETrue;
       
   336 		TRAPD(err, InitPhoneL());
       
   337 		if(err != KErrNone)
       
   338 			{
       
   339 			return err;
       
   340 			}
       
   341 
       
   342 		//Start request for notification
       
   343 		iFirstTime = ETrue;
       
   344 		StartRequest();
       
   345 		}
       
   346 	return KErrNone;
       
   347 	}
       
   348 
       
   349 void CMIPCdmaEtelZoneChangeRequest::StopListening()
       
   350 /**
       
   351 This function is called when the link is brought down. It is responsible to stop
       
   352 the phone object and the phone server 
       
   353 */
       
   354 	{
       
   355 	if(iStarted)
       
   356 		{
       
   357 		iStarted=EFalse;
       
   358 		Cancel();
       
   359 
       
   360 		iMmPhone.Close();
       
   361 		(void)iTelServer.UnloadPhoneModule(*iTsyName);
       
   362 		delete iTsyName;
       
   363 		iTsyName = NULL;
       
   364 		iTelServer.Close();
       
   365 		}
       
   366 	}
       
   367 
       
   368 void CMIPCdmaEtelZoneChangeRequest::InitPhoneL()
       
   369 /**
       
   370 This function is help function that creates and intializes a phone object 
       
   371 
       
   372 @exception Leaves if no memory is available or if initiation of phone or server failed.
       
   373 */
       
   374 	{
       
   375 	TFileName tsyName;
       
   376 	iDb.GetTsyNameL(tsyName);
       
   377 	if (tsyName.Right(4).CompareF(KTsyNameExtension) == 0)
       
   378 		tsyName = tsyName.Left(tsyName.Length() - 4);
       
   379 
       
   380 	// Connect to ETel
       
   381 	(void)User::LeaveIfError(iTelServer.Connect());
       
   382 
       
   383 	TInt err = iTelServer.LoadPhoneModule(tsyName);
       
   384 	if(err == KErrNotFound)
       
   385 		User::Leave(KErrNone);
       
   386 	else if(err != KErrNone)
       
   387 		User::Leave(err);
       
   388 
       
   389 	// Remember the tsy name so it can be unloaded
       
   390 	iTsyName = tsyName.AllocL();
       
   391 
       
   392 	// Find out how many phones are supported e.g. how many TSYs
       
   393 	TInt count = 0;
       
   394 	(void)User::LeaveIfError(iTelServer.EnumeratePhones(count));
       
   395 	if (count <= 0)
       
   396 		User::Leave(KErrNotFound);
       
   397 
       
   398 	RTelServer::TPhoneInfo info;
       
   399 	TBool found = EFalse;
       
   400 
       
   401 	// Loop through all the phones and find correct TSY
       
   402 	for (TInt i = 0; i < count; i++)
       
   403 		{
       
   404 		TBuf<KCommsDbSvrMaxFieldLength> currentTsyName;
       
   405 		(void)User::LeaveIfError(iTelServer.GetTsyName(i, currentTsyName));
       
   406 		// If the loaded object has .tsy extension, compare the name
       
   407 		// with aTsyName
       
   408 		if (currentTsyName.Right(4).CompareF(KTsyNameExtension) == 0)
       
   409 			currentTsyName = currentTsyName.Left(currentTsyName.Length() - 4);
       
   410 		if (currentTsyName.CompareF(tsyName) == 0)
       
   411 			{
       
   412 			// Get phone info from the TSY
       
   413 			(void)User::LeaveIfError(iTelServer.GetPhoneInfo(i, info));
       
   414 			found = ETrue;
       
   415 			break;
       
   416 			}	
       
   417 		}
       
   418 	if (!found)
       
   419 		User::Leave(KErrNotFound);
       
   420 	// Open multimode phone object
       
   421 	(void)User::LeaveIfError(iMmPhone.Open(iTelServer,info.iName));
       
   422 	}
       
   423 
       
   424 void CMIPCdmaEtelZoneChangeRequest::StartRequest()
       
   425 /**
       
   426 Trigger function. Will start the request for notifications for a zone change event from ETEL.
       
   427 
       
   428 If it is the first time the object is called we will get the network information and store it locally
       
   429 After the initial request we will only ask to get notfied when there is a change in network information.
       
   430 */	
       
   431 	{
       
   432 	if (iFirstTime)
       
   433 		{
       
   434 		//Get current netowrk status
       
   435 		iMmPhone.GetCurrentNetwork(iStatus, iPhoneNetworkInfoPckg, iAsyncLocArea);
       
   436 		}
       
   437 	else
       
   438 		{
       
   439 		//start etel request for notifications
       
   440 		iMmPhone.NotifyCurrentNetworkChange(iStatus, iPhoneNetworkInfoPckg, iAsyncLocArea);	
       
   441 		}
       
   442 
       
   443 	SetActive();
       
   444 	}
       
   445 
       
   446 void CMIPCdmaEtelZoneChangeRequest::DoCancel()
       
   447 /**
       
   448 Inherited from the CActive class. Will cancel the ETEL request.
       
   449 */
       
   450 	{
       
   451 	if (iFirstTime)
       
   452 		{
       
   453 		iMmPhone.CancelAsyncRequest(EMobilePhoneGetCurrentNetwork);
       
   454 		}
       
   455 	else
       
   456 		{
       
   457 		// Cancel the ETEL Request
       
   458 		iMmPhone.CancelAsyncRequest(EMobilePhoneNotifyCurrentNetworkChange);
       
   459 		}
       
   460 	}
       
   461 
       
   462 void CMIPCdmaEtelZoneChangeRequest::RunL()
       
   463 /**
       
   464 Inherited from the CActive class. Will notify the owner that a notification has ben received.
       
   465 Will requeue itself, e.g. will re-request notifications from ETEL.
       
   466 */
       
   467 	{
       
   468 	if (iFirstTime)
       
   469 		{
       
   470 		iCurrentCdmaSID = iPhoneNetworkInfoPckg().iCdmaSID;
       
   471 		iCurrentNetworkId = iPhoneNetworkInfoPckg().iNetworkId;
       
   472 		iFirstTime = EFalse;
       
   473 		}
       
   474 	else
       
   475 		{
       
   476 		if ((iPhoneNetworkInfoPckg().iCdmaSID !=iCurrentCdmaSID) || (iPhoneNetworkInfoPckg().iNetworkId !=iCurrentNetworkId))
       
   477 			iHandoverHandler.ETELChangedZoneEvent();
       
   478 		}
       
   479 
       
   480 	//Requeue
       
   481 	StartRequest();
       
   482 	}
       
   483