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