Home | History | Annotate | Download | only in core
      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 
     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 
     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:
    160     inline uint16_t   getGpsWeek()    { return mM1.mGpsWeek; }
    161     inline uint32_t   getGpsTowMs()   { return mM1.mGpsTowMs; }
    162     inline uint8_t    getTimeValid()  { return mM1.mTimeValid; }
    163     inline uint8_t    getTimeSource() { return mM1.mTimeSource; }
    164     inline int32_t    getTimeUnc()    { return mM1.mTimeUnc; }
    165     inline int32_t    getClockFreqBias() { return mM1.mClockFreqBias; }
    166     inline int32_t    getClockFreqBiasUnc() { return mM1.mClockFreqBiasUnc; }
    167     inline uint8_t    getXoState()    { return mM1.mXoState;}
    168     inline int32_t    getPgaGain()    { return mM1.mPgaGain;          }
    169     inline uint32_t   getGpsBpAmpI()  { return mM1.mGpsBpAmpI;        }
    170     inline uint32_t   getGpsBpAmpQ()  { return mM1.mGpsBpAmpQ;        }
    171     inline uint32_t   getAdcI()       { return mM1.mAdcI;             }
    172     inline uint32_t   getAdcQ()       { return mM1.mAdcQ;             }
    173     inline uint32_t   getJammerGps()  { return mM1.mJammerGps;        }
    174     inline uint32_t   getJammerGlo()  { return mM1.mJammerGlo;        }
    175     inline uint32_t   getJammerBds()  { return mM1.mJammerBds;        }
    176     inline uint32_t   getJammerGal()  { return mM1.mJammerGal;        }
    177     inline uint32_t   getAgcGps()     { return mM1.mAgcGps;           }
    178     inline uint32_t   getAgcGlo()     { return mM1.mAgcGlo;           }
    179     inline uint32_t   getAgcBds()     { return mM1.mAgcBds;           }
    180     inline uint32_t   getAgcGal()     { return mM1.mAgcGal;           }
    181     inline uint32_t   getRecErrorRecovery() { return mM1.mRecErrorRecovery; }
    182     inline int32_t    getLeapSeconds(){ return mM1.mLeapSeconds; }
    183     inline int32_t    getLeapSecUnc() { return mM1.mLeapSecUnc; }
    184 
    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 
    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:
    257     inline uint8_t    getEpiValidity() { return mP1.mEpiValidity;      }
    258     inline float      getEpiLat() { return mP1.mEpiLat;           }
    259     inline float      getEpiLon() { return mP1.mEpiLon;           }
    260     inline float      getEpiAlt() { return mP1.mEpiAlt;           }
    261     inline float      getEpiHepe() { return mP1.mEpiHepe;          }
    262     inline float      getEpiAltUnc() { return mP1.mEpiAltUnc;        }
    263     inline uint8_t    getEpiSrc() { return mP1.mEpiSrc;           }
    264 
    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 
    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:
    314     inline float      getBestLat() { return mP2.mBestLat;          }
    315     inline float      getBestLon() { return mP2.mBestLon;          }
    316     inline float      getBestAlt() { return mP2.mBestAlt;          }
    317     inline float      getBestHepe() { return mP2.mBestHepe;         }
    318     inline float      getBestAltUnc() { return mP2.mBestAltUnc;       }
    319 
    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 
    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:
    379     inline uint8_t    getXtraValid() { return mP3.mXtraValidMask;   }
    380     inline uint32_t   getGpsXtraAge() { return mP3.mGpsXtraAge;       }
    381     inline uint32_t   getGloXtraAge() { return mP3.mGloXtraAge;       }
    382     inline uint32_t   getBdsXtraAge() { return mP3.mBdsXtraAge;       }
    383     inline uint32_t   getGalXtraAge() { return mP3.mGalXtraAge;       }
    384     inline uint32_t   getQzssXtraAge() { return mP3.mQzssXtraAge;      }
    385     inline uint32_t   getGpsXtraValid() { return mP3.mGpsXtraValid;     }
    386     inline uint32_t   getGloXtraValid() { return mP3.mGloXtraValid;     }
    387     inline uint64_t   getBdsXtraValid() { return mP3.mBdsXtraValid;     }
    388     inline uint64_t   getGalXtraValid() { return mP3.mGalXtraValid;     }
    389     inline uint8_t    getQzssXtraValid() { return mP3.mQzssXtraValid;    }
    390 
    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 
    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:
    444     inline uint32_t   getGpsEpheValid() { return mP4.mGpsEpheValid;     }
    445     inline uint32_t   getGloEpheValid() { return mP4.mGloEpheValid;     }
    446     inline uint64_t   getBdsEpheValid() { return mP4.mBdsEpheValid;     }
    447     inline uint64_t   getGalEpheValid() { return mP4.mGalEpheValid;     }
    448     inline uint8_t    getQzssEpheValid() { return mP4.mQzssEpheValid;    }
    449 
    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 
    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:
    517     inline uint32_t   getGpsUnknownMask() { return mP5.mGpsUnknownMask;   }
    518     inline uint32_t   getGloUnknownMask() { return mP5.mGloUnknownMask;   }
    519     inline uint64_t   getBdsUnknownMask() { return mP5.mBdsUnknownMask;   }
    520     inline uint64_t   getGalUnknownMask() { return mP5.mGalUnknownMask;   }
    521     inline uint8_t    getQzssUnknownMask() { return mP5.mQzssUnknownMask;  }
    522     inline uint32_t   getGpsGoodMask() { return mP5.mGpsGoodMask;      }
    523     inline uint32_t   getGloGoodMask() { return mP5.mGloGoodMask;      }
    524     inline uint64_t   getBdsGoodMask() { return mP5.mBdsGoodMask;      }
    525     inline uint64_t   getGalGoodMask() { return mP5.mGalGoodMask;      }
    526     inline uint8_t    getQzssGoodMask() { return mP5.mQzssGoodMask;     }
    527     inline uint32_t   getGpsBadMask() { return mP5.mGpsBadMask;       }
    528     inline uint32_t   getGloBadMask() { return mP5.mGloBadMask;       }
    529     inline uint64_t   getBdsBadMask() { return mP5.mBdsBadMask;       }
    530     inline uint64_t   getGalBadMask() { return mP5.mGalBadMask;       }
    531     inline uint8_t    getQzssBadMask() { return mP5.mQzssBadMask;      }
    532 
    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 
    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:
    582     inline uint32_t   getFixInfoMask() { return mP6.mFixInfoMask;      }
    583 
    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 
    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:
    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 
    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:
    659     inline uint16_t   getFixInfoMask() { return mS1.mFixInfoMask;      }
    660     inline uint32_t   getHepeLimit()   { return mS1.mHepeLimit;      }
    661 
    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 
    673     inline SystemStatusPQWS1& get() { return mS1;}
    674 };
    675 
    676 /******************************************************************************
    677  SystemStatusTimeAndClock
    678 ******************************************************************************/
    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 
    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 
    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 ******************************************************************************/
    727 SystemStatusXoState::SystemStatusXoState(const SystemStatusPQWM1& nmea) :
    728     mXoState(nmea.mXoState)
    729 {
    730 }
    731 
    732 bool SystemStatusXoState::equals(SystemStatusXoState& peer)
    733 {
    734     if (mXoState != peer.mXoState) {
    735         return false;
    736     }
    737     return true;
    738 }
    739 
    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 ******************************************************************************/
    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 
    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 
    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 ******************************************************************************/
    813 SystemStatusErrRecovery::SystemStatusErrRecovery(const SystemStatusPQWM1& nmea) :
    814     mRecErrorRecovery(nmea.mRecErrorRecovery)
    815 {
    816 }
    817 
    818 bool SystemStatusErrRecovery::equals(SystemStatusErrRecovery& peer)
    819 {
    820     if (mRecErrorRecovery != peer.mRecErrorRecovery) {
    821         return false;
    822     }
    823     return true;
    824 }
    825 
    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 ******************************************************************************/
    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 
    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 
    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 ******************************************************************************/
    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 
    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 
    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 ******************************************************************************/
    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 
    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 
    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 ******************************************************************************/
    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 
    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 
    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 ******************************************************************************/
   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 
   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 
   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 ******************************************************************************/
   1075 SystemStatusPdr::SystemStatusPdr(const SystemStatusPQWP6& nmea) :
   1076     mFixInfoMask(nmea.mFixInfoMask)
   1077 {
   1078 }
   1079 
   1080 bool SystemStatusPdr::equals(SystemStatusPdr& peer)
   1081 {
   1082     if (mFixInfoMask != peer.mFixInfoMask) {
   1083         return false;
   1084     }
   1085     return true;
   1086 }
   1087 
   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 ******************************************************************************/
   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 
   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 
   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 ******************************************************************************/
   1132 SystemStatusPositionFailure::SystemStatusPositionFailure(const SystemStatusPQWS1& nmea) :
   1133     mFixInfoMask(nmea.mFixInfoMask),
   1134     mHepeLimit(nmea.mHepeLimit)
   1135 {
   1136 }
   1137 
   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 
   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 ******************************************************************************/
   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 
   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 
   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 
   1204 void SystemStatus::destroyInstance()
   1205 {
   1206     delete mInstance;
   1207     mInstance = NULL;
   1208 }
   1209 
   1210 IOsObserver* SystemStatus::getOsObserver()
   1211 {
   1212     return &mSysStatusObsvr;
   1213 }
   1214 
   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 ******************************************************************************/
   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 
   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 
   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 
   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 ******************************************************************************/
   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 
   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 
   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 
   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 
   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 
   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 
   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 ******************************************************************************/
   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 ******************************************************************************/
   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 
   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 ******************************************************************************/
   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 ******************************************************************************/
   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 ******************************************************************************/
   1588 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 ******************************************************************************/
   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 ******************************************************************************/
   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