1 /*
2 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
3 * Not a Contribution
4 */
5 /*
6 * Copyright (C) 2016 The Android Open Source Project
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 #define LOG_TAG "LocSvc_GnssDebugInterface"
22
23 #include <log/log.h>
24 #include <log_util.h>
25 #include "Gnss.h"
26 #include "GnssDebug.h"
27 #include "LocationUtil.h"
28
29 namespace android {
30 namespace hardware {
31 namespace gnss {
32 namespace V2_0 {
33 namespace implementation {
34
35 using ::android::hardware::hidl_vec;
36 using ::android::hardware::gnss::V2_0::IGnssDebug;
37
38 #define GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS (20000000)
39 #define GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS (20000)
40 #define GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC (500)
41 #define GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG (180)
42
43 #define GNSS_DEBUG_UNKNOWN_UTC_TIME (1483228800000LL) // 1/1/2017 00:00 GMT
44 #define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MIN (999) // 999 ns
45 #define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX (1.57783680E17) // 5 years in ns
46 #define GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC (2.0e5) // ppm
47
GnssDebug(Gnss * gnss)48 GnssDebug::GnssDebug(Gnss* gnss) : mGnss(gnss)
49 {
50 }
51
52 /*
53 * This methods requests position, time and satellite ephemeris debug information
54 * from the HAL.
55 *
56 * @return void
57 */
getDebugData(getDebugData_cb _hidl_cb)58 Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)
59 {
60 LOC_LOGD("%s]: ", __func__);
61
62 V1_0::IGnssDebug::DebugData data = { };
63
64 if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
65 LOC_LOGE("GnssDebug - Null GNSS interface");
66 _hidl_cb(data);
67 return Void();
68 }
69
70 // get debug report snapshot via hal interface
71 GnssDebugReport reports = { };
72 mGnss->getGnssInterface()->getDebugReport(reports);
73
74 // location block
75 if (reports.mLocation.mValid) {
76 data.position.valid = true;
77 data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
78 data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
79 data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
80
81 data.position.speedMetersPerSec =
82 (double)(reports.mLocation.mLocation.speed);
83 data.position.bearingDegrees =
84 (double)(reports.mLocation.mLocation.bearing);
85 data.position.horizontalAccuracyMeters =
86 (double)(reports.mLocation.mLocation.accuracy);
87 data.position.verticalAccuracyMeters =
88 reports.mLocation.verticalAccuracyMeters;
89 data.position.speedAccuracyMetersPerSecond =
90 reports.mLocation.speedAccuracyMetersPerSecond;
91 data.position.bearingAccuracyDegrees =
92 reports.mLocation.bearingAccuracyDegrees;
93
94 timeval tv_now, tv_report;
95 tv_report.tv_sec = reports.mLocation.mUtcReported.tv_sec;
96 tv_report.tv_usec = reports.mLocation.mUtcReported.tv_nsec / 1000ULL;
97 gettimeofday(&tv_now, NULL);
98 data.position.ageSeconds =
99 (tv_now.tv_sec - tv_report.tv_sec) +
100 (float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
101 }
102 else {
103 data.position.valid = false;
104 }
105
106 if (data.position.horizontalAccuracyMeters <= 0 ||
107 data.position.horizontalAccuracyMeters > GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS) {
108 data.position.horizontalAccuracyMeters = GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS;
109 }
110 if (data.position.verticalAccuracyMeters <= 0 ||
111 data.position.verticalAccuracyMeters > GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS) {
112 data.position.verticalAccuracyMeters = GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS;
113 }
114 if (data.position.speedAccuracyMetersPerSecond <= 0 ||
115 data.position.speedAccuracyMetersPerSecond > GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC) {
116 data.position.speedAccuracyMetersPerSecond = GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC;
117 }
118 if (data.position.bearingAccuracyDegrees <= 0 ||
119 data.position.bearingAccuracyDegrees > GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG) {
120 data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG;
121 }
122
123 // time block
124 if (reports.mTime.mValid) {
125 data.time.timeEstimate = reports.mTime.timeEstimate;
126 data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
127 data.time.frequencyUncertaintyNsPerSec =
128 reports.mTime.frequencyUncertaintyNsPerSec;
129 }
130
131 if (data.time.timeEstimate < GNSS_DEBUG_UNKNOWN_UTC_TIME) {
132 data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME;
133 }
134 if (data.time.timeUncertaintyNs <= 0) {
135 data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MIN;
136 } else if (data.time.timeUncertaintyNs > GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX) {
137 data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX;
138 }
139 if (data.time.frequencyUncertaintyNsPerSec <= 0 ||
140 data.time.frequencyUncertaintyNsPerSec > (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC) {
141 data.time.frequencyUncertaintyNsPerSec = (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC;
142 }
143
144 // satellite data block
145 V1_0::IGnssDebug::SatelliteData s = { };
146 std::vector<V1_0::IGnssDebug::SatelliteData> s_array;
147
148 for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
149 memset(&s, 0, sizeof(s));
150 s.svid = reports.mSatelliteInfo[i].svid;
151 convertGnssConstellationType(
152 reports.mSatelliteInfo[i].constellation, s.constellation);
153 convertGnssEphemerisType(
154 reports.mSatelliteInfo[i].mEphemerisType, s.ephemerisType);
155 convertGnssEphemerisSource(
156 reports.mSatelliteInfo[i].mEphemerisSource, s.ephemerisSource);
157 convertGnssEphemerisHealth(
158 reports.mSatelliteInfo[i].mEphemerisHealth, s.ephemerisHealth);
159
160 s.ephemerisAgeSeconds =
161 reports.mSatelliteInfo[i].ephemerisAgeSeconds;
162 s.serverPredictionIsAvailable =
163 reports.mSatelliteInfo[i].serverPredictionIsAvailable;
164 s.serverPredictionAgeSeconds =
165 reports.mSatelliteInfo[i].serverPredictionAgeSeconds;
166
167 s_array.push_back(s);
168 }
169 data.satelliteDataArray = s_array;
170
171 // callback HIDL with collected debug data
172 _hidl_cb(data);
173 return Void();
174 }
175
getDebugData_2_0(getDebugData_2_0_cb _hidl_cb)176 Return<void> GnssDebug::getDebugData_2_0(getDebugData_2_0_cb _hidl_cb)
177 {
178 LOC_LOGD("%s]: ", __func__);
179
180 V2_0::IGnssDebug::DebugData data = { };
181
182 if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
183 LOC_LOGE("GnssDebug - Null GNSS interface");
184 _hidl_cb(data);
185 return Void();
186 }
187
188 // get debug report snapshot via hal interface
189 GnssDebugReport reports = { };
190 mGnss->getGnssInterface()->getDebugReport(reports);
191
192 // location block
193 if (reports.mLocation.mValid) {
194 data.position.valid = true;
195 data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
196 data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
197 data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
198
199 data.position.speedMetersPerSec =
200 (double)(reports.mLocation.mLocation.speed);
201 data.position.bearingDegrees =
202 (double)(reports.mLocation.mLocation.bearing);
203 data.position.horizontalAccuracyMeters =
204 (double)(reports.mLocation.mLocation.accuracy);
205 data.position.verticalAccuracyMeters =
206 reports.mLocation.verticalAccuracyMeters;
207 data.position.speedAccuracyMetersPerSecond =
208 reports.mLocation.speedAccuracyMetersPerSecond;
209 data.position.bearingAccuracyDegrees =
210 reports.mLocation.bearingAccuracyDegrees;
211
212 timeval tv_now, tv_report;
213 tv_report.tv_sec = reports.mLocation.mUtcReported.tv_sec;
214 tv_report.tv_usec = reports.mLocation.mUtcReported.tv_nsec / 1000ULL;
215 gettimeofday(&tv_now, NULL);
216 data.position.ageSeconds =
217 (tv_now.tv_sec - tv_report.tv_sec) +
218 (float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
219 }
220 else {
221 data.position.valid = false;
222 }
223
224 if (data.position.horizontalAccuracyMeters <= 0 ||
225 data.position.horizontalAccuracyMeters > GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS) {
226 data.position.horizontalAccuracyMeters = GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS;
227 }
228 if (data.position.verticalAccuracyMeters <= 0 ||
229 data.position.verticalAccuracyMeters > GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS) {
230 data.position.verticalAccuracyMeters = GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS;
231 }
232 if (data.position.speedAccuracyMetersPerSecond <= 0 ||
233 data.position.speedAccuracyMetersPerSecond > GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC) {
234 data.position.speedAccuracyMetersPerSecond = GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC;
235 }
236 if (data.position.bearingAccuracyDegrees <= 0 ||
237 data.position.bearingAccuracyDegrees > GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG) {
238 data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG;
239 }
240
241 // time block
242 if (reports.mTime.mValid) {
243 data.time.timeEstimate = reports.mTime.timeEstimate;
244 data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
245 data.time.frequencyUncertaintyNsPerSec =
246 reports.mTime.frequencyUncertaintyNsPerSec;
247 }
248
249 if (data.time.timeEstimate < GNSS_DEBUG_UNKNOWN_UTC_TIME) {
250 data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME;
251 }
252 if (data.time.timeUncertaintyNs <= 0) {
253 data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MIN;
254 }
255 else if (data.time.timeUncertaintyNs > GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX) {
256 data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX;
257 }
258 if (data.time.frequencyUncertaintyNsPerSec <= 0 ||
259 data.time.frequencyUncertaintyNsPerSec > (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC) {
260 data.time.frequencyUncertaintyNsPerSec = (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC;
261 }
262
263 // satellite data block
264 V2_0::IGnssDebug::SatelliteData s = { };
265 std::vector<V2_0::IGnssDebug::SatelliteData> s_array;
266
267 for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
268 memset(&s, 0, sizeof(s));
269 s.v1_0.svid = reports.mSatelliteInfo[i].svid;
270 convertGnssConstellationType(
271 reports.mSatelliteInfo[i].constellation, s.constellation);
272 convertGnssEphemerisType(
273 reports.mSatelliteInfo[i].mEphemerisType, s.v1_0.ephemerisType);
274 convertGnssEphemerisSource(
275 reports.mSatelliteInfo[i].mEphemerisSource, s.v1_0.ephemerisSource);
276 convertGnssEphemerisHealth(
277 reports.mSatelliteInfo[i].mEphemerisHealth, s.v1_0.ephemerisHealth);
278
279 s.v1_0.ephemerisAgeSeconds =
280 reports.mSatelliteInfo[i].ephemerisAgeSeconds;
281 s.v1_0.serverPredictionIsAvailable =
282 reports.mSatelliteInfo[i].serverPredictionIsAvailable;
283 s.v1_0.serverPredictionAgeSeconds =
284 reports.mSatelliteInfo[i].serverPredictionAgeSeconds;
285
286 s_array.push_back(s);
287 }
288 data.satelliteDataArray = s_array;
289
290 // callback HIDL with collected debug data
291 _hidl_cb(data);
292 return Void();
293 }
294
295 } // namespace implementation
296 } // namespace V2_0
297 } // namespace gnss
298 } // namespace hardware
299 } // namespace android
300