locationrequestmgmt/networkrequesthandler/src/lbsnrhprivacycontrollerserver.cpp
changeset 0 9cfd9a3ee49c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationrequestmgmt/networkrequesthandler/src/lbsnrhprivacycontrollerserver.cpp	Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,375 @@
+// 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;
+	}