locationrequestmgmt/networkrequesthandler/src/lbsnrhprivacycontrollerserver.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 11 May 2010 17:31:17 +0300
branchRCL_3
changeset 28 cf8bf9651775
parent 0 9cfd9a3ee49c
permissions -rw-r--r--
Revision: 201014 Kit: 201019

// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// lbsnrhserver.cpp
// server side exmaple of how to use the abstract server framework
// 
//

#include <e32debug.h>
#include <lbs/lbslocclasstypes.h>
#include "lbsnrhprivacycontrollerserver.h"
#include "opensessionparams.h"
#include "lbsnrhmessageenums.h"
#include "lbsnrhserverdata.h"
#include "nrhpanic.h"

TPositionInfoClassTypeFixer::TPositionInfoClassTypeFixer(const TPositionInfo& aPositionInfo) :
TPositionInfo(aPositionInfo)
  	{
  	iPosClassType = EPositionInfoClass;
  	iPosClassSize = sizeof(TPositionInfo);
  	}

CNrhPrivacyServerSubsession::CNrhPrivacyServerSubsession() :
	iPendingPrivacyRequests(1)
	{
	}

CNrhPrivacyServerSubsession::~CNrhPrivacyServerSubsession()
	{
	// cancel ANY outstanding requests with KErrServerTerminated
	// or some other error code to indicate that the session has been closed
	// early
	if(!iPrivacyControllerMessage.IsNull())
		{
		iPrivacyControllerMessage.Complete(KErrServerTerminated); 	
		}

	iPendingMessage.Reset();
	iPendingPrivacyRequests.Reset();
	iPendingLocationUpdates.Reset();
	iPendingSessionCompletes.Reset();
	CloseSubSession();
	}

