Merge "SystemStatus - Add BugReport support"

This commit is contained in:
Linux Build Service Account 2017-03-24 06:31:22 -07:00 committed by Gerrit - the friendly Code Review server
commit 50952f03af
12 changed files with 452 additions and 6 deletions

View file

@ -12,6 +12,7 @@ LOCAL_SRC_FILES := \
GnssMeasurement.cpp \
GnssNi.cpp \
GnssConfiguration.cpp \
GnssDebug.cpp \
LOCAL_SRC_FILES += \
location_api/LocationUtil.cpp \

View file

@ -310,6 +310,12 @@ Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching() {
return mGnssBatching;
}
Return<sp<IGnssDebug>> Gnss::getExtensionGnssDebug() {
ENTRY_LOG_CALLFLOW();
mGnssDebug = new GnssDebug(this);
return mGnssDebug;
}
IGnss* HIDL_FETCH_IGnss(const char* hal) {
ENTRY_LOG_CALLFLOW();
IGnss* iface = nullptr;

View file

@ -27,6 +27,7 @@
#include <GnssGeofencing.h>
#include <GnssMeasurement.h>
#include <GnssNi.h>
#include <GnssDebug.h>
#include <android/hardware/gnss/1.0/IGnss.h>
#include <hidl/Status.h>
@ -102,9 +103,7 @@ struct Gnss : public IGnss {
return nullptr;
}
inline Return<sp<IGnssDebug>> getExtensionGnssDebug() override {
return nullptr;
}
Return<sp<IGnssDebug>> getExtensionGnssDebug() override;
// These methods are not part of the IGnss base class.
GnssAPIClient* getApi();
@ -130,6 +129,7 @@ struct Gnss : public IGnss {
sp<GnssConfiguration> mGnssConfig = nullptr;
sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
sp<GnssBatching> mGnssBatching = nullptr;
sp<IGnssDebug> mGnssDebug = nullptr;
GnssAPIClient* mApi = nullptr;
sp<IGnssCallback> mGnssCbIface = nullptr;

117
android/GnssDebug.cpp Normal file
View file

@ -0,0 +1,117 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "LocSvc_GnssDebugInterface"
#include <log/log.h>
#include <log_util.h>
#include "Gnss.h"
#include "GnssDebug.h"
#include "LocationUtil.h"
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
using ::android::hardware::hidl_vec;
GnssDebug::GnssDebug(Gnss* gnss) : mGnss(gnss)
{
}
/*
* This methods requests position, time and satellite ephemeris debug information
* from the HAL.
*
* @return void
*/
Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)
{
LOC_LOGI("GnssDebug - 0317a");
DebugData data = { };
if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
LOC_LOGE("GnssDebug - Null GNSS interface");
_hidl_cb(data);
return Void();
}
// get debug report snapshot via hal interface
GnssDebugReport reports = { };
mGnss->getGnssInterface()->getDebugReport(reports);
// location block
data.position.valid = true;
data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
data.position.speedMetersPerSec = (double)(reports.mLocation.mLocation.speed);
data.position.bearingDegrees = (double)(reports.mLocation.mLocation.bearing);
data.position.horizontalAccuracyMeters = (double)(reports.mLocation.mLocation.accuracy);
data.position.verticalAccuracyMeters = reports.mLocation.verticalAccuracyMeters;
data.position.speedAccuracyMetersPerSecond = reports.mLocation.speedAccuracyMetersPerSecond;
data.position.bearingAccuracyDegrees = reports.mLocation.bearingAccuracyDegrees;
LOC_LOGV("GnssDebug - lat=%f lon=%f", data.position.latitudeDegrees, data.position.longitudeDegrees);
timeval tv_now, tv_report;
tv_report.tv_sec = reports.mLocation.mLocation.timestamp / 1000ULL;
tv_report.tv_usec = (reports.mLocation.mLocation.timestamp % 1000ULL) * 1000ULL;
gettimeofday(&tv_now, NULL);
data.position.ageSeconds =
(tv_now.tv_sec - tv_report.tv_sec) + (float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
LOC_LOGV("GnssDebug - time now=%lld:%lld", tv_now.tv_sec, tv_now.tv_usec);
LOC_LOGV("GnssDebug - time rep=%lld:%lld", tv_report.tv_sec, tv_report.tv_usec);
LOC_LOGV("GnssDebug - age=%f", data.position.ageSeconds);
// time block
data.time.valid = true;
data.time.timeEstimate = reports.mTime.timeEstimate;
data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
LOC_LOGV("GnssDebug - timeestimate=%lld", data.time.timeEstimate);
// satellite data block
SatelliteData s = { };
std::vector<SatelliteData> s_array = { };
for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
memset(&s, 0, sizeof(s));
s.svid = reports.mSatelliteInfo[i].svid;
convertGnssConstellationType(reports.mSatelliteInfo[i].constellation, s.constellation);
s.ephemerisType = SatelliteEphemerisType::UNKNOWN;
s.ephemerisAgeSeconds = reports.mSatelliteInfo[i].ephemerisAgeSeconds;
s_array.push_back(s);
}
data.satelliteDataArray = s_array;
LOC_LOGV("GnssDebug - satellite=%d", data.satelliteDataArray.size());
// callback HIDL with collected debug data
_hidl_cb(data);
LOC_LOGV("GnssDebug - done");
return Void();
}
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android

