diff options
| author | 2016-05-17 16:14:48 -0700 | |
|---|---|---|
| committer | 2016-05-19 09:55:42 -0700 | |
| commit | 49d9891c573f8c4994841b24f8d90690c342e8ae (patch) | |
| tree | a55b9330e3ac92e294d523d66cfb26b3af06c4ae | |
| parent | 7996b96311eec2343c16d3677fb834d2ec7cf082 (diff) | |
Mapping up/down of legacy Gps vs. Gnss Status
- Maps incoming (from HAL) GpsSvStatus for Glonass, Beidou, SBAS, and QZSS
from defacto (NMEA-like) numbers to internal platform with detected constellation.
- Maps outgoing (to Java API) GpsStatus getSatellite info back into the de-facto
overloaded (beyond 32) "GPS" ID numbers.
- Simplifies Glonass ID definition for N (comments only.)
- This enables GPS/GNSS Test apps a non-degrading upgrade path.
Bug: 28623392
Change-Id: I9a19db1f11267032c6927daed767df5afa51c770
| -rw-r--r-- | location/java/android/location/GnssStatus.java | 10 | ||||
| -rw-r--r-- | location/java/android/location/GpsStatus.java | 19 | ||||
| -rw-r--r-- | services/core/jni/com_android_server_location_GnssLocationProvider.cpp | 28 |
3 files changed, 47 insertions, 10 deletions
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java index e834c301f093..e68821b5a220 100644 --- a/location/java/android/location/GnssStatus.java +++ b/location/java/android/location/GnssStatus.java @@ -146,13 +146,11 @@ public final class GnssStatus { * <ul> * <li>GPS: 1-32</li> * <li>SBAS: 120-151, 183-192</li> - * <li>GLONASS: + * <li>GLONASS: One of: OSN, or FCN+100 * <ul> - * <li>The least significant 8 bits, signed, are the orbital slot number (OSN) in the range - * from 1-24, if known, or -127 if unknown</li> - * <li>The next least signficant 8 bits, signed, are the frequency channel number (FCN) in the - * range from -7 to +6, if known, and -127, if unknown</li> - * <li>At least one of the two (FCN & OSN) shall be set to a known value</li> + * <li>1-24 as the orbital slot number (OSN) (preferred, if known)</li> + * <li>93-106 as the frequency channel number (FCN) (-7 to +6) plus 100. + * i.e. encode FCN of -7 as 93, 0 as 100, and +6 as 106</li> * </ul></li> * <li>QZSS: 193-200</li> * <li>Galileo: 1-36</li> diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java index 038247bb691e..5561b229dd25 100644 --- a/location/java/android/location/GpsStatus.java +++ b/location/java/android/location/GpsStatus.java @@ -32,6 +32,8 @@ import java.util.NoSuchElementException; @Deprecated public final class GpsStatus { private static final int NUM_SATELLITES = 255; + private static final int GLONASS_SVID_OFFSET = 64; + private static final int BEIDOU_SVID_OFFSET = 200; /* These package private values are modified by the LocationManager class */ private int mTimeToFirstFix; @@ -153,11 +155,22 @@ public final class GpsStatus { final int constellationType = (svidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH) & GnssStatus.CONSTELLATION_TYPE_MASK; - // Skip all non-GPS satellites. - if (constellationType != GnssStatus.CONSTELLATION_GPS) { + int prn = svidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH; + // Other satellites passed through these APIs before GnssSvStatus was availble. + // GPS, SBAS & QZSS can pass through at their nominally + // assigned prn number (as long as it fits in the valid 0-255 range below.) + // Glonass, and Beidou are passed through with the defacto standard offsets + // Other future constellation reporting (e.g. Galileo) needs to use + // GnssSvStatus on (N level) HAL & Java layers. + if (constellationType == GnssStatus.CONSTELLATION_GLONASS) { + prn += GLONASS_SVID_OFFSET; + } else if (constellationType == GnssStatus.CONSTELLATION_BEIDOU) { + prn += BEIDOU_SVID_OFFSET; + } else if ((constellationType != GnssStatus.CONSTELLATION_GPS) && + (constellationType != GnssStatus.CONSTELLATION_QZSS) && + (constellationType != GnssStatus.CONSTELLATION_SBAS)) { continue; } - int prn = svidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH; if (prn > 0 && prn <= NUM_SATELLITES) { GpsSatellite satellite = mSatellites.get(prn); if (satellite == null) { diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index c5c90e02f200..e29452a17bd0 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -72,6 +72,18 @@ static const GnssConfigurationInterface* sGnssConfigurationInterface = NULL; #define GPS_MAX_SATELLITE_COUNT 32 #define GNSS_MAX_SATELLITE_COUNT 64 +// Let these through, with ID remapped by offset +#define GLONASS_SVID_OFFSET 64 +#define GLONASS_SVID_COUNT 24 +#define BEIDOU_SVID_OFFSET 200 +#define BEIDOU_SVID_COUNT 35 + +// Let these through, with no ID remapping +#define SBAS_SVID_MIN 120 +#define SBAS_SVID_MAX 151 +#define QZSS_SVID_MIN 193 +#define QZSS_SVID_MAX 200 + #define SVID_SHIFT_WIDTH 7 #define CONSTELLATION_TYPE_SHIFT_WIDTH 3 @@ -134,8 +146,21 @@ static void sv_status_callback(GpsSvStatus* sv_status) for (size_t i = 0; i < sGnssSvListSize; i++) { GnssSvInfo& info = sGnssSvList[i]; info.svid = sv_status->sv_list[i].prn; + // Defacto mapping from the overused API that was designed for GPS-only if (info.svid >=1 && info.svid <= 32) { info.constellation = GNSS_CONSTELLATION_GPS; + } else if (info.svid > GLONASS_SVID_OFFSET && + info.svid <= GLONASS_SVID_OFFSET + GLONASS_SVID_COUNT) { + info.constellation = GNSS_CONSTELLATION_GLONASS; + info.svid -= GLONASS_SVID_OFFSET; + } else if (info.svid > BEIDOU_SVID_OFFSET && + info.svid <= BEIDOU_SVID_OFFSET + BEIDOU_SVID_COUNT) { + info.constellation = GNSS_CONSTELLATION_BEIDOU; + info.svid -= BEIDOU_SVID_OFFSET; + } else if (info.svid >= SBAS_SVID_MIN && info.svid <= SBAS_SVID_MAX) { + info.constellation = GNSS_CONSTELLATION_SBAS; + } else if (info.svid >= QZSS_SVID_MIN && info.svid <= QZSS_SVID_MAX) { + info.constellation = GNSS_CONSTELLATION_QZSS; } else { ALOGD("Unknown constellation type with Svid = %d.", info.svid); info.constellation = GNSS_CONSTELLATION_UNKNOWN; @@ -144,7 +169,8 @@ static void sv_status_callback(GpsSvStatus* sv_status) info.elevation = sv_status->sv_list[i].elevation; info.azimuth = sv_status->sv_list[i].azimuth; info.flags = GNSS_SV_FLAGS_NONE; - if (info.svid > 0 && info.svid <= 32) { + // Only GPS info is valid for these fields, as these masks are just 32 bits, by GPS prn + if (info.constellation == GNSS_CONSTELLATION_GPS) { int32_t this_svid_mask = (1 << (info.svid - 1)); if ((ephemeris_mask & this_svid_mask) != 0) { info.flags |= GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA; |