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