1 /* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation, nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #include <LocationUtil.h>
31 #include <log_util.h>
32 #include <inttypes.h>
33 #include <gps_extended_c.h>
34 #include <loc_misc_utils.h>
35
36 namespace android {
37 namespace hardware {
38 namespace gnss {
39 namespace V2_0 {
40 namespace implementation {
41
42 using ::android::hardware::gnss::V2_0::GnssLocation;
43 using ::android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
44 using ::android::hardware::gnss::V2_0::GnssConstellationType;
45 using ::android::hardware::gnss::V1_0::GnssLocationFlags;
46
convertGnssLocation(Location & in,V1_0::GnssLocation & out)47 void convertGnssLocation(Location& in, V1_0::GnssLocation& out)
48 {
49 memset(&out, 0, sizeof(V1_0::GnssLocation));
50 if (in.flags & LOCATION_HAS_LAT_LONG_BIT) {
51 out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
52 out.latitudeDegrees = in.latitude;
53 out.longitudeDegrees = in.longitude;
54 }
55 if (in.flags & LOCATION_HAS_ALTITUDE_BIT) {
56 out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
57 out.altitudeMeters = in.altitude;
58 }
59 if (in.flags & LOCATION_HAS_SPEED_BIT) {
60 out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
61 out.speedMetersPerSec = in.speed;
62 }
63 if (in.flags & LOCATION_HAS_BEARING_BIT) {
64 out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
65 out.bearingDegrees = in.bearing;
66 }
67 if (in.flags & LOCATION_HAS_ACCURACY_BIT) {
68 out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
69 out.horizontalAccuracyMeters = in.accuracy;
70 }
71 if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) {
72 out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
73 out.verticalAccuracyMeters = in.verticalAccuracy;
74 }
75 if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) {
76 out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
77 out.speedAccuracyMetersPerSecond = in.speedAccuracy;
78 }
79 if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) {
80 out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
81 out.bearingAccuracyDegrees = in.bearingAccuracy;
82 }
83
84 out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
85 }
86
convertGnssLocation(Location & in,V2_0::GnssLocation & out)87 void convertGnssLocation(Location& in, V2_0::GnssLocation& out)
88 {
89 memset(&out, 0, sizeof(V2_0::GnssLocation));
90 convertGnssLocation(in, out.v1_0);
91
92 if (in.flags & LOCATION_HAS_ELAPSED_REAL_TIME) {
93 out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
94 out.elapsedRealtime.timestampNs = in.elapsedRealTime;
95 out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
96 out.elapsedRealtime.timeUncertaintyNs = in.elapsedRealTimeUnc;
97 LOC_LOGd("out.elapsedRealtime.timestampNs=%" PRIi64 ""
98 " out.elapsedRealtime.timeUncertaintyNs=%" PRIi64 ""
99 " out.elapsedRealtime.flags=0x%X",
100 out.elapsedRealtime.timestampNs,
101 out.elapsedRealtime.timeUncertaintyNs, out.elapsedRealtime.flags);
102 }
103 }
104
convertGnssLocation(const V1_0::GnssLocation & in,Location & out)105 void convertGnssLocation(const V1_0::GnssLocation& in, Location& out)
106 {
107 memset(&out, 0, sizeof(out));
108 if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) {
109 out.flags |= LOCATION_HAS_LAT_LONG_BIT;
110 out.latitude = in.latitudeDegrees;
111 out.longitude = in.longitudeDegrees;
112 }
113 if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE) {
114 out.flags |= LOCATION_HAS_ALTITUDE_BIT;
115 out.altitude = in.altitudeMeters;
116 }
117 if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED) {
118 out.flags |= LOCATION_HAS_SPEED_BIT;
119 out.speed = in.speedMetersPerSec;
120 }
121 if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
122 out.flags |= LOCATION_HAS_BEARING_BIT;
123 out.bearing = in.bearingDegrees;
124 }
125 if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
126 out.flags |= LOCATION_HAS_ACCURACY_BIT;
127 out.accuracy = in.horizontalAccuracyMeters;
128 }
129 if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
130 out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
131 out.verticalAccuracy = in.verticalAccuracyMeters;
132 }
133 if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
134 out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
135 out.speedAccuracy = in.speedAccuracyMetersPerSecond;
136 }
137 if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
138 out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
139 out.bearingAccuracy = in.bearingAccuracyDegrees;
140 }
141
142 out.timestamp = static_cast<uint64_t>(in.timestamp);
143 }
144
convertGnssLocation(const V2_0::GnssLocation & in,Location & out)145 void convertGnssLocation(const V2_0::GnssLocation& in, Location& out)
146 {
147 memset(&out, 0, sizeof(out));
148 convertGnssLocation(in.v1_0, out);
149 }
150
convertGnssConstellationType(GnssSvType & in,V1_0::GnssConstellationType & out)151 void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out)
152 {
153 switch(in) {
154 case GNSS_SV_TYPE_GPS:
155 out = V1_0::GnssConstellationType::GPS;
156 break;
157 case GNSS_SV_TYPE_SBAS:
158 out = V1_0::GnssConstellationType::SBAS;
159 break;
160 case GNSS_SV_TYPE_GLONASS:
161 out = V1_0::GnssConstellationType::GLONASS;
162 break;
163 case GNSS_SV_TYPE_QZSS:
164 out = V1_0::GnssConstellationType::QZSS;
165 break;
166 case GNSS_SV_TYPE_BEIDOU:
167 out = V1_0::GnssConstellationType::BEIDOU;
168 break;
169 case GNSS_SV_TYPE_GALILEO:
170 out = V1_0::GnssConstellationType::GALILEO;
171 break;
172 case GNSS_SV_TYPE_UNKNOWN:
173 default:
174 out = V1_0::GnssConstellationType::UNKNOWN;
175 break;
176 }
177 }
178
convertGnssConstellationType(GnssSvType & in,V2_0::GnssConstellationType & out)179 void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out)
180 {
181 switch(in) {
182 case GNSS_SV_TYPE_GPS:
183 out = V2_0::GnssConstellationType::GPS;
184 break;
185 case GNSS_SV_TYPE_SBAS:
186 out = V2_0::GnssConstellationType::SBAS;
187 break;
188 case GNSS_SV_TYPE_GLONASS:
189 out = V2_0::GnssConstellationType::GLONASS;
190 break;
191 case GNSS_SV_TYPE_QZSS:
192 out = V2_0::GnssConstellationType::QZSS;
193 break;
194 case GNSS_SV_TYPE_BEIDOU:
195 out = V2_0::GnssConstellationType::BEIDOU;
196 break;
197 case GNSS_SV_TYPE_GALILEO:
198 out = V2_0::GnssConstellationType::GALILEO;
199 break;
200 case GNSS_SV_TYPE_NAVIC:
201 out = V2_0::GnssConstellationType::IRNSS;
202 break;
203 case GNSS_SV_TYPE_UNKNOWN:
204 default:
205 out = V2_0::GnssConstellationType::UNKNOWN;
206 break;
207 }
208 }
209
convertGnssSvid(GnssSv & in,int16_t & out)210 void convertGnssSvid(GnssSv& in, int16_t& out)
211 {
212 switch (in.type) {
213 case GNSS_SV_TYPE_GPS:
214 out = in.svId;
215 break;
216 case GNSS_SV_TYPE_SBAS:
217 out = in.svId;
218 break;
219 case GNSS_SV_TYPE_GLONASS:
220 if (!isGloSlotUnknown(in.svId)) { // OSN is known
221 out = in.svId - GLO_SV_PRN_MIN + 1;
222 } else { // OSN is not known, report FCN
223 out = in.gloFrequency + 92;
224 }
225 break;
226 case GNSS_SV_TYPE_QZSS:
227 out = in.svId;
228 break;
229 case GNSS_SV_TYPE_BEIDOU:
230 out = in.svId - BDS_SV_PRN_MIN + 1;
231 break;
232 case GNSS_SV_TYPE_GALILEO:
233 out = in.svId - GAL_SV_PRN_MIN + 1;
234 break;
235 case GNSS_SV_TYPE_NAVIC:
236 out = in.svId - NAVIC_SV_PRN_MIN + 1;
237 break;
238 default:
239 out = in.svId;
240 break;
241 }
242 }
243
convertGnssSvid(GnssMeasurementsData & in,int16_t & out)244 void convertGnssSvid(GnssMeasurementsData& in, int16_t& out)
245 {
246 switch (in.svType) {
247 case GNSS_SV_TYPE_GPS:
248 out = in.svId;
249 break;
250 case GNSS_SV_TYPE_SBAS:
251 out = in.svId;
252 break;
253 case GNSS_SV_TYPE_GLONASS:
254 if (!isGloSlotUnknown(in.svId)) { // OSN is known
255 out = in.svId - GLO_SV_PRN_MIN + 1;
256 } else { // OSN is not known, report FCN
257 out = in.gloFrequency + 92;
258 }
259 break;
260 case GNSS_SV_TYPE_QZSS:
261 out = in.svId;
262 break;
263 case GNSS_SV_TYPE_BEIDOU:
264 out = in.svId - BDS_SV_PRN_MIN + 1;
265 break;
266 case GNSS_SV_TYPE_GALILEO:
267 out = in.svId - GAL_SV_PRN_MIN + 1;
268 break;
269 case GNSS_SV_TYPE_NAVIC:
270 out = in.svId - NAVIC_SV_PRN_MIN + 1;
271 break;
272 default:
273 out = in.svId;
274 break;
275 }
276 }
277
convertGnssEphemerisType(GnssEphemerisType & in,GnssDebug::SatelliteEphemerisType & out)278 void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
279 {
280 switch(in) {
281 case GNSS_EPH_TYPE_EPHEMERIS:
282 out = GnssDebug::SatelliteEphemerisType::EPHEMERIS;
283 break;
284 case GNSS_EPH_TYPE_ALMANAC:
285 out = GnssDebug::SatelliteEphemerisType::ALMANAC_ONLY;
286 break;
287 case GNSS_EPH_TYPE_UNKNOWN:
288 default:
289 out = GnssDebug::SatelliteEphemerisType::NOT_AVAILABLE;
290 break;
291 }
292 }
293
convertGnssEphemerisSource(GnssEphemerisSource & in,GnssDebug::SatelliteEphemerisSource & out)294 void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out)
295 {
296 switch(in) {
297 case GNSS_EPH_SOURCE_DEMODULATED:
298 out = GnssDebug::SatelliteEphemerisSource::DEMODULATED;
299 break;
300 case GNSS_EPH_SOURCE_SUPL_PROVIDED:
301 out = GnssDebug::SatelliteEphemerisSource::SUPL_PROVIDED;
302 break;
303 case GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED:
304 out = GnssDebug::SatelliteEphemerisSource::OTHER_SERVER_PROVIDED;
305 break;
306 case GNSS_EPH_SOURCE_LOCAL:
307 case GNSS_EPH_SOURCE_UNKNOWN:
308 default:
309 out = GnssDebug::SatelliteEphemerisSource::OTHER;
310 break;
311 }
312 }
313
convertGnssEphemerisHealth(GnssEphemerisHealth & in,GnssDebug::SatelliteEphemerisHealth & out)314 void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out)
315 {
316 switch(in) {
317 case GNSS_EPH_HEALTH_GOOD:
318 out = GnssDebug::SatelliteEphemerisHealth::GOOD;
319 break;
320 case GNSS_EPH_HEALTH_BAD:
321 out = GnssDebug::SatelliteEphemerisHealth::BAD;
322 break;
323 case GNSS_EPH_HEALTH_UNKNOWN:
324 default:
325 out = GnssDebug::SatelliteEphemerisHealth::UNKNOWN;
326 break;
327 }
328 }
329
330 } // namespace implementation
331 } // namespace V2_0
332 } // namespace gnss
333 } // namespace hardware
334 } // namespace android
335