1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _ANDROID_SERVER_GNSS_GNSSDEBUG_H
18 #define _ANDROID_SERVER_GNSS_GNSSDEBUG_H
19 
20 #pragma once
21 
22 #ifndef LOG_TAG
23 #error LOG_TAG must be defined before including this file.
24 #endif
25 
26 #include <android/hardware/gnss/1.0/IGnssDebug.h>
27 #include <android/hardware/gnss/2.0/IGnssDebug.h>
28 #include <android/hardware/gnss/BnGnssDebug.h>
29 #include <log/log.h>
30 
31 #include <iomanip>
32 
33 #include "jni.h"
34 
35 namespace android::gnss {
36 
37 class GnssDebugInterface {
38 public:
~GnssDebugInterface()39     virtual ~GnssDebugInterface() {}
40     virtual jstring getDebugData(JNIEnv* env) = 0;
41 };
42 
43 class GnssDebug : public GnssDebugInterface {
44 public:
45     GnssDebug(const sp<android::hardware::gnss::IGnssDebug>& iGnssDebug);
46     jstring getDebugData(JNIEnv* env) override;
47 
48 private:
49     const sp<android::hardware::gnss::IGnssDebug> mIGnssDebug;
50 };
51 
52 class GnssDebug_V1_0 : public GnssDebugInterface {
53 public:
54     GnssDebug_V1_0(const sp<android::hardware::gnss::V1_0::IGnssDebug>& iGnssDebug);
55     jstring getDebugData(JNIEnv* env) override;
56 
57 private:
58     const sp<android::hardware::gnss::V1_0::IGnssDebug> mIGnssDebug_V1_0;
59 };
60 
61 class GnssDebug_V2_0 : public GnssDebugInterface {
62 public:
63     GnssDebug_V2_0(const sp<android::hardware::gnss::V2_0::IGnssDebug>& iGnssDebug);
64     jstring getDebugData(JNIEnv* env) override;
65 
66 private:
67     const sp<android::hardware::gnss::V2_0::IGnssDebug> mIGnssDebug_V2_0;
68 };
69 
70 struct GnssDebugUtil {
71     template <class T>
72     static uint32_t getConstellationType(const hardware::hidl_vec<T>& satelliteDataArray, size_t i);
73 
74     template <class T>
75     static uint32_t getConstellationType(const std::vector<T>& satelliteDataArray, size_t i);
76 
77     template <class T>
78     static int64_t getTimeEstimateMs(const T& data);
79 
80     template <class T_DebugData, class T_SatelliteData>
81     static jstring parseDebugData(JNIEnv* env, std::stringstream& internalState,
82                                   const T_DebugData& data);
83 
84     const static android::hardware::gnss::V1_0::IGnssDebug::SatelliteData& getSatelliteData(
85             const hardware::hidl_vec<android::hardware::gnss::V1_0::IGnssDebug::SatelliteData>&
86                     satelliteDataArray,
87             size_t i);
88 
89     const static android::hardware::gnss::V1_0::IGnssDebug::SatelliteData& getSatelliteData(
90             const hardware::hidl_vec<android::hardware::gnss::V2_0::IGnssDebug::SatelliteData>&
91                     satelliteDataArray,
92             size_t i);
93 
94     const static android::hardware::gnss::IGnssDebug::SatelliteData& getSatelliteData(
95             const std::vector<android::hardware::gnss::IGnssDebug::SatelliteData>&
96                     satelliteDataArray,
97             size_t i);
98 };
99 
100 template <class T>
getConstellationType(const hardware::hidl_vec<T> & satelliteDataArray,size_t i)101 uint32_t GnssDebugUtil::getConstellationType(const hardware::hidl_vec<T>& satelliteDataArray,
102                                              size_t i) {
103     return static_cast<uint32_t>(satelliteDataArray[i].constellation);
104 }
105 
106 template <class T>
getConstellationType(const std::vector<T> & satelliteDataArray,size_t i)107 uint32_t GnssDebugUtil::getConstellationType(const std::vector<T>& satelliteDataArray, size_t i) {
108     return static_cast<uint32_t>(satelliteDataArray[i].constellation);
109 }
110 
111 template <class T>
getTimeEstimateMs(const T & data)112 int64_t GnssDebugUtil::getTimeEstimateMs(const T& data) {
113     return data.time.timeEstimate;
114 }
115 
116 template <class T_DebugData, class T_SatelliteData>
parseDebugData(JNIEnv * env,std::stringstream & internalState,const T_DebugData & data)117 jstring GnssDebugUtil::parseDebugData(JNIEnv* env, std::stringstream& internalState,
118                                       const T_DebugData& data) {
119     internalState << "Gnss Location Data:: ";
120     if (!data.position.valid) {
121         internalState << "not valid";
122     } else {
123         internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
124                       << ", LongitudeDegrees: " << data.position.longitudeDegrees
125                       << ", altitudeMeters: " << data.position.altitudeMeters
126                       << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
127                       << ", bearingDegrees: " << data.position.bearingDegrees
128                       << ", horizontalAccuracyMeters: " << data.position.horizontalAccuracyMeters
129                       << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
130                       << ", speedAccuracyMetersPerSecond: "
131                       << data.position.speedAccuracyMetersPerSecond
132                       << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
133                       << ", ageSeconds: " << data.position.ageSeconds;
134     }
135     internalState << std::endl;
136 
137     internalState << "Gnss Time Data:: timeEstimate: " << GnssDebugUtil::getTimeEstimateMs(data)
138                   << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
139                   << ", frequencyUncertaintyNsPerSec: " << data.time.frequencyUncertaintyNsPerSec
140                   << std::endl;
141 
142     if (data.satelliteDataArray.size() != 0) {
143         internalState << "Satellite Data for " << data.satelliteDataArray.size()
144                       << " satellites:: " << std::endl;
145     }
146 
147     internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL, 7=IRNSS; "
148                   << "ephType: 0=Eph, 1=Alm, 2=Unk; "
149                   << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; "
150                   << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl;
151     for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
152         T_SatelliteData satelliteData = getSatelliteData(data.satelliteDataArray, i);
153         internalState << "constell: "
154                       << GnssDebugUtil::getConstellationType(data.satelliteDataArray, i)
155                       << ", svid: " << std::setw(3) << satelliteData.svid
156                       << ", serverPredAvail: " << satelliteData.serverPredictionIsAvailable
157                       << ", serverPredAgeSec: " << std::setw(7)
158                       << satelliteData.serverPredictionAgeSeconds
159                       << ", ephType: " << static_cast<uint32_t>(satelliteData.ephemerisType)
160                       << ", ephSource: " << static_cast<uint32_t>(satelliteData.ephemerisSource)
161                       << ", ephHealth: " << static_cast<uint32_t>(satelliteData.ephemerisHealth)
162                       << ", ephAgeSec: " << std::setw(7) << satelliteData.ephemerisAgeSeconds
163                       << std::endl;
164     }
165     return (jstring)env->NewStringUTF(internalState.str().c_str());
166 }
167 
168 } // namespace android::gnss
169 
170 #endif // _ANDROID_SERVER_GNSS_GNSSDEBUG_H
171