CNrhPrivacyServerSubsession* CNrhPrivacyServerSubsession::NewL()
	{
	CNrhPrivacyServerSubsession* self = new (ELeave) CNrhPrivacyServerSubsession;
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

void CNrhPrivacyServerSubsession::ConstructL()
	{
	}

void CNrhPrivacyServerSubsession::DispatchL(const RMessage2& aMessage)
	{
	switch(aMessage.Function())
		{
		case ENrhPrivacyControllerRegister:
			SetClientReady(aMessage);
			break;
			
		case ENrhPrivacyControllerCancelRegister:
			CancelClientReady(aMessage);
			break;
			
		case ENrhPrivacyControllerResponse:
			HandlePrivacyResponse(aMessage);
			break;
			
		case ENrhPrivacyControllerCancel:
			HandlePrivacyCancel(aMessage);
			break;
		}
	}
	
void CNrhPrivacyServerSubsession::DispatchError(const RMessage2& /*aMessage*/, TInt /*aError*/)
	{
	// errors from DispatchL end up in here
	}
	
void CNrhPrivacyServerSubsession::CreateSubSessionL(const RMessage2& aMessage, 
									const CSecureServerBase* aServer)
	{	
	// Get hold of something for this subsession 
	// to pass on its messages (respond/cancel privacy request) to	
	iNrhServer = reinterpret_cast<const CNrhServer*>(aServer);

	// Check the version of the MLbsPrivacyObserver is supported
	User::LeaveIfError(CheckPrivacyObserverVersion(aMessage));

	// Let the privacyhandler know where it should be passing its messages
	// (privacy request, location update, session complete) to.
	iNrhServer->PrivacyObserver()->SetServerObserver(this);
	}
	
void CNrhPrivacyServerSubsession::CloseSubSession()
	{
	if (iNrhServer->PrivacyObserver() != NULL)
		{
		iNrhServer->PrivacyObserver()->SetServerObserver(NULL);
		}
	}
	
void CNrhPrivacyServerSubsession::VirtualRelease()
	{	
	//delete ourselves - can be called on a via CS on a leave
	delete this; // we are allocated via the GetImpl above, and a handle to "us" is returned
	}
	
void CNrhPrivacyServerSubsession::SetClientReady(const RMessage2& aMessage)
	{
	iPrivacyControllerMessage = aMessage;
	
	/* 
	 * See whether there are any messages which have been received since 
	 * sending the last one on to the client
	 */
	TInt pendingMessages = iPendingMessage.Count();
	if(pendingMessages)
		{
		TNrhServerMessageType messageType = iPendingMessage[0];
		iPendingMessage.Remove(0);
		switch(messageType)
			{
			case ENrhServerPrivacyRequest:
				{
				TPrivacyRequestParams privacyRequestParams = 
												iPendingPrivacyRequests[0];
		
				TPrivacyRequestParamsPckgC privacyRequestParamsPckg(privacyRequestParams);
				MessageUtils::Write(iPrivacyControllerMessage, 
							EPrivacyRequestParams, 
							privacyRequestParamsPckg);
				iPrivacyControllerMessage.Complete(ENrhServerPrivacyRequest);
				iPendingPrivacyRequests.Delete(0);
				break;
				}
				
			case ENrhServerLocationUpdate:
				{
				TLocationUpdateParams locationUpdateParams;
				locationUpdateParams.iSessionId = iPendingLocationUpdates[0].iSessionId;
								
				//It is necessary to update tha class type and size to TPositionInfo class type and size
				//in case if the pos update is of TPositionCourseInfo, TPositionSatelliteInfo, 
				//TPositionExtendedSatelliteInfo or HPositionGenericInfo class type.
				// Because only TPositionInfo part is passed to the LbsPrivacyController.
				TPositionInfoClassTypeFixer posFixer = iPendingLocationUpdates[0].iPositionInfo;  
				locationUpdateParams.iPositionInfo = posFixer;

				TLocationUpdateParamsPckgC locationUpdateParamsPckg(locationUpdateParams);
		
				MessageUtils::Write(iPrivacyControllerMessage, 
							ELocationUpdateParams, 
							locationUpdateParamsPckg);
				iPrivacyControllerMessage.Complete(ENrhServerLocationUpdate);
				iPendingLocationUpdates.Remove(0);
				break;
				}
				
			case ENrhServerLbsSessionComplete:
				{
				TLbsSessionCompleteParams lbsSessionCompleteParams = 
												iPendingSessionCompletes[0];
				TLbsSessionCompleteParamsPckgC lbsSessionCompleteParamsPckg(lbsSessionCompleteParams);
		
				MessageUtils::Write(iPrivacyControllerMessage, 
							ELbsSessionCompleteParams, 
							lbsSessionCompleteParamsPckg);
				iPrivacyControllerMessage.Complete(ENrhServerLbsSessionComplete);
				iPendingSessionCompletes.Remove(0);
				break;
				}
			}
		}
	}
	
void CNrhPrivacyServerSubsession::CancelClientReady(const RMessage2& aMessage)
	{
	// Cancel the outstanding request as well.
	if(!iPrivacyControllerMessage.IsNull())
		{
		iPrivacyControllerMessage.Complete(KErrNone); 	
		}

	// Complete this message (the cancel request)
	aMessage.Complete(KErrNone);
	}
	
void CNrhPrivacyServerSubsession::HandlePrivacyResponse(const RMessage2& aMessage)
	{
	
	// Get the data from the IPC message
	TPrivacyResponseParams privacyResponseParams;	
	TPckg<TPrivacyResponseParams> privacyResponseParamsBuf(privacyResponseParams);

	MessageUtils::Read(aMessage, 0, privacyResponseParamsBuf);

	TLbsNetworkEnumInt::TLbsPrivacyResponseInt response;
	
	if(privacyResponseParams.iResult == CLbsPrivacyController::ERequestAccepted)
		{
		response = TLbsNetworkEnumInt::EPrivacyResponseAccepted;
		}
	else
		{
		response = TLbsNetworkEnumInt::EPrivacyResponseRejected;
		}

	iNrhServer->PrivacyObserver()->OnRespondNetworkLocationRequest(privacyResponseParams.iSessionId,
												response, KErrNone);

	aMessage.Complete(KErrNone);
	
	}
	
void CNrhPrivacyServerSubsession::HandlePrivacyCancel(const RMessage2& aMessage)
	{

	// Get the data from the IPC message
	TPrivacyCancelParams privacyCancelParams;	
	TPckg<TPrivacyCancelParams> privacyCancelParamsBuf(privacyCancelParams);

	MessageUtils::Read(aMessage, 0, privacyCancelParamsBuf);

	iNrhServer->PrivacyObserver()->OnCancelNetworkLocationRequest(privacyCancelParams.iSessionId);

	aMessage.Complete(KErrNone);
	
	}
void CNrhPrivacyServerSubsession::ProcessNetworkLocationRequest(TLbsNetSessionIdInt aSessionId, 
																const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt /*aSessionType*/,
                                         						const TLbsExternalRequestInfo&  aRequestInfo, 
                       											const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy,
                       											TBool /*aIsEmergency*/)
	{
	__ASSERT_DEBUG((aRequestInfo.ClassType() == EExternalRequestInfoClass) 
				   || (aRequestInfo.ClassType() == 
						(EExternalRequestInfoClass | EExternalRequestInfoClass2)), 
				   Panic(ENrhPanicInvalidExternalRequestInfoType));
	
	TPrivacyRequestParams privacyRequestData;
	privacyRequestData.iSessionId = aSessionId;
	Mem::Copy(&privacyRequestData.iRequestInfo,
			  &aRequestInfo,
			  aRequestInfo.ClassSize());
	privacyRequestData.iRequestPrivacy = aNetPosRequestPrivacy;

	if(!iPrivacyControllerMessage.IsNull())
		{
		TPrivacyRequestParamsPckgC privacyRequestDataPckg(privacyRequestData);
		MessageUtils::Write(iPrivacyControllerMessage, 
							EPrivacyRequestParams, 
							privacyRequestDataPckg);
		iPrivacyControllerMessage.Complete(ENrhServerPrivacyRequest); 	
		}
	else
		{
		TRAPD(err, iPendingPrivacyRequests.AppendL(privacyRequestData));
		// No point flagging a pending message if we didn't manage to store it
		if(err == KErrNone)
			{
			err = iPendingMessage.Append(ENrhServerPrivacyRequest);
			}
		}

	}
	
void CNrhPrivacyServerSubsession::ProcessNetworkPositionUpdate(TLbsNetSessionIdInt aSessionId, 
                              const TPositionInfo& aPositionInfo)
	{
	//It is necessary to update tha class type and size to TPositionInfo class type and size
	//in case if the pos update is of TPositionCourseInfo, TPositionSatelliteInfo, 
	//or HPositionGenericInfo class type. Because only TPositionInfo part is 
	//passed to the LbsPrivacyController.
	TLocationUpdateParams locationUpdateParams;
	locationUpdateParams.iSessionId = aSessionId;
	TPositionInfoClassTypeFixer posFixer = aPositionInfo;  
	locationUpdateParams.iPositionInfo = posFixer;
    
	if(!iPrivacyControllerMessage.IsNull())
		{
		TLocationUpdateParamsPckgC locationUpdateParamsPckg(locationUpdateParams);
		MessageUtils::Write(iPrivacyControllerMessage, 
							ELocationUpdateParams, 
							locationUpdateParamsPckg);
		iPrivacyControllerMessage.Complete(ENrhServerLocationUpdate); 	
		}
	else
		{
		TInt err = iPendingLocationUpdates.Append(locationUpdateParams);
		// No point flagging a pending message if we didn't manage to store it
		if(err == KErrNone)
			{
			err = iPendingMessage.Append(ENrhServerLocationUpdate);
			}
		}
	}
	
	
void CNrhPrivacyServerSubsession::ProcessRequestComplete(TLbsNetSessionIdInt aSessionId, 
                                TInt aReason)
	{


	TLbsSessionCompleteParams lbsSessionCompleteParams;
	lbsSessionCompleteParams.iSessionId = aSessionId;
	lbsSessionCompleteParams.iReason = aReason;

	if(!iPrivacyControllerMessage.IsNull())
		{
		TLbsSessionCompleteParamsPckgC lbsSessionCompleteParamsPckg(lbsSessionCompleteParams);
		MessageUtils::Write(iPrivacyControllerMessage, 
							ELbsSessionCompleteParams, 
							lbsSessionCompleteParamsPckg);
		iPrivacyControllerMessage.Complete(ENrhServerLbsSessionComplete); 	
		}
	else
		{
		TInt err = iPendingSessionCompletes.Append(lbsSessionCompleteParams);
		// No point flagging a pending message if we didn't manage to store it
		if(err == KErrNone)
			{
			err = iPendingMessage.Append(ENrhServerLbsSessionComplete);
			}
		}
	}

/** Check the version of MLbsPrivacyObserver the client is using is supported. 
*/
TInt CNrhPrivacyServerSubsession::CheckPrivacyObserverVersion(const RMessage2& aMessage)
	{
	TInt result = KErrNone;
	
	TNrhPrivacyControllerData data;
	TPckg<TNrhPrivacyControllerData> dataPckg(data);
	MessageUtils::Read(aMessage, 1, dataPckg);

	if (data.iVersion.iMajor == KLbsPrivacyObserverVersionMajor
		&& data.iVersion.iMinor == KLbsPrivacyObserverVersionMinor)
		{
		result = KErrNone;
		}
	else if (data.iVersion.iMajor == KLbsPrivacyObserverVersion2Major
			 && data.iVersion.iMinor == KLbsPrivacyObserverVersion2Minor)
		{
#if defined(SYMBIAN_LOCATION_PRIVACY_V2)
		result = KErrNone;
#else
		result = KErrNotSupported;
#endif // SYMBIAN_LOCATION_PRIVACY_V2
		}
	else
		{
		// Unrecognised version; so return KErrNotSupported
		result = KErrNotSupported;
		}
	
	return result;
	}