1 /* Copyright (c) 2017-2019, 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
34 namespace android {
35 namespace hardware {
36 namespace gnss {
37 namespace V2_0 {
38 namespace implementation {
39
40 using ::android::hardware::gnss::V2_0::GnssLocation;
41 using ::android::hardware::gnss::V2_0::GnssConstellationType;
42 using ::android::hardware::gnss::V1_0::GnssLocationFlags;
43
convertGnssLocation(Location & in,V1_0::GnssLocation & out)44 void convertGnssLocation(Location& in, V1_0::GnssLocation& out)
45 {
46 memset(&out, 0, sizeof(V1_0::GnssLocation));
47 if (in.flags & LOCATION_HAS_LAT_LONG_BIT) {
48 out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
49 out.latitudeDegrees = in.latitude;
50 out.longitudeDegrees = in.longitude;
51 }
52 if (in.flags & LOCATION_HAS_ALTITUDE_BIT) {
53 out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
54 out.altitudeMeters = in.altitude;
55 }
56 if (in.flags & LOCATION_HAS_SPEED_BIT) {
57 out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
58 out.speedMetersPerSec = in.speed;
59 }
60 if (in.flags & LOCATION_HAS_BEARING_BIT) {
61 out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
62 out.bearingDegrees = in.bearing;
63 }
64 if (in.flags & LOCATION_HAS_ACCURACY_BIT) {
65 out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
66 out.horizontalAccuracyMeters = in.accuracy;
67 }
68 if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) {
69 out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
70 out.verticalAccuracyMeters = in.verticalAccuracy;
71 }
72 if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) {
73 out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
74 out.speedAccuracyMetersPerSecond = in.speedAccuracy;
75 }
76 if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) {
77 out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
78 out.bearingAccuracyDegrees = in.bearingAccuracy;
79 }
80
81 out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
82 }
83
convertGnssLocation(Location & in,V2_0::GnssLocation & out)84 void convertGnssLocation(Location& in, V2_0::GnssLocation& out)
85 {
86 memset(&out, 0, sizeof(V2_0::GnssLocation));
87 convertGnssLocation(in, out.v1_0);
88
89 struct timespec sinceBootTime;
90 struct timespec currentTime;
91 if (0 == clock_gettime(CLOCK_BOOTTIME,&sinceBootTime) &&
92 0 == clock_gettime(CLOCK_REALTIME,¤tTime)) {
93
94 int64_t sinceBootTimeNanos = sinceBootTime.tv_sec*1000000000 + sinceBootTime.tv_nsec;
95 int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec;
96 int64_t locationTimeNanos = in.timestamp*1000000;
97 LOC_LOGD("%s]: sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
98 " locationTimeNanos:%" PRIi64 "",
99 __FUNCTION__, sinceBootTimeNanos, currentTimeNanos, locationTimeNanos);
100 if (currentTimeNanos >= locationTimeNanos) {
101 int64_t ageTimeNanos = currentTimeNanos - locationTimeNanos;
102 LOC_LOGD("%s]: ageTimeNanos:%" PRIi64 ")", __FUNCTION__, ageTimeNanos);
103 if (ageTimeNanos >= 0 && ageTimeNanos <= sinceBootTimeNanos) {
104 out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
105 out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos;
106 out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
107 // time uncertainty is 1 ms since it is calculated from utc time that is in ms
108 out.elapsedRealtime.timeUncertaintyNs = 1000000;
109 LOC_LOGD("%s]: timestampNs:%" PRIi64 ")",
110 __FUNCTION__, out.elapsedRealtime.timestampNs);
111 }
112 }
113 }
114
115 }
116
convertGnssLocation(const V1_0::GnssLocation & in,Location & out)117 void convertGnssLocation(const V1_0::GnssLocation& in, Location& out)
118 {
119 memset(&out, 0, sizeof(out));
120 if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) {
121 out.flags |= LOCATION_HAS_LAT_LONG_BIT;
122 out.latitude = in.latitudeDegrees;
123 out.longitude = in.longitudeDegrees;
124 }
125 if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE) {
126 out.flags |= LOCATION_HAS_ALTITUDE_BIT;
127 out.altitude = in.altitudeMeters;
128 }
129 if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED) {
130 out.flags |= LOCATION_HAS_SPEED_BIT;
131 out.speed = in.speedMetersPerSec;
132 }
133 if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
134 out.flags |= LOCATION_HAS_BEARING_BIT;
135 out.bearing = in.bearingDegrees;
136 }
137 if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
138 out.flags |= LOCATION_HAS_ACCURACY_BIT;
139 out.accuracy = in.horizontalAccuracyMeters;
140 }
141 if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
142 out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
143 out.verticalAccuracy = in.verticalAccuracyMeters;
144 }
145 if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
146 out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
147 out.speedAccuracy = in.speedAccuracyMetersPerSecond;
148 }
149 if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
150 out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
151 out.bearingAccuracy = in.bearingAccuracyDegrees;
152 }
153
154 out.timestamp = static_cast<uint64_t>(in.timestamp);
155 }
156
convertGnssLocation(const V2_0::GnssLocation & in,Location & out)157 void convertGnssLocation(const V2_0::GnssLocation& in, Location& out)
158 {
159 memset(&out, 0, sizeof(out));
160 convertGnssLocation(in.v1_0, out);
161 }
162
convertGnssConstellationType(GnssSvType & in,V1_0::GnssConstellationType & out)163 void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out)
164 {
165 switch(in) {
166 case GNSS_SV_TYPE_GPS:
167 out = V1_0::GnssConstellationType::GPS;
168 break;
169 case GNSS_SV_TYPE_SBAS:
170 out = V1_0::GnssConstellationType::SBAS;
171 break;
172 case GNSS_SV_TYPE_GLONASS:
173 out = V1_0::GnssConstellationType::GLONASS;
174 break;
175 case GNSS_SV_TYPE_QZSS:
176 out = V1_0::GnssConstellationType::QZSS;
177 break;
178 case GNSS_SV_TYPE_BEIDOU:
179 out = V1_0::GnssConstellationType::BEIDOU;
180 break;
181 case GNSS_SV_TYPE_GALILEO:
182 out = V1_0::GnssConstellationType::GALILEO;
183 break;
184 case GNSS_SV_TYPE_UNKNOWN:
185 default:
186 out = V1_0::GnssConstellationType::UNKNOWN;
187 break;
188 }
189 }
190
convertGnssConstellationType(GnssSvType & in,V2_0::GnssConstellationType & out)191 void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out)
192 {
193 switch(in) {
194 case GNSS_SV_TYPE_GPS:
195 out = V2_0::GnssConstellationType::GPS;
196 break;
197 case GNSS_SV_TYPE_SBAS:
198 out = V2_0::GnssConstellationType::SBAS;
199 break;
200 case GNSS_SV_TYPE_GLONASS:
201 out = V2_0::GnssConstellationType::GLONASS;
202 break;
203 case GNSS_SV_TYPE_QZSS:
204 out = V2_0::GnssConstellationType::QZSS;
205 break;
206 case GNSS_SV_TYPE_BEIDOU:
207 out = V2_0::GnssConstellationType::BEIDOU;
208 break;
209 case GNSS_SV_TYPE_GALILEO:
210 out = V2_0::GnssConstellationType::GALILEO;
211 break;
212 case GNSS_SV_TYPE_NAVIC:
213 out = V2_0::GnssConstellationType::IRNSS;
214 break;
215 case GNSS_SV_TYPE_UNKNOWN:
216 default:
217 out = V2_0::GnssConstellationType::UNKNOWN;
218 break;
219 }
220 }
221
convertGnssEphemerisType(GnssEphemerisType & in,GnssDebug::SatelliteEphemerisType & out)222 void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
223 {
224 switch(in) {
225 case GNSS_EPH_TYPE_EPHEMERIS:
226 out = GnssDebug::SatelliteEphemerisType::EPHEMERIS;
227 break;
228 case GNSS_EPH_TYPE_ALMANAC:
229 out = GnssDebug::SatelliteEphemerisType::ALMANAC_ONLY;
230 break;
231 case GNSS_EPH_TYPE_UNKNOWN:
232 default:
233 out = GnssDebug::SatelliteEphemerisType::NOT_AVAILABLE;
234 break;
235 }
236 }
237
convertGnssEphemerisSource(GnssEphemerisSource & in,GnssDebug::SatelliteEphemerisSource & out)238 void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out)
239 {
240 switch(in) {
241 case GNSS_EPH_SOURCE_DEMODULATED:
242 out = GnssDebug::SatelliteEphemerisSource::DEMODULATED;
243 break;
244 case GNSS_EPH_SOURCE_SUPL_PROVIDED:
245 out = GnssDebug::SatelliteEphemerisSource::SUPL_PROVIDED;
246 break;
247 case GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED:
248 out = GnssDebug::SatelliteEphemerisSource::OTHER_SERVER_PROVIDED;
249 break;
250 case GNSS_EPH_SOURCE_LOCAL:
251 case GNSS_EPH_SOURCE_UNKNOWN:
252 default:
253 out = GnssDebug::SatelliteEphemerisSource::OTHER;
254 break;
255 }
256 }
257
convertGnssEphemerisHealth(GnssEphemerisHealth & in,GnssDebug::SatelliteEphemerisHealth & out)258 void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out)
259 {
260 switch(in) {
261 case GNSS_EPH_HEALTH_GOOD:
262 out = GnssDebug::SatelliteEphemerisHealth::GOOD;
263 break;
264 case GNSS_EPH_HEALTH_BAD:
265 out = GnssDebug::SatelliteEphemerisHealth::BAD;
266 break;
267 case GNSS_EPH_HEALTH_UNKNOWN:
268 default:
269 out = GnssDebug::SatelliteEphemerisHealth::UNKNOWN;
270 break;
271 }
272 }
273
274 } // namespace implementation
275 } // namespace V2_0
276 } // namespace gnss
277 } // namespace hardware
278 } // namespace android
279