networkprotocolmodules/suplprotocolmodule/SuplProtocol/src/suplmtlrstatehandler.cpp
changeset 36 b47902b73a93
parent 0 9cfd9a3ee49c
equal deleted inserted replaced
35:a2efdd544abf 36:b47902b73a93
       
     1 // Copyright (c) 2008-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 provides the implementation of the class for
       
    15 // the SUPL MT-LR procedure state handler
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalTechnology
       
    22  @deprecated
       
    23 */
       
    24 
       
    25 #include "suplmtlrfsmsession.h"
       
    26 #include "suplmtlrstatehandler.h"
       
    27 #include "suplgatewayinterface.h"
       
    28 #include "suplmessagebase.h"
       
    29 #include "suplstart.h"
       
    30 #include "suplpos.h"
       
    31 #include "suplposinit.h"
       
    32 #include "suplresponse.h"
       
    33 #include "suplend.h"
       
    34 #include <etelmm.h>
       
    35 #include "supldevloggermacros.h"
       
    36 
       
    37 
       
    38 /** Static constructor.
       
    39 @param aMachine A reference to the parent state machine.
       
    40 @return A new instance of the CSuplMtLrStateHandler class
       
    41 */
       
    42 CSuplMtLrStateHandler* CSuplMtLrStateHandler::NewL(CSuplFsmSessionBase& aMachine)
       
    43 	{
       
    44 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::NewL() \n");
       
    45 	CSuplMtLrStateHandler* self = new (ELeave) CSuplMtLrStateHandler(aMachine);
       
    46 	return self;
       
    47 	}
       
    48 
       
    49 /** Standard constructor.
       
    50 @param aMachine A reference to the parent state machine.
       
    51 */  
       
    52 CSuplMtLrStateHandler::CSuplMtLrStateHandler(CSuplFsmSessionBase& aMachine)
       
    53 : CSuplStateHandlerBase(aMachine)
       
    54 	{
       
    55 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::CSuplMtLrStateHandler() Begin\n");
       
    56 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::CSuplMtLrStateHandler() End\n");
       
    57 	}
       
    58 
       
    59 
       
    60 /** Standard destructor.
       
    61 */  
       
    62 CSuplMtLrStateHandler::~CSuplMtLrStateHandler()
       
    63 	{
       
    64 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::~CSuplMtLrStateHandler() Begin\n");
       
    65 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::~CSuplMtLrStateHandler() End\n");
       
    66 	}
       
    67 
       
    68 	
       
    69 /** Perform entry actions.
       
    70 This is called from the state machine to perform any actions
       
    71 associated with entering the current state following an external
       
    72 event or an autonomous state transition.
       
    73 
       
    74 For some states, there is only one possible course of action.
       
    75 For other states, the event store has to be checked to see what
       
    76 events have occurred and what actions have to be taken to handle
       
    77 such events.
       
    78 
       
    79 If an event conductive to cancelling the state machine had occurred
       
    80 (e.g, an explicit client cancel, an error, or a timeout), then the
       
    81 state machine would have been set in an state that terminates the 
       
    82 session before this method is called (either EStateSuplSessionEnded
       
    83 or EStatePosSessionEnded).
       
    84 
       
    85 @return TBool ETrue if any actions have been taken
       
    86 */  
       
    87 TBool CSuplMtLrStateHandler::EntryActionsL()
       
    88 	{
       
    89 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::EntryActionsL() Begin\n");
       
    90 	TBool actionsTaken = ETrue;
       
    91 	// Retrieve current state and act accordingly
       
    92 	switch(iMachine.CurrentState())
       
    93 		{
       
    94 		case CSuplFsmSessionBase::EStateProcedureNull:
       
    95 			// No action required
       
    96 			break;
       
    97 		
       
    98 		case CSuplFsmSessionBase::EStateSuplInitReceived:
       
    99 			actionsTaken = EntryActionsFromSuplInitReceived();
       
   100 			break;
       
   101 			
       
   102 		case CSuplFsmSessionBase::EStateNetConnectionStarted:
       
   103 			actionsTaken = EntryActionsFromNetConnectionStarted();
       
   104 			break;
       
   105 			
       
   106 		case CSuplFsmSessionBase::EStatePosInitSent:
       
   107 			// Build and send a SUPL POS INIT
       
   108 			actionsTaken = EntryActionsFromPosInitSentStateL();
       
   109 			break;
       
   110 
       
   111 		case CSuplFsmSessionBase::EStatePositioningInProgress:
       
   112 			actionsTaken = EntryActionsFromPositioningInProgressStateL();
       
   113 			break;
       
   114 
       
   115 		case CSuplFsmSessionBase::EStatePositionReceived:
       
   116 			actionsTaken = EntryActionsFromPositionReceivedStateL();
       
   117 			break;
       
   118 			
       
   119 		case CSuplFsmSessionBase::EStateSuplSessionEnded:
       
   120 			// Send SUPL END
       
   121 			actionsTaken = EntryActionsFromSuplSessionEndedStateL();
       
   122 			break;
       
   123 
       
   124 		case CSuplFsmSessionBase::EStatePosSessionEnded:
       
   125 			// Send to Positioning FSM an instruction to terminate silently
       
   126 			//
       
   127 			iMachine.PositioningFsm()->CancelMachine(CSuplPositioningProtocolFsm::ESuplFsmCancel, CSuplFsmSessionBase::EReasonNone);
       
   128 			break;
       
   129 			
       
   130 		case CSuplFsmSessionBase::EStateLbsSessionEnded:
       
   131 			// Send session complete indication to LBS
       
   132 			actionsTaken = EntryActionsFromLbsSessionEndedStateL();
       
   133 			break;
       
   134 			
       
   135 		case CSuplFsmSessionBase::EStateNetConnectionClosed:
       
   136 			// Close the network connection
       
   137 			iMachine.CompleteProcedure();
       
   138 			break;
       
   139 
       
   140 		default:
       
   141 			ASSERT(EFalse);
       
   142 			break;
       
   143 		}
       
   144 	
       
   145 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::EntryActionsL() End\n");
       
   146 	return actionsTaken;
       
   147 	}
       
   148 //---------------------------------------------------------------------------------------------------------------------
       
   149 // -----------------------     METHODS FOR ACTIONS AFTER ENTERING STATES  ---------------------------------------------
       
   150 //---------------------------------------------------------------------------------------------------------------------
       
   151 
       
   152 /** Actions on entering state EStateSuplInitReceived
       
   153 This method sends a LocationRequest and a PrivacyRequest
       
   154 to LBS.
       
   155 */
       
   156 TBool CSuplMtLrStateHandler::EntryActionsFromSuplInitReceived()
       
   157 	{
       
   158 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::EntryActionsFromSuplInitReceived() Begin\n");
       
   159 	TLbsNetPosRequestPrivacy privacyAdvice;
       
   160 	TLbsExternalRequestInfo requestor;
       
   161 	TLbsNetPosRequestMethod posMethods;
       
   162 	TLbsNetPosMethod selectedMethod; // only one method is sent to LBS
       
   163 	TLbsNetPosRequestQuality quality;
       
   164 
       
   165 	// Send a PrivacyRequest followed by a Location Request to LBS
       
   166 	iMachine.RetrievePrivacyAdvice(privacyAdvice);
       
   167 	iMachine.RetrieveRequestorInfo(requestor);
       
   168 	iMachine.Observer().PrivacyReq(iMachine.LbsSessionId(), privacyAdvice, requestor);
       
   169 
       
   170 
       
   171 	// Get the pos methods received in a SUPL INIT
       
   172 	// (kept in event store).
       
   173 	iMachine.RetrieveInitPosMethod(posMethods);
       
   174 	TLbsNetPosMethod netPrefMethod;
       
   175 	posMethods.GetPosMethod(0, netPrefMethod);
       
   176 	if (KLbsPositioningMeansNone != netPrefMethod.PosMeans()) // not a "noPosition" INIT
       
   177 		{
       
   178 		// Check that there are supported positioning methods different 
       
   179 		// from Cell Based (Cell-Based can't be requested from LBS).
       
   180 		TLbsNetPosCapabilities capabilities;
       
   181 		iMachine.Observer().Gateway().GetCapabilities(capabilities);
       
   182 		if (iMachine.PosMethodSupported(posMethods, selectedMethod,capabilities) &&
       
   183 			KLbsPositioningMeansCell != selectedMethod.PosMeans())
       
   184 			{
       
   185 			// Method to be presented to LBS
       
   186 			posMethods.SetPosMethods(&selectedMethod, 1);
       
   187 			}
       
   188 		else
       
   189 			{
       
   190 			// No mutually supported positioning methods.
       
   191 			// Send to LBS the positioning method that is preferred
       
   192 			// by LBS (the first in the capabilities)
       
   193 			capabilities.GetPosMethod(0, selectedMethod);
       
   194 			posMethods.SetPosMethods(&selectedMethod, 1);
       
   195 			}
       
   196 
       
   197 		iMachine.RetrieveInitQuality(quality);
       
   198 		iMachine.Observer().LocationReq(iMachine.LbsSessionId(),	iMachine.LocReqType(),
       
   199 										   quality, posMethods);	
       
   200 		}
       
   201 
       
   202 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::EntryActionsFromSuplInitReceived() End\n");
       
   203 	return ETrue;
       
   204 	}
       
   205 	
       
   206 
       
   207 /** Actions on entering state EStateNetConnectionStarted
       
   208 
       
   209 This method obtains an SLP Id from the Host Settings store
       
   210 and asks the Connection Manager to provide a connection with it.
       
   211 */
       
   212 TBool CSuplMtLrStateHandler::EntryActionsFromNetConnectionStarted()
       
   213 	{
       
   214 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::EntryActionsFromNetConnectionStarted() Begin\n");
       
   215 	TBool ret = ETrue;
       
   216 	TLbsHostSettingsId hostId = TUid::Uid(0);
       
   217 	TLbsNetSessionId::TSessionNum sessIdNum = 0;
       
   218 	// Request a connection if one has not been set up already
       
   219 	if (!iMachine.IsSessionConnected())
       
   220 		{
       
   221 		TInt err = iMachine.GetHostId(hostId); 
       
   222 			
       
   223 		if (KErrNone == err)
       
   224 			{
       
   225 			// Request a connection from the Connection Manager
       
   226 			//
       
   227 			sessIdNum = iMachine.SessionId().SessionNum();
       
   228 			iMachine.Observer().ConnectionManager().Connect(sessIdNum, hostId, CSuplSessionRecord::EServiceMtlr, iMachine);
       
   229 			// start the timer that oversees connection creation
       
   230 			iMachine.StartConnectionTimer();		
       
   231 			}
       
   232 		else
       
   233 			{
       
   234 			// Cancel session as a SUPL server could not be determined
       
   235 			iMachine.CancelMachine(CSuplFsmSessionBase::ECancelSuplProt, CSuplFsmSessionBase::EReasonSlpSettingsMissing);
       
   236 			}
       
   237 		}
       
   238 	else
       
   239 		{
       
   240 		 // This will happen if the connection has been created but the state
       
   241 		 // machine remains in EStateNetConnectionStarted due to being waiting
       
   242 		 // for an event from LBS (either a position notification or an assistance
       
   243 		 // data request). Nothing to be done.
       
   244 		 ret = EFalse;
       
   245 		}
       
   246 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::EntryActionsFromNetConnectionStarted() End\n");
       
   247 	return ret;
       
   248 	}
       
   249 	
       
   250 
       
   251 
       
   252 /** Actions on entering state EStatePosInitSent
       
   253 This method builds a SUPL POS INIT message and hands it over to 
       
   254 the Connection Manager for sending to the SUPL server.
       
   255 */
       
   256 TBool CSuplMtLrStateHandler::EntryActionsFromPosInitSentStateL()
       
   257 	{
       
   258 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::EntryActionsFromPosInitSentStateL() Begin\n");
       
   259 	TBool err = EFalse;
       
   260 	TLbsNetPosRequestQuality quality;
       
   261 	TLbsNetPosCapabilities capabilities;
       
   262 	TBool actionsTaken = EFalse;
       
   263 	
       
   264 	// There should be either an assistance data request 
       
   265 	// or a position from LBS in the event store
       
   266 	if (iMachine.IsAssistanceDataRequestStored() || iMachine.IsPositionStored())
       
   267 		{
       
   268 		ASSERT(iMachine.IsSessionConnected()); // should not have transitioned into this state without a connection
       
   269 
       
   270 		// Create the SUPL POS INIT Message
       
   271 		CSuplPosInit* suplPosInit = CSuplPosInit::NewL();
       
   272 		CleanupStack::PushL(suplPosInit);
       
   273 		
       
   274 		// Set the Location Id in the message
       
   275 		CSuplLocationId* locationId;
       
   276 		if (BuildLocationIdL(locationId))
       
   277 			{
       
   278 			CleanupStack::PushL(locationId);
       
   279 
       
   280 			suplPosInit->SetLocationId(*locationId);
       
   281 			CleanupStack::PopAndDestroy(locationId);
       
   282 
       
   283 			// Set Capabilities in the message
       
   284 			BuildCapabilitiesL(capabilities,quality);
       
   285 		    User::LeaveIfError(suplPosInit->SetCapabilities(capabilities));
       
   286 
       
   287 		    // Set either a supplied position or assistance data request in the message
       
   288 		 	if (iMachine.IsPositionStored())
       
   289 			 	{
       
   290 				TPositionInfoBase* posPtr = iMachine.RetrievePositionL();
       
   291 				User::LeaveIfError(suplPosInit->SetPosition(*posPtr));
       
   292 			 	}
       
   293 			else if (iMachine.IsAssistanceDataRequestStored())
       
   294 				{
       
   295 				TLbsAsistanceDataGroup assitDataReqMask;
       
   296 				TBool assitDataReqPresent = iMachine.RetrieveAssistanceDataRequest(assitDataReqMask);
       
   297 				if (assitDataReqMask != 0)
       
   298 					{
       
   299 					User::LeaveIfError(suplPosInit->SetRequestedAssistanceData(assitDataReqMask));
       
   300 					}
       
   301 				else
       
   302 					{
       
   303 					// This was an empty assistance data request. No need to set it
       
   304 					// in the POS INIT message (intentionally no action take here)
       
   305 					}
       
   306 				}
       
   307 			
       
   308 			// Set in message header the stored session id
       
   309 			// after adding to it the SET session ID
       
   310 			CSuplSessionId* sessionId = iMachine.MessageSessionId();
       
   311 			TUint32 ipAddr = iMachine.RetrieveLocalIpAddress().Address();
       
   312 			sessionId->iSetSessionIdPresent = ETrue;
       
   313 			sessionId->iSetSessionId->iSessionId = iMachine.SessionId().SessionNum();
       
   314 			sessionId->iSetSessionId->iSetId->iSetIdType = ESuplSetIdTypeMsisdn; // TSuplSetIdType
       
   315 			
       
   316 			const TUint8 KMaxMsisdnLength = 8;
       
   317 			TDes8& des = sessionId->iSetSessionId->iSetId->iSetId;
       
   318 			if(iMachine.Msisdn())
       
   319 				{
       
   320 				ConvertToBcd(des);
       
   321 				}
       
   322 			else
       
   323 				{
       
   324 				//Fill the descriptor with all bits set to 0, then append a 0xFF to the end to indicate the end of the MSISDN
       
   325 				des.SetLength(KMaxMsisdnLength);
       
   326 				des.Fill(0x00, (KMaxMsisdnLength -1));	//7 0's
       
   327 				des.Append(0xFF);	//Final 1 FF
       
   328 				}
       
   329 			
       
   330 			//sessionId->iSetSessionId->iSetId->iSetIdType = ESuplSetIdTypeIPAddress;
       
   331 			//sessionId->iSetSessionId->iSetId->iIpAddress->iIpAddressType = ESuplIpAddressTypeV4;
       
   332 			//sessionId->iSetSessionId->iSetId->iIpAddress->iIpAddress.Copy(reinterpret_cast<unsigned char*>(&ipAddr), 4);
       
   333 			
       
   334 			User::LeaveIfError(suplPosInit->SetSessionId(*sessionId));
       
   335 			
       
   336 			// Set in message the Ver field
       
   337 			TBuf8<8> ver;
       
   338 			iMachine.RetrieveVer(ver);
       
   339 			User::LeaveIfError(suplPosInit->SetVer(ver));
       
   340 			
       
   341 			CleanupStack::Pop(suplPosInit);
       
   342 			// Ask the Connection Manager to send the SUPL POS INIT message
       
   343 			iMachine.Observer().ConnectionManager().SendMessage(suplPosInit, iMachine.SessionId().SessionNum());
       
   344 
       
   345 			// Start the timer that oversees the arrival of SUPL POS
       
   346 			iMachine.StartSuplPosTimer();
       
   347 			
       
   348 			actionsTaken = ETrue;
       
   349 			}
       
   350 		else
       
   351 			{
       
   352 			// Failed to build Location Id
       
   353 			err = ETrue;
       
   354 			CleanupStack::PopAndDestroy(suplPosInit);
       
   355 			}
       
   356 		}
       
   357 	else
       
   358 		{
       
   359 		err = ETrue;
       
   360 		}
       
   361 		
       
   362 	if (err)
       
   363 		{
       
   364 		iMachine.CancelMachine(CSuplFsmSessionBase::ECancelSuplProt, CSuplFsmSessionBase::EReasonNone);			
       
   365 		}
       
   366 	
       
   367 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::EntryActionsFromPosInitSentStateL() End\n");
       
   368 	return actionsTaken;
       
   369 	}
       
   370 
       
   371 /**
       
   372 Utility method that builds the capabilities to send in a SUPL POS INIT using LBS's supported
       
   373 capabilities and network preferred positioning method.
       
   374 */
       
   375 TBool CSuplMtLrStateHandler::BuildCapabilitiesL(TLbsNetPosCapabilities& aCapabilities, TLbsNetPosRequestQuality& aQuality)
       
   376 {
       
   377 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::BuildCapabilitiesL() Begin\n");
       
   378 	TLbsNetPosRequestMethod locReqMethods;
       
   379 	TLbsNetPosMethod prefMethod;
       
   380 	TInt numMethods;
       
   381 	TInt index;
       
   382 	TBool ecidSupported = EFalse;
       
   383 	TInt additionalMethods = 1; // preferred method
       
   384 
       
   385 	iMachine.Observer().Gateway().GetCapabilities(aCapabilities);
       
   386 	numMethods = aCapabilities.NumPosMethods();
       
   387 	// Check if E-CID is possible
       
   388 	// (currently this mean Timing Advance only)
       
   389 	if(iMachine.IsNetworkInfoAvailable())
       
   390 		{
       
   391 		RMobilePhone::TMobilePhoneNetworkInfoV1 networkInfo;
       
   392 		RMobilePhone::TMobilePhoneLocationAreaV1 locationArea;
       
   393 		iMachine.RetrieveStoredNetworkInfo(networkInfo, locationArea);	
       
   394 		if (RMobilePhone::ENetworkModeGsm == networkInfo.iMode)
       
   395 			{
       
   396 			RMobilePhone::TMobilePhoneCellInfoV9 cellInfo;
       
   397 			if(iMachine.RetrieveStoredCellInfo(cellInfo))
       
   398 				{
       
   399 				// Timing Advance not supported if negative
       
   400 				ecidSupported = (cellInfo.iTimingAdvance >= 0);
       
   401 				additionalMethods++;
       
   402 				}
       
   403 			}
       
   404 		}
       
   405 
       
   406 	// Determine what method has been used for this session (prefMethod).
       
   407 	// The positioning method preferred by the SLP had been received in the 
       
   408 	// SUPL INIT message and is kept in the event store.
       
   409 	iMachine.RetrieveInitPosMethod(locReqMethods);
       
   410 	TLbsNetPosCapabilities capabilities;
       
   411 	iMachine.Observer().Gateway().GetCapabilities(capabilities);
       
   412 	if (!iMachine.PosMethodSupported(locReqMethods, prefMethod, capabilities) &&
       
   413 			KLbsPositioningMeansCell != prefMethod.PosMeans())
       
   414 		{
       
   415 		// No pos method received from the SLP was used for the session as
       
   416 		// no supported method was found. The first method in 
       
   417 		// the array of capabilities (LBS's preferred) was used instead. Get it.
       
   418 		aCapabilities.GetPosMethod(0, prefMethod);
       
   419 		}
       
   420 
       
   421 	// The prefMethod has to be added at the end of the array of methods in aCapabilities
       
   422 	// because that is where the ASN1 encoder expects it to be.
       
   423 	// If E-CID is supported and there is room for it in the array, it will also be added to the 
       
   424 	// array.
       
   425 	TLbsNetPosMethod* methods = NULL;
       
   426 	if  (numMethods + additionalMethods < KLbsMaxNetPosMethods)
       
   427 		{
       
   428 		TLbsNetPosMethod ecidMethod;
       
   429 		ecidMethod.SetPosMethod(KLbsPositioningMeansCell, TPositionModuleInfo::ETechnologyNetwork);
       
   430 		methods = new (ELeave) TLbsNetPosMethod[numMethods + additionalMethods];
       
   431 		
       
   432 		for (index =0; index < numMethods; index++)
       
   433 			{
       
   434 			aCapabilities.GetPosMethod(index, methods[index]);
       
   435 			}
       
   436 			
       
   437 		if (ecidSupported)
       
   438 			{
       
   439 			methods[numMethods] = ecidMethod;	
       
   440 			}
       
   441 			
       
   442 		// Add preferred method at the end
       
   443 		methods[numMethods + additionalMethods - 1] = prefMethod;
       
   444 		aCapabilities.SetPosMethods(methods, numMethods + additionalMethods);
       
   445 		}
       
   446 	else 
       
   447 		{
       
   448 		// There is only additional room for 1 or 0 methods.
       
   449 		methods = new (ELeave) TLbsNetPosMethod[KLbsMaxNetPosMethods];
       
   450 		for (index =0; index < KLbsMaxNetPosMethods; index++)
       
   451 			{
       
   452 			aCapabilities.GetPosMethod(index, methods[index]);
       
   453 			}
       
   454 
       
   455 		// Set the preferred method at the end (even if it 
       
   456 		// overwrites current entry)
       
   457 		methods[KLbsMaxNetPosMethods-1] = prefMethod;
       
   458 		aCapabilities.SetPosMethods(methods, KLbsMaxNetPosMethods);	
       
   459 		}
       
   460 			
       
   461 	delete[] methods;
       
   462 
       
   463 	iMachine.RetrieveInitQuality(aQuality);
       
   464 	SUPLLOG(ELogP1, "CSuplMtLrStateHandler::BuildCapabilitiesL() End\n");
       
   465 	return ETrue;
       
   466 }
       
   467