diff options
| -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; |