1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "GnssHAL_GnssMeasurementInterface" 18 19 #include "GnssMeasurement.h" 20 21 namespace android { 22 namespace hardware { 23 namespace gnss { 24 namespace V1_0 { 25 namespace implementation { 26 27 sp<IGnssMeasurementCallback> GnssMeasurement::sGnssMeasureCbIface = nullptr; 28 GpsMeasurementCallbacks GnssMeasurement::sGnssMeasurementCbs = { 29 .size = sizeof(GpsMeasurementCallbacks), 30 .measurement_callback = gpsMeasurementCb, 31 .gnss_measurement_callback = gnssMeasurementCb 32 }; 33 34 GnssMeasurement::GnssMeasurement(const GpsMeasurementInterface* gpsMeasurementIface) 35 : mGnssMeasureIface(gpsMeasurementIface) {} 36 37 void GnssMeasurement::gnssMeasurementCb(LegacyGnssData* legacyGnssData) { 38 if (sGnssMeasureCbIface == nullptr) { 39 ALOGE("%s: GNSSMeasurement Callback Interface configured incorrectly", __func__); 40 return; 41 } 42 43 if (legacyGnssData == nullptr) { 44 ALOGE("%s: Invalid GnssData from GNSS HAL", __func__); 45 return; 46 } 47 48 IGnssMeasurementCallback::GnssData gnssData; 49 gnssData.measurementCount = std::min(legacyGnssData->measurement_count, 50 static_cast<size_t>(GnssMax::SVS_COUNT)); 51 52 for (size_t i = 0; i < gnssData.measurementCount; i++) { 53 auto entry = legacyGnssData->measurements[i]; 54 auto state = static_cast<GnssMeasurementState>(entry.state); 55 if (state & IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED) { 56 state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_KNOWN; 57 } 58 if (state & IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED) { 59 state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_KNOWN; 60 } 61 gnssData.measurements[i] = { 62 .flags = entry.flags, 63 .svid = entry.svid, 64 .constellation = static_cast<GnssConstellationType>(entry.constellation), 65 .timeOffsetNs = entry.time_offset_ns, 66 .state = state, 67 .receivedSvTimeInNs = entry.received_sv_time_in_ns, 68 .receivedSvTimeUncertaintyInNs = entry.received_sv_time_uncertainty_in_ns, 69 .cN0DbHz = entry.c_n0_dbhz, 70 .pseudorangeRateMps = entry.pseudorange_rate_mps, 71 .pseudorangeRateUncertaintyMps = entry.pseudorange_rate_uncertainty_mps, 72 .accumulatedDeltaRangeState = entry.accumulated_delta_range_state, 73 .accumulatedDeltaRangeM = entry.accumulated_delta_range_m, 74 .accumulatedDeltaRangeUncertaintyM = entry.accumulated_delta_range_uncertainty_m, 75 .carrierFrequencyHz = entry.carrier_frequency_hz, 76 .carrierCycles = entry.carrier_cycles, 77 .carrierPhase = entry.carrier_phase, 78 .carrierPhaseUncertainty = entry.carrier_phase_uncertainty, 79 .multipathIndicator = static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>( 80 entry.multipath_indicator), 81 .snrDb = entry.snr_db 82 }; 83 } 84 85 auto clockVal = legacyGnssData->clock; 86 gnssData.clock = { 87 .gnssClockFlags = clockVal.flags, 88 .leapSecond = clockVal.leap_second, 89 .timeNs = clockVal.time_ns, 90 .timeUncertaintyNs = clockVal.time_uncertainty_ns, 91 .fullBiasNs = clockVal.full_bias_ns, 92 .biasNs = clockVal.bias_ns, 93 .biasUncertaintyNs = clockVal.bias_uncertainty_ns, 94 .driftNsps = clockVal.drift_nsps, 95 .driftUncertaintyNsps = clockVal.drift_uncertainty_nsps, 96 .hwClockDiscontinuityCount = clockVal.hw_clock_discontinuity_count 97 }; 98 99 auto ret = sGnssMeasureCbIface->GnssMeasurementCb(gnssData); 100 if (!ret.isOk()) { 101 ALOGE("%s: Unable to invoke callback", __func__); 102 } 103 } 104 105 /* 106 * The code in the following method has been moved here from GnssLocationProvider. 107 * It converts GpsData to GnssData. This code is no longer required in 108 * GnssLocationProvider since GpsData is deprecated and no longer part of the 109 * GNSS interface. 110 */ 111 void GnssMeasurement::gpsMeasurementCb(GpsData* gpsData) { 112 if (sGnssMeasureCbIface == nullptr) { 113 ALOGE("%s: GNSSMeasurement Callback Interface configured incorrectly", __func__); 114 return; 115 } 116 117 if (gpsData == nullptr) { 118 ALOGE("%s: Invalid GpsData from GNSS HAL", __func__); 119 return; 120 } 121 122 IGnssMeasurementCallback::GnssData gnssData; 123 gnssData.measurementCount = std::min(gpsData->measurement_count, 124 static_cast<size_t>(GnssMax::SVS_COUNT)); 125 126 127 for (size_t i = 0; i < gnssData.measurementCount; i++) { 128 auto entry = gpsData->measurements[i]; 129 gnssData.measurements[i].flags = entry.flags; 130 gnssData.measurements[i].svid = static_cast<int32_t>(entry.prn); 131 if (entry.prn >= 1 && entry.prn <= 32) { 132 gnssData.measurements[i].constellation = GnssConstellationType::GPS; 133 } else { 134 gnssData.measurements[i].constellation = 135 GnssConstellationType::UNKNOWN; 136 } 137 138 gnssData.measurements[i].timeOffsetNs = entry.time_offset_ns; 139 gnssData.measurements[i].state = entry.state; 140 gnssData.measurements[i].receivedSvTimeInNs = entry.received_gps_tow_ns; 141 gnssData.measurements[i].receivedSvTimeUncertaintyInNs = 142 entry.received_gps_tow_uncertainty_ns; 143 gnssData.measurements[i].cN0DbHz = entry.c_n0_dbhz; 144 gnssData.measurements[i].pseudorangeRateMps = entry.pseudorange_rate_mps; 145 gnssData.measurements[i].pseudorangeRateUncertaintyMps = 146 entry.pseudorange_rate_uncertainty_mps; 147 gnssData.measurements[i].accumulatedDeltaRangeState = 148 entry.accumulated_delta_range_state; 149 gnssData.measurements[i].accumulatedDeltaRangeM = 150 entry.accumulated_delta_range_m; 151 gnssData.measurements[i].accumulatedDeltaRangeUncertaintyM = 152 entry.accumulated_delta_range_uncertainty_m; 153 154 if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY) { 155 gnssData.measurements[i].carrierFrequencyHz = entry.carrier_frequency_hz; 156 } else { 157 gnssData.measurements[i].carrierFrequencyHz = 0; 158 } 159 160 if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_PHASE) { 161 gnssData.measurements[i].carrierPhase = entry.carrier_phase; 162 } else { 163 gnssData.measurements[i].carrierPhase = 0; 164 } 165 166 if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY) { 167 gnssData.measurements[i].carrierPhaseUncertainty = entry.carrier_phase_uncertainty; 168 } else { 169 gnssData.measurements[i].carrierPhaseUncertainty = 0; 170 } 171 172 gnssData.measurements[i].multipathIndicator = 173 static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>( 174 entry.multipath_indicator); 175 176 if (entry.flags & GNSS_MEASUREMENT_HAS_SNR) { 177 gnssData.measurements[i].snrDb = entry.snr_db; 178 } else { 179 gnssData.measurements[i].snrDb = 0; 180 } 181 } 182 183 auto clockVal = gpsData->clock; 184 static uint32_t discontinuity_count_to_handle_old_clock_type = 0; 185 186 gnssData.clock.leapSecond = clockVal.leap_second; 187 /* 188 * GnssClock only supports the more effective HW_CLOCK type, so type 189 * handling and documentation complexity has been removed. To convert the 190 * old GPS_CLOCK types (active only in a limited number of older devices), 191 * the GPS time information is handled as an always discontinuous HW clock, 192 * with the GPS time information put into the full_bias_ns instead - so that 193 * time_ns - full_bias_ns = local estimate of GPS time. Additionally, the 194 * sign of full_bias_ns and bias_ns has flipped between GpsClock & 195 * GnssClock, so that is also handled below. 196 */ 197 switch (clockVal.type) { 198 case GPS_CLOCK_TYPE_UNKNOWN: 199 // Clock type unsupported. 200 ALOGE("Unknown clock type provided."); 201 break; 202 case GPS_CLOCK_TYPE_LOCAL_HW_TIME: 203 // Already local hardware time. No need to do anything. 204 break; 205 case GPS_CLOCK_TYPE_GPS_TIME: 206 // GPS time, need to convert. 207 clockVal.flags |= GPS_CLOCK_HAS_FULL_BIAS; 208 clockVal.full_bias_ns = clockVal.time_ns; 209 clockVal.time_ns = 0; 210 gnssData.clock.hwClockDiscontinuityCount = 211 discontinuity_count_to_handle_old_clock_type++; 212 break; 213 } 214 215 gnssData.clock.timeNs = clockVal.time_ns; 216 gnssData.clock.timeUncertaintyNs = clockVal.time_uncertainty_ns; 217 /* 218 * Definition of sign for full_bias_ns & bias_ns has been changed since N, 219 * so flip signs here. 220 */ 221 gnssData.clock.fullBiasNs = -(clockVal.full_bias_ns); 222 gnssData.clock.biasNs = -(clockVal.bias_ns); 223 gnssData.clock.biasUncertaintyNs = clockVal.bias_uncertainty_ns; 224 gnssData.clock.driftNsps = clockVal.drift_nsps; 225 gnssData.clock.driftUncertaintyNsps = clockVal.drift_uncertainty_nsps; 226 gnssData.clock.gnssClockFlags = clockVal.flags; 227 228 auto ret = sGnssMeasureCbIface->GnssMeasurementCb(gnssData); 229 if (!ret.isOk()) { 230 ALOGE("%s: Unable to invoke callback", __func__); 231 } 232 } 233 234 // Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow. 235 Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback( 236 const sp<IGnssMeasurementCallback>& callback) { 237 if (mGnssMeasureIface == nullptr) { 238 ALOGE("%s: GnssMeasure interface is unavailable", __func__); 239 return GnssMeasurementStatus::ERROR_GENERIC; 240 } 241 sGnssMeasureCbIface = callback; 242 243 return static_cast<GnssMeasurement::GnssMeasurementStatus>( 244 mGnssMeasureIface->init(&sGnssMeasurementCbs)); 245 } 246 247 Return<void> GnssMeasurement::close() { 248 if (mGnssMeasureIface == nullptr) { 249 ALOGE("%s: GnssMeasure interface is unavailable", __func__); 250 } else { 251 mGnssMeasureIface->close(); 252 } 253 return Void(); 254 } 255 256 } // namespace implementation 257 } // namespace V1_0 258 } // namespace gnss 259 } // namespace hardware 260 } // namespace android 261