diff -r 000000000000 -r 9cfd9a3ee49c networkprotocolmodules/common/suplrrlpasn1/src/rrlpmeasureposresponse.cpp --- /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 +#include +#include + +/* +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 (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 (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 (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; + } +