networkprotocolmodules/common/suplrrlpasn1/src/rrlpmeasureposresponse.cpp
changeset 0 9cfd9a3ee49c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networkprotocolmodules/common/suplrrlpasn1/src/rrlpmeasureposresponse.cpp	Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,724 @@
+// Copyright (c) 2008-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:
+//
+
+/**
+ @file
+ @internalTechnology
+ 
+*/
+
+#include "RRLP-Messages.h"
+#include "rrlpmeasureposresponse.h"
+#include "supldevloggermacros.h" 
+#include "suplrrlpasn1common.h"
+
+#include <lbssatellite.h>
+#include <lbs/lbsgpsmeasurement.h>
+#include <lbs/lbsextendedsatellite.h>
+
+/*
+Modulus used in conversion of GPS TOW in GPS Measurement Information Element.
+*/
+const TInt KLbsTowMod = 14400000;
+
+
+/**
+CRrlpMeasurePositionResponse
+
+Class for building an outgoing RRLP Measure Position Response Message
+Translates content of passed LBS defined data structures to data encoded as per
+the RRLP specification 3GPP 44.031 v5.12 and related documents. 
+Provides a mechanism to encode the data to a target buffer as an ASN1 PER encoded 
+data stream
+
+
+The RRLP Measure Position Repsonse message consists of the following components:
+
+Multiple Sets (optional):
+  allows the mobile terminal to specify the number of sets of location or
+  measurement datum included in this message. This is not used by Symbian LBS
+  and is left absent, indicating a single measurement set is included.
+
+Reference BTS Identity Element (optional):
+  Identifies the Base Transceiver Stations used in the calculation of position.
+  This element is conditional to the number of reference BTSs. It is mandatory, 
+  if there is more than one reference BTS, and optional otherwise. If this 
+  element is not included, the Reference BTS, used in other elements, is the 
+  current serving BTS of MS. If this element is included, the BTSs defined here
+  are used as Reference BTSs in all other elements.
+  Currently not included in this implementation.
+  
+E-OTD Measurement Information (optional):
+  Provides OTD measurements of signals sent from the reference and neighbor base
+  stations. Mandatory if E-OTD is the agreed positioning method, omitted otherwise.
+  Symbian LBS currently does not support E-OTD positioning, so this component is
+  omitted.
+
+Location Information (optional):
+  The purpose of Location Information element is to provide the location 
+  estimate from the MS to the network, if the MS is capable of determining its 
+  own position. Optionally, the element may contain the velocity parameters 
+  computed by the MS.
+  
+  This element is populated via calls to the SetLocationInformation() API
+
+GPS Measurement Information (optional):
+  The purpose of the GPS Measurement Information element is to provide GPS 
+  measurement information from the MS to the SMLC. This information includes 
+  the measurements of code phase and Doppler, which enables the network-based
+  GPS method where position is computed in the SMLC.
+  
+  This element is populated via a call to the SetMeasurementInformation() API
+
+Location Information Error (optional):
+  The purpose of Location Information Error element is to provide the indication
+  of error and the reason for it, when the MS can not perform the required 
+  location or the network can not determine the position estimate. The element 
+  may also indicate what further assistance data may be needed by the target MS 
+  to produce a successful location estimate or location measurements.
+  
+  This element is populated via a call to the SetLocationError() APIs
+
+GPS Time Assistance Measurements (optional):
+  This IE contains measurements that are used to define an accurate relation 
+  between GSM and GPS time or to provide additional GPS TOW information for MS
+  Assisted A-GPS.
+
+Extended Reference (optional):
+  This IE shall be included in any Measure Position Response if and only if an 
+  Extended Reference IE was received in the corresponding previous Measure 
+  Position Request message.
+  
+  This element is populated via a call to the SetReference() API.
+  
+
+Uplink RRLP Pseudo Segmentation Indication (optional):
+  This element is included by the MS when up-link RRLP pseudo-segmentation is used. 
+  In the first segment, 'first of many' is indicated and in the second 'second of 
+  many' is indicated. 
+  This implementation does not use up-link pseudo-segmentation hence this component
+  is not included.
+
+*/
+
+/**
+Static factory constructor
+*/
+EXPORT_C CRrlpMeasurePositionResponse* CRrlpMeasurePositionResponse::NewL()
+	{
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::NewL() Begin\n");
+	CRrlpMeasurePositionResponse* self = CRrlpMeasurePositionResponse::NewLC();
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::NewL() End\n");
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+Static factory constructor
+*/
+EXPORT_C CRrlpMeasurePositionResponse* CRrlpMeasurePositionResponse::NewLC()
+	{
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::NewLC() Begin\n");
+	CRrlpMeasurePositionResponse* self = new (ELeave) CRrlpMeasurePositionResponse();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::NewLC() End\n");
+	return self;
+	}
+
+/** 
+Default constructor 
+*/
+CRrlpMeasurePositionResponse::CRrlpMeasurePositionResponse()
+ : CRrlpMessageBase(ERrlpMeasurePositionResp, ETrue)
+	{
+	}
+
+/** 
+Second stage constructor 
+*/
+void CRrlpMeasurePositionResponse::ConstructL()
+	{
+	// outgoing message - call base class ConstructL to create data structures.
+	CRrlpMessageBase::ConstructL();
+		
+	// local reference to context object
+	OSCTXT* pctxt = iControl->getCtxtPtr();
+
+	iData->component.t = T_RRLP_Component_msrPositionRsp;
+	iData->component.u.msrPositionRsp = (ASN1T_MsrPosition_Rsp*)rtxMemAllocZ(pctxt, sizeof(ASN1T_MsrPosition_Rsp));
+   	LeaveIfAllocErrorL();
+	}
+
+/** 
+Destructor 
+*/
+CRrlpMeasurePositionResponse::~CRrlpMeasurePositionResponse()
+	{
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::~CRrlpMeasurePositionResponse() Begin\n");
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::~CRrlpMeasurePositionResponse() End\n");
+	}
+	
+
+/**	
+SetLocationInformation()
+
+Sets the content of the location information component of the RRLP Measure 
+Position Response Message.
+
+RRLP Location Information component consists of the following:
+
+Reference Frame (mandatory):
+  This field specifies the reference BTS Reference Frame number during which
+  the location estimate was measured. This information is not available at the
+  Protocol Module, hence this is set to a value which is ignored by the SMLC.
+
+GPS TOW (optional):
+  This field specifies the GPS TOW for which the location estimate is valid, 
+  rounded down to the nearest millisecond unit. This field is optional but 
+  shall be included if GPS Time Assistance Measurements are included. 
+  Currently omitted in this implementation.
+ 
+Fix Type (mandatory)
+  This field contains an indication as to the type of measurements performed 
+  by the MS: 2D or 3D. 
+  Set to 3D if altitude information is available, 2D otherwise.
+
+Position Estimate (mandatory)
+  This field contains the calculated position estimate in the format defined 
+  in 3GPP TS 23.032. The allowed shapes are ellipsoid Point, ellipsoid point 
+  with uncertainty circle, ellipsoid point with uncertainty ellipse, ellipsoid 
+  point with altitude and uncertainty ellipsoid.
+
+
+@param  aPosInfo reference to the reported position data from LBS
+@return error indication, KErrNone otherwise
+*/
+EXPORT_C TInt CRrlpMeasurePositionResponse::SetLocationInformation(TPositionInfoBase& aPosInfo)
+	{
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetLocationInformation() Begin\n");
+	__ASSERT_DEBUG(iData->component.u.msrPositionRsp != NULL, User::Invariant());
+	
+	ASN1T_MsrPosition_Rsp* msgBody = iData->component.u.msrPositionRsp;
+	
+	// handle Position Info class type
+	if (aPosInfo.PositionClassType() & EPositionInfoClass)
+		{
+		TPositionInfo& posInfo = reinterpret_cast <TPositionInfo&>(aPosInfo);
+
+		// the position
+		TPosition position;
+		posInfo.GetPosition(position);
+		
+		// indicate that location information is present
+		msgBody->m.locationInfoPresent = 1;
+
+		// BTS Reference Frame (mandatory) 0-65535 - however is ignored if 
+		// is in the range 42432..65535
+		// In this case GPS TOW should be provided if available. Which it is not.
+		msgBody->locationInfo.refFrame = 65535;
+		
+		// GPS Time Of Week (optional) should be included if GPS Time Assistance 
+		// Measurements  are included in the Measure Position Response, or if the
+		// BTS Reference Frame is in the "ignore" range. Not available.
+		msgBody->locationInfo.m.gpsTOWPresent = 0;
+		
+		// Position Estimate 
+		// ASN1T_Ext_GeographicalInformation is a 20 byte array, populated as 
+		// described in 3GPP 23.032. 
+
+		// Latitude/Longitude description is common to all supported position types
+		// Latitude is 23 bits of value and 1 bit describing direction (0 = north, 1 = south)
+		TReal64 latitudeDegrees = position.Latitude();
+		TInt latitudeEncoded;
+		TBool isSouth = EFalse;
+		if (latitudeDegrees < 0)
+			{
+			latitudeDegrees *= -1;
+			isSouth = ETrue;
+			}
+		 
+		latitudeEncoded = latitudeDegrees * KLbsLatitudeConst;	// * 2^23 / 90
+		if (isSouth)
+			{
+			// set the 24th bit
+			latitudeEncoded |= KBit23;
+			}
+
+		// Longitude is 24 bit 2's complimentary binary
+		TReal64 longitudeDegrees = position.Longitude();
+		TInt longitudeEncoded;
+		TBool isNegative = EFalse;
+		if (longitudeDegrees < 0)
+			{
+			longitudeDegrees *= -1;
+			isNegative = ETrue;
+			}
+		
+		longitudeEncoded = longitudeDegrees *  16777216 / 360; // * 2^24 / 360
+		if (isNegative)
+			{
+			// invert and add 1 for 2's complimentary binary
+			longitudeEncoded = ~longitudeEncoded;
+			longitudeEncoded += 1;
+			}
+
+		// insert into the octet array
+		const TInt bottom8bits = 255;
+		msgBody->locationInfo.posEstimate.data[1] = (latitudeEncoded >> 16) & bottom8bits;
+		msgBody->locationInfo.posEstimate.data[2] = (latitudeEncoded >> 8) & bottom8bits;
+		msgBody->locationInfo.posEstimate.data[3] = (latitudeEncoded) & bottom8bits;
+
+		msgBody->locationInfo.posEstimate.data[4] = (longitudeEncoded >> 16) & bottom8bits;
+		msgBody->locationInfo.posEstimate.data[5] = (longitudeEncoded >> 8) & bottom8bits;
+		msgBody->locationInfo.posEstimate.data[6] = (longitudeEncoded) & bottom8bits;
+		
+		// encode the horizontal uncertainty, if present;
+		TInt horizontalUncertaintyEncoded = 0;
+		if (position.HorizontalAccuracy() > 0)
+			{
+			horizontalUncertaintyEncoded = MetersToHorizontalUncertainty(position.HorizontalAccuracy());
+			}
+				
+		// encode altitude if present in the position estimate:
+		TInt altitudeEncoded = 0;
+		TInt altitudeUncertaintyEncoded = 0;
+		if(!Math::IsNaN(position.Altitude()))
+			{
+			TBool isUp = ETrue;
+			TReal32 altitude = position.Altitude();
+			if (altitude < 0)
+				{
+				isUp = EFalse;
+				altitude *= -1;
+				}
+			if (altitude > 32767) // = (2^15)-1  maximum size is 15 bits.
+				{
+				altitude = 32767;
+				}
+			
+			altitudeEncoded = altitude;
+			// 16th bit indicates direction of altitude, 1 indicates below surface
+			if (!isUp)
+				{
+				altitudeEncoded |= KBit15;
+				}
+			
+			// is vertical accuracy defined?
+			if (position.VerticalAccuracy() != 0)
+				{
+				altitudeUncertaintyEncoded = MetersToVerticalUncertainty(position.VerticalAccuracy());
+				}
+			} // end of altitude conversion
+		
+		
+		// clear the first byte and set remaining content according to data available
+		if (altitudeEncoded)
+			{
+			// EEllipsoidPointWithAltitudeAndUncertaintyEllipsoid
+			msgBody->locationInfo.posEstimate.data[0]  = EGeoInfoEllipsoidPointWithAltitudeAndUncertaintyEllipsoid<<4;
+			msgBody->locationInfo.posEstimate.data[7]  = altitudeEncoded>>8;
+			msgBody->locationInfo.posEstimate.data[8]  = altitudeEncoded;
+			msgBody->locationInfo.posEstimate.data[9]  = horizontalUncertaintyEncoded; // semi-major axis
+			msgBody->locationInfo.posEstimate.data[10] = horizontalUncertaintyEncoded; // semi-major axis
+			msgBody->locationInfo.posEstimate.data[11] = 0; // orientation
+			msgBody->locationInfo.posEstimate.data[12] = altitudeUncertaintyEncoded;
+			msgBody->locationInfo.posEstimate.data[13] = 0; // confidence, 0 == "no information"
+			msgBody->locationInfo.posEstimate.numocts = 14;
+			
+			msgBody->locationInfo.fixType = FixType::threeDFix;
+			}
+		else if (horizontalUncertaintyEncoded)
+			{
+			// EEllipsoidPointWithUncertaintyCircle
+			msgBody->locationInfo.posEstimate.data[0] = EGeoInfoEllipsoidPointWithUncertaintyCircle<<4;
+			msgBody->locationInfo.posEstimate.data[7] = horizontalUncertaintyEncoded;
+			msgBody->locationInfo.posEstimate.numocts = 8;
+
+			msgBody->locationInfo.fixType = FixType::twoDFix;
+			}
+		else
+			{
+			// EEllipsoidPoint
+			msgBody->locationInfo.posEstimate.data[0] = EGeoInfoEllipsoidPoint<<4;
+			msgBody->locationInfo.posEstimate.numocts = 7;
+
+			msgBody->locationInfo.fixType = FixType::twoDFix;
+			}
+		}
+	else
+		{
+		SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetLocationInformation() End (not a EPositionInfoClass)\n");
+		return KErrNotSupported;
+		}
+	
+	// additional handling for extended satellite info 
+	if (aPosInfo.PositionClassType() & EPositionExtendedSatelliteInfoClass)
+	    {
+	    TPositionExtendedSatelliteInfo& extSatInfo = reinterpret_cast <TPositionExtendedSatelliteInfo&>(aPosInfo);
+
+	    // GPS Timing Measurements
+        TGpsTimingMeasurementData timingData;
+        if  (KErrNone == extSatInfo.GetGpsTimingData(timingData))
+            {
+            SetGpsTimingData(timingData);
+            }
+	    }
+
+
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetLocationInformation() End\n");
+	return KErrNone;
+	}
+
+/**	
+MetersToHorizontalUncertainty()
+
+Converts from meters to uncertainty code, as defined in 3GPP TS 23.032:
+uncertainty r = C( (1+x)^k - 1 )
+
+r = uncertainty in meters
+C = 10;
+x = 0.1
+k = uncertainty code
+
+hence k = ln(h/C + 1) / ln(1+x), limited to 7 bits
+*/
+TInt CRrlpMeasurePositionResponse::MetersToHorizontalUncertainty(const TReal32& aDistance)
+	{
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::MetersToHorizontalUncertainty() Begin\n");
+	TReal uncert;
+	Math::Ln(uncert,  (aDistance/10) + 1 );
+	uncert /= KLbsLogOnePointOne;
+	if (uncert>KLbsMaxUncert)
+		{
+		uncert = KLbsMaxUncert;
+		}
+
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::MetersToHorizontalUncertainty() End\n");
+	return (TInt)uncert;	
+	}
+
+/**	
+MetersToVerticalUncertainty()
+
+Converts from meters to uncertainty code, as defined in 3GPP TS 23.032:
+uncertainty h = C( (1+x)^k - 1 )
+
+h = uncertainty in meters
+C = 45;
+x = 0.025
+k = uncertainty code
+
+hence k = ln(h/C + 1) / ln(1+x), limited to 7 bits
+*/
+TInt CRrlpMeasurePositionResponse::MetersToVerticalUncertainty(const TReal32& aDistance)
+	{
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::MetersToVerticalUncertainty() Begin\n");
+	TReal uncert;
+	Math::Ln(uncert,  (aDistance/45) + 1 );
+	uncert /= KLbsLogOnePointZeroTwoFive;
+	if (uncert>KLbsMaxUncert)
+		{
+		uncert = KLbsMaxUncert;
+		}
+
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::MetersToVerticalUncertainty() End\n");
+	return (TInt)uncert;
+	}
+
+/** 
+Sets measurement information
+
+@param  aPosInfo reference to the reported position data from LBS
+@return error indication, KErrNone otherwise
+*/
+EXPORT_C TInt CRrlpMeasurePositionResponse::SetMeasurementInformation(const TPositionInfoBase& aPosInfo)
+	{
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetMeasurementInformation() Begin\n");
+	__ASSERT_DEBUG(iData->component.u.msrPositionRsp != NULL, User::Invariant());
+	
+	ASN1T_MsrPosition_Rsp* msgBody = iData->component.u.msrPositionRsp;
+	
+	// handle Position Info class type
+	if ((aPosInfo.PositionClassType() & EPositionGpsMeasurementInfoClass) != 0)
+		{
+		const TPositionGpsMeasurementInfo& measurementInfo = reinterpret_cast <const TPositionGpsMeasurementInfo&>(aPosInfo);
+		msgBody->m.gps_MeasureInfoPresent = 1;
+		
+		// only support the sending of a single set of GPS measurements.
+		ASN1C_SeqOfGPS_MsrSetElement msrSetArray(*iControl, msgBody->gps_MeasureInfo.gpsMsrSetList);
+		msrSetArray.init();
+		ASN1T_GPS_MsrSetElement* gpsMsrSetElement = msrSetArray.NewElement();
+		if (gpsMsrSetElement == NULL)
+			{
+			return KErrNoMemory;
+			}
+		
+		// LBS API does not provide optional Reference Frame information.
+		gpsMsrSetElement->m.refFramePresent = 0;
+		
+		// GPS Time Of Week - RRLP parameter is described as the least significant 
+		// 24 bits of the GPS TOW. Further study indicates it is in fact the result
+		// of the TOW within a 4 hour window period (144000000ms). Therefore the
+		// value is calculated as GPS_TOW_MS mod 144000000.
+		TReal tow = 0;
+		Math::Mod(tow, measurementInfo.GpsTimeOfWeek(), KLbsTowMod);
+		gpsMsrSetElement->gpsTOW = tow;
+		
+		// build the array of measurements
+		ASN1C_SeqOfGPS_MsrElement msrElementArray(*iControl, gpsMsrSetElement->gps_msrList);
+		msrElementArray.init();
+
+		for (TInt i = 0; i < measurementInfo.NumMeasurements(); ++i)
+			{
+			TPositionGpsMeasurementData data;
+			if (measurementInfo.GetMeasurementData(i, data) == KErrNone)
+				{
+				ASN1T_GPS_MsrElement* gpsMsrElement = msrElementArray.NewElement();
+				if (gpsMsrElement == NULL)
+					{
+					return KErrNoMemory;
+					}
+
+				gpsMsrElement->satelliteID     = data.SatelliteId();
+				gpsMsrElement->cNo             = data.CarrierNoiseRatio();
+				gpsMsrElement->doppler         = data.Doppler();
+				gpsMsrElement->wholeChips      = data.WholeGpsChips();
+				gpsMsrElement->fracChips       = data.FractionalGpsChips();
+				gpsMsrElement->mpathIndic      = data.MultiPathIndicator();
+				gpsMsrElement->pseuRangeRMSErr = data.PseudoRangeRmsError();
+				
+				msrElementArray.Append(gpsMsrElement);
+				}
+			}
+		msrSetArray.Append(gpsMsrSetElement);
+		
+		// append any GPS Timing Measurement Data
+		TGpsTimingMeasurementData timingData;
+		if  (KErrNone == measurementInfo.GetGpsTimingData(timingData))
+		    {
+		    SetGpsTimingData(timingData);
+		    }
+		}
+	
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetMeasurementInformation() End\n");
+	return KErrNone;
+	}
+
+
+/** 
+SetLocationError()
+
+Sets Location Error element
+
+@param  aLocError - location error
+@return error indication, KErrNone otherwise
+*/
+EXPORT_C TInt CRrlpMeasurePositionResponse::SetLocationError(TRrlpLocError aLocError)
+	{
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetLocationError() Begin\n");
+	SUPLLOG2(ELogP1, "    - TRrlpLocError aLocError = %d", aLocError);
+	
+	__ASSERT_DEBUG(iData->component.u.msrPositionRsp != NULL, User::Invariant());
+	ASN1T_MsrPosition_Rsp* msgBody = iData->component.u.msrPositionRsp;
+	msgBody->m.locationErrorPresent = 1;
+	msgBody->locationError.locErrorReason = aLocError;
+	
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetLocationError() End\n");
+	return KErrNone;
+	}
+
+	
+/** 
+SetLocationError()
+
+Sets Location Error element with request for additional assistance data 
+
+@see TRrlpLocError
+@param  aLocError - location error
+@return error indication, KErrNone otherwise
+*/
+EXPORT_C TInt CRrlpMeasurePositionResponse::SetLocationError(TRrlpLocError aLocError, const TLbsAsistanceDataGroup& aDataReqMask)
+	{
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetLocationError() Begin\n");
+	SUPLLOG2(ELogP1, "    - TRrlpLocError aLocError = %d", aLocError);
+	SUPLLOG2(ELogP1, "    - TLbsAsistanceDataGroup aDataReqMask  = 0x%08X\n", aDataReqMask);
+	
+	__ASSERT_DEBUG(iData->component.u.msrPositionRsp != NULL, User::Invariant());
+	ASN1T_MsrPosition_Rsp* msgBody = iData->component.u.msrPositionRsp;
+	msgBody->m.locationErrorPresent = 1;
+	msgBody->locationError.locErrorReason = aLocError;
+
+	// Additional Assistance Data is encoded according to 3GPP TS 49.031, excluding
+	// the IEI and length octets.
+	if (aDataReqMask != EAssistanceDataNone)
+		{
+		msgBody->locationError.m.additionalAssistanceDataPresent = 1;
+		//ASN1T_AdditionalAssistanceData
+		msgBody->locationError.additionalAssistanceData.m.extensionContainerPresent = 0;
+		msgBody->locationError.additionalAssistanceData.m.gpsAssistanceDataPresent = 1;
+
+		// short name reference
+		ASN1T_GPSAssistanceData& requestedData = msgBody->locationError.additionalAssistanceData.gpsAssistanceData;
+
+		// ensure the data masks are clear and set number of octets to be sent
+		requestedData.data[0] = 0;
+		requestedData.data[1] = 0;
+		requestedData.numocts = 2;
+				
+		// set requested assistance types
+		// we do not request Ephemeris Extension or Ephemeris Extension Check or inform
+		// the SMLC of satellite specific information we already have.
+		// data is described by bit location, as per the following:
+
+		//         | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
+		// octet 1 | H | G | F | E | D | C | B | A | 
+		// octet 2 | P | O | N | M | L | K | J | I |
+		if (EAssistanceDataAquisitionAssistance & aDataReqMask)
+			{
+			// bit H
+			requestedData.data[0] |= 1<<7;
+			}
+		if (EAssistanceDataBadSatList & aDataReqMask)
+			{
+			// bit I
+			requestedData.data[1] |= 1;
+			}
+		if (EAssistanceDataNavigationModel & aDataReqMask)
+			{
+			// bit D
+			requestedData.data[0] |= 1<<3;
+			}
+		if (EAssistanceDataReferenceTime & aDataReqMask)
+			{
+			// bit G
+			requestedData.data[0] |= 1<<6;
+			}
+		if (EAssistanceDataIonosphericModel & aDataReqMask)
+			{
+			// bit C
+			requestedData.data[0] |= 1<<2;
+			}
+		if (EAssistanceDataDgpsCorrections & aDataReqMask)
+			{
+			// bit E
+			requestedData.data[0] |= 1<<4;
+			}
+		if (EAssistanceDataReferenceLocation & aDataReqMask)
+			{
+		 	// bit F
+		 	requestedData.data[0] |= 1<<5;
+			}
+		if (EAssistanceDataAlmanac & aDataReqMask)
+			{
+			// bit A
+			requestedData.data[0] |= 1;
+			}
+		if (EAssistanceDataPositioningGpsUtcModel & aDataReqMask)
+			{
+			// bit B
+			requestedData.data[0] |= 1<<1;
+			}
+		}
+	
+	SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetLocationError() End\n");
+	return KErrNone;
+	}
+
+/** 
+SetGpsTimingData()
+
+Sets GPS Fine Timing Data
+
+@see TGpsTimingMeasurementData
+@param  aTimingData - timing data
+@return error indication, KErrNone otherwise
+*/
+void CRrlpMeasurePositionResponse::SetGpsTimingData(const TGpsTimingMeasurementData& aTimingData)
+    {
+    SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetGpsTimingData() Begin\n");
+    
+    // check that the timing structure contains GPS data
+    if (TGpsTimingMeasurementData::EGpsTimingDataTypeGsm != aTimingData.DataType())
+        {
+        SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetGpsTimingData() End Unsupported Data Type\n");
+        return;
+        }
+        
+    __ASSERT_DEBUG(iData->component.u.msrPositionRsp != NULL, User::Invariant());
+    ASN1T_MsrPosition_Rsp* msgBody = iData->component.u.msrPositionRsp;
+
+    // mark r98 extension and timing measurements parameter present
+    msgBody->m.rel_98_MsrPosition_Rsp_ExtensionPresent = 1;
+    msgBody->rel_98_MsrPosition_Rsp_Extension.m.timeAssistanceMeasurementsPresent = 1;
+    
+    // reference to the data member to be populated
+    ASN1T_GPSTimeAssistanceMeasurements& measurements = msgBody->rel_98_MsrPosition_Rsp_Extension.timeAssistanceMeasurements;
+
+    // populate the data structure. 
+    measurements.referenceFrameMSB = aTimingData.ReferenceFrameMsb();
+    if (aTimingData.GpsTowSubms() >= 0)
+        {
+        measurements.m.gpsTowSubmsPresent = 1;
+        measurements.gpsTowSubms = aTimingData.GpsTowSubms();
+        }
+    if (aTimingData.DeltaTow() >= 0)
+        {
+        measurements.m.deltaTowPresent = 1;
+        measurements.deltaTow = aTimingData.DeltaTow();
+        }
+    if (aTimingData.GpsReferenceTimeUncertainty() >= 0)
+        {
+        measurements.m.gpsReferenceTimeUncertaintyPresent = 1;
+        measurements.gpsReferenceTimeUncertainty = aTimingData.GpsReferenceTimeUncertainty();
+        }
+
+    SUPLLOG(ELogP1, "CRrlpMeasurePositionResponse::SetGpsTimingData() End\n");
+    return;
+    }
+
+
+/**
+SetExtendedReference()
+
+Sets the extended reference parameters in the outgoing message, if they are set
+in the passed container.
+
+@param aRrlpRef on return, populated with the session reference details
+@return KErrNotFound if no extended reference data is present, 
+		KErrNone otherwise
+*/	
+TInt CRrlpMeasurePositionResponse::SetExtendedReference(const TRrlpReference& aRrlpRef)
+	{
+	__ASSERT_DEBUG(iData->component.u.msrPositionRsp != NULL, User::Invariant());
+	
+	// if present, populate the optional Rel-5 extended reference
+	if (aRrlpRef.aRel5EntendedRefPresent)
+		{
+		// mark the optional component present
+		iData->component.u.msrPositionRsp->m.rel_5_MsrPosition_Rsp_ExtensionPresent = 1;
+		iData->component.u.msrPositionRsp->rel_5_MsrPosition_Rsp_Extension.m.extended_referencePresent = 1;
+		ASN1T_Extended_reference* extendedRef = &iData->component.u.msrPositionRsp->rel_5_MsrPosition_Rsp_Extension.extended_reference;
+		extendedRef->smlc_code = aRrlpRef.aRel5SmlcCode;
+		extendedRef->transaction_ID = aRrlpRef.aRel5TransactionId;
+		}
+	else
+		{
+		return KErrNotFound;
+		}
+	
+	return KErrNone;
+	}
+