59
android/GnssDebug.h Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
#define ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
#include <android/hardware/gnss/1.0/IGnssDebug.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
using ::android::hardware::gnss::V1_0::IGnssDebug;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
/* Interface for GNSS Debug support. */
struct Gnss;
struct GnssDebug : public IGnssDebug {
GnssDebug(Gnss* gnss);
~GnssDebug() {};
/*
* Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
* These declarations were generated from IGnssDebug.hal.
*/
Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
private:
Gnss* mGnss = nullptr;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H

View file

@ -1078,6 +1078,29 @@ void SystemStatusPositionFailure::dump()
return;
}
/******************************************************************************
SystemStatusLocation
******************************************************************************/
bool SystemStatusLocation::equals(SystemStatusLocation& peer)
{
if ((mLocation.gpsLocation.latitude != peer.mLocation.gpsLocation.latitude) ||
(mLocation.gpsLocation.longitude != peer.mLocation.gpsLocation.longitude) ||
(mLocation.gpsLocation.altitude != peer.mLocation.gpsLocation.altitude)) {
return false;
}
return true;
}
void SystemStatusLocation::dump()
{
LOC_LOGV("Location: lat=%f lon=%f alt=%f spd=%f",
mLocation.gpsLocation.latitude,
mLocation.gpsLocation.longitude,
mLocation.gpsLocation.altitude,
mLocation.gpsLocation.speed);
return;
}
/******************************************************************************
SystemStatus
******************************************************************************/
@ -1085,6 +1108,8 @@ pthread_mutex_t SystemStatus::mMutexSystemStatus = PTHREAD_MUTEX_INITIALIZER;
SystemStatus::SystemStatus()
{
mCache.mLocation.clear();
mCache.mTimeAndClock.clear();
mCache.mXoState.clear();
mCache.mRfAndParams.clear();
@ -1269,7 +1294,7 @@ bool SystemStatus::setNmeaString(const char *data, uint32_t len)
char buf[SystemStatusNmeaBase::NMEA_MAXSIZE + 1] = { 0 };
strncpy(buf, data, len);
LOC_LOGI("setNmeaString-0320a: len=%d str=%d nmea=%s", len, strlen(data), buf);
LOC_LOGI("setNmeaString-0321a: nmea=%s", buf);
pthread_mutex_lock(&mMutexSystemStatus);
@ -1329,6 +1354,36 @@ bool SystemStatus::setNmeaString(const char *data, uint32_t len)
return ret;
}
/******************************************************************************
@brief API to set report position data into internal buffer
@param[In] UlpLocation
@return true when successfully done
******************************************************************************/
bool SystemStatus::eventPosition(const UlpLocation& location,
const GpsLocationExtended& locationEx)
{
timespec ts;
ts.tv_sec = location.gpsLocation.timestamp / 1000ULL;
ts.tv_nsec = (location.gpsLocation.timestamp % 1000ULL) * 1000000ULL;
SystemStatusLocation s(location, locationEx, ts);
if ((mCache.mLocation.empty()) || !mCache.mLocation.back().equals(s)) {
mCache.mLocation.push_back(s);
if (mCache.mLocation.size() > maxLocation) {
mCache.mLocation.erase(mCache.mLocation.begin());
}
LOC_LOGV("eventPosition - lat=%f lon=%f alt=%f speed=%f",
s.mLocation.gpsLocation.latitude,
s.mLocation.gpsLocation.longitude,
s.mLocation.gpsLocation.altitude,
s.mLocation.gpsLocation.speed);
}
return true;
}
/******************************************************************************
@brief API to get report data into a given buffer
@ -1343,6 +1398,12 @@ bool SystemStatus::getReport(SystemStatusReports& report, bool isLatestOnly) con
if (isLatestOnly) {
// push back only the latest report and return it
report.mLocation.clear();
if (mCache.mLocation.size() >= 1) {
report.mLocation.push_back(mCache.mLocation.back());
report.mLocation.back().dump();
}
report.mTimeAndClock.clear();
if (mCache.mTimeAndClock.size() >= 1) {
report.mTimeAndClock.push_back(mCache.mTimeAndClock.back());
@ -1402,6 +1463,8 @@ bool SystemStatus::getReport(SystemStatusReports& report, bool isLatestOnly) con
}
else {
// copy entire reports and return them
report.mLocation.clear();
report.mTimeAndClock.clear();
report.mXoState.clear();
report.mRfAndParams.clear();

View file

@ -29,7 +29,16 @@
#ifndef __SYSTEM_STATUS__
#define __SYSTEM_STATUS__
#include <stdint.h>
#include <vector>
#include <gps_extended_c.h>
#define GPS_MIN (1)
#define SBAS_MIN (33)
#define GLO_MIN (65)
#define BDS_MIN (201)
#define QZSS_MIN (193)
#define GAL_MIN (301)
namespace loc_core
{
@ -46,6 +55,21 @@ public:
virtual void dump(void) { };
};
class SystemStatusLocation : public SystemStatusItemBase
{
public:
UlpLocation mLocation;
GpsLocationExtended mLocationEx;
SystemStatusLocation(const UlpLocation& location,
const GpsLocationExtended& locationEx,
const timespec& ts) :
SystemStatusItemBase(ts),
mLocation(location),
mLocationEx(locationEx){ };
bool equals(SystemStatusLocation& peer);
void dump(void);
};
class SystemStatusPQWM1;
class SystemStatusTimeAndClock : public SystemStatusItemBase
{
@ -212,6 +236,8 @@ public:
class SystemStatusReports
{
public:
std::vector<SystemStatusLocation> mLocation;
std::vector<SystemStatusTimeAndClock> mTimeAndClock;
std::vector<SystemStatusXoState> mXoState;
std::vector<SystemStatusRfAndParams> mRfAndParams;
@ -233,6 +259,8 @@ class SystemStatus
{
static pthread_mutex_t mMutexSystemStatus;
static const uint32_t maxLocation = 5;
static const uint32_t maxTimeAndClock = 5;
static const uint32_t maxXoState = 5;
static const uint32_t maxRfAndParams = 5;
@ -248,6 +276,8 @@ class SystemStatus
SystemStatusReports mCache;
bool setLocation(const UlpLocation& location);
bool setTimeAndCLock(const SystemStatusPQWM1& nmea);
bool setXoState(const SystemStatusPQWM1& nmea);
bool setRfAndParams(const SystemStatusPQWM1& nmea);
@ -265,6 +295,7 @@ public:
SystemStatus();
~SystemStatus() { }
bool eventPosition(const UlpLocation& location,const GpsLocationExtended& locationEx);
bool setNmeaString(const char *data, uint32_t len);
bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const;
};

View file

@ -1813,6 +1813,11 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation,
mStatus(status),
mTechMask(techMask) {}
inline virtual void proc() const {
// extract bug report info - this returns true if consumed by systemstatus
SystemStatus* s = LocDualContext::getSystemStatus();
if (nullptr != s) {
s->eventPosition(mUlpLocation, mLocationExtended);
}
mAdapter.reportPosition(mUlpLocation, mLocationExtended, mStatus, mTechMask);
}
};
@ -1977,7 +1982,6 @@ GnssAdapter::reportSv(GnssSvNotification& svNotify)
void
GnssAdapter::reportNmeaEvent(const char* nmea, size_t length, bool fromUlp)
{
//LOC_LOGD("%s]: fromUlp %u", __func__, fromUlp);
// if this event is not called from ULP, then try to call into ULP and return if successfull
if (!fromUlp) {
@ -3242,3 +3246,121 @@ void GnssAdapter::dataConnFailedCommand(AGpsExtType agpsType){
sendMsg( new AgpsMsgAtlOpenFailed(&mAgpsManager, (AGpsExtType)agpsType));
}
void GnssAdapter::convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
const GnssSvType& in_constellation,
const SystemStatusReports& in)
{
GnssDebugSatelliteInfo s = {};
uint64_t mask = 0ULL;
float age = 0.0;
uint32_t svid_min = 0;
uint32_t mask_size = 0;
switch (in_constellation) {
case GNSS_SV_TYPE_GPS:
svid_min = GPS_MIN;
mask_size = 32;
break;
case GNSS_SV_TYPE_GLONASS:
svid_min = GLO_MIN;
mask_size = 32;
break;
case GNSS_SV_TYPE_BEIDOU:
svid_min = BDS_MIN;
mask_size = 64;
break;
case GNSS_SV_TYPE_QZSS:
svid_min = QZSS_MIN;
mask_size = 32;
break;
case GNSS_SV_TYPE_GALILEO:
svid_min = GAL_MIN;
mask_size = 64;
break;
default:
return;
}
if(!in.mEphemeris.empty()) {
mask = in.mEphemeris.back().mGpsEpheValid;
if(!in.mXtra.empty()) {
age = (float)(in.mXtra.back().mGpsXtraAge);
}
else {
age = 0.0;
}
for(uint32_t i=0; i<mask_size; i++) {
if (0 != (mask & (1<<i))) {
s.size = sizeof(s);
s.svid = i + svid_min;
s.constellation = in_constellation;
s.ephemerisType = 0;
s.ephemerisAgeSeconds = age;
out.push_back(s);
}
}
}
return;
}
bool GnssAdapter::getDebugReport(GnssDebugReport& r)
{
LOC_LOGD("%s]: ", __func__);
SystemStatus* systemstatus = LocDualContext::getSystemStatus();
if (nullptr == systemstatus) {
return false;
}
SystemStatusReports reports = {};
systemstatus->getReport(reports, true);
r.size = sizeof(r);
// location block
r.mLocation.size = sizeof(r.mLocation);
if(!reports.mLocation.empty()) {
r.mLocation.mLocation.latitude = reports.mLocation.back().mLocation.gpsLocation.latitude;
r.mLocation.mLocation.longitude = reports.mLocation.back().mLocation.gpsLocation.longitude;
r.mLocation.mLocation.altitude = reports.mLocation.back().mLocation.gpsLocation.altitude;
r.mLocation.mLocation.speed = (double)(reports.mLocation.back().mLocation.gpsLocation.speed);
r.mLocation.mLocation.bearing = (double)(reports.mLocation.back().mLocation.gpsLocation.bearing);
r.mLocation.mLocation.accuracy = (double)(reports.mLocation.back().mLocation.gpsLocation.accuracy);
r.mLocation.verticalAccuracyMeters = reports.mLocation.back().mLocationEx.vert_unc;
r.mLocation.speedAccuracyMetersPerSecond = reports.mLocation.back().mLocationEx.speed_unc;
r.mLocation.bearingAccuracyDegrees = reports.mLocation.back().mLocationEx.bearing_unc;
}
else if(!reports.mBestPosition.empty()) {
r.mLocation.mLocation.latitude = (double)(reports.mBestPosition.back().mBestLat);
r.mLocation.mLocation.longitude = (double)(reports.mBestPosition.back().mBestLon);
r.mLocation.mLocation.altitude = reports.mBestPosition.back().mBestAlt;
}
LOC_LOGV("getDebugReport - lat=%f lon=%f alt=%f speed=%f",
r.mLocation.mLocation.latitude,
r.mLocation.mLocation.longitude,
r.mLocation.mLocation.altitude,
r.mLocation.mLocation.speed);
// time block
if(!reports.mBestPosition.empty()) {
r.mTime.size = sizeof(r.mTime);
r.mTime.timeEstimate = reports.mBestPosition.back().mUtcTime.tv_sec;
r.mTime.timeUncertaintyNs = (float)(reports.mTimeAndClock.back().mTimeUnc);
}
LOC_LOGV("getDebugReport - timeestimate=%lld", r.mTime.timeEstimate);
// satellite info block
convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GPS, reports);
convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GLONASS, reports);
convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_BEIDOU, reports);
convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_QZSS, reports);
convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GALILEO, reports);
LOC_LOGV("getDebugReport - satellite=%d", r.mSatelliteInfo.size());
return true;
}

View file

@ -34,6 +34,7 @@
#include <UlpProxyBase.h>
#include <LocationAPI.h>
#include <Agps.h>
#include <SystemStatus.h>
#define MAX_URL_LEN 256
#define NMEA_SENTENCE_MAX_LENGTH 200
@ -255,6 +256,9 @@ public:
/*======== UTILITIES ================================================================*/
int nmeaPutChecksum(char *nmea, size_t maxSize);
/*======== GNSSDEBUG ================================================================*/
bool getDebugReport(GnssDebugReport& report);
/*==== CONVERSION ===================================================================*/
static uint32_t convertGpsLock(const GnssConfigGpsLock gpsLock);
static GnssConfigGpsLock convertGpsLock(const uint32_t gpsLock);
@ -270,6 +274,9 @@ public:
static GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask);
static uint32_t convertAGloProt(const GnssConfigAGlonassPositionProtocolMask);
static uint32_t convertSuplMode(const GnssConfigSuplModeMask suplModeMask);
static void convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
const GnssSvType& in_constellation,
const SystemStatusReports& in);
void injectLocationCommand(double latitude, double longitude, float accuracy);
void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);

