• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2017, 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 #define LOG_TAG "LocSvc_SystemStatus"
30 
31 #include <inttypes.h>
32 #include <string>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/time.h>
36 #include <pthread.h>
37 #include <loc_pla.h>
38 #include <log_util.h>
39 #include <loc_nmea.h>
40 #include <DataItemsFactoryProxy.h>
41 #include <SystemStatus.h>
42 #include <SystemStatusOsObserver.h>
43 #include <DataItemConcreteTypesBase.h>
44 
45 namespace loc_core
46 {
47 
48 /******************************************************************************
49  SystemStatusNmeaBase - base class for all NMEA parsers
50 ******************************************************************************/
51 class SystemStatusNmeaBase
52 {
53 protected:
54     std::vector<std::string> mField;
55 
SystemStatusNmeaBase(const char * str_in,uint32_t len_in)56     SystemStatusNmeaBase(const char *str_in, uint32_t len_in)
57     {
58         // check size and talker
59         if (!loc_nmea_is_debug(str_in, len_in)) {
60             return;
61         }
62 
63         std::string parser(str_in);
64         std::string::size_type index = 0;
65 
66         // verify checksum field
67         index = parser.find("*");
68         if (index == std::string::npos) {
69             return;
70         }
71         parser[index] = ',';
72 
73         // tokenize parser
74         while (1) {
75             std::string str;
76             index = parser.find(",");
77             if (index == std::string::npos) {
78                 break;
79             }
80             str = parser.substr(0, index);
81             parser = parser.substr(index + 1);
82             mField.push_back(str);
83         }
84     }
85 
~SystemStatusNmeaBase()86     virtual ~SystemStatusNmeaBase() { }
87 
88 public:
89     static const uint32_t NMEA_MINSIZE = DEBUG_NMEA_MINSIZE;
90     static const uint32_t NMEA_MAXSIZE = DEBUG_NMEA_MAXSIZE;
91 };
92 
93 /******************************************************************************
94  SystemStatusPQWM1
95 ******************************************************************************/
96 class SystemStatusPQWM1
97 {
98 public:
99     uint16_t mGpsWeek;    // x1
100     uint32_t mGpsTowMs;   // x2
101     uint8_t  mTimeValid;  // x3
102     uint8_t  mTimeSource; // x4
103     int32_t  mTimeUnc;    // x5
104     int32_t  mClockFreqBias; // x6
105     int32_t  mClockFreqBiasUnc; // x7
106     uint8_t  mXoState;    // x8
107     int32_t  mPgaGain;    // x9
108     uint32_t mGpsBpAmpI;  // xA
109     uint32_t mGpsBpAmpQ;  // xB
110     uint32_t mAdcI;       // xC
111     uint32_t mAdcQ;       // xD
112     uint32_t mJammerGps;  // xE
113     uint32_t mJammerGlo;  // xF
114     uint32_t mJammerBds;  // x10
115     uint32_t mJammerGal;  // x11
116     uint32_t mRecErrorRecovery; // x12
117     double   mAgcGps;     // x13
118     double   mAgcGlo;     // x14
119     double   mAgcBds;     // x15
120     double   mAgcGal;     // x16
121     int32_t  mLeapSeconds;// x17
122     int32_t  mLeapSecUnc; // x18
123     uint32_t mGloBpAmpI;  // x19
124     uint32_t mGloBpAmpQ;  // x1A
125     uint32_t mBdsBpAmpI;  // x1B
126     uint32_t mBdsBpAmpQ;  // x1C
127     uint32_t mGalBpAmpI;  // x1D
128     uint32_t mGalBpAmpQ;  // x1E
129     uint64_t mTimeUncNs;  // x1F
130 };
131 
132 // parser
133 class SystemStatusPQWM1parser : public SystemStatusNmeaBase
134 {
135 private:
136     enum
137     {
138         eTalker = 0,
139         eGpsWeek = 1,
140         eGpsTowMs = 2,
141         eTimeValid = 3,
142         eTimeSource = 4,
143         eTimeUnc = 5,
144         eClockFreqBias = 6,
145         eClockFreqBiasUnc = 7,
146         eXoState = 8,
147         ePgaGain = 9,
148         eGpsBpAmpI = 10,
149         eGpsBpAmpQ = 11,
150         eAdcI = 12,
151         eAdcQ = 13,
152         eJammerGps = 14,
153         eJammerGlo = 15,
154         eJammerBds = 16,
155         eJammerGal = 17,
156         eRecErrorRecovery = 18,
157         eAgcGps = 19,
158         eAgcGlo = 20,
159         eAgcBds = 21,
160         eAgcGal = 22,
161         eLeapSeconds = 23,
162         eLeapSecUnc = 24,
163         eGloBpAmpI = 25,
164         eGloBpAmpQ = 26,
165         eBdsBpAmpI = 27,
166         eBdsBpAmpQ = 28,
167         eGalBpAmpI = 29,
168         eGalBpAmpQ = 30,
169         eMax0 = eGalBpAmpQ,
170         eTimeUncNs = 31,
171         eMax
172     };
173     SystemStatusPQWM1 mM1;
174 
175 public:
getGpsWeek()176     inline uint16_t   getGpsWeek()    { return mM1.mGpsWeek; }
getGpsTowMs()177     inline uint32_t   getGpsTowMs()   { return mM1.mGpsTowMs; }
getTimeValid()178     inline uint8_t    getTimeValid()  { return mM1.mTimeValid; }
getTimeSource()179     inline uint8_t    getTimeSource() { return mM1.mTimeSource; }
getTimeUnc()180     inline int32_t    getTimeUnc()    { return mM1.mTimeUnc; }
getClockFreqBias()181     inline int32_t    getClockFreqBias() { return mM1.mClockFreqBias; }
getClockFreqBiasUnc()182     inline int32_t    getClockFreqBiasUnc() { return mM1.mClockFreqBiasUnc; }
getXoState()183     inline uint8_t    getXoState()    { return mM1.mXoState;}
getPgaGain()184     inline int32_t    getPgaGain()    { return mM1.mPgaGain;          }
getGpsBpAmpI()185     inline uint32_t   getGpsBpAmpI()  { return mM1.mGpsBpAmpI;        }
getGpsBpAmpQ()186     inline uint32_t   getGpsBpAmpQ()  { return mM1.mGpsBpAmpQ;        }
getAdcI()187     inline uint32_t   getAdcI()       { return mM1.mAdcI;             }
getAdcQ()188     inline uint32_t   getAdcQ()       { return mM1.mAdcQ;             }
getJammerGps()189     inline uint32_t   getJammerGps()  { return mM1.mJammerGps;        }
getJammerGlo()190     inline uint32_t   getJammerGlo()  { return mM1.mJammerGlo;        }
getJammerBds()191     inline uint32_t   getJammerBds()  { return mM1.mJammerBds;        }
getJammerGal()192     inline uint32_t   getJammerGal()  { return mM1.mJammerGal;        }
getAgcGps()193     inline uint32_t   getAgcGps()     { return mM1.mAgcGps;           }
getAgcGlo()194     inline uint32_t   getAgcGlo()     { return mM1.mAgcGlo;           }
getAgcBds()195     inline uint32_t   getAgcBds()     { return mM1.mAgcBds;           }
getAgcGal()196     inline uint32_t   getAgcGal()     { return mM1.mAgcGal;           }
getRecErrorRecovery()197     inline uint32_t   getRecErrorRecovery() { return mM1.mRecErrorRecovery; }
getLeapSeconds()198     inline int32_t    getLeapSeconds(){ return mM1.mLeapSeconds; }
getLeapSecUnc()199     inline int32_t    getLeapSecUnc() { return mM1.mLeapSecUnc; }
getGloBpAmpI()200     inline uint32_t   getGloBpAmpI()  { return mM1.mGloBpAmpI; }
getGloBpAmpQ()201     inline uint32_t   getGloBpAmpQ()  { return mM1.mGloBpAmpQ; }
getBdsBpAmpI()202     inline uint32_t   getBdsBpAmpI()  { return mM1.mBdsBpAmpI; }
getBdsBpAmpQ()203     inline uint32_t   getBdsBpAmpQ()  { return mM1.mBdsBpAmpQ; }
getGalBpAmpI()204     inline uint32_t   getGalBpAmpI()  { return mM1.mGalBpAmpI; }
getGalBpAmpQ()205     inline uint32_t   getGalBpAmpQ()  { return mM1.mGalBpAmpQ; }
getTimeUncNs()206     inline uint64_t   getTimeUncNs()  { return mM1.mTimeUncNs; }
207 
SystemStatusPQWM1parser(const char * str_in,uint32_t len_in)208     SystemStatusPQWM1parser(const char *str_in, uint32_t len_in)
209         : SystemStatusNmeaBase(str_in, len_in)
210     {
211         memset(&mM1, 0, sizeof(mM1));
212         if (mField.size() <= eMax0) {
213             LOC_LOGE("PQWM1parser - invalid size=%zu", mField.size());
214             mM1.mTimeValid = 0;
215             return;
216         }
217         mM1.mGpsWeek = atoi(mField[eGpsWeek].c_str());
218         mM1.mGpsTowMs = atoi(mField[eGpsTowMs].c_str());
219         mM1.mTimeValid = atoi(mField[eTimeValid].c_str());
220         mM1.mTimeSource = atoi(mField[eTimeSource].c_str());
221         mM1.mTimeUnc = atoi(mField[eTimeUnc].c_str());
222         mM1.mClockFreqBias = atoi(mField[eClockFreqBias].c_str());
223         mM1.mClockFreqBiasUnc = atoi(mField[eClockFreqBiasUnc].c_str());
224         mM1.mXoState = atoi(mField[eXoState].c_str());
225         mM1.mPgaGain = atoi(mField[ePgaGain].c_str());
226         mM1.mGpsBpAmpI = atoi(mField[eGpsBpAmpI].c_str());
227         mM1.mGpsBpAmpQ = atoi(mField[eGpsBpAmpQ].c_str());
228         mM1.mAdcI = atoi(mField[eAdcI].c_str());
229         mM1.mAdcQ = atoi(mField[eAdcQ].c_str());
230         mM1.mJammerGps = atoi(mField[eJammerGps].c_str());
231         mM1.mJammerGlo = atoi(mField[eJammerGlo].c_str());
232         mM1.mJammerBds = atoi(mField[eJammerBds].c_str());
233         mM1.mJammerGal = atoi(mField[eJammerGal].c_str());
234         mM1.mRecErrorRecovery = atoi(mField[eRecErrorRecovery].c_str());
235         mM1.mAgcGps = atof(mField[eAgcGps].c_str());
236         mM1.mAgcGlo = atof(mField[eAgcGlo].c_str());
237         mM1.mAgcBds = atof(mField[eAgcBds].c_str());
238         mM1.mAgcGal = atof(mField[eAgcGal].c_str());
239         mM1.mLeapSeconds = atoi(mField[eLeapSeconds].c_str());
240         mM1.mLeapSecUnc = atoi(mField[eLeapSecUnc].c_str());
241         mM1.mGloBpAmpI = atoi(mField[eGloBpAmpI].c_str());
242         mM1.mGloBpAmpQ = atoi(mField[eGloBpAmpQ].c_str());
243         mM1.mBdsBpAmpI = atoi(mField[eBdsBpAmpI].c_str());
244         mM1.mBdsBpAmpQ = atoi(mField[eBdsBpAmpQ].c_str());
245         mM1.mGalBpAmpI = atoi(mField[eGalBpAmpI].c_str());
246         mM1.mGalBpAmpQ = atoi(mField[eGalBpAmpQ].c_str());
247         if (mField.size() > eTimeUncNs) {
248             mM1.mTimeUncNs = strtoull(mField[eTimeUncNs].c_str(), nullptr, 10);
249         }
250     }
251 
get()252     inline SystemStatusPQWM1& get() { return mM1;} //getparser
253 };
254 
255 /******************************************************************************
256  SystemStatusPQWP1
257 ******************************************************************************/
258 class SystemStatusPQWP1
259 {
260 public:
261     uint8_t  mEpiValidity; // x4
262     float    mEpiLat;    // x5
263     float    mEpiLon;    // x6
264     float    mEpiAlt;    // x7
265     float    mEpiHepe;   // x8
266     float    mEpiAltUnc; // x9
267     uint8_t  mEpiSrc;    // x10
268 };
269 
270 class SystemStatusPQWP1parser : public SystemStatusNmeaBase
271 {
272 private:
273     enum
274     {
275         eTalker = 0,
276         eUtcTime = 1,
277         eEpiValidity = 2,
278         eEpiLat = 3,
279         eEpiLon = 4,
280         eEpiAlt = 5,
281         eEpiHepe = 6,
282         eEpiAltUnc = 7,
283         eEpiSrc = 8,
284         eMax
285     };
286     SystemStatusPQWP1 mP1;
287 
288 public:
getEpiValidity()289     inline uint8_t    getEpiValidity() { return mP1.mEpiValidity;      }
getEpiLat()290     inline float      getEpiLat() { return mP1.mEpiLat;           }
getEpiLon()291     inline float      getEpiLon() { return mP1.mEpiLon;           }
getEpiAlt()292     inline float      getEpiAlt() { return mP1.mEpiAlt;           }
getEpiHepe()293     inline float      getEpiHepe() { return mP1.mEpiHepe;          }
getEpiAltUnc()294     inline float      getEpiAltUnc() { return mP1.mEpiAltUnc;        }
getEpiSrc()295     inline uint8_t    getEpiSrc() { return mP1.mEpiSrc;           }
296 
SystemStatusPQWP1parser(const char * str_in,uint32_t len_in)297     SystemStatusPQWP1parser(const char *str_in, uint32_t len_in)
298         : SystemStatusNmeaBase(str_in, len_in)
299     {
300         if (mField.size() < eMax) {
301             return;
302         }
303         memset(&mP1, 0, sizeof(mP1));
304         mP1.mEpiValidity = strtol(mField[eEpiValidity].c_str(), NULL, 16);
305         mP1.mEpiLat = atof(mField[eEpiLat].c_str());
306         mP1.mEpiLon = atof(mField[eEpiLon].c_str());
307         mP1.mEpiAlt = atof(mField[eEpiAlt].c_str());
308         mP1.mEpiHepe = atoi(mField[eEpiHepe].c_str());
309         mP1.mEpiAltUnc = atof(mField[eEpiAltUnc].c_str());
310         mP1.mEpiSrc = atoi(mField[eEpiSrc].c_str());
311     }
312 
get()313     inline SystemStatusPQWP1& get() { return mP1;}
314 };
315 
316 /******************************************************************************
317  SystemStatusPQWP2
318 ******************************************************************************/
319 class SystemStatusPQWP2
320 {
321 public:
322     float    mBestLat;   // x4
323     float    mBestLon;   // x5
324     float    mBestAlt;   // x6
325     float    mBestHepe;  // x7
326     float    mBestAltUnc; // x8
327 };
328 
329 class SystemStatusPQWP2parser : public SystemStatusNmeaBase
330 {
331 private:
332     enum
333     {
334         eTalker = 0,
335         eUtcTime = 1,
336         eBestLat = 2,
337         eBestLon = 3,
338         eBestAlt = 4,
339         eBestHepe = 5,
340         eBestAltUnc = 6,
341         eMax
342     };
343     SystemStatusPQWP2 mP2;
344 
345 public:
getBestLat()346     inline float      getBestLat() { return mP2.mBestLat;          }
getBestLon()347     inline float      getBestLon() { return mP2.mBestLon;          }
getBestAlt()348     inline float      getBestAlt() { return mP2.mBestAlt;          }
getBestHepe()349     inline float      getBestHepe() { return mP2.mBestHepe;         }
getBestAltUnc()350     inline float      getBestAltUnc() { return mP2.mBestAltUnc;       }
351 
SystemStatusPQWP2parser(const char * str_in,uint32_t len_in)352     SystemStatusPQWP2parser(const char *str_in, uint32_t len_in)
353         : SystemStatusNmeaBase(str_in, len_in)
354     {
355         if (mField.size() < eMax) {
356             return;
357         }
358         memset(&mP2, 0, sizeof(mP2));
359         mP2.mBestLat = atof(mField[eBestLat].c_str());
360         mP2.mBestLon = atof(mField[eBestLon].c_str());
361         mP2.mBestAlt = atof(mField[eBestAlt].c_str());
362         mP2.mBestHepe = atof(mField[eBestHepe].c_str());
363         mP2.mBestAltUnc = atof(mField[eBestAltUnc].c_str());
364     }
365 
get()366     inline SystemStatusPQWP2& get() { return mP2;}
367 };
368 
369 /******************************************************************************
370  SystemStatusPQWP3
371 ******************************************************************************/
372 class SystemStatusPQWP3
373 {
374 public:
375     uint8_t   mXtraValidMask;
376     uint32_t  mGpsXtraAge;
377     uint32_t  mGloXtraAge;
378     uint32_t  mBdsXtraAge;
379     uint32_t  mGalXtraAge;
380     uint32_t  mQzssXtraAge;
381     uint32_t  mGpsXtraValid;
382     uint32_t  mGloXtraValid;
383     uint64_t  mBdsXtraValid;
384     uint64_t  mGalXtraValid;
385     uint8_t   mQzssXtraValid;
386 };
387 
388 class SystemStatusPQWP3parser : public SystemStatusNmeaBase
389 {
390 private:
391     enum
392     {
393         eTalker = 0,
394         eUtcTime = 1,
395         eXtraValidMask = 2,
396         eGpsXtraAge = 3,
397         eGloXtraAge = 4,
398         eBdsXtraAge = 5,
399         eGalXtraAge = 6,
400         eQzssXtraAge = 7,
401         eGpsXtraValid = 8,
402         eGloXtraValid = 9,
403         eBdsXtraValid = 10,
404         eGalXtraValid = 11,
405         eQzssXtraValid = 12,
406         eMax
407     };
408     SystemStatusPQWP3 mP3;
409 
410 public:
getXtraValid()411     inline uint8_t    getXtraValid() { return mP3.mXtraValidMask;   }
getGpsXtraAge()412     inline uint32_t   getGpsXtraAge() { return mP3.mGpsXtraAge;       }
getGloXtraAge()413     inline uint32_t   getGloXtraAge() { return mP3.mGloXtraAge;       }
getBdsXtraAge()414     inline uint32_t   getBdsXtraAge() { return mP3.mBdsXtraAge;       }
getGalXtraAge()415     inline uint32_t   getGalXtraAge() { return mP3.mGalXtraAge;       }
getQzssXtraAge()416     inline uint32_t   getQzssXtraAge() { return mP3.mQzssXtraAge;      }
getGpsXtraValid()417     inline uint32_t   getGpsXtraValid() { return mP3.mGpsXtraValid;     }
getGloXtraValid()418     inline uint32_t   getGloXtraValid() { return mP3.mGloXtraValid;     }
getBdsXtraValid()419     inline uint64_t   getBdsXtraValid() { return mP3.mBdsXtraValid;     }
getGalXtraValid()420     inline uint64_t   getGalXtraValid() { return mP3.mGalXtraValid;     }
getQzssXtraValid()421     inline uint8_t    getQzssXtraValid() { return mP3.mQzssXtraValid;    }
422 
SystemStatusPQWP3parser(const char * str_in,uint32_t len_in)423     SystemStatusPQWP3parser(const char *str_in, uint32_t len_in)
424         : SystemStatusNmeaBase(str_in, len_in)
425     {
426         if (mField.size() < eMax) {
427             return;
428         }
429         memset(&mP3, 0, sizeof(mP3));
430         mP3.mXtraValidMask = strtol(mField[eXtraValidMask].c_str(), NULL, 16);
431         mP3.mGpsXtraAge = atoi(mField[eGpsXtraAge].c_str());
432         mP3.mGloXtraAge = atoi(mField[eGloXtraAge].c_str());
433         mP3.mBdsXtraAge = atoi(mField[eBdsXtraAge].c_str());
434         mP3.mGalXtraAge = atoi(mField[eGalXtraAge].c_str());
435         mP3.mQzssXtraAge = atoi(mField[eQzssXtraAge].c_str());
436         mP3.mGpsXtraValid = strtol(mField[eGpsXtraValid].c_str(), NULL, 16);
437         mP3.mGloXtraValid = strtol(mField[eGloXtraValid].c_str(), NULL, 16);
438         mP3.mBdsXtraValid = strtol(mField[eBdsXtraValid].c_str(), NULL, 16);
439         mP3.mGalXtraValid = strtol(mField[eGalXtraValid].c_str(), NULL, 16);
440         mP3.mQzssXtraValid = strtol(mField[eQzssXtraValid].c_str(), NULL, 16);
441     }
442 
get()443     inline SystemStatusPQWP3& get() { return mP3;}
444 };
445 
446 /******************************************************************************
447  SystemStatusPQWP4
448 ******************************************************************************/
449 class SystemStatusPQWP4
450 {
451 public:
452     uint32_t  mGpsEpheValid;
453     uint32_t  mGloEpheValid;
454     uint64_t  mBdsEpheValid;
455     uint64_t  mGalEpheValid;
456     uint8_t   mQzssEpheValid;
457 };
458 
459 class SystemStatusPQWP4parser : public SystemStatusNmeaBase
460 {
461 private:
462     enum
463     {
464         eTalker = 0,
465         eUtcTime = 1,
466         eGpsEpheValid = 2,
467         eGloEpheValid = 3,
468         eBdsEpheValid = 4,
469         eGalEpheValid = 5,
470         eQzssEpheValid = 6,
471         eMax
472     };
473     SystemStatusPQWP4 mP4;
474 
475 public:
getGpsEpheValid()476     inline uint32_t   getGpsEpheValid() { return mP4.mGpsEpheValid;     }
getGloEpheValid()477     inline uint32_t   getGloEpheValid() { return mP4.mGloEpheValid;     }
getBdsEpheValid()478     inline uint64_t   getBdsEpheValid() { return mP4.mBdsEpheValid;     }
getGalEpheValid()479     inline uint64_t   getGalEpheValid() { return mP4.mGalEpheValid;     }
getQzssEpheValid()480     inline uint8_t    getQzssEpheValid() { return mP4.mQzssEpheValid;    }
481 
SystemStatusPQWP4parser(const char * str_in,uint32_t len_in)482     SystemStatusPQWP4parser(const char *str_in, uint32_t len_in)
483         : SystemStatusNmeaBase(str_in, len_in)
484     {
485         if (mField.size() < eMax) {
486             return;
487         }
488         memset(&mP4, 0, sizeof(mP4));
489         mP4.mGpsEpheValid = strtol(mField[eGpsEpheValid].c_str(), NULL, 16);
490         mP4.mGloEpheValid = strtol(mField[eGloEpheValid].c_str(), NULL, 16);
491         mP4.mBdsEpheValid = strtol(mField[eBdsEpheValid].c_str(), NULL, 16);
492         mP4.mGalEpheValid = strtol(mField[eGalEpheValid].c_str(), NULL, 16);
493         mP4.mQzssEpheValid = strtol(mField[eQzssEpheValid].c_str(), NULL, 16);
494     }
495 
get()496     inline SystemStatusPQWP4& get() { return mP4;}
497 };
498 
499 /******************************************************************************
500  SystemStatusPQWP5
501 ******************************************************************************/
502 class SystemStatusPQWP5
503 {
504 public:
505     uint32_t  mGpsUnknownMask;
506     uint32_t  mGloUnknownMask;
507     uint64_t  mBdsUnknownMask;
508     uint64_t  mGalUnknownMask;
509     uint8_t   mQzssUnknownMask;
510     uint32_t  mGpsGoodMask;
511     uint32_t  mGloGoodMask;
512     uint64_t  mBdsGoodMask;
513     uint64_t  mGalGoodMask;
514     uint8_t   mQzssGoodMask;
515     uint32_t  mGpsBadMask;
516     uint32_t  mGloBadMask;
517     uint64_t  mBdsBadMask;
518     uint64_t  mGalBadMask;
519     uint8_t   mQzssBadMask;
520 };
521 
522 class SystemStatusPQWP5parser : public SystemStatusNmeaBase
523 {
524 private:
525     enum
526     {
527         eTalker = 0,
528         eUtcTime = 1,
529         eGpsUnknownMask = 2,
530         eGloUnknownMask = 3,
531         eBdsUnknownMask = 4,
532         eGalUnknownMask = 5,
533         eQzssUnknownMask = 6,
534         eGpsGoodMask = 7,
535         eGloGoodMask = 8,
536         eBdsGoodMask = 9,
537         eGalGoodMask = 10,
538         eQzssGoodMask = 11,
539         eGpsBadMask = 12,
540         eGloBadMask = 13,
541         eBdsBadMask = 14,
542         eGalBadMask = 15,
543         eQzssBadMask = 16,
544         eMax
545     };
546     SystemStatusPQWP5 mP5;
547 
548 public:
getGpsUnknownMask()549     inline uint32_t   getGpsUnknownMask() { return mP5.mGpsUnknownMask;   }
getGloUnknownMask()550     inline uint32_t   getGloUnknownMask() { return mP5.mGloUnknownMask;   }
getBdsUnknownMask()551     inline uint64_t   getBdsUnknownMask() { return mP5.mBdsUnknownMask;   }
getGalUnknownMask()552     inline uint64_t   getGalUnknownMask() { return mP5.mGalUnknownMask;   }
getQzssUnknownMask()553     inline uint8_t    getQzssUnknownMask() { return mP5.mQzssUnknownMask;  }
getGpsGoodMask()554     inline uint32_t   getGpsGoodMask() { return mP5.mGpsGoodMask;      }
getGloGoodMask()555     inline uint32_t   getGloGoodMask() { return mP5.mGloGoodMask;      }
getBdsGoodMask()556     inline uint64_t   getBdsGoodMask() { return mP5.mBdsGoodMask;      }
getGalGoodMask()557     inline uint64_t   getGalGoodMask() { return mP5.mGalGoodMask;      }
getQzssGoodMask()558     inline uint8_t    getQzssGoodMask() { return mP5.mQzssGoodMask;     }
getGpsBadMask()559     inline uint32_t   getGpsBadMask() { return mP5.mGpsBadMask;       }
getGloBadMask()560     inline uint32_t   getGloBadMask() { return mP5.mGloBadMask;       }
getBdsBadMask()561     inline uint64_t   getBdsBadMask() { return mP5.mBdsBadMask;       }
getGalBadMask()562     inline uint64_t   getGalBadMask() { return mP5.mGalBadMask;       }
getQzssBadMask()563     inline uint8_t    getQzssBadMask() { return mP5.mQzssBadMask;      }
564 
SystemStatusPQWP5parser(const char * str_in,uint32_t len_in)565     SystemStatusPQWP5parser(const char *str_in, uint32_t len_in)
566         : SystemStatusNmeaBase(str_in, len_in)
567     {
568         if (mField.size() < eMax) {
569             return;
570         }
571         memset(&mP5, 0, sizeof(mP5));
572         mP5.mGpsUnknownMask = strtol(mField[eGpsUnknownMask].c_str(), NULL, 16);
573         mP5.mGloUnknownMask = strtol(mField[eGloUnknownMask].c_str(), NULL, 16);
574         mP5.mBdsUnknownMask = strtol(mField[eBdsUnknownMask].c_str(), NULL, 16);
575         mP5.mGalUnknownMask = strtol(mField[eGalUnknownMask].c_str(), NULL, 16);
576         mP5.mQzssUnknownMask = strtol(mField[eQzssUnknownMask].c_str(), NULL, 16);
577         mP5.mGpsGoodMask = strtol(mField[eGpsGoodMask].c_str(), NULL, 16);
578         mP5.mGloGoodMask = strtol(mField[eGloGoodMask].c_str(), NULL, 16);
579         mP5.mBdsGoodMask = strtol(mField[eBdsGoodMask].c_str(), NULL, 16);
580         mP5.mGalGoodMask = strtol(mField[eGalGoodMask].c_str(), NULL, 16);
581         mP5.mQzssGoodMask = strtol(mField[eQzssGoodMask].c_str(), NULL, 16);
582         mP5.mGpsBadMask = strtol(mField[eGpsBadMask].c_str(), NULL, 16);
583         mP5.mGloBadMask = strtol(mField[eGloBadMask].c_str(), NULL, 16);
584         mP5.mBdsBadMask = strtol(mField[eBdsBadMask].c_str(), NULL, 16);
585         mP5.mGalBadMask = strtol(mField[eGalBadMask].c_str(), NULL, 16);
586         mP5.mQzssBadMask = strtol(mField[eQzssBadMask].c_str(), NULL, 16);
587     }
588 
get()589     inline SystemStatusPQWP5& get() { return mP5;}
590 };
591 
592 /******************************************************************************
593  SystemStatusPQWP6parser
594 ******************************************************************************/
595 class SystemStatusPQWP6
596 {
597 public:
598     uint32_t  mFixInfoMask;
599 };
600 
601 class SystemStatusPQWP6parser : public SystemStatusNmeaBase
602 {
603 private:
604     enum
605     {
606         eTalker = 0,
607         eUtcTime = 1,
608         eFixInfoMask = 2,
609         eMax
610     };
611     SystemStatusPQWP6 mP6;
612 
613 public:
getFixInfoMask()614     inline uint32_t   getFixInfoMask() { return mP6.mFixInfoMask;      }
615 
SystemStatusPQWP6parser(const char * str_in,uint32_t len_in)616     SystemStatusPQWP6parser(const char *str_in, uint32_t len_in)
617         : SystemStatusNmeaBase(str_in, len_in)
618     {
619         if (mField.size() < eMax) {
620             return;
621         }
622         memset(&mP6, 0, sizeof(mP6));
623         mP6.mFixInfoMask = strtol(mField[eFixInfoMask].c_str(), NULL, 16);
624     }
625 
get()626     inline SystemStatusPQWP6& get() { return mP6;}
627 };
628 
629 /******************************************************************************
630  SystemStatusPQWP7parser
631 ******************************************************************************/
632 class SystemStatusPQWP7
633 {
634 public:
635     SystemStatusNav mNav[SV_ALL_NUM];
636 };
637 
638 class SystemStatusPQWP7parser : public SystemStatusNmeaBase
639 {
640 private:
641     enum
642     {
643         eTalker = 0,
644         eUtcTime = 1,
645         eMax = 2 + SV_ALL_NUM*3
646     };
647     SystemStatusPQWP7 mP7;
648 
649 public:
SystemStatusPQWP7parser(const char * str_in,uint32_t len_in)650     SystemStatusPQWP7parser(const char *str_in, uint32_t len_in)
651         : SystemStatusNmeaBase(str_in, len_in)
652     {
653         if (mField.size() < eMax) {
654             LOC_LOGE("PQWP7parser - invalid size=%zu", mField.size());
655             return;
656         }
657         for (uint32_t i=0; i<SV_ALL_NUM; i++) {
658             mP7.mNav[i].mType   = GnssEphemerisType(atoi(mField[i*3+2].c_str()));
659             mP7.mNav[i].mSource = GnssEphemerisSource(atoi(mField[i*3+3].c_str()));
660             mP7.mNav[i].mAgeSec = atoi(mField[i*3+4].c_str());
661         }
662     }
663 
get()664     inline SystemStatusPQWP7& get() { return mP7;}
665 };
666 
667 /******************************************************************************
668  SystemStatusPQWS1parser
669 ******************************************************************************/
670 class SystemStatusPQWS1
671 {
672 public:
673     uint32_t  mFixInfoMask;
674     uint32_t  mHepeLimit;
675 };
676 
677 class SystemStatusPQWS1parser : public SystemStatusNmeaBase
678 {
679 private:
680     enum
681     {
682         eTalker = 0,
683         eUtcTime = 1,
684         eFixInfoMask = 2,
685         eHepeLimit = 3,
686         eMax
687     };
688     SystemStatusPQWS1 mS1;
689 
690 public:
getFixInfoMask()691     inline uint16_t   getFixInfoMask() { return mS1.mFixInfoMask;      }
getHepeLimit()692     inline uint32_t   getHepeLimit()   { return mS1.mHepeLimit;      }
693 
SystemStatusPQWS1parser(const char * str_in,uint32_t len_in)694     SystemStatusPQWS1parser(const char *str_in, uint32_t len_in)
695         : SystemStatusNmeaBase(str_in, len_in)
696     {
697         if (mField.size() < eMax) {
698             return;
699         }
700         memset(&mS1, 0, sizeof(mS1));
701         mS1.mFixInfoMask = atoi(mField[eFixInfoMask].c_str());
702         mS1.mHepeLimit = atoi(mField[eHepeLimit].c_str());
703     }
704 
get()705     inline SystemStatusPQWS1& get() { return mS1;}
706 };
707 
708 /******************************************************************************
709  SystemStatusTimeAndClock
710 ******************************************************************************/
SystemStatusTimeAndClock(const SystemStatusPQWM1 & nmea)711 SystemStatusTimeAndClock::SystemStatusTimeAndClock(const SystemStatusPQWM1& nmea) :
712     mGpsWeek(nmea.mGpsWeek),
713     mGpsTowMs(nmea.mGpsTowMs),
714     mTimeValid(nmea.mTimeValid),
715     mTimeSource(nmea.mTimeSource),
716     mTimeUnc(nmea.mTimeUnc),
717     mClockFreqBias(nmea.mClockFreqBias),
718     mClockFreqBiasUnc(nmea.mClockFreqBiasUnc),
719     mLeapSeconds(nmea.mLeapSeconds),
720     mLeapSecUnc(nmea.mLeapSecUnc),
721     mTimeUncNs(nmea.mTimeUncNs)
722 {
723 }
724 
equals(const SystemStatusTimeAndClock & peer)725 bool SystemStatusTimeAndClock::equals(const SystemStatusTimeAndClock& peer)
726 {
727     if ((mGpsWeek != peer.mGpsWeek) ||
728         (mGpsTowMs != peer.mGpsTowMs) ||
729         (mTimeValid != peer.mTimeValid) ||
730         (mTimeSource != peer.mTimeSource) ||
731         (mTimeUnc != peer.mTimeUnc) ||
732         (mClockFreqBias != peer.mClockFreqBias) ||
733         (mClockFreqBiasUnc != peer.mClockFreqBiasUnc) ||
734         (mLeapSeconds != peer.mLeapSeconds) ||
735         (mLeapSecUnc != peer.mLeapSecUnc) ||
736         (mTimeUncNs != peer.mTimeUncNs)) {
737         return false;
738     }
739     return true;
740 }
741 
dump()742 void SystemStatusTimeAndClock::dump()
743 {
744     LOC_LOGV("TimeAndClock: u=%ld:%ld g=%d:%d v=%d ts=%d tu=%d b=%d bu=%d ls=%d lu=%d un=%" PRIu64,
745              mUtcTime.tv_sec, mUtcTime.tv_nsec,
746              mGpsWeek,
747              mGpsTowMs,
748              mTimeValid,
749              mTimeSource,
750              mTimeUnc,
751              mClockFreqBias,
752              mClockFreqBiasUnc,
753              mLeapSeconds,
754              mLeapSecUnc,
755              mTimeUncNs);
756     return;
757 }
758 
759 /******************************************************************************
760  SystemStatusXoState
761 ******************************************************************************/
SystemStatusXoState(const SystemStatusPQWM1 & nmea)762 SystemStatusXoState::SystemStatusXoState(const SystemStatusPQWM1& nmea) :
763     mXoState(nmea.mXoState)
764 {
765 }
766 
equals(const SystemStatusXoState & peer)767 bool SystemStatusXoState::equals(const SystemStatusXoState& peer)
768 {
769     if (mXoState != peer.mXoState) {
770         return false;
771     }
772     return true;
773 }
774 
dump()775 void SystemStatusXoState::dump()
776 {
777     LOC_LOGV("XoState: u=%ld:%ld x=%d",
778              mUtcTime.tv_sec, mUtcTime.tv_nsec,
779              mXoState);
780     return;
781 }
782 
783 /******************************************************************************
784  SystemStatusRfAndParams
785 ******************************************************************************/
SystemStatusRfAndParams(const SystemStatusPQWM1 & nmea)786 SystemStatusRfAndParams::SystemStatusRfAndParams(const SystemStatusPQWM1& nmea) :
787     mPgaGain(nmea.mPgaGain),
788     mGpsBpAmpI(nmea.mGpsBpAmpI),
789     mGpsBpAmpQ(nmea.mGpsBpAmpQ),
790     mAdcI(nmea.mAdcI),
791     mAdcQ(nmea.mAdcQ),
792     mJammerGps(nmea.mJammerGps),
793     mJammerGlo(nmea.mJammerGlo),
794     mJammerBds(nmea.mJammerBds),
795     mJammerGal(nmea.mJammerGal),
796     mAgcGps(nmea.mAgcGps),
797     mAgcGlo(nmea.mAgcGlo),
798     mAgcBds(nmea.mAgcBds),
799     mAgcGal(nmea.mAgcGal),
800     mGloBpAmpI(nmea.mGloBpAmpI),
801     mGloBpAmpQ(nmea.mGloBpAmpQ),
802     mBdsBpAmpI(nmea.mBdsBpAmpI),
803     mBdsBpAmpQ(nmea.mBdsBpAmpQ),
804     mGalBpAmpI(nmea.mGalBpAmpI),
805     mGalBpAmpQ(nmea.mGalBpAmpQ)
806 {
807 }
808 
equals(const SystemStatusRfAndParams & peer)809 bool SystemStatusRfAndParams::equals(const SystemStatusRfAndParams& peer)
810 {
811     if ((mPgaGain != peer.mPgaGain) ||
812         (mGpsBpAmpI != peer.mGpsBpAmpI) ||
813         (mGpsBpAmpQ != peer.mGpsBpAmpQ) ||
814         (mAdcI != peer.mAdcI) ||
815         (mAdcQ != peer.mAdcQ) ||
816         (mJammerGps != peer.mJammerGps) ||
817         (mJammerGlo != peer.mJammerGlo) ||
818         (mJammerBds != peer.mJammerBds) ||
819         (mJammerGal != peer.mJammerGal) ||
820         (mAgcGps != peer.mAgcGps) ||
821         (mAgcGlo != peer.mAgcGlo) ||
822         (mAgcBds != peer.mAgcBds) ||
823         (mAgcGal != peer.mAgcGal) ||
824         (mGloBpAmpI != peer.mGloBpAmpI) ||
825         (mGloBpAmpQ != peer.mGloBpAmpQ) ||
826         (mBdsBpAmpI != peer.mBdsBpAmpI) ||
827         (mBdsBpAmpQ != peer.mBdsBpAmpQ) ||
828         (mGalBpAmpI != peer.mGalBpAmpI) ||
829         (mGalBpAmpQ != peer.mGalBpAmpQ)) {
830         return false;
831     }
832     return true;
833 }
834 
dump()835 void SystemStatusRfAndParams::dump()
836 {
837     LOC_LOGV("RfAndParams: u=%ld:%ld p=%d bi=%d bq=%d ai=%d aq=%d "
838              "jgp=%d jgl=%d jbd=%d jga=%d "
839              "agp=%lf agl=%lf abd=%lf aga=%lf",
840              mUtcTime.tv_sec, mUtcTime.tv_nsec,
841              mPgaGain,
842              mGpsBpAmpI,
843              mGpsBpAmpQ,
844              mAdcI,
845              mAdcQ,
846              mJammerGps,
847              mJammerGlo,
848              mJammerBds,
849              mJammerGal,
850              mAgcGps,
851              mAgcGlo,
852              mAgcBds,
853              mAgcGal);
854     return;
855 }
856 
857 /******************************************************************************
858  SystemStatusErrRecovery
859 ******************************************************************************/
SystemStatusErrRecovery(const SystemStatusPQWM1 & nmea)860 SystemStatusErrRecovery::SystemStatusErrRecovery(const SystemStatusPQWM1& nmea) :
861     mRecErrorRecovery(nmea.mRecErrorRecovery)
862 {
863 }
864 
equals(const SystemStatusErrRecovery & peer)865 bool SystemStatusErrRecovery::equals(const SystemStatusErrRecovery& peer)
866 {
867     if (mRecErrorRecovery != peer.mRecErrorRecovery) {
868         return false;
869     }
870     return true;
871 }
872 
dump()873 void SystemStatusErrRecovery::dump()
874 {
875     LOC_LOGV("ErrRecovery: u=%ld:%ld e=%d",
876              mUtcTime.tv_sec, mUtcTime.tv_nsec,
877              mRecErrorRecovery);
878     return;
879 }
880 
881 /******************************************************************************
882  SystemStatusInjectedPosition
883 ******************************************************************************/
SystemStatusInjectedPosition(const SystemStatusPQWP1 & nmea)884 SystemStatusInjectedPosition::SystemStatusInjectedPosition(const SystemStatusPQWP1& nmea) :
885     mEpiValidity(nmea.mEpiValidity),
886     mEpiLat(nmea.mEpiLat),
887     mEpiLon(nmea.mEpiLon),
888     mEpiAlt(nmea.mEpiAlt),
889     mEpiHepe(nmea.mEpiHepe),
890     mEpiAltUnc(nmea.mEpiAltUnc),
891     mEpiSrc(nmea.mEpiSrc)
892 {
893 }
894 
equals(const SystemStatusInjectedPosition & peer)895 bool SystemStatusInjectedPosition::equals(const SystemStatusInjectedPosition& peer)
896 {
897     if ((mEpiValidity != peer.mEpiValidity) ||
898         (mEpiLat != peer.mEpiLat) ||
899         (mEpiLon != peer.mEpiLon) ||
900         (mEpiAlt != peer.mEpiAlt) ||
901         (mEpiHepe != peer.mEpiHepe) ||
902         (mEpiAltUnc != peer.mEpiAltUnc) ||
903         (mEpiSrc != peer.mEpiSrc)) {
904         return false;
905     }
906     return true;
907 }
908 
dump()909 void SystemStatusInjectedPosition::dump()
910 {
911     LOC_LOGV("InjectedPosition: u=%ld:%ld v=%x la=%f lo=%f al=%f he=%f au=%f es=%d",
912              mUtcTime.tv_sec, mUtcTime.tv_nsec,
913              mEpiValidity,
914              mEpiLat,
915              mEpiLon,
916              mEpiAlt,
917              mEpiHepe,
918              mEpiAltUnc,
919              mEpiSrc);
920     return;
921 }
922 
923 /******************************************************************************
924  SystemStatusBestPosition
925 ******************************************************************************/
SystemStatusBestPosition(const SystemStatusPQWP2 & nmea)926 SystemStatusBestPosition::SystemStatusBestPosition(const SystemStatusPQWP2& nmea) :
927     mValid(true),
928     mBestLat(nmea.mBestLat),
929     mBestLon(nmea.mBestLon),
930     mBestAlt(nmea.mBestAlt),
931     mBestHepe(nmea.mBestHepe),
932     mBestAltUnc(nmea.mBestAltUnc)
933 {
934 }
935 
equals(const SystemStatusBestPosition & peer)936 bool SystemStatusBestPosition::equals(const SystemStatusBestPosition& peer)
937 {
938     if ((mBestLat != peer.mBestLat) ||
939         (mBestLon != peer.mBestLon) ||
940         (mBestAlt != peer.mBestAlt) ||
941         (mBestHepe != peer.mBestHepe) ||
942         (mBestAltUnc != peer.mBestAltUnc)) {
943         return false;
944     }
945     return true;
946 }
947 
dump()948 void SystemStatusBestPosition::dump()
949 {
950     LOC_LOGV("BestPosition: u=%ld:%ld la=%f lo=%f al=%f he=%f au=%f",
951              mUtcTime.tv_sec, mUtcTime.tv_nsec,
952              mBestLat,
953              mBestLon,
954              mBestAlt,
955              mBestHepe,
956              mBestAltUnc);
957     return;
958 }
959 
960 /******************************************************************************
961  SystemStatusXtra
962 ******************************************************************************/
SystemStatusXtra(const SystemStatusPQWP3 & nmea)963 SystemStatusXtra::SystemStatusXtra(const SystemStatusPQWP3& nmea) :
964     mXtraValidMask(nmea.mXtraValidMask),
965     mGpsXtraAge(nmea.mGpsXtraAge),
966     mGloXtraAge(nmea.mGloXtraAge),
967     mBdsXtraAge(nmea.mBdsXtraAge),
968     mGalXtraAge(nmea.mGalXtraAge),
969     mQzssXtraAge(nmea.mQzssXtraAge),
970     mGpsXtraValid(nmea.mGpsXtraValid),
971     mGloXtraValid(nmea.mGloXtraValid),
972     mBdsXtraValid(nmea.mBdsXtraValid),
973     mGalXtraValid(nmea.mGalXtraValid),
974     mQzssXtraValid(nmea.mQzssXtraValid)
975 {
976 }
977 
equals(const SystemStatusXtra & peer)978 bool SystemStatusXtra::equals(const SystemStatusXtra& peer)
979 {
980     if ((mXtraValidMask != peer.mXtraValidMask) ||
981         (mGpsXtraAge != peer.mGpsXtraAge) ||
982         (mGloXtraAge != peer.mGloXtraAge) ||
983         (mBdsXtraAge != peer.mBdsXtraAge) ||
984         (mGalXtraAge != peer.mGalXtraAge) ||
985         (mQzssXtraAge != peer.mQzssXtraAge) ||
986         (mGpsXtraValid != peer.mGpsXtraValid) ||
987         (mGloXtraValid != peer.mGloXtraValid) ||
988         (mBdsXtraValid != peer.mBdsXtraValid) ||
989         (mGalXtraValid != peer.mGalXtraValid) ||
990         (mQzssXtraValid != peer.mQzssXtraValid)) {
991         return false;
992     }
993     return true;
994 }
995 
dump()996 void SystemStatusXtra::dump()
997 {
998     LOC_LOGV("SystemStatusXtra: u=%ld:%ld m=%x a=%d:%d:%d:%d:%d v=%x:%x:%" PRIx64 ":%" PRIx64":%x",
999              mUtcTime.tv_sec, mUtcTime.tv_nsec,
1000              mXtraValidMask,
1001              mGpsXtraAge,
1002              mGloXtraAge,
1003              mBdsXtraAge,
1004              mGalXtraAge,
1005              mQzssXtraAge,
1006              mGpsXtraValid,
1007              mGloXtraValid,
1008              mBdsXtraValid,
1009              mGalXtraValid,
1010              mQzssXtraValid);
1011     return;
1012 }
1013 
1014 /******************************************************************************
1015  SystemStatusEphemeris
1016 ******************************************************************************/
SystemStatusEphemeris(const SystemStatusPQWP4 & nmea)1017 SystemStatusEphemeris::SystemStatusEphemeris(const SystemStatusPQWP4& nmea) :
1018     mGpsEpheValid(nmea.mGpsEpheValid),
1019     mGloEpheValid(nmea.mGloEpheValid),
1020     mBdsEpheValid(nmea.mBdsEpheValid),
1021     mGalEpheValid(nmea.mGalEpheValid),
1022     mQzssEpheValid(nmea.mQzssEpheValid)
1023 {
1024 }
1025 
equals(const SystemStatusEphemeris & peer)1026 bool SystemStatusEphemeris::equals(const SystemStatusEphemeris& peer)
1027 {
1028     if ((mGpsEpheValid != peer.mGpsEpheValid) ||
1029         (mGloEpheValid != peer.mGloEpheValid) ||
1030         (mBdsEpheValid != peer.mBdsEpheValid) ||
1031         (mGalEpheValid != peer.mGalEpheValid) ||
1032         (mQzssEpheValid != peer.mQzssEpheValid)) {
1033         return false;
1034     }
1035     return true;
1036 }
1037 
dump()1038 void SystemStatusEphemeris::dump()
1039 {
1040     LOC_LOGV("Ephemeris: u=%ld:%ld ev=%x:%x:%" PRIx64 ":%" PRIx64 ":%x",
1041              mUtcTime.tv_sec, mUtcTime.tv_nsec,
1042              mGpsEpheValid,
1043              mGloEpheValid,
1044              mBdsEpheValid,
1045              mGalEpheValid,
1046              mQzssEpheValid);
1047     return;
1048 }
1049 
1050 /******************************************************************************
1051  SystemStatusSvHealth
1052 ******************************************************************************/
SystemStatusSvHealth(const SystemStatusPQWP5 & nmea)1053 SystemStatusSvHealth::SystemStatusSvHealth(const SystemStatusPQWP5& nmea) :
1054     mGpsUnknownMask(nmea.mGpsUnknownMask),
1055     mGloUnknownMask(nmea.mGloUnknownMask),
1056     mBdsUnknownMask(nmea.mBdsUnknownMask),
1057     mGalUnknownMask(nmea.mGalUnknownMask),
1058     mQzssUnknownMask(nmea.mQzssUnknownMask),
1059     mGpsGoodMask(nmea.mGpsGoodMask),
1060     mGloGoodMask(nmea.mGloGoodMask),
1061     mBdsGoodMask(nmea.mBdsGoodMask),
1062     mGalGoodMask(nmea.mGalGoodMask),
1063     mQzssGoodMask(nmea.mQzssGoodMask),
1064     mGpsBadMask(nmea.mGpsBadMask),
1065     mGloBadMask(nmea.mGloBadMask),
1066     mBdsBadMask(nmea.mBdsBadMask),
1067     mGalBadMask(nmea.mGalBadMask),
1068     mQzssBadMask(nmea.mQzssBadMask)
1069 {
1070 }
1071 
equals(const SystemStatusSvHealth & peer)1072 bool SystemStatusSvHealth::equals(const SystemStatusSvHealth& peer)
1073 {
1074     if ((mGpsUnknownMask != peer.mGpsUnknownMask) ||
1075         (mGloUnknownMask != peer.mGloUnknownMask) ||
1076         (mBdsUnknownMask != peer.mBdsUnknownMask) ||
1077         (mGalUnknownMask != peer.mGalUnknownMask) ||
1078         (mQzssUnknownMask != peer.mQzssUnknownMask) ||
1079         (mGpsGoodMask != peer.mGpsGoodMask) ||
1080         (mGloGoodMask != peer.mGloGoodMask) ||
1081         (mBdsGoodMask != peer.mBdsGoodMask) ||
1082         (mGalGoodMask != peer.mGalGoodMask) ||
1083         (mQzssGoodMask != peer.mQzssGoodMask) ||
1084         (mGpsBadMask != peer.mGpsBadMask) ||
1085         (mGloBadMask != peer.mGloBadMask) ||
1086         (mBdsBadMask != peer.mBdsBadMask) ||
1087         (mGalBadMask != peer.mGalBadMask) ||
1088         (mQzssBadMask != peer.mQzssBadMask)) {
1089         return false;
1090     }
1091     return true;
1092 }
1093 
dump()1094 void SystemStatusSvHealth::dump()
1095 {
1096     LOC_LOGV("SvHealth: u=%ld:%ld \
1097              u=%x:%x:%" PRIx64 ":%" PRIx64 ":%x \
1098              g=%x:%x:%" PRIx64 ":%" PRIx64 ":%x \
1099              b=%x:%x:%" PRIx64 ":%" PRIx64 ":%x",
1100              mUtcTime.tv_sec, mUtcTime.tv_nsec,
1101              mGpsUnknownMask,
1102              mGloUnknownMask,
1103              mBdsUnknownMask,
1104              mGalUnknownMask,
1105              mQzssUnknownMask,
1106              mGpsGoodMask,
1107              mGloGoodMask,
1108              mBdsGoodMask,
1109              mGalGoodMask,
1110              mQzssGoodMask,
1111              mGpsBadMask,
1112              mGloBadMask,
1113              mBdsBadMask,
1114              mGalBadMask,
1115              mQzssBadMask);
1116     return;
1117 }
1118 
1119 /******************************************************************************
1120  SystemStatusPdr
1121 ******************************************************************************/
SystemStatusPdr(const SystemStatusPQWP6 & nmea)1122 SystemStatusPdr::SystemStatusPdr(const SystemStatusPQWP6& nmea) :
1123     mFixInfoMask(nmea.mFixInfoMask)
1124 {
1125 }
1126 
equals(const SystemStatusPdr & peer)1127 bool SystemStatusPdr::equals(const SystemStatusPdr& peer)
1128 {
1129     if (mFixInfoMask != peer.mFixInfoMask) {
1130         return false;
1131     }
1132     return true;
1133 }
1134 
dump()1135 void SystemStatusPdr::dump()
1136 {
1137     LOC_LOGV("Pdr: u=%ld:%ld m=%x",
1138              mUtcTime.tv_sec, mUtcTime.tv_nsec,
1139              mFixInfoMask);
1140     return;
1141 }
1142 
1143 /******************************************************************************
1144  SystemStatusNavData
1145 ******************************************************************************/
SystemStatusNavData(const SystemStatusPQWP7 & nmea)1146 SystemStatusNavData::SystemStatusNavData(const SystemStatusPQWP7& nmea)
1147 {
1148     for (uint32_t i=0; i<SV_ALL_NUM; i++) {
1149         mNav[i] = nmea.mNav[i];
1150     }
1151 }
1152 
equals(const SystemStatusNavData & peer)1153 bool SystemStatusNavData::equals(const SystemStatusNavData& peer)
1154 {
1155     for (uint32_t i=0; i<SV_ALL_NUM; i++) {
1156         if ((mNav[i].mType != peer.mNav[i].mType) ||
1157             (mNav[i].mSource != peer.mNav[i].mSource) ||
1158             (mNav[i].mAgeSec != peer.mNav[i].mAgeSec)) {
1159             return false;
1160         }
1161     }
1162     return true;
1163 }
1164 
dump()1165 void SystemStatusNavData::dump()
1166 {
1167     LOC_LOGV("NavData: u=%ld:%ld",
1168             mUtcTime.tv_sec, mUtcTime.tv_nsec);
1169     for (uint32_t i=0; i<SV_ALL_NUM; i++) {
1170         LOC_LOGV("i=%d type=%d src=%d age=%d",
1171             i, mNav[i].mType, mNav[i].mSource, mNav[i].mAgeSec);
1172     }
1173     return;
1174 }
1175 
1176 /******************************************************************************
1177  SystemStatusPositionFailure
1178 ******************************************************************************/
SystemStatusPositionFailure(const SystemStatusPQWS1 & nmea)1179 SystemStatusPositionFailure::SystemStatusPositionFailure(const SystemStatusPQWS1& nmea) :
1180     mFixInfoMask(nmea.mFixInfoMask),
1181     mHepeLimit(nmea.mHepeLimit)
1182 {
1183 }
1184 
equals(const SystemStatusPositionFailure & peer)1185 bool SystemStatusPositionFailure::equals(const SystemStatusPositionFailure& peer)
1186 {
1187     if ((mFixInfoMask != peer.mFixInfoMask) ||
1188         (mHepeLimit != peer.mHepeLimit)) {
1189         return false;
1190     }
1191     return true;
1192 }
1193 
dump()1194 void SystemStatusPositionFailure::dump()
1195 {
1196     LOC_LOGV("PositionFailure: u=%ld:%ld m=%d h=%d",
1197              mUtcTime.tv_sec, mUtcTime.tv_nsec,
1198              mFixInfoMask,
1199              mHepeLimit);
1200     return;
1201 }
1202 
1203 /******************************************************************************
1204  SystemStatusLocation
1205 ******************************************************************************/
equals(const SystemStatusLocation & peer)1206 bool SystemStatusLocation::equals(const SystemStatusLocation& peer)
1207 {
1208     if ((mLocation.gpsLocation.latitude != peer.mLocation.gpsLocation.latitude) ||
1209         (mLocation.gpsLocation.longitude != peer.mLocation.gpsLocation.longitude) ||
1210         (mLocation.gpsLocation.altitude != peer.mLocation.gpsLocation.altitude)) {
1211         return false;
1212     }
1213     return true;
1214 }
1215 
dump()1216 void SystemStatusLocation::dump()
1217 {
1218     LOC_LOGV("Location: lat=%f lon=%f alt=%f spd=%f",
1219              mLocation.gpsLocation.latitude,
1220              mLocation.gpsLocation.longitude,
1221              mLocation.gpsLocation.altitude,
1222              mLocation.gpsLocation.speed);
1223     return;
1224 }
1225 
1226 /******************************************************************************
1227  SystemStatus
1228 ******************************************************************************/
1229 pthread_mutex_t   SystemStatus::mMutexSystemStatus = PTHREAD_MUTEX_INITIALIZER;
1230 SystemStatus*     SystemStatus::mInstance = NULL;
1231 
getInstance(const MsgTask * msgTask)1232 SystemStatus* SystemStatus::getInstance(const MsgTask* msgTask)
1233 {
1234     pthread_mutex_lock(&mMutexSystemStatus);
1235 
1236     if (!mInstance) {
1237         // Instantiating for the first time. msgTask should not be NULL
1238         if (msgTask == NULL) {
1239             LOC_LOGE("SystemStatus: msgTask is NULL!!");
1240             pthread_mutex_unlock(&mMutexSystemStatus);
1241             return NULL;
1242         }
1243         mInstance = new (nothrow) SystemStatus(msgTask);
1244         LOC_LOGD("SystemStatus::getInstance:%p. Msgtask:%p", mInstance, msgTask);
1245     }
1246 
1247     pthread_mutex_unlock(&mMutexSystemStatus);
1248     return mInstance;
1249 }
1250 
destroyInstance()1251 void SystemStatus::destroyInstance()
1252 {
1253     delete mInstance;
1254     mInstance = NULL;
1255 }
1256 
getOsObserver()1257 IOsObserver* SystemStatus::getOsObserver()
1258 {
1259     return &mSysStatusObsvr;
1260 }
1261 
SystemStatus(const MsgTask * msgTask)1262 SystemStatus::SystemStatus(const MsgTask* msgTask) :
1263     mSysStatusObsvr(this, msgTask)
1264 {
1265     int result = 0;
1266     ENTRY_LOG ();
1267     mCache.mLocation.clear();
1268 
1269     mCache.mTimeAndClock.clear();
1270     mCache.mXoState.clear();
1271     mCache.mRfAndParams.clear();
1272     mCache.mErrRecovery.clear();
1273 
1274     mCache.mInjectedPosition.clear();
1275     mCache.mBestPosition.clear();
1276     mCache.mXtra.clear();
1277     mCache.mEphemeris.clear();
1278     mCache.mSvHealth.clear();
1279     mCache.mPdr.clear();
1280     mCache.mNavData.clear();
1281 
1282     mCache.mPositionFailure.clear();
1283 
1284     mCache.mAirplaneMode.clear();
1285     mCache.mENH.clear();
1286     mCache.mGPSState.clear();
1287     mCache.mNLPStatus.clear();
1288     mCache.mWifiHardwareState.clear();
1289     mCache.mNetworkInfo.clear();
1290     mCache.mRilServiceInfo.clear();
1291     mCache.mRilCellInfo.clear();
1292     mCache.mServiceStatus.clear();
1293     mCache.mModel.clear();
1294     mCache.mManufacturer.clear();
1295     mCache.mAssistedGps.clear();
1296     mCache.mScreenState.clear();
1297     mCache.mPowerConnectState.clear();
1298     mCache.mTimeZoneChange.clear();
1299     mCache.mTimeChange.clear();
1300     mCache.mWifiSupplicantStatus.clear();
1301     mCache.mShutdownState.clear();
1302     mCache.mTac.clear();
1303     mCache.mMccMnc.clear();
1304     mCache.mBtDeviceScanDetail.clear();
1305     mCache.mBtLeDeviceScanDetail.clear();
1306 
1307     EXIT_LOG_WITH_ERROR ("%d",result);
1308 }
1309 
1310 /******************************************************************************
1311  SystemStatus - storing dataitems
1312 ******************************************************************************/
1313 template <typename TYPE_REPORT, typename TYPE_ITEM>
setIteminReport(TYPE_REPORT & report,TYPE_ITEM && s)1314 bool SystemStatus::setIteminReport(TYPE_REPORT& report, TYPE_ITEM&& s)
1315 {
1316     if (!report.empty() && report.back().equals(static_cast<TYPE_ITEM&>(s.collate(report.back())))) {
1317         // there is no change - just update reported timestamp
1318         report.back().mUtcReported = s.mUtcReported;
1319         return false;
1320     }
1321 
1322     // first event or updated
1323     report.push_back(s);
1324     if (report.size() > s.maxItem) {
1325         report.erase(report.begin());
1326     }
1327     return true;
1328 }
1329 
1330 template <typename TYPE_REPORT, typename TYPE_ITEM>
setDefaultIteminReport(TYPE_REPORT & report,const TYPE_ITEM & s)1331 void SystemStatus::setDefaultIteminReport(TYPE_REPORT& report, const TYPE_ITEM& s)
1332 {
1333     report.push_back(s);
1334     if (report.size() > s.maxItem) {
1335         report.erase(report.begin());
1336     }
1337 }
1338 
1339 template <typename TYPE_REPORT, typename TYPE_ITEM>
getIteminReport(TYPE_REPORT & reportout,const TYPE_ITEM & c) const1340 void SystemStatus::getIteminReport(TYPE_REPORT& reportout, const TYPE_ITEM& c) const
1341 {
1342     reportout.clear();
1343     if (c.size() >= 1) {
1344         reportout.push_back(c.back());
1345         reportout.back().dump();
1346     }
1347 }
1348 
1349 /******************************************************************************
1350 @brief      API to set report data into internal buffer
1351 
1352 @param[In]  data pointer to the NMEA string
1353 @param[In]  len  length of the NMEA string
1354 
1355 @return     true when the NMEA is consumed by the method.
1356 ******************************************************************************/
setNmeaString(const char * data,uint32_t len)1357 bool SystemStatus::setNmeaString(const char *data, uint32_t len)
1358 {
1359     if (!loc_nmea_is_debug(data, len)) {
1360         return false;
1361     }
1362 
1363     char buf[SystemStatusNmeaBase::NMEA_MAXSIZE + 1] = { 0 };
1364     strlcpy(buf, data, sizeof(buf));
1365 
1366     pthread_mutex_lock(&mMutexSystemStatus);
1367 
1368     // parse the received nmea strings here
1369     if (0 == strncmp(data, "$PQWM1", SystemStatusNmeaBase::NMEA_MINSIZE)) {
1370         SystemStatusPQWM1 s = SystemStatusPQWM1parser(buf, len).get();
1371         setIteminReport(mCache.mTimeAndClock, SystemStatusTimeAndClock(s));
1372         setIteminReport(mCache.mXoState, SystemStatusXoState(s));
1373         setIteminReport(mCache.mRfAndParams, SystemStatusRfAndParams(s));
1374         setIteminReport(mCache.mErrRecovery, SystemStatusErrRecovery(s));
1375     }
1376     else if (0 == strncmp(data, "$PQWP1", SystemStatusNmeaBase::NMEA_MINSIZE)) {
1377         setIteminReport(mCache.mInjectedPosition,
1378                 SystemStatusInjectedPosition(SystemStatusPQWP1parser(buf, len).get()));
1379     }
1380     else if (0 == strncmp(data, "$PQWP2", SystemStatusNmeaBase::NMEA_MINSIZE)) {
1381         setIteminReport(mCache.mBestPosition,
1382                 SystemStatusBestPosition(SystemStatusPQWP2parser(buf, len).get()));
1383     }
1384     else if (0 == strncmp(data, "$PQWP3", SystemStatusNmeaBase::NMEA_MINSIZE)) {
1385         setIteminReport(mCache.mXtra,
1386                 SystemStatusXtra(SystemStatusPQWP3parser(buf, len).get()));
1387     }
1388     else if (0 == strncmp(data, "$PQWP4", SystemStatusNmeaBase::NMEA_MINSIZE)) {
1389         setIteminReport(mCache.mEphemeris,
1390                 SystemStatusEphemeris(SystemStatusPQWP4parser(buf, len).get()));
1391     }
1392     else if (0 == strncmp(data, "$PQWP5", SystemStatusNmeaBase::NMEA_MINSIZE)) {
1393         setIteminReport(mCache.mSvHealth,
1394                 SystemStatusSvHealth(SystemStatusPQWP5parser(buf, len).get()));
1395     }
1396     else if (0 == strncmp(data, "$PQWP6", SystemStatusNmeaBase::NMEA_MINSIZE)) {
1397         setIteminReport(mCache.mPdr,
1398                 SystemStatusPdr(SystemStatusPQWP6parser(buf, len).get()));
1399     }
1400     else if (0 == strncmp(data, "$PQWP7", SystemStatusNmeaBase::NMEA_MINSIZE)) {
1401         setIteminReport(mCache.mNavData,
1402                 SystemStatusNavData(SystemStatusPQWP7parser(buf, len).get()));
1403     }
1404     else if (0 == strncmp(data, "$PQWS1", SystemStatusNmeaBase::NMEA_MINSIZE)) {
1405         setIteminReport(mCache.mPositionFailure,
1406                 SystemStatusPositionFailure(SystemStatusPQWS1parser(buf, len).get()));
1407     }
1408     else {
1409         // do nothing
1410     }
1411 
1412     pthread_mutex_unlock(&mMutexSystemStatus);
1413     return true;
1414 }
1415 
1416 /******************************************************************************
1417 @brief      API to set report position data into internal buffer
1418 
1419 @param[In]  UlpLocation
1420 
1421 @return     true when successfully done
1422 ******************************************************************************/
eventPosition(const UlpLocation & location,const GpsLocationExtended & locationEx)1423 bool SystemStatus::eventPosition(const UlpLocation& location,
1424                                  const GpsLocationExtended& locationEx)
1425 {
1426     bool ret = false;
1427     pthread_mutex_lock(&mMutexSystemStatus);
1428 
1429     ret = setIteminReport(mCache.mLocation, SystemStatusLocation(location, locationEx));
1430     LOC_LOGV("eventPosition - lat=%f lon=%f alt=%f speed=%f",
1431              location.gpsLocation.latitude,
1432              location.gpsLocation.longitude,
1433              location.gpsLocation.altitude,
1434              location.gpsLocation.speed);
1435 
1436     pthread_mutex_unlock(&mMutexSystemStatus);
1437     return ret;
1438 }
1439 
1440 /******************************************************************************
1441 @brief      API to set report DataItem event into internal buffer
1442 
1443 @param[In]  DataItem
1444 
1445 @return     true when info is updatated
1446 ******************************************************************************/
eventDataItemNotify(IDataItemCore * dataitem)1447 bool SystemStatus::eventDataItemNotify(IDataItemCore* dataitem)
1448 {
1449     bool ret = false;
1450     pthread_mutex_lock(&mMutexSystemStatus);
1451     switch(dataitem->getId())
1452     {
1453         case AIRPLANEMODE_DATA_ITEM_ID:
1454             ret = setIteminReport(mCache.mAirplaneMode,
1455                     SystemStatusAirplaneMode(*(static_cast<AirplaneModeDataItemBase*>(dataitem))));
1456             break;
1457         case ENH_DATA_ITEM_ID:
1458             ret = setIteminReport(mCache.mENH,
1459                     SystemStatusENH(*(static_cast<ENHDataItemBase*>(dataitem))));
1460             break;
1461         case GPSSTATE_DATA_ITEM_ID:
1462             ret = setIteminReport(mCache.mGPSState,
1463                     SystemStatusGpsState(*(static_cast<GPSStateDataItemBase*>(dataitem))));
1464             break;
1465         case NLPSTATUS_DATA_ITEM_ID:
1466             ret = setIteminReport(mCache.mNLPStatus,
1467                     SystemStatusNLPStatus(*(static_cast<NLPStatusDataItemBase*>(dataitem))));
1468             break;
1469         case WIFIHARDWARESTATE_DATA_ITEM_ID:
1470             ret = setIteminReport(mCache.mWifiHardwareState,
1471                     SystemStatusWifiHardwareState(*(static_cast<WifiHardwareStateDataItemBase*>(dataitem))));
1472             break;
1473         case NETWORKINFO_DATA_ITEM_ID:
1474             ret = setIteminReport(mCache.mNetworkInfo,
1475                     SystemStatusNetworkInfo(*(static_cast<NetworkInfoDataItemBase*>(dataitem))));
1476             break;
1477         case RILSERVICEINFO_DATA_ITEM_ID:
1478             ret = setIteminReport(mCache.mRilServiceInfo,
1479                     SystemStatusServiceInfo(*(static_cast<RilServiceInfoDataItemBase*>(dataitem))));
1480             break;
1481         case RILCELLINFO_DATA_ITEM_ID:
1482             ret = setIteminReport(mCache.mRilCellInfo,
1483                     SystemStatusRilCellInfo(*(static_cast<RilCellInfoDataItemBase*>(dataitem))));
1484             break;
1485         case SERVICESTATUS_DATA_ITEM_ID:
1486             ret = setIteminReport(mCache.mServiceStatus,
1487                     SystemStatusServiceStatus(*(static_cast<ServiceStatusDataItemBase*>(dataitem))));
1488             break;
1489         case MODEL_DATA_ITEM_ID:
1490             ret = setIteminReport(mCache.mModel,
1491                     SystemStatusModel(*(static_cast<ModelDataItemBase*>(dataitem))));
1492             break;
1493         case MANUFACTURER_DATA_ITEM_ID:
1494             ret = setIteminReport(mCache.mManufacturer,
1495                     SystemStatusManufacturer(*(static_cast<ManufacturerDataItemBase*>(dataitem))));
1496             break;
1497         case ASSISTED_GPS_DATA_ITEM_ID:
1498             ret = setIteminReport(mCache.mAssistedGps,
1499                     SystemStatusAssistedGps(*(static_cast<AssistedGpsDataItemBase*>(dataitem))));
1500             break;
1501         case SCREEN_STATE_DATA_ITEM_ID:
1502             ret = setIteminReport(mCache.mScreenState,
1503                     SystemStatusScreenState(*(static_cast<ScreenStateDataItemBase*>(dataitem))));
1504             break;
1505         case POWER_CONNECTED_STATE_DATA_ITEM_ID:
1506             ret = setIteminReport(mCache.mPowerConnectState,
1507                     SystemStatusPowerConnectState(*(static_cast<PowerConnectStateDataItemBase*>(dataitem))));
1508             break;
1509         case TIMEZONE_CHANGE_DATA_ITEM_ID:
1510             ret = setIteminReport(mCache.mTimeZoneChange,
1511                     SystemStatusTimeZoneChange(*(static_cast<TimeZoneChangeDataItemBase*>(dataitem))));
1512             break;
1513         case TIME_CHANGE_DATA_ITEM_ID:
1514             ret = setIteminReport(mCache.mTimeChange,
1515                     SystemStatusTimeChange(*(static_cast<TimeChangeDataItemBase*>(dataitem))));
1516             break;
1517         case WIFI_SUPPLICANT_STATUS_DATA_ITEM_ID:
1518             ret = setIteminReport(mCache.mWifiSupplicantStatus,
1519                     SystemStatusWifiSupplicantStatus(*(static_cast<WifiSupplicantStatusDataItemBase*>(dataitem))));
1520             break;
1521         case SHUTDOWN_STATE_DATA_ITEM_ID:
1522             ret = setIteminReport(mCache.mShutdownState,
1523                     SystemStatusShutdownState(*(static_cast<ShutdownStateDataItemBase*>(dataitem))));
1524             break;
1525         case TAC_DATA_ITEM_ID:
1526             ret = setIteminReport(mCache.mTac,
1527                     SystemStatusTac(*(static_cast<TacDataItemBase*>(dataitem))));
1528             break;
1529         case MCCMNC_DATA_ITEM_ID:
1530             ret = setIteminReport(mCache.mMccMnc,
1531                     SystemStatusMccMnc(*(static_cast<MccmncDataItemBase*>(dataitem))));
1532             break;
1533         case BTLE_SCAN_DATA_ITEM_ID:
1534             ret = setIteminReport(mCache.mBtDeviceScanDetail,
1535                     SystemStatusBtDeviceScanDetail(*(static_cast<BtDeviceScanDetailsDataItemBase*>(dataitem))));
1536             break;
1537         case BT_SCAN_DATA_ITEM_ID:
1538             ret = setIteminReport(mCache.mBtLeDeviceScanDetail,
1539                     SystemStatusBtleDeviceScanDetail(*(static_cast<BtLeDeviceScanDetailsDataItemBase*>(dataitem))));
1540             break;
1541         default:
1542             break;
1543     }
1544     pthread_mutex_unlock(&mMutexSystemStatus);
1545     return ret;
1546 }
1547 
1548 /******************************************************************************
1549 @brief      API to get report data into a given buffer
1550 
1551 @param[In]  reference to report buffer
1552 @param[In]  bool flag to identify latest only or entire buffer
1553 
1554 @return     true when successfully done
1555 ******************************************************************************/
getReport(SystemStatusReports & report,bool isLatestOnly) const1556 bool SystemStatus::getReport(SystemStatusReports& report, bool isLatestOnly) const
1557 {
1558     pthread_mutex_lock(&mMutexSystemStatus);
1559 
1560     if (isLatestOnly) {
1561         // push back only the latest report and return it
1562         getIteminReport(report.mLocation, mCache.mLocation);
1563 
1564         getIteminReport(report.mTimeAndClock, mCache.mTimeAndClock);
1565         getIteminReport(report.mXoState, mCache.mXoState);
1566         getIteminReport(report.mRfAndParams, mCache.mRfAndParams);
1567         getIteminReport(report.mErrRecovery, mCache.mErrRecovery);
1568 
1569         getIteminReport(report.mInjectedPosition, mCache.mInjectedPosition);
1570         getIteminReport(report.mBestPosition, mCache.mBestPosition);
1571         getIteminReport(report.mXtra, mCache.mXtra);
1572         getIteminReport(report.mEphemeris, mCache.mEphemeris);
1573         getIteminReport(report.mSvHealth, mCache.mSvHealth);
1574         getIteminReport(report.mPdr, mCache.mPdr);
1575         getIteminReport(report.mNavData, mCache.mNavData);
1576 
1577         getIteminReport(report.mPositionFailure, mCache.mPositionFailure);
1578 
1579         getIteminReport(report.mAirplaneMode, mCache.mAirplaneMode);
1580         getIteminReport(report.mENH, mCache.mENH);
1581         getIteminReport(report.mGPSState, mCache.mGPSState);
1582         getIteminReport(report.mNLPStatus, mCache.mNLPStatus);
1583         getIteminReport(report.mWifiHardwareState, mCache.mWifiHardwareState);
1584         getIteminReport(report.mNetworkInfo, mCache.mNetworkInfo);
1585         getIteminReport(report.mRilServiceInfo, mCache.mRilServiceInfo);
1586         getIteminReport(report.mRilCellInfo, mCache.mRilCellInfo);
1587         getIteminReport(report.mServiceStatus, mCache.mServiceStatus);
1588         getIteminReport(report.mModel, mCache.mModel);
1589         getIteminReport(report.mManufacturer, mCache.mManufacturer);
1590         getIteminReport(report.mAssistedGps, mCache.mAssistedGps);
1591         getIteminReport(report.mScreenState, mCache.mScreenState);
1592         getIteminReport(report.mPowerConnectState, mCache.mPowerConnectState);
1593         getIteminReport(report.mTimeZoneChange, mCache.mTimeZoneChange);
1594         getIteminReport(report.mTimeChange, mCache.mTimeChange);
1595         getIteminReport(report.mWifiSupplicantStatus, mCache.mWifiSupplicantStatus);
1596         getIteminReport(report.mShutdownState, mCache.mShutdownState);
1597         getIteminReport(report.mTac, mCache.mTac);
1598         getIteminReport(report.mMccMnc, mCache.mMccMnc);
1599         getIteminReport(report.mBtDeviceScanDetail, mCache.mBtDeviceScanDetail);
1600         getIteminReport(report.mBtLeDeviceScanDetail, mCache.mBtLeDeviceScanDetail);
1601     }
1602     else {
1603         // copy entire reports and return them
1604         report.mLocation.clear();
1605 
1606         report.mTimeAndClock.clear();
1607         report.mXoState.clear();
1608         report.mRfAndParams.clear();
1609         report.mErrRecovery.clear();
1610 
1611         report.mInjectedPosition.clear();
1612         report.mBestPosition.clear();
1613         report.mXtra.clear();
1614         report.mEphemeris.clear();
1615         report.mSvHealth.clear();
1616         report.mPdr.clear();
1617         report.mNavData.clear();
1618 
1619         report.mPositionFailure.clear();
1620 
1621         report.mAirplaneMode.clear();
1622         report.mENH.clear();
1623         report.mGPSState.clear();
1624         report.mNLPStatus.clear();
1625         report.mWifiHardwareState.clear();
1626         report.mNetworkInfo.clear();
1627         report.mRilServiceInfo.clear();
1628         report.mRilCellInfo.clear();
1629         report.mServiceStatus.clear();
1630         report.mModel.clear();
1631         report.mManufacturer.clear();
1632         report.mAssistedGps.clear();
1633         report.mScreenState.clear();
1634         report.mPowerConnectState.clear();
1635         report.mTimeZoneChange.clear();
1636         report.mTimeChange.clear();
1637         report.mWifiSupplicantStatus.clear();
1638         report.mShutdownState.clear();
1639         report.mTac.clear();
1640         report.mMccMnc.clear();
1641         report.mBtDeviceScanDetail.clear();
1642         report.mBtLeDeviceScanDetail.clear();
1643 
1644         report = mCache;
1645     }
1646 
1647     pthread_mutex_unlock(&mMutexSystemStatus);
1648     return true;
1649 }
1650 
1651 /******************************************************************************
1652 @brief      API to set default report data
1653 
1654 @param[In]  none
1655 
1656 @return     true when successfully done
1657 ******************************************************************************/
setDefaultGnssEngineStates(void)1658 bool SystemStatus::setDefaultGnssEngineStates(void)
1659 {
1660     pthread_mutex_lock(&mMutexSystemStatus);
1661 
1662     setDefaultIteminReport(mCache.mLocation, SystemStatusLocation());
1663 
1664     setDefaultIteminReport(mCache.mTimeAndClock, SystemStatusTimeAndClock());
1665     setDefaultIteminReport(mCache.mXoState, SystemStatusXoState());
1666     setDefaultIteminReport(mCache.mRfAndParams, SystemStatusRfAndParams());
1667     setDefaultIteminReport(mCache.mErrRecovery, SystemStatusErrRecovery());
1668 
1669     setDefaultIteminReport(mCache.mInjectedPosition, SystemStatusInjectedPosition());
1670     setDefaultIteminReport(mCache.mBestPosition, SystemStatusBestPosition());
1671     setDefaultIteminReport(mCache.mXtra, SystemStatusXtra());
1672     setDefaultIteminReport(mCache.mEphemeris, SystemStatusEphemeris());
1673     setDefaultIteminReport(mCache.mSvHealth, SystemStatusSvHealth());
1674     setDefaultIteminReport(mCache.mPdr, SystemStatusPdr());
1675     setDefaultIteminReport(mCache.mNavData, SystemStatusNavData());
1676 
1677     setDefaultIteminReport(mCache.mPositionFailure, SystemStatusPositionFailure());
1678 
1679     pthread_mutex_unlock(&mMutexSystemStatus);
1680     return true;
1681 }
1682 
1683 /******************************************************************************
1684 @brief      API to handle connection status update event from GnssRil
1685 
1686 @param[In]  Connection status
1687 
1688 @return     true when successfully done
1689 ******************************************************************************/
eventConnectionStatus(bool connected,int8_t type)1690 bool SystemStatus::eventConnectionStatus(bool connected, int8_t type)
1691 {
1692     // send networkinof dataitem to systemstatus observer clients
1693     SystemStatusNetworkInfo s(type, "", "", connected);
1694     mSysStatusObsvr.notify({&s});
1695 
1696     return true;
1697 }
1698 
1699 } // namespace loc_core
1700 
1701