--- /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;
+ }
+