View file

@ -58,6 +58,7 @@ static void agpsInit(void* statusV4Cb);
static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnLen, int ipType);
static void agpsDataConnClosed(AGpsExtType agpsType);
static void agpsDataConnFailed(AGpsExtType agpsType);
static void getDebugReport(GnssDebugReport& report);
static const GnssInterface gGnssInterface = {
sizeof(GnssInterface),
@ -80,7 +81,8 @@ static const GnssInterface gGnssInterface = {
agpsInit,
agpsDataConnOpen,
agpsDataConnClosed,
agpsDataConnFailed
agpsDataConnFailed,
getDebugReport,
};
#ifndef DEBUG_X86
@ -239,3 +241,10 @@ static void agpsDataConnFailed(AGpsExtType agpsType) {
gGnssAdapter->dataConnFailedCommand(agpsType);
}
}
static void getDebugReport(GnssDebugReport& report) {
if (NULL != gGnssAdapter) {
gGnssAdapter->getDebugReport(report);
}
}

View file

@ -29,6 +29,7 @@
#ifndef LOCATION_H
#define LOCATION_H
#include <vector>
#include <stdint.h>
#include <functional>
@ -553,6 +554,35 @@ typedef struct {
GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits
} GnssConfig;
typedef struct {
size_t size; // set to sizeof
Location mLocation;
double verticalAccuracyMeters;
double speedAccuracyMetersPerSecond;
double bearingAccuracyDegrees;
} GnssDebugLocation;
typedef struct {
size_t size; // set to sizeof
int64_t timeEstimate;
float timeUncertaintyNs;
} GnssDebugTime;
typedef struct {
size_t size; // set to sizeof
uint32_t svid;
GnssSvType constellation;
uint32_t ephemerisType;
float ephemerisAgeSeconds;
} GnssDebugSatelliteInfo;
typedef struct {
size_t size; // set to sizeof
GnssDebugLocation mLocation;
GnssDebugTime mTime;
std::vector<GnssDebugSatelliteInfo> mSatelliteInfo;
} GnssDebugReport;
/* Provides the capabilities of the system
capabilities callback is called once soon after createInstance is called */
typedef std::function<void(

View file

@ -53,6 +53,7 @@ struct GnssInterface {
void (*agpsDataConnOpen)(short agpsType, const char* apnName, int apnLen, int ipType);
void (*agpsDataConnClosed)(short agpsType);
void (*agpsDataConnFailed)(short agpsType);
void (*getDebugReport)(GnssDebugReport& report);
};
struct FlpInterface {