locationrequestmgmt/networkrequesthandler/src/privacyhandler.cpp
changeset 36 b47902b73a93
parent 0 9cfd9a3ee49c
child 52 29dbbeac905d
equal deleted inserted replaced
35:a2efdd544abf 36:b47902b73a93
       
     1 // Copyright (c) 2006-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 // Privacy handler for Location Update requests
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <e32base.h>
       
    19 #include <lbs/lbsadmin.h>
       
    20 
       
    21 #include "lbsdevloggermacros.h"
       
    22 #include <lbs/lbslocclasstypes.h>
       
    23 #include "lbsprivacynotifier.h"
       
    24 #include "privacyhandlerobserver.h"
       
    25 #include "privacyhandler.h"
       
    26 #include "lbsprivacycontrollerdata.h"
       
    27 #include "LbsInternalInterface.h"
       
    28 #include "lbsqualityprofile.h"
       
    29 #ifdef SYMBIAN_LOCATION_PRIVACY_V2
       
    30 	#include "privacyadvancednotifierhandler.h"
       
    31 #endif
       
    32 
       
    33 
       
    34 const TInt KErrLbsNotifierUnknown = KErrUnknown; // for now....
       
    35 
       
    36 //===================================================================================================
       
    37 CPrivacyHandler* CPrivacyHandler::CreateL(MPrivacyHandlerObserver* aObserver,
       
    38                                           CLbsAdmin& aLbsAdmin,
       
    39                                           RLbsNetworkRegistrationStatus& aNetRegStatus)
       
    40 	{
       
    41 	CPrivacyHandler* implementation = 0;
       
    42 
       
    43 	
       
    44 	// Find out whether we're referring notification/verification to a notifier 
       
    45 	// or a controller.
       
    46 	CLbsAdmin::TPrivacyHandler privacyHandler;
       
    47 	aLbsAdmin.Get(KLbsSettingPrivacyHandler, privacyHandler);
       
    48 
       
    49 	switch(privacyHandler)
       
    50 		{
       
    51 		case CLbsAdmin::EPrivacyHandleByNotifier:
       
    52 			{
       
    53 			implementation = CPrivacyNotifierHandler::NewL(aLbsAdmin,
       
    54 														   aNetRegStatus);
       
    55 			break;
       
    56 			}
       
    57 		case CLbsAdmin::EPrivacyHandleByController:
       
    58 			{
       
    59 			implementation = CPrivacyControllerHandler::NewL(aLbsAdmin,
       
    60 															 aNetRegStatus);
       
    61 			break;
       
    62 			}
       
    63 #ifdef SYMBIAN_LOCATION_PRIVACY_V2
       
    64 		case CLbsAdmin::EPrivacyHandleByAdvancedNotifier:
       
    65 			{
       
    66 			implementation = CPrivacyAdvancedNotifierHandler::NewL(aLbsAdmin,
       
    67 																   aNetRegStatus);
       
    68 			break;
       
    69 			}
       
    70 #endif
       
    71 		default:
       
    72 			{
       
    73 			User::Leave(KErrLbsNotifierUnknown);
       
    74 			break;
       
    75 			}
       
    76 		}
       
    77 	implementation->RegisterObserver(aObserver);    
       
    78 	return(implementation);
       
    79 	}
       
    80 
       
    81 CPrivacyHandler::CPrivacyHandler(CLbsAdmin& aLbsAdmin,
       
    82 								 RLbsNetworkRegistrationStatus& aNetRegStatus)
       
    83 : CActive(EPriorityStandard),
       
    84 	iLbsAdmin(aLbsAdmin),
       
    85 	iNetRegStatus(aNetRegStatus)
       
    86 	{		
       
    87 	}
       
    88 
       
    89 /* Get the current value for the admin setting for external locate.
       
    90 
       
    91 This functions checks the network registration (i.e. 'roaming') status
       
    92 and reads either the 'home' or 'network' admin setting as appropriate. 
       
    93 */
       
    94 void CPrivacyHandler::GetExternalLocateAdminSetting(const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, CLbsAdmin::TExternalLocateService& aExternalLocateService)
       
    95 	{
       
    96 	CLbsAdmin::TExternalLocateService								serviceStatus(CLbsAdmin::EExternalLocateOff);
       
    97 	RLbsNetworkRegistrationStatus::TLbsNetworkRegistrationStatus	netRegStatus(RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown);	
       
    98 
       
    99 	// Rread the network regisration to determine if currently roaming.
       
   100 	TInt err = iNetRegStatus.GetNetworkRegistrationStatus(netRegStatus);
       
   101 	if (err == KErrNone)
       
   102 		{
       
   103 		// Determine service status based on the normal MT-LR admin settings.
       
   104 		if (aSessionType == TLbsNetworkEnumInt::EServiceMobileTerminated)
       
   105 			{
       
   106 			switch (netRegStatus)
       
   107 				{
       
   108 				case RLbsNetworkRegistrationStatus::ERegisteredHomeNetwork:
       
   109 					{
       
   110 					err = iLbsAdmin.Get(KLbsSettingHomeExternalLocate, serviceStatus);
       
   111 					break;
       
   112 					}
       
   113 				case RLbsNetworkRegistrationStatus::ERegisteredRoamingNetwork:
       
   114 				case RLbsNetworkRegistrationStatus::ENotRegistered:
       
   115 					{
       
   116 					err = iLbsAdmin.Get(KLbsSettingRoamingExternalLocate, serviceStatus);
       
   117 					break;
       
   118 					}		
       
   119 				case RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown:
       
   120 				default:
       
   121 					{
       
   122 					LBSLOG_WARN2(ELogP4, "Unrecognised TLbsNetworkRegistrationStatus (%d), defaulting to EExternalLocateOff", netRegStatus);
       
   123 					break;
       
   124 					}
       
   125 				}
       
   126 			}
       
   127 			
       
   128 		// Determine service status based on the network induced MT-LR admin settings.
       
   129 		else if (aSessionType == TLbsNetworkEnumInt::EServiceNetworkInduced)
       
   130 			{
       
   131 			switch (netRegStatus)
       
   132 				{
       
   133 				case RLbsNetworkRegistrationStatus::ERegisteredHomeNetwork:
       
   134 					{
       
   135 					err = iLbsAdmin.Get(KLbsSettingHomeNetworkInducedLocate, serviceStatus);
       
   136 					break;
       
   137 					}
       
   138 				case RLbsNetworkRegistrationStatus::ERegisteredRoamingNetwork:
       
   139 				case RLbsNetworkRegistrationStatus::ENotRegistered:
       
   140 					{
       
   141 					err = iLbsAdmin.Get(KLbsSettingRoamingNetworkInducedLocate, serviceStatus);
       
   142 					break;
       
   143 					}		
       
   144 				case RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown:
       
   145 				default:
       
   146 					{
       
   147 					LBSLOG_WARN2(ELogP4, "Unrecognised TLbsNetworkRegistrationStatus (%d), defaulting to EExternalLocateOff", netRegStatus);
       
   148 					break;
       
   149 					}
       
   150 				}
       
   151 			}
       
   152 
       
   153 		else
       
   154 			{
       
   155 			LBSLOG_WARN2(ELogP4, "Unsupported TLbsNetworkEnumInt::TLbsNetProtocolServiceInt (%d), defaulting to EExternalLocateOff", aSessionType);
       
   156 			}
       
   157 		}
       
   158 
       
   159 	else
       
   160 		{
       
   161 		LBSLOG_WARN2(ELogP4, "Failed to get TExternalLocateService, couldn't read roaming status (err %d), defaulting to EExternalLocateOff", err);		
       
   162 		}
       
   163 
       
   164 	// Error during admin get. 
       
   165 	if (err)
       
   166 		{
       
   167 		serviceStatus = CLbsAdmin::EExternalLocateOff;
       
   168 		}
       
   169 	
       
   170 	aExternalLocateService = serviceStatus;
       
   171 	}
       
   172 
       
   173 /** Get the default privacy response based on the admin setting.
       
   174  */
       
   175 void CPrivacyHandler::GetPrivacyTimeoutAction(
       
   176 		TLbsNetworkEnumInt::TLbsPrivacyResponseInt& aResponse, 
       
   177 		const TLbsNetPosRequestPrivacyInt& aRequestPrivacy)
       
   178 	{
       
   179 	CLbsAdmin::TPrivacyTimeoutAction privacyTimeoutAction;
       
   180 	iLbsAdmin.Get(KLbsSettingPrivacyTimeoutAction, privacyTimeoutAction);
       
   181 	
       
   182 	switch(privacyTimeoutAction)
       
   183 		{
       
   184 		case CLbsAdmin::EPrivacyTimeoutReject:
       
   185 			{
       
   186 			aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   187 			break;
       
   188 			}
       
   189 		
       
   190 		case CLbsAdmin::EPrivacyTimeoutNetworkDefined:
       
   191 			{
       
   192 			//Use the network defined action to decide whether to reject/accept
       
   193 			switch(aRequestPrivacy.RequestAction())
       
   194 				{
       
   195 				case TLbsNetPosRequestPrivacyInt::ERequestActionAllow:
       
   196 					{
       
   197 					aResponse = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
       
   198 					break;
       
   199 					}
       
   200 				case TLbsNetPosRequestPrivacyInt::ERequestActionReject:
       
   201 				case TLbsNetPosRequestPrivacyInt::ERequestActionNotUsed:
       
   202 					{
       
   203 					aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   204 					break;
       
   205 					}
       
   206 				}
       
   207 			break;
       
   208 			}
       
   209 		default:
       
   210 			{
       
   211 			aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   212 			break;
       
   213 			}
       
   214 		}	
       
   215 	}
       
   216 
       
   217 //
       
   218 // CPrivacyRequest
       
   219 //
       
   220 CPrivacyRequest::CPrivacyRequest()
       
   221 	{
       
   222 	}
       
   223 
       
   224 CPrivacyRequest::~CPrivacyRequest()
       
   225 	{
       
   226 	}
       
   227 
       
   228 CPrivacyRequest* CPrivacyRequest::NewL()
       
   229 	{
       
   230 	CPrivacyRequest* self = new (ELeave) CPrivacyRequest;
       
   231 	CleanupStack::PushL(self);
       
   232 	self->ConstructL();
       
   233 	CleanupStack::Pop(self);
       
   234 	return self;
       
   235 	}
       
   236 
       
   237 void CPrivacyRequest::ConstructL()
       
   238 	{
       
   239 	}
       
   240 
       
   241 CPrivacyRequest::TPrivReqState CPrivacyRequest::State() const
       
   242 	{
       
   243 	return iState;
       
   244 	}
       
   245 
       
   246 void CPrivacyRequest::SetState(CPrivacyRequest::TPrivReqState aState)
       
   247 	{
       
   248 	iState = aState;
       
   249 	}
       
   250 
       
   251 const TLbsNetSessionIdInt& CPrivacyRequest::SessionId() const
       
   252 	{
       
   253 	return iSessionId;
       
   254 	}
       
   255 
       
   256 void CPrivacyRequest::SetSessionId(const TLbsNetSessionIdInt& aSessionId)
       
   257 	{
       
   258 	iSessionId = aSessionId;
       
   259 	}
       
   260 
       
   261 const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt& CPrivacyRequest::SessionType() const
       
   262 	{
       
   263 	return iSessionType;
       
   264 	}
       
   265 
       
   266 void CPrivacyRequest::SetSessionType(const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt& aSessionType)
       
   267 	{
       
   268 	iSessionType = aSessionType;
       
   269 	}
       
   270 
       
   271 const TLbsExternalRequestInfo& CPrivacyRequest::RequestInfo() const
       
   272 	{
       
   273 	return iRequestInfo;
       
   274 	}
       
   275 
       
   276 void CPrivacyRequest::SetRequestInfo(const TLbsExternalRequestInfo& aRequestInfo)
       
   277 	{
       
   278 	Mem::Copy(&iRequestInfo, &aRequestInfo, aRequestInfo.ClassSize());
       
   279 	}
       
   280 
       
   281 const TLbsNetPosRequestPrivacyInt& CPrivacyRequest::RequestPrivacy() const
       
   282 	{
       
   283 	return iRequestPrivacy;
       
   284 	}
       
   285 
       
   286 void CPrivacyRequest::SetRequestPrivacy(const TLbsNetPosRequestPrivacyInt& aRequestPrivacy)
       
   287 	{
       
   288 	iRequestPrivacy = aRequestPrivacy;
       
   289 	}
       
   290 
       
   291 TBool CPrivacyRequest::IsEmergency() const
       
   292 	{
       
   293 	return iIsEmergency;
       
   294 	}
       
   295 
       
   296 void CPrivacyRequest::SetIsEmergency(TBool aIsEmergency)
       
   297 	{
       
   298 	iIsEmergency = aIsEmergency;
       
   299 	}
       
   300 
       
   301 TTime CPrivacyRequest::StartTime() const
       
   302 	{
       
   303 	return iStartTime;
       
   304 	}
       
   305 
       
   306 void CPrivacyRequest::SetStartTime()
       
   307 	{
       
   308 	iStartTime.UniversalTime();
       
   309 	}
       
   310 
       
   311 /** Comparison function for RPointerArray<CPrivacyRequest>::Find()
       
   312  */
       
   313 TBool CPrivacyRequest::IsSessionIdEqual(
       
   314 		const TLbsNetSessionIdInt* aSessionId,
       
   315 		const CPrivacyRequest& aItem)
       
   316 	{
       
   317 	return (*aSessionId == aItem.SessionId());
       
   318 	}
       
   319 	
       
   320 //
       
   321 // CPrivacyNotifierHandler
       
   322 //
       
   323 CPrivacyNotifierHandler::CPrivacyNotifierHandler(CLbsAdmin& aLbsAdmin,
       
   324 												 RLbsNetworkRegistrationStatus& aNetRegStatus) : 
       
   325 	CPrivacyHandler(aLbsAdmin, aNetRegStatus)
       
   326     {
       
   327 	iPrivacyResponseOutstanding = EFalse;
       
   328     }
       
   329     
       
   330 CPrivacyNotifierHandler* CPrivacyNotifierHandler::NewL(CLbsAdmin& aLbsAdmin,
       
   331 													   RLbsNetworkRegistrationStatus& aNetRegStatus)
       
   332     {
       
   333 	CPrivacyNotifierHandler* self = new (ELeave)CPrivacyNotifierHandler(aLbsAdmin,
       
   334 																		aNetRegStatus);
       
   335 	CleanupStack::PushL(self);
       
   336 	self->ConstructL();
       
   337 	CleanupStack::Pop(self);
       
   338 	return(self);
       
   339     }
       
   340 
       
   341 /**
       
   342 */
       
   343 void CPrivacyNotifierHandler::ConstructL()
       
   344 	{
       
   345 	CActiveScheduler::Add(this);
       
   346 	iPrivacyResponseTimer = CLbsCallbackTimer::NewL(*this);
       
   347 	}
       
   348 
       
   349 /**
       
   350  * Called when the response timer expires.
       
   351  * An accept or reject of the original query is reported to the NRH 
       
   352  * depending on the request action parameter received with the original request.
       
   353  * @param aTimerId always 1 (we only use one timer in this subcomponent)
       
   354  */
       
   355 void CPrivacyNotifierHandler::OnTimerEventL(TInt aTimerId)
       
   356 	{
       
   357 	iNotifier->Cancel();
       
   358 	switch (aTimerId)
       
   359 		{
       
   360 		case 1:
       
   361 			{
       
   362 			// The privacy notifier has timed out without a response being
       
   363 			// received. Generate a response as required depending upon
       
   364 			// the LbsAdmin setting: TPrivacyTimeoutAction
       
   365 			CPrivacyRequest* request = iRequestBuffer[0];
       
   366 			TLbsNetworkEnumInt::TLbsPrivacyResponseInt response;
       
   367 			GetPrivacyTimeoutAction(response, request->RequestPrivacy());
       
   368 			
       
   369 			iObserver->OnRespondNetworkLocationRequest(
       
   370 					request->SessionId(), response, KErrNone);
       
   371 
       
   372 			// Delete the current request and start the next one in the buffer
       
   373 			iRequestBuffer.Remove(0);
       
   374 			delete request; 
       
   375           	SendNextPrivacyRequest();
       
   376 			break;
       
   377 			}
       
   378 		default:
       
   379 			// do nothing
       
   380 			break;	
       
   381 		}
       
   382 	}
       
   383 	
       
   384 TInt CPrivacyNotifierHandler::OnTimerError(TInt /*aTimerId*/, 
       
   385 											TInt aError)
       
   386 	{
       
   387 	// Not used - OnTimerEventL doesn't generate any error.
       
   388 	return(aError);
       
   389 	}
       
   390 
       
   391 
       
   392 void CPrivacyNotifierHandler::ProcessNetworkLocationRequest(
       
   393 		TLbsNetSessionIdInt aSessionId,
       
   394 		const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 		
       
   395         const TLbsExternalRequestInfo&  aRequestInfo, 
       
   396         const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy,
       
   397         TBool aIsEmergency)
       
   398            
       
   399 	{
       
   400 	BufferPrivacyRequest(aSessionId, aSessionType, aRequestInfo, aNetPosRequestPrivacy, aIsEmergency);
       
   401 	
       
   402 	if (!IsPrivacyRequestActive())
       
   403 		{
       
   404 		SendNextPrivacyRequest();
       
   405 		}
       
   406 	}
       
   407 void CPrivacyNotifierHandler::ProcessNetworkPositionUpdate(TLbsNetSessionIdInt /*aSessionId*/, 
       
   408                                            const TPositionInfo& /*aPosInfo*/)
       
   409     {
       
   410     }
       
   411 		
       
   412 void CPrivacyNotifierHandler::ProcessRequestComplete(TLbsNetSessionIdInt aSessionId, TInt /*aReason*/)
       
   413     {
       
   414     // If the current request is still in the buffer here, 
       
   415     // it is because it is still waiting for a reponse.
       
   416     // So, we need to cancel the notifier and clean up.
       
   417     if (iRequestBuffer.Count() > 0
       
   418     	&& aSessionId == iRequestBuffer[0]->SessionId())
       
   419     	{
       
   420     	CPrivacyRequest* request = iRequestBuffer[0];
       
   421     	
       
   422     	// If the completed request is the currently active one,
       
   423     	// may need to cancel the notifer and timer as well.
       
   424 		if (iNotifier)
       
   425 			{
       
   426 			iNotifier->Cancel();
       
   427 			}
       
   428 		
       
   429 		iPrivacyResponseTimer->Cancel();
       
   430 		
       
   431 		// Delete the completed request
       
   432 		iRequestBuffer.Remove(0);
       
   433 		delete request; 
       
   434     	}
       
   435     }
       
   436 
       
   437 void CPrivacyNotifierHandler::RegisterObserver(MPrivacyHandlerObserver* aObserver)
       
   438     {
       
   439     iObserver = aObserver;	
       
   440     }
       
   441     
       
   442 CPrivacyNotifierHandler::~CPrivacyNotifierHandler()
       
   443     {	
       
   444     if(iNotifier)
       
   445     	{
       
   446     	iNotifier->Cancel();
       
   447     	}
       
   448     delete iNotifier;
       
   449     iRequestBuffer.ResetAndDestroy();
       
   450 	iPrivacyResponseTimer->Cancel();
       
   451 	delete iPrivacyResponseTimer;
       
   452     Cancel();
       
   453     }
       
   454 
       
   455 // From MLbsPrivacyNotifierObserver
       
   456 void CPrivacyNotifierHandler::OnNotificationDialogResponse(TInt aErr , 
       
   457 	                         const TLbsPrivacyNotifierResponse& aResponse)
       
   458 	{
       
   459 	iPrivacyResponseTimer->Cancel();
       
   460 	iPrivacyResponseOutstanding = EFalse;
       
   461 	
       
   462 	CPrivacyRequest* request = iRequestBuffer[0];
       
   463 	if(aErr == KErrNone)
       
   464 		{
       
   465 		switch(aResponse)
       
   466 			{
       
   467 			case EResponseAccepted:
       
   468 				{
       
   469 				iObserver->OnRespondNetworkLocationRequest(request->SessionId(), 
       
   470 						TLbsNetworkEnumInt::EPrivacyResponseAccepted, KErrNone);				
       
   471 				break;
       
   472 				}
       
   473 				
       
   474 			case EResponseTimedOut:
       
   475 				{
       
   476 				iNotifier->Cancel();
       
   477 				TLbsNetworkEnumInt::TLbsPrivacyResponseInt response;
       
   478 				GetPrivacyTimeoutAction(response, request->RequestPrivacy());
       
   479 				iObserver->OnRespondNetworkLocationRequest(
       
   480 									request->SessionId(), response, KErrNone);
       
   481 				break; // case EResponseTimedOut
       
   482 				}
       
   483 
       
   484 			default:				
       
   485 			case EResponseRejected:
       
   486 				{
       
   487 				iObserver->OnRespondNetworkLocationRequest(request->SessionId(), 
       
   488 						TLbsNetworkEnumInt::EPrivacyResponseRejected, KErrNone);				
       
   489 				break;
       
   490 				}
       
   491 			}
       
   492 		}
       
   493 	else			
       
   494 	// Treat any error as an 'unknown' response
       
   495 		{
       
   496 		iObserver->OnRespondNetworkLocationRequest(request->SessionId(), 
       
   497 					TLbsNetworkEnumInt::EPrivacyResponseUnknown, KErrArgument);
       
   498 		}
       
   499 	
       
   500 	// Delete the current request and start the next one in the buffer
       
   501 	iRequestBuffer.Remove(0);
       
   502 	delete request; 
       
   503    	SendNextPrivacyRequest();
       
   504 	}
       
   505 
       
   506 /* Return ETrue if we are currently waiting on the RNotifier dialog.
       
   507 
       
   508 Uses the response timer, because this should only be running
       
   509 when we are waiting for the RNotifier.
       
   510 */
       
   511 TBool CPrivacyNotifierHandler::IsPrivacyRequestActive()
       
   512 	{
       
   513 	return (iPrivacyResponseTimer->IsActive());
       
   514 	}
       
   515 
       
   516 void CPrivacyNotifierHandler::WaitForPrivacyResponse()
       
   517 	{
       
   518 	// Start a timeout timer, in case the privacy notifier doesn't reply.
       
   519 	iPrivacyResponseTimer->Cancel();
       
   520 	TUint privacyVerifyTimeoutInMilliSeconds = 0;		
       
   521 	// Note: the following should never fail as we create a default setting in case of absence
       
   522 	iLbsAdmin.Get(KLbsSettingPrivacyAppTimeout, privacyVerifyTimeoutInMilliSeconds);	
       
   523 	TTimeIntervalMicroSeconds privacyVerifyTimeout = privacyVerifyTimeoutInMilliSeconds * 1000;
       
   524 	if (privacyVerifyTimeout > 0)
       
   525 		{
       
   526 		iPrivacyResponseTimer->EventAfter(privacyVerifyTimeout, 1);		
       
   527 		}	
       
   528 	// flag to show we're waiting for a response
       
   529 	iPrivacyResponseOutstanding = ETrue;
       
   530 	}
       
   531 
       
   532 void CPrivacyNotifierHandler::SendNextPrivacyRequest()
       
   533 	{
       
   534 	// May need to loop over multiple *notify* requests,
       
   535 	// because we don't wait for a response for those.	
       
   536 	while (iRequestBuffer.Count() > 0 && !IsPrivacyRequestActive())
       
   537 		{
       
   538 		CPrivacyRequest* request = iRequestBuffer[0];
       
   539 		
       
   540 		TRequiredPrivacyAction notifierAction(ERequiredPrivacyActionNone);
       
   541 		TBool waitForResponse(ETrue);
       
   542 		TLbsNetworkEnumInt::TLbsPrivacyResponseInt response(TLbsNetworkEnumInt::EPrivacyResponseAccepted);
       
   543 		TInt responseReason = KErrNone;
       
   544 		
       
   545 		CLbsAdmin::TExternalLocateService externalLocate(CLbsAdmin::EExternalLocateOff);
       
   546 		GetExternalLocateAdminSetting(request->SessionType(), externalLocate);
       
   547 
       
   548 		// ERequestAdviceStealth is not supported, so reject any such request
       
   549 		if(request->RequestPrivacy().RequestAdvice() == 
       
   550 			TLbsNetPosRequestPrivacyInt::ERequestAdviceStealth)
       
   551 			{
       
   552 			notifierAction = ERequiredPrivacyActionNone;
       
   553 			waitForResponse = EFalse;
       
   554 			response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   555 			responseReason = KErrNotSupported;
       
   556 			}
       
   557 		else
       
   558 			{
       
   559 			TLbsNetPosRequestPrivacyInt privacy = request->RequestPrivacy();
       
   560 			GetRequiredNotificationAction(	request->IsEmergency(), 
       
   561 											externalLocate,
       
   562 											notifierAction, 
       
   563 											waitForResponse, 
       
   564 											response,
       
   565 											privacy);
       
   566 			request->SetRequestPrivacy(privacy);
       
   567 			}
       
   568 		
       
   569 		// If required, raise a notification/verification
       
   570 		TInt displayErr = KErrNone;
       
   571 		if(iNotifier && iNotifierAction != notifierAction)
       
   572 			{
       
   573 	    	iNotifier->Cancel();
       
   574 			delete iNotifier;	
       
   575 			iNotifier = NULL;	
       
   576 			}
       
   577 			
       
   578 		// Start a notify or verify notifier depending on the type of the privacy request.
       
   579 		if(iNotifier == NULL)
       
   580 			{
       
   581 			switch(notifierAction)
       
   582 				{
       
   583 				case ERequiredPrivacyActionNotify:
       
   584 					{
       
   585 					TRAPD(err, iNotifier = CLbsPrivacyNotifier::NewL(EPrivacyDialogNotification));
       
   586 					if(err == KErrNone)
       
   587 					    {
       
   588                         iNotifier->SetObserver(this);
       
   589 					    }
       
   590 					break;
       
   591 					}
       
   592 
       
   593 				case ERequiredPrivacyActionVerify:
       
   594 					{
       
   595 					TRAPD(err, iNotifier = CLbsPrivacyNotifier::NewL(EPrivacyDialogVerification));
       
   596 					if(err == KErrNone)
       
   597 					    {
       
   598                         iNotifier->SetObserver(this);
       
   599 					    }
       
   600 					break;
       
   601 					}
       
   602 			
       
   603 				default:
       
   604 				case ERequiredPrivacyActionNone:
       
   605 					{
       
   606 					// do nothing
       
   607 					break;
       
   608 					}
       
   609 				}
       
   610 			}
       
   611 			
       
   612 		iNotifierAction = notifierAction;
       
   613 		if(iNotifier)
       
   614 			{
       
   615 			TRAPD(displayLeaveErr, iNotifier->DisplayL(displayErr, request->RequestInfo()));
       
   616 			// If there is an error, treat the notification as having returned an
       
   617 			// 'unknown' response.
       
   618 			if(displayLeaveErr != KErrNone || displayErr != KErrNone)
       
   619 				{
       
   620 				response = TLbsNetworkEnumInt::EPrivacyResponseUnknown;
       
   621 				waitForResponse = EFalse;
       
   622 				}	
       
   623 			}
       
   624 		
       
   625 		// If the privacy controller application is responsible for accepting
       
   626 		// or rejecting the privacy request, wait for its response
       
   627 		if (waitForResponse)
       
   628 			{
       
   629 			WaitForPrivacyResponse();		
       
   630 			}
       
   631 		else
       
   632 			{
       
   633 			// Send an immediate response
       
   634 			iObserver->OnRespondNetworkLocationRequest(request->SessionId(), response, responseReason);
       
   635 			
       
   636 			// Remove the request since we don't need to wait for the response.
       
   637 			iRequestBuffer.Remove(0);
       
   638 			delete request; 
       
   639          	}
       
   640 		}
       
   641 	}
       
   642 
       
   643 void CPrivacyNotifierHandler::SendPrivacyResponse()
       
   644 	{
       
   645 	}
       
   646 	
       
   647 TInt CPrivacyNotifierHandler::BufferPrivacyRequest(
       
   648 		const TLbsNetSessionIdInt& aSessionId,
       
   649 		const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType,		
       
   650 		const TLbsExternalRequestInfo& aRequestInfo,
       
   651 		const TLbsNetPosRequestPrivacyInt& aRequestPrivacy,
       
   652 		TBool aIsEmergency)
       
   653 	{
       
   654 	CPrivacyRequest* requestData = NULL;
       
   655 	TRAPD(err, requestData = CPrivacyRequest::NewL());
       
   656 	if (err == KErrNone)
       
   657 		{
       
   658 		requestData->SetSessionId(aSessionId);
       
   659 		requestData->SetSessionType(aSessionType);
       
   660 		requestData->SetRequestInfo(aRequestInfo);
       
   661 		requestData->SetRequestPrivacy(aRequestPrivacy);
       
   662 		requestData->SetIsEmergency(aIsEmergency);
       
   663 		requestData->SetStartTime();
       
   664 		err = iRequestBuffer.Append(requestData);
       
   665 		}
       
   666 	
       
   667 	return err;
       
   668 	}
       
   669 
       
   670 void CPrivacyNotifierHandler::RemovePrivacyRequestFromBuffer(
       
   671 		const TLbsNetSessionIdInt& aSessionId)
       
   672 	{
       
   673 	TInt index = iRequestBuffer.Find(aSessionId, CPrivacyRequest::IsSessionIdEqual);
       
   674 	while (KErrNotFound != index)
       
   675 		{
       
   676 		CPrivacyRequest* reqData = iRequestBuffer[index];
       
   677 		iRequestBuffer.Remove(index);
       
   678 		delete reqData; 
       
   679     	index = iRequestBuffer.Find(aSessionId, CPrivacyRequest::IsSessionIdEqual);
       
   680 		}
       
   681 	}
       
   682 	
       
   683 void CPrivacyNotifierHandler::OnRespondNetworkLocationRequest(const TLbsNetSessionIdInt& /* aRequestId */, 
       
   684                             TLbsNetworkEnumInt::TLbsPrivacyResponseInt /* aRequestResult */,
       
   685                             TInt /*aResponseReason*/)
       
   686 	{
       
   687 	}
       
   688 	
       
   689 /**
       
   690  * Unused for Notifier - cancel from the notifier is reported via 
       
   691  * MLbsPrivacyNotifierObserver::OnNotificationDialogResponse.
       
   692  */
       
   693 void CPrivacyNotifierHandler::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& /*aRequestId*/)
       
   694 	{
       
   695 	}
       
   696 
       
   697 void CPrivacyNotifierHandler::RunL()
       
   698 	{
       
   699 	}
       
   700 	
       
   701 void CPrivacyNotifierHandler::DoCancel()
       
   702 	{
       
   703 	}
       
   704 	
       
   705 void CPrivacyNotifierHandler::SetServerObserver(MLbsSessionObserver* /*aNrhServer*/)
       
   706     {
       
   707     // Unused for notifier
       
   708     }
       
   709 // A privacy request must be accepted or rejected, based on a
       
   710 // combination of iPrivacyRequest->RequestPrivacy() settings, LbsAdmin settings
       
   711 // and whether it is an emergency request.
       
   712 //
       
   713 
       
   714 void CPrivacyNotifierHandler::GetRequiredNotificationAction(
       
   715 									TBool aIsEmergency,
       
   716 									CLbsAdmin::TExternalLocateService aExternalLocate,
       
   717 									TRequiredPrivacyAction& aPrivacyAction, 
       
   718 									TBool& aTimeoutRequired,
       
   719 									TLbsNetworkEnumInt::TLbsPrivacyResponseInt& aResponse,
       
   720 									TLbsNetPosRequestPrivacyInt& aPrivacy
       
   721 									)
       
   722 	{
       
   723 	
       
   724     if (aIsEmergency)
       
   725     	{
       
   726     	TBool silent = (aPrivacy.RequestAdvice() == TLbsNetPosRequestPrivacyInt::ERequestAdviceSilent);
       
   727 		aTimeoutRequired = EFalse; // always the case for emergency - it's only ever notified
       
   728 										
       
   729     	// Decide whether to accept or reject an emergency request.
       
   730     	switch (aPrivacy.RequestAction())
       
   731     		{
       
   732     		case TLbsNetPosRequestPrivacyInt::ERequestActionAllow:
       
   733     			{
       
   734 				aResponse = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
       
   735 				if(silent)
       
   736 					{
       
   737     				aPrivacyAction = ERequiredPrivacyActionNone;										
       
   738 					}
       
   739 				else
       
   740 					{
       
   741     				aPrivacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify);
       
   742     				aPrivacyAction = ERequiredPrivacyActionNotify;
       
   743 					}
       
   744     			break;
       
   745     			}
       
   746 			case TLbsNetPosRequestPrivacyInt::ERequestActionReject:
       
   747 				{
       
   748 				aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   749 				if(silent)
       
   750 					{
       
   751     				aPrivacyAction = ERequiredPrivacyActionNone;										
       
   752 					}
       
   753 				else
       
   754 					{
       
   755     				aPrivacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify);
       
   756     				aPrivacyAction = ERequiredPrivacyActionNotify;					
       
   757 					}
       
   758     			break;
       
   759     			}
       
   760     		default:
       
   761     			{
       
   762 	    		LBSLOG2(ELogP4, "CPrivCntrllrHandler::ProcessNetworkLocationRequest :  Unknown RequestAction() (0x%x), rejecting privacy request", 
       
   763 	    						 aPrivacy.RequestAction());    			
       
   764     			aPrivacyAction = ERequiredPrivacyActionNone;
       
   765 				aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   766     			break;
       
   767     			}
       
   768     		}
       
   769     		// For the privacy notifier, if the original advice is not
       
   770     		// notify or verify, don't do anything
       
   771     	}
       
   772     else
       
   773     	{
       
   774     	// Decide wether the privacy controller application should be notified,
       
   775     	// and if not, whether the request should be accepted or rejected.
       
   776 	    switch (aExternalLocate)
       
   777 	    	{
       
   778 	    	case CLbsAdmin::EExternalLocateOn:
       
   779 	    		{
       
   780 				// Whether we wait for the privacy controller application response
       
   781 				// depends on the RequestAdvice() from the network
       
   782 				switch (aPrivacy.RequestAdvice())
       
   783 					{
       
   784 					case TLbsNetPosRequestPrivacyInt::ERequestAdviceVerify:
       
   785 						{
       
   786     					aPrivacyAction = ERequiredPrivacyActionVerify;
       
   787 						aTimeoutRequired = ETrue;
       
   788 						break;
       
   789 						}
       
   790 					case TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify:
       
   791 						{
       
   792     					aPrivacyAction = ERequiredPrivacyActionNotify;
       
   793 						aTimeoutRequired = EFalse;
       
   794 						if(aPrivacy.RequestAction() == TLbsNetPosRequestPrivacyInt::ERequestActionAllow)
       
   795 							{
       
   796 							aResponse = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
       
   797 							}
       
   798 						else
       
   799 							{
       
   800 							aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   801 							}
       
   802 						break;
       
   803 						}
       
   804 					case TLbsNetPosRequestPrivacyInt::ERequestAdviceSilent:
       
   805 						{
       
   806 						// Always accept these types of privacy request for the controller - and 
       
   807 						// tell the controller about them. For the notifier, just do what it says, 
       
   808 						// without any notification
       
   809 						// Either way, no timer is needed
       
   810 						aTimeoutRequired = EFalse;
       
   811 						aPrivacyAction = ERequiredPrivacyActionNone;
       
   812 						if(aPrivacy.RequestAction() == TLbsNetPosRequestPrivacyInt::ERequestActionAllow)
       
   813 							{
       
   814 							aResponse = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
       
   815 							}
       
   816 						else
       
   817 							{
       
   818 							aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   819 							}
       
   820 						break;
       
   821 						}
       
   822 					default:
       
   823 						{
       
   824 						// Error: Unknown RequestAdvice() value. Send a 
       
   825 						// 'reject' back to the network
       
   826 			    		LBSLOG2(ELogP4, "CPrivCntrllrHandler::ProcessNetworkLocationRequest : \
       
   827 			    						 Unknown RequestAdvice() (0x%x), \
       
   828 			    						 rejecting privacy request", 
       
   829 			    						 aPrivacy.RequestAdvice());
       
   830     					aPrivacyAction = ERequiredPrivacyActionNone;
       
   831 						aTimeoutRequired = EFalse;
       
   832 						aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   833 						break;
       
   834 						}
       
   835 					}
       
   836 	    		break;
       
   837 	    		}
       
   838 	    	case CLbsAdmin::EExternalLocateOnButAlwaysVerify:
       
   839 	    		{
       
   840     			aPrivacyAction = ERequiredPrivacyActionVerify;
       
   841 	    		aTimeoutRequired = ETrue;
       
   842 	    		aPrivacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceVerify);
       
   843 	    		break;
       
   844 	    		}
       
   845 	    	case CLbsAdmin::EExternalLocateOff:
       
   846 	    		{
       
   847     			aPrivacyAction = ERequiredPrivacyActionNone;
       
   848 	    		aTimeoutRequired = EFalse;
       
   849 	    		aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   850 	    		break;
       
   851 	    		}
       
   852 	    	case CLbsAdmin::EExternalLocateOffButNotify:
       
   853 	    		{
       
   854     			aPrivacyAction = ERequiredPrivacyActionNotify;
       
   855 	    		aTimeoutRequired = EFalse;
       
   856 	    		aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   857 	    		aPrivacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify);
       
   858 	    		aPrivacy.SetRequestAction(TLbsNetPosRequestPrivacyInt::ERequestActionReject);
       
   859 	    		break;
       
   860 	    		}
       
   861 	    	case CLbsAdmin::EExternalLocateUnknown:
       
   862 	    	default:
       
   863 	    		{
       
   864 	    		LBSLOG2(ELogP4, "CPrivCntrllrHandler::ProcessNetworkLocationRequest : \
       
   865 	    						 Unknown Admin setting (0x%x), \
       
   866 	    						 rejecting privacy request", aExternalLocate);
       
   867     			aPrivacyAction = ERequiredPrivacyActionNone;
       
   868 	    		aTimeoutRequired = EFalse;
       
   869 	    		aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
   870 	    		break;
       
   871 	    		}
       
   872 	    	}
       
   873     	
       
   874     	}
       
   875 	}
       
   876 
       
   877 //================================================================================
       
   878 /**
       
   879  * The CPrivacyControllerHandler class handles privacy requests when the
       
   880  * configuration specifies that a Privacy Controller Application is 
       
   881  * present, rather than a Notifier Handler.
       
   882  * Its main task is to pass on messages to the Privacy Controller using 
       
   883  * he NRH server. Communications between this class and the NRH server 
       
   884  * are mediated by internally-defined properties
       
   885  */
       
   886 CPrivacyControllerHandler::CPrivacyControllerHandler(CLbsAdmin& aLbsAdmin,
       
   887 													 RLbsNetworkRegistrationStatus& aNetRegStatus)  :
       
   888 	CPrivacyHandler(aLbsAdmin, aNetRegStatus)
       
   889     {
       
   890 	iSessionActive = EFalse;
       
   891 	iIsEmergency = EFalse;
       
   892 	iAlwaysVerify = EFalse;
       
   893 	TInt err = iLbsAdmin.Get(KLbsSettingBehaviourMode, iLbsBehaviourMode);
       
   894 	if (err != KErrNone)
       
   895 		{
       
   896 		iLbsBehaviourMode = CLbsAdmin::ELbsBehaviourCustom1;
       
   897 		}	
       
   898     }
       
   899 CPrivacyControllerHandler::~CPrivacyControllerHandler()
       
   900 	{
       
   901 	iRequestBuffer.ResetAndDestroy();
       
   902 	iPrivacyResponseTimer->Cancel();
       
   903 	delete iPrivacyResponseTimer;
       
   904 	delete iEmergencyPrivReq;
       
   905 	}
       
   906     
       
   907 CPrivacyControllerHandler* CPrivacyControllerHandler::NewL(CLbsAdmin& aLbsAdmin,
       
   908 														   RLbsNetworkRegistrationStatus& aNetRegStatus)
       
   909     {
       
   910 	CPrivacyControllerHandler* self = new (ELeave)CPrivacyControllerHandler(aLbsAdmin,
       
   911 																			aNetRegStatus);
       
   912 	CleanupStack::PushL(self);
       
   913 	self->ConstructL();
       
   914 	CleanupStack::Pop(self);
       
   915 	return(self);
       
   916     }
       
   917     
       
   918 void CPrivacyControllerHandler::ConstructL()
       
   919 	{
       
   920 	CActiveScheduler::Add(this);
       
   921 	iPrivacyResponseTimer = CLbsCallbackTimer::NewL(*this);
       
   922 	iEmergencyPrivReq = CPrivacyRequest::NewL();
       
   923 	}
       
   924 
       
   925 /**
       
   926  * Passes on a privacy request to the server.
       
   927  * @param aSessionId identified the location update session within the LBS System
       
   928  * @param aRequestInfo 	data about the source of the request
       
   929  * @param aNetPosRequestPrivacy defines what notification is necessary (e.g.
       
   930  *                              notify or confirm). 
       
   931  */
       
   932 void CPrivacyControllerHandler::ProcessNetworkLocationRequest(TLbsNetSessionIdInt aSessionId, 
       
   933 												const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType,
       
   934 												const TLbsExternalRequestInfo&  aRequestInfo, 
       
   935 												const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy,
       
   936 												TBool aIsEmergency)
       
   937 	{	
       
   938 	CPrivacyRequest* privReq = NULL;
       
   939 	if (aIsEmergency)
       
   940 	    {
       
   941 	    privReq = iEmergencyPrivReq;
       
   942 	    }
       
   943 	else
       
   944 	    {
       
   945 	    TRAPD(err, privReq = CPrivacyRequest::NewL());
       
   946 	    if(err != KErrNone)
       
   947 	        {
       
   948             // We can do nothing here
       
   949             return;
       
   950 	        }
       
   951 	    }
       
   952 	privReq->SetIsEmergency(aIsEmergency);
       
   953 	privReq->SetSessionId(aSessionId);
       
   954 	privReq->SetSessionType(aSessionType);
       
   955 	privReq->SetRequestInfo(aRequestInfo);
       
   956 	// If the admin setting timeout strategy is reject
       
   957 	TLbsNetworkEnumInt::TLbsPrivacyResponseInt adminTimeoutAction;
       
   958 	GetPrivacyTimeoutAction(adminTimeoutAction, aNetPosRequestPrivacy);
       
   959 	if((adminTimeoutAction == TLbsNetworkEnumInt::EPrivacyResponseRejected)
       
   960 		&& (aNetPosRequestPrivacy.RequestAdvice() == TLbsNetPosRequestPrivacyInt::ERequestAdviceVerify))
       
   961 		{
       
   962 		// We should update the request timeout action so it is also reject
       
   963 		TLbsNetPosRequestPrivacyInt rejectNetPosRequestPrivacy;
       
   964 		rejectNetPosRequestPrivacy.SetRequestAdvice(aNetPosRequestPrivacy.RequestAdvice());
       
   965 		rejectNetPosRequestPrivacy.SetRequestAction(TLbsNetPosRequestPrivacyInt::ERequestActionReject);
       
   966 		privReq->SetRequestPrivacy(rejectNetPosRequestPrivacy);
       
   967 		}
       
   968 	else
       
   969 		{
       
   970 		// Otherwise keep it the same
       
   971 		privReq->SetRequestPrivacy(aNetPosRequestPrivacy);
       
   972 		}
       
   973 	privReq->SetStartTime();
       
   974 	iRequestBuffer.Append(privReq);
       
   975 	iAlwaysVerify = EFalse;	
       
   976 	
       
   977 	if (iNrhServer == 0)
       
   978 		{
       
   979 		if (privReq->IsEmergency())
       
   980 			{
       
   981 			// No handler to ProcessNetworkLocationRequest - just continue with processing emergency.
       
   982 			TLbsNetworkEnumInt::TLbsPrivacyResponseInt response(TLbsNetworkEnumInt::EPrivacyResponseAccepted);    
       
   983 			iObserver->OnRespondNetworkLocationRequest(privReq->SessionId(), response, KErrNone);
       
   984 			privReq->SetState(CPrivacyRequest::EPrivReqStateResponseSent);
       
   985 			return;			
       
   986 			}
       
   987 		else
       
   988 			{
       
   989 			// No handler to ProcessNetworkLocationRequest - respond depending on type:
       
   990 			// Verify - reject
       
   991 			// Notify - default action
       
   992 			TLbsNetworkEnumInt::TLbsPrivacyResponseInt response;
       
   993 			TInt responseReason = KErrNone;
       
   994 			switch (privReq->RequestPrivacy().RequestAdvice())
       
   995 				{
       
   996 				case TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify:
       
   997 					{
       
   998 					switch (privReq->RequestPrivacy().RequestAction())
       
   999 			    		{
       
  1000 			    		case TLbsNetPosRequestPrivacyInt::ERequestActionAllow:
       
  1001 			    			{
       
  1002 			    			response = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
       
  1003 			    			break;
       
  1004 			    			}
       
  1005 			    		case TLbsNetPosRequestPrivacyInt::ERequestActionReject:
       
  1006 			    			{
       
  1007 			    			response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1008 			    			break;
       
  1009 			    			}
       
  1010 			    		default:
       
  1011 			    			{
       
  1012 			    			response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1013 			    			responseReason = KErrArgument;
       
  1014 			    			break;
       
  1015 			    			}
       
  1016 			    		}
       
  1017 					break;
       
  1018 					}
       
  1019 				case TLbsNetPosRequestPrivacyInt::ERequestAdviceVerify:
       
  1020 					{
       
  1021 					response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1022 					responseReason = KErrServerBusy;
       
  1023 					break;
       
  1024 					}
       
  1025 				default:
       
  1026 					{
       
  1027 					response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1028 					responseReason = KErrArgument;
       
  1029 					break;
       
  1030 					}
       
  1031 				}
       
  1032 			iObserver->OnRespondNetworkLocationRequest(privReq->SessionId(), response, responseReason);
       
  1033 			privReq->SetState(CPrivacyRequest::EPrivReqStateResponseSent);
       
  1034 			return;
       
  1035 			}
       
  1036 		}
       
  1037 
       
  1038     // The new privacy request must be accepted or rejected, based on a
       
  1039     // combination of iPrivacyRequest->RequestPrivacy() settings, LbsAdmin settings
       
  1040     // and whether it is an emergency request.
       
  1041     //
       
  1042     // For a normal privacy request, the privacy controller application usually
       
  1043     // has the responsibility for accepting or rejecting it. (Although this depends
       
  1044     // on the LbsAdmin settings). 
       
  1045     // NOTE (1): Any non-emergency request with RequestAdvice() of ERequestAdviceStealth 
       
  1046 	//           will be rejected, since this is not currently supported by LBS.
       
  1047 	// NOTE (2): If the current quality profile Id (admin setting) refers to an invalid
       
  1048 	//           quality profile then any non-ememrgency request will be rejected.
       
  1049     //
       
  1050     // For an emergency privacy request, the privacy controller application
       
  1051     // is always notified of the request, but it has no say over whether
       
  1052     // the request is accepted or not. The request is accepted if the 
       
  1053     // RequestAction() is ERequestActionAllow, otherwise it will be rejected.
       
  1054     
       
  1055     TBool notifyController(EFalse);
       
  1056 	TBool waitForResponse(ETrue);
       
  1057 	TLbsNetworkEnumInt::TLbsPrivacyResponseInt response(TLbsNetworkEnumInt::EPrivacyResponseAccepted);    
       
  1058 	TInt responseReason = KErrNone;
       
  1059 	TLbsNetPosRequestPrivacyInt privacy = privReq->RequestPrivacy();
       
  1060     
       
  1061     if (aIsEmergency)
       
  1062     	{
       
  1063     	// Decide whether to accept or reject an emergency request.
       
  1064     	switch (privacy.RequestAction())
       
  1065     		{
       
  1066     		case TLbsNetPosRequestPrivacyInt::ERequestActionAllow:
       
  1067     			{
       
  1068     			privacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify);
       
  1069     			notifyController = ETrue;
       
  1070 				waitForResponse = EFalse;
       
  1071 				response = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
       
  1072     			break;
       
  1073     			}
       
  1074     		case TLbsNetPosRequestPrivacyInt::ERequestActionReject:
       
  1075     			{
       
  1076     			privacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify);
       
  1077     			notifyController = ETrue;
       
  1078 				waitForResponse = EFalse;
       
  1079 				response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1080     			break;
       
  1081     			}
       
  1082     		default:
       
  1083     			{
       
  1084 	    		LBSLOG2(ELogP4, "CPrivCntrllrHandler::ProcessNetworkLocationRequest : \
       
  1085 	    						 Unknown RequestAction() (0x%x), \
       
  1086 	    						 rejecting privacy request", 
       
  1087 	    						 privacy.RequestAction());
       
  1088     			notifyController = EFalse;
       
  1089 				waitForResponse = EFalse;
       
  1090 				response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1091 				responseReason = KErrArgument;
       
  1092     			break;
       
  1093     			}
       
  1094     		}
       
  1095     	
       
  1096 		privReq->SetRequestPrivacy(privacy);	
       
  1097     		
       
  1098     	}
       
  1099     else
       
  1100     	{
       
  1101     	// Decide wether the privacy controller application should be notified,
       
  1102     	// and if not, whether the request should be accepted or rejected.
       
  1103     	CLbsAdmin::TExternalLocateService externalLocate(CLbsAdmin::EExternalLocateOff);
       
  1104 		GetExternalLocateAdminSetting(privReq->SessionType(), externalLocate);
       
  1105 	    switch (externalLocate)
       
  1106 	    	{
       
  1107 	    	case CLbsAdmin::EExternalLocateOn:
       
  1108 	    		{
       
  1109 				// Whether we wait for the privacy controller application response
       
  1110 				// depends on the RequestAdvice() from the network
       
  1111 				switch (privacy.RequestAdvice())
       
  1112 					{
       
  1113 					case TLbsNetPosRequestPrivacyInt::ERequestAdviceVerify:
       
  1114 						{
       
  1115 						notifyController = ETrue;
       
  1116 						waitForResponse = ETrue;
       
  1117 						break;
       
  1118 						}
       
  1119 					case TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify:
       
  1120 						{
       
  1121 						switch(privacy.RequestAction())
       
  1122 							{
       
  1123 							case TLbsNetPosRequestPrivacyInt::ERequestActionReject:
       
  1124 								{
       
  1125 								// automatically reject and inform user
       
  1126 								notifyController = ETrue;
       
  1127 								waitForResponse = EFalse;
       
  1128 								response = TLbsNetworkEnumInt::EPrivacyResponseRejected;								
       
  1129 								}
       
  1130 								break;
       
  1131 							case TLbsNetPosRequestPrivacyInt::ERequestActionAllow:
       
  1132 								{
       
  1133 								// Always accept these types of privacy request
       
  1134 								notifyController = ETrue;
       
  1135 								waitForResponse = EFalse;
       
  1136 								response = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
       
  1137 								}
       
  1138 								break;
       
  1139 							case TLbsNetPosRequestPrivacy::ERequestActionNotUsed:
       
  1140 							default:
       
  1141 								{
       
  1142 								// Error: Unknown RequestAdvice() value. Send a 
       
  1143 								// 'reject' back to the network
       
  1144 					    		LBSLOG2(ELogP4, "CPrivCntrllrHandler::ProcessNetworkLocationRequest : \
       
  1145 					    						 Unknown TLbsRequestAction() (0x%x), \
       
  1146 					    						 rejecting privacy request", 
       
  1147 					    						 privacy.RequestAdvice());
       
  1148 					    		notifyController = EFalse;
       
  1149 								waitForResponse = EFalse;
       
  1150 								response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1151 								responseReason = KErrArgument;
       
  1152 								}
       
  1153 								break;
       
  1154 							}
       
  1155 						break;
       
  1156 						}
       
  1157 					case TLbsNetPosRequestPrivacyInt::ERequestAdviceSilent:
       
  1158 						{
       
  1159 						// Always accept these types of privacy request
       
  1160 						notifyController = ETrue;
       
  1161 						waitForResponse = EFalse;
       
  1162 						// For 'vanilla' lbs we should reject if network action = reject
       
  1163 						if((iLbsBehaviourMode == CLbsAdmin::ELbsBehaviourModeOriginal) && (privacy.RequestAction() == TLbsNetPosRequestPrivacyInt::ERequestActionReject))
       
  1164 							{
       
  1165 							response = TLbsNetworkEnumInt::EPrivacyResponseRejected;							
       
  1166 							}
       
  1167 						else	// Always accept these types of privacy request for 'custom1' behaviour
       
  1168 							{
       
  1169 							response = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
       
  1170 							privacy.SetRequestAction(TLbsNetPosRequestPrivacyInt::ERequestActionAllow);							
       
  1171 							}						
       
  1172 						break;
       
  1173 						}
       
  1174 					case TLbsNetPosRequestPrivacyInt::ERequestAdviceStealth:
       
  1175 						{
       
  1176 						notifyController = EFalse;
       
  1177 						waitForResponse = EFalse;
       
  1178 						response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1179 						responseReason = KErrNotSupported;
       
  1180 						break;
       
  1181 						}
       
  1182 					default:
       
  1183 						{
       
  1184 						// Error: Unknown RequestAdvice() value. Send a 
       
  1185 						// 'reject' back to the network
       
  1186 			    		LBSLOG2(ELogP4, "CPrivCntrllrHandler::ProcessNetworkLocationRequest : \
       
  1187 			    						 Unknown RequestAdvice() (0x%x), \
       
  1188 			    						 rejecting privacy request", 
       
  1189 			    						 privacy.RequestAdvice());
       
  1190 			    		notifyController = EFalse;
       
  1191 						waitForResponse = EFalse;
       
  1192 						response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1193 						responseReason = KErrArgument;
       
  1194 						break;
       
  1195 						}
       
  1196 					}
       
  1197 	    		break;
       
  1198 	    		}
       
  1199 	    	case CLbsAdmin::EExternalLocateOnButAlwaysVerify:
       
  1200 	    		{
       
  1201 	    		iAlwaysVerify = ETrue; 	    		
       
  1202 	    		notifyController = ETrue;
       
  1203 	    		waitForResponse = ETrue;
       
  1204 	    		privacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceVerify);
       
  1205 	    		break;
       
  1206 	    		}
       
  1207 	    	case CLbsAdmin::EExternalLocateOff:
       
  1208 	    		{
       
  1209 	    		notifyController = EFalse;
       
  1210 	    		waitForResponse = EFalse;
       
  1211 	    		response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1212 	    		break;
       
  1213 	    		}
       
  1214 	    	case CLbsAdmin::EExternalLocateOffButNotify:
       
  1215 	    		{
       
  1216 	    		notifyController = ETrue;
       
  1217 	    		waitForResponse = EFalse;
       
  1218 	    		response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1219 	    		privacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify);
       
  1220 	    		privacy.SetRequestAction(TLbsNetPosRequestPrivacyInt::ERequestActionReject);
       
  1221 	    		break;
       
  1222 	    		}
       
  1223 	    	case CLbsAdmin::EExternalLocateUnknown:
       
  1224 	    	default:
       
  1225 	    		{
       
  1226 	    		LBSLOG2(ELogP4, "CPrivCntrllrHandler::ProcessNetworkLocationRequest : \
       
  1227 	    						 Unknown Admin setting (0x%x), \
       
  1228 	    						 rejecting privacy request", externalLocate);
       
  1229 	    		notifyController = EFalse;
       
  1230 	    		waitForResponse = EFalse;
       
  1231 	    		response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1232 	    		responseReason = KErrArgument;
       
  1233 	    		break;
       
  1234 	    		}
       
  1235 	    	}
       
  1236 	    privReq->SetRequestPrivacy(privacy);	
       
  1237     	
       
  1238     	// ERequestAdviceStealth is currently not implemented/supported,
       
  1239     	// so regardless of the admin settings, etc. reject all requests
       
  1240     	// with RequestAdvice() of ERequestAdviceStealth.
       
  1241     	if (privReq->RequestPrivacy().RequestAdvice() == TLbsNetPosRequestPrivacyInt::ERequestAdviceStealth)
       
  1242     		{
       
  1243 			notifyController = EFalse;
       
  1244 			waitForResponse = EFalse;
       
  1245 			response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1246 			responseReason = KErrNotSupported;
       
  1247     		}
       
  1248     	
       
  1249 		// For 'custom1' behaviour, always reject the request if the current quality profile is invalid,
       
  1250     	// For 'vanilla' we should allow for no profile in use (quality will be taken from request params)
       
  1251     	// note that the profileid is not used here, we just verify whether it exists.
       
  1252     	// When the location request arrives the quality settings from the profile are read and used
       
  1253 	    TLbsQualityProfileId profileId(KLbsNullQualityProfileId);
       
  1254 	    TInt err = iLbsAdmin.Get(KLbsSettingQualityProfileExternalLocate, profileId);
       
  1255 	    if (err == KErrNone)	// there should always be a profile setting of some kind in admin
       
  1256 	    	{
       
  1257 	    	if(!((iLbsBehaviourMode == CLbsAdmin::ELbsBehaviourModeOriginal) && (profileId == KLbsNoProfileInUseQualityProfileId)))
       
  1258 	    		{
       
  1259 		    	TQualityProfile qualityProfile;
       
  1260 	    		err = LbsQualityProfile::GetQualityProfileById(profileId, qualityProfile);
       
  1261 	    		}
       
  1262 	       	}
       
  1263 		
       
  1264 		if (err != KErrNone)	// no profile specified in admin, or profile in use and profile doesn't exist in profile ini file
       
  1265 			{
       
  1266 			notifyController = EFalse;
       
  1267 			waitForResponse = EFalse;
       
  1268 			response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1269 			}
       
  1270     	}
       
  1271 
       
  1272 	// If required, send a notification to the privacy controller application.
       
  1273 	if (notifyController)
       
  1274 		{
       
  1275 		iNrhServer->ProcessNetworkLocationRequest(aSessionId, privReq->SessionType(), aRequestInfo, 
       
  1276 												  privReq->RequestPrivacy(), 
       
  1277 												  aIsEmergency);
       
  1278 		iSessionActive = ETrue;
       
  1279 		iRefPosReported = EFalse;
       
  1280 		}
       
  1281 	
       
  1282 	// If the privacy controller application is responsible for accepting
       
  1283 	// or rejecting the privacy request, wait for its response
       
  1284 	if (waitForResponse)
       
  1285 		{
       
  1286 		privReq->SetState(CPrivacyRequest::EPrivReqStateWaitPrivacyResponse);
       
  1287 		
       
  1288 		// Start a timeout timer, in case the privacy controller application
       
  1289 		// doesn't reply.
       
  1290 		CancelResponseTimer();
       
  1291 		StartResponseTimer();		
       
  1292 		}
       
  1293 	else
       
  1294 		{
       
  1295 		// Send an immediate response
       
  1296 		iObserver->OnRespondNetworkLocationRequest(privReq->SessionId(), response, responseReason);
       
  1297 		// If it's being rejected straight off, make sure any 
       
  1298 		// 'request completes' which come along later aren't passed on, UNLESS
       
  1299 		// the controller is to be told about the request (e.g. when the
       
  1300 		// external locate is EExternalLocateOffButNotify.
       
  1301 		if(response == TLbsNetworkEnumInt::EPrivacyResponseRejected && !notifyController)
       
  1302 			{
       
  1303 			iSessionActive = EFalse;
       
  1304 			iIsEmergency = EFalse;
       
  1305 			privReq->SetState(CPrivacyRequest::EPrivReqStateCompleted);
       
  1306 			}
       
  1307 		else
       
  1308 			{
       
  1309 			privReq->SetState(CPrivacyRequest::EPrivReqStateResponseSent);
       
  1310 			}
       
  1311 		}
       
  1312 	}
       
  1313 
       
  1314 /**
       
  1315  * Not used. Here for symmetry with the Notifier Handler class
       
  1316  */
       
  1317 void CPrivacyControllerHandler::RunL()
       
  1318 	{
       
  1319 	}	
       
  1320 void CPrivacyControllerHandler::DoCancel()
       
  1321 	{
       
  1322 	}
       
  1323 
       
  1324 /**
       
  1325  * Called when a location update has been received. The data is passed on 
       
  1326  * to the server.
       
  1327  * @param aSessionId identifies the session within the LBS System
       
  1328  * @param aPositionInfo position data to be passed on to the 
       
  1329  *                      Privacy Controller
       
  1330  */
       
  1331 void CPrivacyControllerHandler::ProcessNetworkPositionUpdate(
       
  1332 		TLbsNetSessionIdInt aSessionId, 
       
  1333 		const TPositionInfo& aPositionInfo)
       
  1334 	{
       
  1335 	// If there is no privacy handler, ignore the position update.
       
  1336 	if (iNrhServer == 0)
       
  1337 		{
       
  1338 		return;
       
  1339 		}
       
  1340 	
       
  1341 	CPrivacyRequest* privReq = FindPrivacyRequest(aSessionId, EFalse);
       
  1342 	if (privReq == NULL)
       
  1343 		{
       
  1344 		// Not matching request found, so return.
       
  1345 		return;
       
  1346 		}
       
  1347 
       
  1348 	// For terminal assisted mode there may be several update requests.
       
  1349 	// We don't want to bombard the privacy controller with all of these, 
       
  1350 	// so just send the first one. Position updates that aren't flagged
       
  1351 	// with PositionMode() of ETechnologyNetwork are  OK - these are 'real' 
       
  1352 	// updates which the privacy controller wants to know about.
       
  1353 	if(aPositionInfo.PositionMode() == TPositionModuleInfo::ETechnologyNetwork)
       
  1354 		{
       
  1355 		iRefPosReported = ETrue;
       
  1356 		}
       
  1357 		
       
  1358 	if (iNrhServer != 0)
       
  1359 		{
       
  1360 		iNrhServer->ProcessNetworkPositionUpdate(
       
  1361 			privReq->SessionId(), 
       
  1362 			aPositionInfo);
       
  1363 		}
       
  1364 
       
  1365 	}
       
  1366 	
       
  1367 /**
       
  1368  * Called when a session complete message has been received. 
       
  1369  * The data is passed on to the server.
       
  1370  * @param aSessionId identifies the session within the LBS System
       
  1371  * @param aReason reason for termination of the session
       
  1372  */
       
  1373 void CPrivacyControllerHandler::ProcessRequestComplete(
       
  1374 		TLbsNetSessionIdInt aSessionId, 
       
  1375 		TInt aReason)
       
  1376 	{
       
  1377 	CPrivacyRequest* privReq = FindPrivacyRequest(aSessionId, ETrue);
       
  1378 	if (privReq == NULL)
       
  1379 		{
       
  1380 		// Not matching request found, so return.
       
  1381 		return;
       
  1382 		}
       
  1383 
       
  1384 	if (privReq->State() != CPrivacyRequest::EPrivReqStateCompleted)
       
  1385 		{
       
  1386 		// Notify the privacy controller of the session complete message
       
  1387 		if (iNrhServer != 0)
       
  1388 			{
       
  1389 			iNrhServer->ProcessRequestComplete(privReq->SessionId(), aReason);	
       
  1390 			}
       
  1391 		privReq->SetState(CPrivacyRequest::EPrivReqStateCompleted);
       
  1392 		}
       
  1393 	
       
  1394 	// Delete the completed request.
       
  1395 	// do not delete emergency buffer - not onheap
       
  1396 	if(privReq != iEmergencyPrivReq)
       
  1397 	    {
       
  1398 	    delete privReq; 
       
  1399 	    }
       
  1400 	// Cancel the response timer, then re-start if any outstanding requests.
       
  1401 	CancelResponseTimer();
       
  1402 	StartResponseTimer();
       
  1403 	}
       
  1404 
       
  1405 /**
       
  1406  * Called when the server passes on a response to a privacy query.
       
  1407  * Message wtaxchers and the timer are stopped, and the response is passed
       
  1408  * on to the Privacy and Location Handler subcomponent.
       
  1409  * @param aSessionId identifies the session within the LBS System
       
  1410  * @param aRequestResult response to the query
       
  1411  */
       
  1412 void CPrivacyControllerHandler::OnRespondNetworkLocationRequest(
       
  1413 		const TLbsNetSessionIdInt& aRequestId, 
       
  1414 		TLbsNetworkEnumInt::TLbsPrivacyResponseInt aRequestResult,
       
  1415 		TInt aResponseReason)
       
  1416 	{
       
  1417 	CPrivacyRequest* privReq = FindPrivacyRequest(aRequestId, EFalse);
       
  1418 	if (privReq)
       
  1419 		{
       
  1420 		if (privReq->State() == CPrivacyRequest::EPrivReqStateWaitPrivacyResponse)
       
  1421 			{
       
  1422 			iObserver->OnRespondNetworkLocationRequest(
       
  1423 						privReq->SessionId(), aRequestResult, aResponseReason);
       
  1424 			privReq->SetState(CPrivacyRequest::EPrivReqStateResponseSent);
       
  1425 			}
       
  1426 
       
  1427 		CancelResponseTimer();
       
  1428 		StartResponseTimer();
       
  1429 		}
       
  1430 	}
       
  1431 	
       
  1432 /**
       
  1433  * Called when the server passes on cancellation of a privacy query by thet 
       
  1434  * Privacy Controller.
       
  1435  * Message wtaxchers and the timer are stopped, and the cancellation
       
  1436  * is passed on to the Privacy and Location Handler subcomponent.
       
  1437  * @param aSessionId identifies the session within the LBS System
       
  1438  */
       
  1439 void CPrivacyControllerHandler::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& aRequestId)
       
  1440 	{
       
  1441 	CPrivacyRequest* privReq = FindPrivacyRequest(aRequestId, EFalse);
       
  1442 	if (privReq)
       
  1443 		{
       
  1444 		// Cancel/Restart the timeout timer.
       
  1445 		CancelResponseTimer();
       
  1446 		StartResponseTimer();
       
  1447 		
       
  1448 		// Send cancel to the network.
       
  1449 		iObserver->OnCancelNetworkLocationRequest(privReq->SessionId());
       
  1450 		}
       
  1451 	}
       
  1452 
       
  1453 void CPrivacyControllerHandler::StartResponseTimer()
       
  1454 	{
       
  1455 	if (iPrivacyResponseTimer->IsActive())
       
  1456 		{
       
  1457 		// Timer is currently active, don't start again.
       
  1458 		return;
       
  1459 		}
       
  1460 	
       
  1461 	// Find the earliest request that is waiting for a response.
       
  1462 	// (Buffer should be in order of time started, so earliest request
       
  1463 	// should always be the one nearest the start of the buffer.
       
  1464 	const TInt count = iRequestBuffer.Count();
       
  1465 	TUint privacyVerifyTimeoutInMilliSeconds = 0;		
       
  1466 	// Read timeout from admin (nb: should never fail as we create a default setting in case of absence)
       
  1467 	iLbsAdmin.Get(KLbsSettingPrivacyAppTimeout, privacyVerifyTimeoutInMilliSeconds);
       
  1468 	TTimeIntervalMicroSeconds timeout(privacyVerifyTimeoutInMilliSeconds*1000);	
       
  1469 	for (TInt i = 0; i < count; i++)
       
  1470 		{
       
  1471 		if (iRequestBuffer[i]->State() == CPrivacyRequest::EPrivReqStateWaitPrivacyResponse)
       
  1472 			{
       
  1473 			// Pending request was found; start the timer.
       
  1474 			CPrivacyRequest* privReq = iRequestBuffer[i];
       
  1475 			
       
  1476 			// Calculate the time at which the request would timeout.			
       
  1477 			TTime endTime = privReq->StartTime() + timeout;
       
  1478 			
       
  1479 			// Start the timer.
       
  1480 			iPrivacyResponseTimer->EventAtUTC(endTime, 1);
       
  1481 			
       
  1482 			break;
       
  1483 			}
       
  1484 		}
       
  1485 	}
       
  1486 
       
  1487 void CPrivacyControllerHandler::CancelResponseTimer()
       
  1488 	{
       
  1489 	iPrivacyResponseTimer->Cancel();
       
  1490 	}
       
  1491 
       
  1492 /**
       
  1493  * Called when the response timer expires.
       
  1494  * An accept or reject of the original query is reported to the NRH 
       
  1495  * depending on the request action parameter received with the original request.
       
  1496  * @param aTimerId always 1 (we only use one timer in this subcomponent)
       
  1497  */
       
  1498 void CPrivacyControllerHandler::OnTimerEventL(TInt aTimerId)
       
  1499 	{
       
  1500 	// 1) Get time 'now'
       
  1501 	// 2) search through all requests to see if 'now' > 'start' + timeout
       
  1502 	// 3) For each request found in 2), send default response
       
  1503 	// 4) Need to remove the response from the buffer??
       
  1504 	// 5) Search through requests to find earliest 'start'
       
  1505 	// 6) If 5) finds a request, re-start timer for it. 
       
  1506 	//    (need to calculate revised interval).
       
  1507 	
       
  1508 	switch (aTimerId)
       
  1509 		{
       
  1510 		case 1:
       
  1511 			{
       
  1512 			// Find the earliest request that is waiting for a response.
       
  1513 			// (Buffer should be in order of time started, so earliest request
       
  1514 			// should always be the one nearest the start of the buffer.
       
  1515 			const TInt count = iRequestBuffer.Count();
       
  1516 			for (TInt i = 0; i < count; i++)
       
  1517 				{
       
  1518 				if (iRequestBuffer[i]->State() == CPrivacyRequest::EPrivReqStateWaitPrivacyResponse)
       
  1519 					{
       
  1520 					// Found a request in the correct state, assume
       
  1521 					// this is the one which has timed out.
       
  1522 					CPrivacyRequest* privReq = iRequestBuffer[i];
       
  1523 					
       
  1524 					// The privacy controller has timed out without a response being
       
  1525 					// received. Generate a response as required depending upon
       
  1526 					// the LbsAdmin setting: TPrivacyTimeoutAction
       
  1527 					TLbsNetworkEnumInt::TLbsPrivacyResponseInt response;
       
  1528 					GetPrivacyTimeoutAction(response, privReq->RequestPrivacy());	
       
  1529 					iObserver->OnRespondNetworkLocationRequest(privReq->SessionId(), response, KErrNone);
       
  1530 					
       
  1531 					privReq->SetState(CPrivacyRequest::EPrivReqStateResponseSent);
       
  1532 					
       
  1533 					// Re-start the timer if there are more outstanding requests.
       
  1534 					StartResponseTimer();
       
  1535 					break;
       
  1536 					}
       
  1537 				}
       
  1538 			break;
       
  1539 			}
       
  1540 		default:
       
  1541 			// do nothing
       
  1542 			break;	
       
  1543 		}
       
  1544 	}
       
  1545 	
       
  1546 TInt CPrivacyControllerHandler::OnTimerError(TInt /*aTimerId*/, 
       
  1547 											TInt aError)
       
  1548 	{
       
  1549 	// Not used - OnTimerEventL doesn't generate any error.
       
  1550 	return(aError);
       
  1551 	}
       
  1552 	
       
  1553 /**
       
  1554  * Establish a connection with a server subsession (there is only ever one)
       
  1555  */
       
  1556 void CPrivacyControllerHandler::SetServerObserver(MLbsSessionObserver* aNrhServer)
       
  1557     {
       
  1558     iNrhServer = aNrhServer;
       
  1559     }
       
  1560 
       
  1561 /**
       
  1562  * Register the observer of this subcomponent (the Privacy and Location Request 
       
  1563  * Handler)
       
  1564  */
       
  1565 void CPrivacyControllerHandler::RegisterObserver(MPrivacyHandlerObserver* aObserver)
       
  1566     {
       
  1567     iObserver = aObserver;	
       
  1568     }
       
  1569 
       
  1570 TBool CPrivacyControllerHandler::IsSessionIdMatch(
       
  1571 		const CPrivacyRequest& aReq1, 
       
  1572 		const CPrivacyRequest& aReq2)
       
  1573 	{
       
  1574 	CPrivacyRequest& req1(const_cast<CPrivacyRequest&>(aReq1));
       
  1575 	CPrivacyRequest& req2(const_cast<CPrivacyRequest&>(aReq2));
       
  1576 	
       
  1577 	return (req1.SessionId().SessionOwner() == req2.SessionId().SessionOwner()
       
  1578 			&& req1.SessionId().SessionNum() == req2.SessionId().SessionNum());
       
  1579 	}
       
  1580 
       
  1581 CPrivacyRequest* CPrivacyControllerHandler::FindPrivacyRequest(
       
  1582 		const TLbsNetSessionIdInt& aSessionId,
       
  1583 		TBool aRemoveRequest)
       
  1584 	{
       
  1585 	CPrivacyRequest* privReq = NULL;
       
  1586 	CPrivacyRequest* matchReq = NULL;
       
  1587 	TRAPD(err, matchReq = CPrivacyRequest::NewL());
       
  1588 	if (KErrNone == err)
       
  1589 		{
       
  1590 		matchReq->SetSessionId(aSessionId);
       
  1591 		TInt index = iRequestBuffer.Find(matchReq, IsSessionIdMatch);
       
  1592 		if (KErrNotFound != index)
       
  1593 			{
       
  1594 			privReq = iRequestBuffer[index];
       
  1595 			if (aRemoveRequest)
       
  1596 				{
       
  1597 				iRequestBuffer.Remove(index);
       
  1598 				}
       
  1599 			}
       
  1600 		delete matchReq;
       
  1601 		}
       
  1602 	return privReq;
       
  1603 	}
       
  1604 
       
  1605 /** Get the default privacy response based on the admin setting.
       
  1606  */
       
  1607 void CPrivacyControllerHandler::GetPrivacyTimeoutAction(
       
  1608 		TLbsNetworkEnumInt::TLbsPrivacyResponseInt& aResponse, 
       
  1609 		const TLbsNetPosRequestPrivacyInt& aRequestPrivacy)
       
  1610 	{
       
  1611 	CLbsAdmin::TPrivacyTimeoutAction privacyTimeoutAction;
       
  1612 	iLbsAdmin.Get(KLbsSettingPrivacyTimeoutAction, privacyTimeoutAction);
       
  1613 	
       
  1614 	switch(privacyTimeoutAction)
       
  1615 		{
       
  1616 		case CLbsAdmin::EPrivacyTimeoutReject:
       
  1617 			{
       
  1618 			aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1619 			break;
       
  1620 			}
       
  1621 
       
  1622 		case CLbsAdmin::EPrivacyTimeoutNetworkDefined:
       
  1623 			{
       
  1624 			// For 'vanilla' we shouldn't trust the network-specified action if admin setting says "always verify"			
       
  1625 			if(aRequestPrivacy.RequestAction() == TLbsNetPosRequestPrivacyInt::ERequestActionReject ||
       
  1626 					aRequestPrivacy.RequestAction() == TLbsNetPosRequestPrivacyInt::ERequestActionNotUsed ||
       
  1627 					(iLbsBehaviourMode == CLbsAdmin::ELbsBehaviourModeOriginal && iAlwaysVerify))
       
  1628 				{
       
  1629 				aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;				
       
  1630 				}
       
  1631 			else
       
  1632 				{
       
  1633 				aResponse = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
       
  1634 				}
       
  1635 			break;
       
  1636 			}
       
  1637 		default:
       
  1638 			{
       
  1639 			aResponse = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1640 			break;
       
  1641 			}
       
  1642 		}	
       
  1643 	}