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