code:
/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#ifndef GNSS_ADAPTER_H
#define GNSS_ADAPTER_H

#include <LocAdapterBase.h>
#include <LocContext.h>
#include <IOsObserver.h>
#include <EngineHubProxyBase.h>
#include <LocationAPI.h>
#include <Agps.h>
#include <SystemStatus.h>
#include <XtraSystemStatusObserver.h>
#include <map>
#include <functional>
#include <loc_misc_utils.h>
#include <queue>
#include <NativeAgpsHandler.h>

#define MAX_URL_LEN 256
#define NMEA_SENTENCE_MAX_LENGTH 200
#define GLONASS_SV_ID_OFFSET 64
#define MAX_SATELLITES_IN_USE 12
#define LOC_NI_NO_RESPONSE_TIME 20
#define LOC_GPS_NI_RESPONSE_IGNORE 4
#define ODCPI_EXPECTED_INJECTION_TIME_MS 10000
#define DELETE_AIDING_DATA_EXPECTED_TIME_MS 5000

class GnssAdapter;

typedef std::map<LocationSessionKey, LocationOptions> LocationSessionMap;
typedef std::map<LocationSessionKey, TrackingOptions> TrackingOptionsMap;

class OdcpiTimer : public LocTimer {
public:
    OdcpiTimer(GnssAdapter* adapter) :
            LocTimer(), mAdapter(adapter), mActive(false) {}

    inline void start() {
        mActive = true;
        LocTimer::start(ODCPI_EXPECTED_INJECTION_TIME_MS, false);
    }
    inline void stop() {
        mActive = false;
        LocTimer::stop();
    }
    inline void restart() {
        stop();
        start();
    }
    inline bool isActive() {
        return mActive;
    }

private:
    // Override
    virtual void timeOutCallback() override;

    GnssAdapter* mAdapter;
    bool mActive;
};

typedef struct {
    pthread_t               thread;        /* NI thread */
    uint32_t                respTimeLeft;  /* examine time for NI response */
    bool                    respRecvd;     /* NI User reponse received or not from Java layer*/
    void*                   rawRequest;
    uint32_t                reqID;         /* ID to check against response */
    GnssNiResponse          resp;
    pthread_cond_t          tCond;
    pthread_mutex_t         tLock;
    GnssAdapter*            adapter;
} NiSession;
typedef struct {
    NiSession session;    /* SUPL NI Session */
    NiSession sessionEs;  /* Emergency SUPL NI Session */
    uint32_t reqIDCounter;
} NiData;

typedef enum {
    NMEA_PROVIDER_AP = 0, // Application Processor Provider of NMEA
    NMEA_PROVIDER_MP      // Modem Processor Provider of NMEA
} NmeaProviderType;
typedef struct {
    GnssSvType svType;
    const char* talker;
    uint64_t mask;
    uint32_t svIdOffset;
} NmeaSvMeta;

typedef struct {
    double latitude;
    double longitude;
    float  accuracy;
    // the CPI will be blocked until the boot time
    // specified in blockedTillTsMs
    int64_t blockedTillTsMs;
    // CPIs whose both latitude and longitude differ
    // no more than latLonThreshold will be blocked
    // in units of degree
    double latLonDiffThreshold;
} BlockCPIInfo;

typedef struct {
    bool isValid;
    bool enable;
    float tuncThresholdMs; // need to be specified if enable is true
    uint32_t energyBudget; // need to be specified if enable is true
} TuncConfigInfo;

typedef struct {
    bool isValid;
    bool enable;
} PaceConfigInfo;

typedef struct {
    bool isValid;
    bool enable;
    bool enableFor911;
} RobustLocationConfigInfo;

typedef struct {
    TuncConfigInfo tuncConfigInfo;
    PaceConfigInfo paceConfigInfo;
    RobustLocationConfigInfo robustLocationConfigInfo;
    LeverArmConfigInfo  leverArmConfigInfo;
} LocIntegrationConfigInfo;

using namespace loc_core;

namespace loc_core {
    class SystemStatus;
}

typedef std::function<void(
    uint64_t gnssEnergyConsumedFromFirstBoot
)> GnssEnergyConsumedCallback;

typedef void* QDgnssListenerHDL;
typedef std::function<void(
    bool    sessionActive
)> QDgnssSessionActiveCb;

struct CdfwInterface {
    void (*startDgnssApiService)(const MsgTask& msgTask);
    QDgnssListenerHDL (*createUsableReporter)(
            QDgnssSessionActiveCb sessionActiveCb);
    void (*destroyUsableReporter)(QDgnssListenerHDL handle);
    void (*reportUsable)(QDgnssListenerHDL handle, bool usable);
};

typedef uint16_t  DGnssStateBitMask;
#define DGNSS_STATE_ENABLE_NTRIP_COMMAND      0X01
#define DGNSS_STATE_NO_NMEA_PENDING           0X02
#define DGNSS_STATE_NTRIP_SESSION_STARTED     0X04

class GnssReportLoggerUtil {
public:
    typedef void (*LogGnssLatency)(const GnssLatencyInfo& gnssLatencyMeasInfo);

    GnssReportLoggerUtil() : mLogLatency(nullptr) {
        const char* libname = "liblocdiagiface.so";
        void* libHandle = nullptr;
        mLogLatency = (LogGnssLatency)dlGetSymFromLib(libHandle, libname, "LogGnssLatency");
    }

    bool isLogEnabled();
    void log(const GnssLatencyInfo& gnssLatencyMeasInfo);

private:
    LogGnssLatency mLogLatency;
};

class GnssAdapter : public LocAdapterBase {

    /* ==== Engine Hub ===================================================================== */
    EngineHubProxyBase* mEngHubProxy;
    bool mNHzNeeded;
    bool mSPEAlreadyRunningAtHighestInterval;

    /* ==== TRACKING ======================================================================= */
    TrackingOptionsMap mTimeBasedTrackingSessions;
    LocationSessionMap mDistanceBasedTrackingSessions;
    LocPosMode mLocPositionMode;
    GnssSvUsedInPosition mGnssSvIdUsedInPosition;
    bool mGnssSvIdUsedInPosAvail;
    GnssSvMbUsedInPosition mGnssMbSvIdUsedInPosition;
    bool mGnssMbSvIdUsedInPosAvail;

    /* ==== CONTROL ======================================================================== */
    LocationControlCallbacks mControlCallbacks;
    uint32_t mAfwControlId;
    uint32_t mNmeaMask;
    uint64_t mPrevNmeaRptTimeNsec;
    GnssSvIdConfig mGnssSvIdConfig;
    GnssSvTypeConfig mGnssSeconaryBandConfig;
    GnssSvTypeConfig mGnssSvTypeConfig;
    GnssSvTypeConfigCallback mGnssSvTypeConfigCb;
    bool mSupportNfwControl;
    LocIntegrationConfigInfo mLocConfigInfo;

    /* ==== NI ============================================================================= */
    NiData mNiData;

    /* ==== AGPS =========================================================================== */
    // This must be initialized via initAgps()
    AgpsManager mAgpsManager;
    void initAgps(const AgpsCbInfo& cbInfo);

    /* ==== NFW =========================================================================== */
    NfwStatusCb mNfwCb;
    IsInEmergencySession mIsE911Session;
    inline void initNfw(const NfwCbInfo& cbInfo) {
        mNfwCb = (NfwStatusCb)cbInfo.visibilityControlCb;
        mIsE911Session = (IsInEmergencySession)cbInfo.isInEmergencySession;
    }

    /* ==== Measurement Corrections========================================================= */
    bool mIsMeasCorrInterfaceOpen;
    measCorrSetCapabilitiesCb mMeasCorrSetCapabilitiesCb;
    bool initMeasCorr(bool bSendCbWhenNotSupported);
    bool mIsAntennaInfoInterfaceOpened;

    /* ==== DGNSS Data Usable Report======================================================== */
    QDgnssListenerHDL mQDgnssListenerHDL;
    const CdfwInterface* mCdfwInterface;
    bool mDGnssNeedReport;
    bool mDGnssDataUsage;
    void reportDGnssDataUsable(const GnssSvMeasurementSet &svMeasurementSet);

    /* ==== ODCPI ========================================================================== */
    OdcpiRequestCallback mOdcpiRequestCb;
    bool mOdcpiRequestActive;
    OdcpiPrioritytype mCallbackPriority;
    OdcpiTimer mOdcpiTimer;
    OdcpiRequestInfo mOdcpiRequest;
    void odcpiTimerExpire();

    /* ==== DELETEAIDINGDATA =============================================================== */
    int64_t mLastDeleteAidingDataTime;

    /* === SystemStatus ===================================================================== */
    SystemStatus* mSystemStatus;
    std::string mServerUrl;
    std::string mMoServerUrl;
    XtraSystemStatusObserver mXtraObserver;
    LocationSystemInfo mLocSystemInfo;
    std::vector<GnssSvIdSource> mBlacklistedSvIds;
    PowerStateType mSystemPowerState;

    /* === Misc ===================================================================== */
    BlockCPIInfo mBlockCPIInfo;
    bool mPowerOn;
    uint32_t mAllowFlpNetworkFixes;
    std::queue<GnssLatencyInfo> mGnssLatencyInfoQueue;
    GnssReportLoggerUtil mLogger;
    bool mDreIntEnabled;

    /* === NativeAgpsHandler ======================================================== */
    NativeAgpsHandler mNativeAgpsHandler;

    /* === Misc callback from QMI LOC API ============================================== */
    GnssEnergyConsumedCallback mGnssEnergyConsumedCb;
    std::function<void(bool)> mPowerStateCb;

    /*==== CONVERSION ===================================================================*/
    static void convertOptions(LocPosMode& out, const TrackingOptions& trackingOptions);
    static void convertLocation(Location& out, const UlpLocation& ulpLocation,
                                const GpsLocationExtended& locationExtended);
    static void convertLocationInfo(GnssLocationInfoNotification& out,
                                    const GpsLocationExtended& locationExtended,
                                    loc_sess_status status);
    static uint16_t getNumSvUsed(uint64_t svUsedIdsMask,
                                 int totalSvCntInThisConstellation);

    /* ======== UTILITIES ================================================================== */
    inline void initOdcpi(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority);
    inline void injectOdcpi(const Location& location);
    static bool isFlpClient(LocationCallbacks& locationCallbacks);

    /*==== DGnss Ntrip Source ==========================================================*/
    StartDgnssNtripParams   mStartDgnssNtripParams;
    bool    mSendNmeaConsent;
    DGnssStateBitMask   mDgnssState;
    void checkUpdateDgnssNtrip(bool isLocationValid);
    void stopDgnssNtrip();
    uint64_t   mDgnssLastNmeaBootTimeMilli;

protected:

    /* ==== CLIENT ========================================================================= */
    virtual void updateClientsEventMask();
    virtual void stopClientSessions(LocationAPI* client);
    inline void setNmeaReportRateConfig();
    void logLatencyInfo();

public:
    GnssAdapter();
    virtual inline ~GnssAdapter() { }

    /* ==== SSR ============================================================================ */
    /* ======== EVENTS ====(Called from QMI Thread)========================================= */
    virtual void handleEngineUpEvent();
    /* ======== UTILITIES ================================================================== */
    void restartSessions(bool modemSSR = false);
    void checkAndRestartTimeBasedSession();
    void checkAndRestartSPESession();
    void suspendSessions();

    /* ==== CLIENT ========================================================================= */
    /* ======== COMMANDS ====(Called from Client Thread)==================================== */
    virtual void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);

    /* ==== TRACKING ======================================================================= */
    /* ======== COMMANDS ====(Called from Client Thread)==================================== */
    uint32_t startTrackingCommand(
            LocationAPI* client, TrackingOptions& trackingOptions);
    void updateTrackingOptionsCommand(
            LocationAPI* client, uint32_t id, TrackingOptions& trackingOptions);
    void stopTrackingCommand(LocationAPI* client, uint32_t id);
    /* ======== RESPONSES ================================================================== */
    void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
    /* ======== UTILITIES ================================================================== */
    bool isTimeBasedTrackingSession(LocationAPI* client, uint32_t sessionId);
    bool isDistanceBasedTrackingSession(LocationAPI* client, uint32_t sessionId);
    bool hasCallbacksToStartTracking(LocationAPI* client);
    bool isTrackingSession(LocationAPI* client, uint32_t sessionId);
    void saveTrackingSession(LocationAPI* client, uint32_t sessionId,
                             const TrackingOptions& trackingOptions);
    void eraseTrackingSession(LocationAPI* client, uint32_t sessionId);

    bool setLocPositionMode(const LocPosMode& mode);
    LocPosMode& getLocPositionMode() { return mLocPositionMode; }

    bool startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
                                         const TrackingOptions& trackingOptions);
    void startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
            const TrackingOptions& trackingOptions);
    bool stopTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t id);
    void stopTracking(LocationAPI* client, uint32_t id);
    bool updateTrackingMultiplex(LocationAPI* client, uint32_t id,
            const TrackingOptions& trackingOptions);
    void updateTracking(LocationAPI* client, uint32_t sessionId,
            const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions);
    bool checkAndSetSPEToRunforNHz(TrackingOptions & out);

    void setConstrainedTunc(bool enable, float tuncConstraint,
                            uint32_t energyBudget, uint32_t sessionId);
    void setPositionAssistedClockEstimator(bool enable, uint32_t sessionId);
    void gnssUpdateSvConfig(uint32_t sessionId,
                        const GnssSvTypeConfig& constellationEnablementConfig,
                        const GnssSvIdConfig& blacklistSvConfig);

    void gnssUpdateSecondaryBandConfig(
        uint32_t sessionId, const GnssSvTypeConfig& secondaryBandConfig);
    void gnssGetSecondaryBandConfig(uint32_t sessionId);
    void resetSvConfig(uint32_t sessionId);
    void configLeverArm(uint32_t sessionId, const LeverArmConfigInfo& configInfo);
    void configRobustLocation(uint32_t sessionId, bool enable, bool enableForE911);
    void configMinGpsWeek(uint32_t sessionId, uint16_t minGpsWeek);

    /* ==== NI ============================================================================= */
    /* ======== COMMANDS ====(Called from Client Thread)==================================== */
    void gnssNiResponseCommand(LocationAPI* client, uint32_t id, GnssNiResponse response);
    /* ======================(Called from NI Thread)======================================== */
    void gnssNiResponseCommand(GnssNiResponse response, void* rawRequest);
    /* ======== UTILITIES ================================================================== */
    bool hasNiNotifyCallback(LocationAPI* client);
    NiData& getNiData() { return mNiData; }

    /* ==== CONTROL CLIENT ================================================================= */
    /* ======== COMMANDS ====(Called from Client Thread)==================================== */
    uint32_t enableCommand(LocationTechnologyType techType);
    void disableCommand(uint32_t id);
    void setControlCallbacksCommand(LocationControlCallbacks& controlCallbacks);
    void readConfigCommand();
    void requestUlpCommand();
    void initEngHubProxyCommand();
    uint32_t* gnssUpdateConfigCommand(const GnssConfig& config);
    uint32_t* gnssGetConfigCommand(GnssConfigFlagsMask mask);
    uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
    void deleteAidingData(const GnssAidingData &data, uint32_t sessionId);
    void gnssUpdateXtraThrottleCommand(const bool enabled);
    std::vector<LocationError> gnssUpdateConfig(const std::string& oldMoServerUrl,
            const std::string& moServerUrl,
            const std::string& serverUrl,
            GnssConfig& gnssConfigRequested,
            GnssConfig& gnssConfigNeedEngineUpdate, size_t count = 0);

    /* ==== GNSS SV TYPE CONFIG ============================================================ */
    /* ==== COMMANDS ====(Called from Client Thread)======================================== */
    /* ==== These commands are received directly from client bypassing Location API ======== */
    void gnssUpdateSvTypeConfigCommand(GnssSvTypeConfig config);
    void gnssGetSvTypeConfigCommand(GnssSvTypeConfigCallback callback);
    void gnssResetSvTypeConfigCommand();

    /* ==== UTILITIES ====================================================================== */
    LocationError gnssSvIdConfigUpdateSync(const std::vector<GnssSvIdSource>& blacklistedSvIds);
    LocationError gnssSvIdConfigUpdateSync();
    void gnssSvIdConfigUpdate(const std::vector<GnssSvIdSource>& blacklistedSvIds);
    void gnssSvIdConfigUpdate();
    void gnssSvTypeConfigUpdate(const GnssSvTypeConfig& config);
    void gnssSvTypeConfigUpdate(bool sendReset = false);
    inline void gnssSetSvTypeConfig(const GnssSvTypeConfig& config)
    { mGnssSvTypeConfig = config; }
    inline void gnssSetSvTypeConfigCallback(GnssSvTypeConfigCallback callback)
    { mGnssSvTypeConfigCb = callback; }
    inline GnssSvTypeConfigCallback gnssGetSvTypeConfigCallback()
    { return mGnssSvTypeConfigCb; }
    void setConfig();
    void gnssSecondaryBandConfigUpdate(LocApiResponse* locApiResponse= nullptr);

    /* ========= AGPS ====================================================================== */
    /* ======== COMMANDS ====(Called from Client Thread)==================================== */
    void initDefaultAgpsCommand();
    void initAgpsCommand(const AgpsCbInfo& cbInfo);
    void initNfwCommand(const NfwCbInfo& cbInfo);
    void dataConnOpenCommand(AGpsExtType agpsType,
            const char* apnName, int apnLen, AGpsBearerType bearerType);
    void dataConnClosedCommand(AGpsExtType agpsType);
    void dataConnFailedCommand(AGpsExtType agpsType);
    void getGnssEnergyConsumedCommand(GnssEnergyConsumedCallback energyConsumedCb);
    void nfwControlCommand(bool enable);
    uint32_t setConstrainedTuncCommand (bool enable, float tuncConstraint,
                                        uint32_t energyBudget);
    uint32_t setPositionAssistedClockEstimatorCommand (bool enable);
    uint32_t gnssUpdateSvConfigCommand(const GnssSvTypeConfig& constellationEnablementConfig,
                                       const GnssSvIdConfig& blacklistSvConfig);
    uint32_t gnssUpdateSecondaryBandConfigCommand(
                                       const GnssSvTypeConfig& secondaryBandConfig);
    uint32_t gnssGetSecondaryBandConfigCommand();
    uint32_t configLeverArmCommand(const LeverArmConfigInfo& configInfo);
    uint32_t configRobustLocationCommand(bool enable, bool enableForE911);
    bool openMeasCorrCommand(const measCorrSetCapabilitiesCb setCapabilitiesCb);
    bool measCorrSetCorrectionsCommand(const GnssMeasurementCorrections gnssMeasCorr);
    inline void closeMeasCorrCommand() { mIsMeasCorrInterfaceOpen = false; }
    uint32_t antennaInfoInitCommand(const antennaInfoCb antennaInfoCallback);
    inline void antennaInfoCloseCommand() { mIsAntennaInfoInterfaceOpened = false; }
    uint32_t configMinGpsWeekCommand(uint16_t minGpsWeek);
    uint32_t configDeadReckoningEngineParamsCommand(const DeadReckoningEngineConfig& dreConfig);
    uint32_t configEngineRunStateCommand(PositioningEngineMask engType,
                                         LocEngineRunState engState);

    /* ========= ODCPI ===================================================================== */
    /* ======== COMMANDS ====(Called from Client Thread)==================================== */
    void initOdcpiCommand(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority);
    void injectOdcpiCommand(const Location& location);
    /* ======== RESPONSES ================================================================== */
    void reportResponse(LocationError err, uint32_t sessionId);
    void reportResponse(size_t count, LocationError* errs, uint32_t* ids);
    /* ======== UTILITIES ================================================================== */
    LocationControlCallbacks& getControlCallbacks() { return mControlCallbacks; }
    void setControlCallbacks(const LocationControlCallbacks& controlCallbacks)
    { mControlCallbacks = controlCallbacks; }
    void setAfwControlId(uint32_t id) { mAfwControlId = id; }
    uint32_t getAfwControlId() { return mAfwControlId; }
    virtual bool isInSession() { return !mTimeBasedTrackingSessions.empty(); }
    void initDefaultAgps();
    bool initEngHubProxy();
    void initCDFWService();
    void odcpiTimerExpireEvent();

    /* ==== REPORTS ======================================================================== */
    /* ======== EVENTS ====(Called from QMI/EngineHub Thread)===================================== */
    virtual void reportPositionEvent(const UlpLocation& ulpLocation,
                                     const GpsLocationExtended& locationExtended,
                                     enum loc_sess_status status,
                                     LocPosTechMask techMask,
                                     GnssDataNotification* pDataNotify = nullptr,
                                     int msInWeek = -1);
    virtual void reportEnginePositionsEvent(unsigned int count,
                                            EngineLocationInfo* locationArr);

    virtual void reportSvEvent(const GnssSvNotification& svNotify,
                               bool fromEngineHub=false);
    virtual void reportNmeaEvent(const char* nmea, size_t length);
    virtual void reportDataEvent(const GnssDataNotification& dataNotify, int msInWeek);
    virtual bool requestNiNotifyEvent(const GnssNiNotification& notify, const void* data,
                                      const LocInEmergency emergencyState);
    virtual void reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements,
                                                int msInWeek);
    virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
    virtual void reportSvEphemerisEvent(GnssSvEphemerisReport & svEphemeris);
    virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
    virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config);
    virtual void reportGnssConfigEvent(uint32_t sessionId, const GnssConfig& gnssConfig);
    virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot);
    virtual void reportLocationSystemInfoEvent(const LocationSystemInfo& locationSystemInfo);

    virtual bool requestATL(int connHandle, LocAGpsType agps_type, LocApnTypeMask apn_type_mask);
    virtual bool releaseATL(int connHandle);
    virtual bool requestOdcpiEvent(OdcpiRequestInfo& request);
    virtual bool reportDeleteAidingDataEvent(GnssAidingData& aidingData);
    virtual bool reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& ionoModel);
    virtual bool reportGnssAdditionalSystemInfoEvent(
            GnssAdditionalSystemInfo& additionalSystemInfo);
    virtual void reportNfwNotificationEvent(GnssNfwNotification& notification);
    virtual void reportLatencyInfoEvent(const GnssLatencyInfo& gnssLatencyInfo);
    virtual bool reportQwesCapabilities
    (
        const std::unordered_map<LocationQwesFeatureType, bool> &featureMap
    );
    void reportPdnTypeFromWds(int pdnType, AGpsExtType agpsType, std::string apnName,
            AGpsBearerType bearerType);

    /* ======== UTILITIES ================================================================= */
    bool needReportForGnssClient(const UlpLocation& ulpLocation,
            enum loc_sess_status status, LocPosTechMask techMask);
    bool needReportForFlpClient(enum loc_sess_status status, LocPosTechMask techMask);
    bool needToGenerateNmeaReport(const uint32_t &gpsTimeOfWeekMs,
        const struct timespec32_t &apTimeStamp);
    void reportPosition(const UlpLocation &ulpLocation,
                        const GpsLocationExtended &locationExtended,
                        enum loc_sess_status status,
                        LocPosTechMask techMask);
    void reportEnginePositions(unsigned int count,
                               const EngineLocationInfo* locationArr);
    void reportSv(GnssSvNotification& svNotify);
    void reportNmea(const char* nmea, size_t length);
    void reportData(GnssDataNotification& dataNotify);
    bool requestNiNotify(const GnssNiNotification& notify, const void* data,
                         const bool bInformNiAccept);
    void reportGnssMeasurementData(const GnssMeasurementsNotification& measurements);
    void reportGnssSvIdConfig(const GnssSvIdConfig& config);
    void reportGnssSvTypeConfig(const GnssSvTypeConfig& config);
    void reportGnssConfig(uint32_t sessionId, const GnssConfig& gnssConfig);
    void requestOdcpi(const OdcpiRequestInfo& request);
    void invokeGnssEnergyConsumedCallback(uint64_t energyConsumedSinceFirstBoot);
    void saveGnssEnergyConsumedCallback(GnssEnergyConsumedCallback energyConsumedCb);
    void reportLocationSystemInfo(const LocationSystemInfo & locationSystemInfo);
    inline void reportNfwNotification(const GnssNfwNotification& notification) {
        if (NULL != mNfwCb) {
            mNfwCb(notification);
        }
    }
    inline bool getE911State(void) {
        if (NULL != mIsE911Session) {
            return mIsE911Session();
        }
        return false;
    }

    void updateSystemPowerState(PowerStateType systemPowerState);
    void reportSvPolynomial(const GnssSvPolynomial &svPolynomial);

    std::vector<double> parseDoublesString(char* dString);
    void reportGnssAntennaInformation(const antennaInfoCb antennaInfoCallback);

    /*======== GNSSDEBUG ================================================================*/
    bool getDebugReport(GnssDebugReport& report);
    /* get AGC information from system status and fill it */
    void getAgcInformation(GnssMeasurementsNotification& measurements, int msInWeek);
    /* get Data information from system status and fill it */
    void getDataInformation(GnssDataNotification& data, int msInWeek);

    /*==== SYSTEM STATUS ================================================================*/
    inline SystemStatus* getSystemStatus(void) { return mSystemStatus; }
    std::string& getServerUrl(void) { return mServerUrl; }
    std::string& getMoServerUrl(void) { return mMoServerUrl; }

    /*==== CONVERSION ===================================================================*/
    static uint32_t convertSuplVersion(const GnssConfigSuplVersion suplVersion);
    static uint32_t convertEP4ES(const GnssConfigEmergencyPdnForEmergencySupl);
    static uint32_t convertSuplEs(const GnssConfigSuplEmergencyServices suplEmergencyServices);
    static uint32_t convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask);
    static uint32_t convertLppeUp(const GnssConfigLppeUserPlaneMask lppeUserPlaneMask);
    static uint32_t convertAGloProt(const GnssConfigAGlonassPositionProtocolMask);
    static uint32_t convertSuplMode(const GnssConfigSuplModeMask suplModeMask);
    static void convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
                                     const GnssSvType& in_constellation,
                                     const SystemStatusReports& in);
    static bool convertToGnssSvIdConfig(
            const std::vector<GnssSvIdSource>& blacklistedSvIds, GnssSvIdConfig& config);
    static void convertFromGnssSvIdConfig(
            const GnssSvIdConfig& svConfig, std::vector<GnssSvIdSource>& blacklistedSvIds);
    static void convertGnssSvIdMaskToList(
            uint64_t svIdMask, std::vector<GnssSvIdSource>& svIds,
            GnssSvId initialSvId, GnssSvType svType);
    static void computeVRPBasedLla(const UlpLocation& loc, GpsLocationExtended& locExt,
                                   const LeverArmConfigInfo& leverArmConfigInfo);

    void injectLocationCommand(double latitude, double longitude, float accuracy);
    void injectLocationExtCommand(const GnssLocationInfoNotification &locationInfo);

    void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
    void blockCPICommand(double latitude, double longitude, float accuracy,
                         int blockDurationMsec, double latLonDiffThreshold);

    /* ==== MISCELLANEOUS ================================================================== */
    /* ======== COMMANDS ====(Called from Client Thread)==================================== */
    void getPowerStateChangesCommand(std::function<void(bool)> powerStateCb);
    /* ======== UTILITIES ================================================================== */
    void reportPowerStateIfChanged();
    void savePowerStateCallback(std::function<void(bool)> powerStateCb){
            mPowerStateCb = powerStateCb; }
    bool getPowerState() { return mPowerOn; }
    inline PowerStateType getSystemPowerState() { return mSystemPowerState; }

    void setAllowFlpNetworkFixes(uint32_t allow) { mAllowFlpNetworkFixes = allow; }
    uint32_t getAllowFlpNetworkFixes() { return mAllowFlpNetworkFixes; }
    void setSuplHostServer(const char* server, int port, LocServerType type);
    void notifyClientOfCachedLocationSystemInfo(LocationAPI* client,
                                                const LocationCallbacks& callbacks);
    LocationCapabilitiesMask getCapabilities();
    void updateSystemPowerStateCommand(PowerStateType systemPowerState);

    /*==== DGnss Usable Report Flag ====================================================*/
    inline void setDGnssUsableFLag(bool dGnssNeedReport) { mDGnssNeedReport = dGnssNeedReport;}
    inline bool isNMEAPrintEnabled() {
       return ((mContext != NULL) && (0 != mContext->mGps_conf.ENABLE_NMEA_PRINT));
    }

    /*==== DGnss Ntrip Source ==========================================================*/
    void updateNTRIPGGAConsentCommand(bool consentAccepted) { mSendNmeaConsent = consentAccepted; }
    void enablePPENtripStreamCommand(const GnssNtripConnectionParams& params, bool enableRTKEngine);
    void disablePPENtripStreamCommand();
    void handleEnablePPENtrip(const GnssNtripConnectionParams& params);
    void handleDisablePPENtrip();
    void reportGGAToNtrip(const char* nmea);
    inline bool isDgnssNmeaRequired() { return mSendNmeaConsent &&
            mStartDgnssNtripParams.ntripParams.requiresNmeaLocation;}
};

#endif //GNSS_ADAPTER_H

license: unknown


code:
AM_CFLAGS = \
     $(LOCPLA_CFLAGS) \
     $(LOCHAL_CFLAGS) \
     $(GPSUTILS_CFLAGS) \
     $(LOCCORE_CFLAGS) \
     -I./ \
     -I../utils \
     -I$(WORKSPACE)/hardware/qcom/gps/core/data-items \
     -I../location \
     -std=c++1y

libgnss_la_SOURCES = \
    location_gnss.cpp \
    GnssAdapter.cpp \
    XtraSystemStatusObserver.cpp \
    Agps.cpp \
    NativeAgpsHandler.cpp

if USE_GLIB
libgnss_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
libgnss_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -avoid-version
libgnss_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
else
libgnss_la_CFLAGS = $(AM_CFLAGS)
libgnss_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
libgnss_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
endif

libgnss_la_LIBADD = -lstdc++ -ldl $(GPSUTILS_LIBS) $(LOCCORE_LIBS)

#Create and Install libraries
lib_LTLIBRARIES = libgnss.la


code:
/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#define LOG_TAG "LocSvc_NativeAgpsHandler"

#include <LocAdapterBase.h>
#include <SystemStatus.h>
#include <DataItemId.h>
#include <DataItemsFactoryProxy.h>
#include <DataItemConcreteTypesBase.h>
#include <loc_log.h>
#include <NativeAgpsHandler.h>
#include <GnssAdapter.h>

using namespace loc_core;

// IDataItemObserver overrides
void NativeAgpsHandler::getName(string& name) {
    name = "NativeAgpsHandler";
}

void NativeAgpsHandler::notify(const list<IDataItemCore*>& dlist) {
    for (auto each : dlist) {
        switch (each->getId()) {
            case NETWORKINFO_DATA_ITEM_ID: {
                    NetworkInfoDataItemBase* networkInfo =
                        static_cast<NetworkInfoDataItemBase*>(each);
                    uint64_t mobileBit = (uint64_t )1 << loc_core::TYPE_MOBILE;
                    uint64_t allTypes = networkInfo->mAllTypes;
                    mConnected = ((networkInfo->mAllTypes & mobileBit) == mobileBit);
                    /**
                     * mApn Telephony preferred Access Point Name to use for
                     * carrier data connection when connected to a cellular network.
                     * Empty string, otherwise.
                     */
                    mApn = networkInfo->mApn;
                    LOC_LOGd("updated mConnected:%d, mApn: %s", mConnected, mApn.c_str());
                    break;
            }
            default:
                    break;
        }
    }
}

NativeAgpsHandler* NativeAgpsHandler::sLocalHandle = nullptr;
NativeAgpsHandler::NativeAgpsHandler(IOsObserver* sysStatObs, GnssAdapter& adapter) :
        mSystemStatusObsrvr(sysStatObs), mConnected(false), mAdapter(adapter) {
    sLocalHandle = this;
    list<DataItemId> subItemIdList = {NETWORKINFO_DATA_ITEM_ID};
    mSystemStatusObsrvr->subscribe(subItemIdList, this);
}

NativeAgpsHandler::~NativeAgpsHandler() {
    if (nullptr != mSystemStatusObsrvr) {
        LOC_LOGd("Unsubscribe for network info.");
        list<DataItemId> subItemIdList = {NETWORKINFO_DATA_ITEM_ID};
        mSystemStatusObsrvr->unsubscribe(subItemIdList, this);
    }
    sLocalHandle = nullptr;
    mSystemStatusObsrvr = nullptr;
}

AgpsCbInfo NativeAgpsHandler::getAgpsCbInfo() {
    AgpsCbInfo nativeCbInfo = {};
    nativeCbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
    nativeCbInfo.atlType = AGPS_ATL_TYPE_WWAN;
    return nativeCbInfo;
}

void NativeAgpsHandler::agnssStatusIpV4Cb(AGnssExtStatusIpV4 statusInfo) {
    if (nullptr != sLocalHandle) {
        sLocalHandle->processATLRequestRelease(statusInfo);
    } else {
        LOC_LOGe("sLocalHandle is null");
    }
}

void NativeAgpsHandler::processATLRequestRelease(AGnssExtStatusIpV4 statusInfo) {
    if (LOC_AGPS_TYPE_WWAN_ANY == statusInfo.type) {
        LOC_LOGd("status.type = %d status.apnTypeMask = 0x%X", statusInfo.type,
                 statusInfo.apnTypeMask);
        switch (statusInfo.status) {
        case LOC_GPS_REQUEST_AGPS_DATA_CONN:
            if (mConnected) {
                mAdapter.dataConnOpenCommand(LOC_AGPS_TYPE_WWAN_ANY, mApn.c_str(), mApn.size(),
                    AGPS_APN_BEARER_IPV4);
            } else {
                mAdapter.dataConnFailedCommand(LOC_AGPS_TYPE_WWAN_ANY);
            }
            break;
        case LOC_GPS_RELEASE_AGPS_DATA_CONN:
            mAdapter.dataConnClosedCommand(LOC_AGPS_TYPE_WWAN_ANY);
            break;
        default:
            LOC_LOGe("Invalid Request: %d", statusInfo.status);
        }
    } else {
        LOC_LOGe("mAgpsManger is null or invalid request type!");
    }
}


code:
/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#ifndef NATIVEAGPSHANDLER_H
#define NATIVEAGPSHANDLER_H

#include <cinttypes>
#include <string.h>
#include <gps_extended_c.h>
#include <IDataItemObserver.h>
#include <IDataItemCore.h>
#include <IOsObserver.h>

using namespace std;
using loc_core::IOsObserver;
using loc_core::IDataItemObserver;
using loc_core::IDataItemCore;

class GnssAdapter;

class NativeAgpsHandler : public IDataItemObserver {
public:
    NativeAgpsHandler(IOsObserver* sysStatObs, GnssAdapter& adapter);
    ~NativeAgpsHandler();
    AgpsCbInfo getAgpsCbInfo();
    // IDataItemObserver overrides
    virtual void notify(const list<IDataItemCore*>& dlist);
    inline virtual void getName(string& name);
private:
    static NativeAgpsHandler* sLocalHandle;
    static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 statusInfo);
    void processATLRequestRelease(AGnssExtStatusIpV4 statusInfo);
    IOsObserver* mSystemStatusObsrvr;
    bool mConnected;
    string mApn;
    GnssAdapter& mAdapter;
};

#endif // NATIVEAGPSHANDLER_H


code:
/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#define LOG_TAG "LocSvc_XtraSystemStatusObs"

#include <sys/stat.h>
#include <sys/un.h>
#include <errno.h>
#include <ctype.h>
#include <cutils/properties.h>
#include <math.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string>
#include <loc_log.h>
#include <loc_nmea.h>
#include <SystemStatus.h>
#include <vector>
#include <sstream>
#include <XtraSystemStatusObserver.h>
#include <LocAdapterBase.h>
#include <DataItemId.h>
#include <DataItemsFactoryProxy.h>
#include <DataItemConcreteTypesBase.h>

using namespace loc_util;
using namespace loc_core;

#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "LocSvc_XSSO"

class XtraIpcListener : public ILocIpcListener {
    IOsObserver*    mSystemStatusObsrvr;
    const MsgTask* mMsgTask;
    XtraSystemStatusObserver& mXSSO;
public:
    inline XtraIpcListener(IOsObserver* observer, const MsgTask* msgTask,
                           XtraSystemStatusObserver& xsso) :
            mSystemStatusObsrvr(observer), mMsgTask(msgTask), mXSSO(xsso) {}
    virtual void onReceive(const char* data, uint32_t /*length*/,
                           const LocIpcRecver* /*recver*/) override {
#define STRNCMP(str, constStr) strncmp(str, constStr, sizeof(constStr)-1)
        if (!STRNCMP(data, "ping")) {
            LOC_LOGd("ping received");
#ifdef USE_GLIB
        } else if (!STRNCMP(data, "connectBackhaul")) {
            char clientName[30] = {0};
            sscanf(data, "%*s %29s", clientName);
            mSystemStatusObsrvr->connectBackhaul(string(clientName));
        } else if (!STRNCMP(data, "disconnectBackhaul")) {
            char clientName[30] = {0};
            sscanf(data, "%*s %29s", clientName);
            mSystemStatusObsrvr->disconnectBackhaul(string(clientName));
#endif
        } else if (!STRNCMP(data, "requestStatus")) {
            int32_t xtraStatusUpdated = 0;
            sscanf(data, "%*s %d", &xtraStatusUpdated);

            struct HandleStatusRequestMsg : public LocMsg {
                XtraSystemStatusObserver& mXSSO;
                int32_t mXtraStatusUpdated;
                inline HandleStatusRequestMsg(XtraSystemStatusObserver& xsso,
                                              int32_t xtraStatusUpdated) :
                        mXSSO(xsso), mXtraStatusUpdated(xtraStatusUpdated) {}
                inline void proc() const override {
                    mXSSO.onStatusRequested(mXtraStatusUpdated);
                    /* SSR for DGnss Ntrip Source*/
                    mXSSO.restartDgnssSource();
                }
            };
            mMsgTask->sendMsg(new HandleStatusRequestMsg(mXSSO, xtraStatusUpdated));
        } else {
            LOC_LOGw("unknown event: %s", data);
        }
    }
};

XtraSystemStatusObserver::XtraSystemStatusObserver(IOsObserver* sysStatObs,
                                                   const MsgTask* msgTask) :
        mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask),
        mGpsLock(-1), mConnections(~0), mXtraThrottle(true),
        mReqStatusReceived(false),
        mIsConnectivityStatusKnown(false),
        mSender(LocIpc::getLocIpcLocalSender(LOC_IPC_XTRA)),
        mDelayLocTimer(*mSender) {
    subscribe(true);
    auto recver = LocIpc::getLocIpcLocalRecver(
            make_shared<XtraIpcListener>(sysStatObs, msgTask, *this),
            LOC_IPC_HAL);
    mIpc.startNonBlockingListening(recver);
    mDelayLocTimer.start(100 /*.1 sec*/,  false);
}

bool XtraSystemStatusObserver::updateLockStatus(GnssConfigGpsLock lock) {
    // mask NI(NFW bit) since from XTRA's standpoint GPS is enabled if
    // MO(AFW bit) is enabled and disabled when MO is disabled
    mGpsLock = lock & ~GNSS_CONFIG_GPS_LOCK_NI;

    if (!mReqStatusReceived) {
        return true;
    }

    stringstream ss;
    ss <<  "gpslock";
    ss << " " << mGpsLock;
    string s = ss.str();
    return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}

bool XtraSystemStatusObserver::updateConnections(uint64_t allConnections,
        NetworkInfoType* networkHandleInfo) {
    mIsConnectivityStatusKnown = true;
    mConnections = allConnections;

    LOC_LOGd("updateConnections mConnections:%" PRIx64, mConnections);
    for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
        mNetworkHandle[i] = networkHandleInfo[i];
        LOC_LOGd("updateConnections [%d] networkHandle:%" PRIx64 " networkType:%u",
            i, mNetworkHandle[i].networkHandle, mNetworkHandle[i].networkType);
    }

    if (!mReqStatusReceived) {
        return true;
    }

    stringstream ss;
    ss << "connection" << endl << mConnections << endl
            << mNetworkHandle[0].toString() << endl
            << mNetworkHandle[1].toString() << endl
            << mNetworkHandle[2].toString() << endl
            << mNetworkHandle[3].toString() << endl
            << mNetworkHandle[4].toString() << endl
            << mNetworkHandle[5].toString() << endl
            << mNetworkHandle[6].toString() << endl
            << mNetworkHandle[7].toString() << endl
            << mNetworkHandle[8].toString() << endl
            << mNetworkHandle[MAX_NETWORK_HANDLES-1].toString();
    string s = ss.str();
    return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}

bool XtraSystemStatusObserver::updateTac(const string& tac) {
    mTac = tac;

    if (!mReqStatusReceived) {
        return true;
    }

    stringstream ss;
    ss <<  "tac";
    ss << " " << tac.c_str();
    string s = ss.str();
    return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}

bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) {
    mMccmnc = mccmnc;

    if (!mReqStatusReceived) {
        return true;
    }

    stringstream ss;
    ss <<  "mncmcc";
    ss << " " << mccmnc.c_str();
    string s = ss.str();
    return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}

bool XtraSystemStatusObserver::updateXtraThrottle(const bool enabled) {
    mXtraThrottle = enabled;

    if (!mReqStatusReceived) {
        return true;
    }

    stringstream ss;
    ss <<  "xtrathrottle";
    ss << " " << (enabled ? 1 : 0);
    string s = ss.str();
    return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}

inline bool XtraSystemStatusObserver::onStatusRequested(int32_t xtraStatusUpdated) {
    mReqStatusReceived = true;

    if (xtraStatusUpdated) {
        return true;
    }

    stringstream ss;

    ss << "respondStatus" << endl;
    (mGpsLock == -1 ? ss : ss << mGpsLock) << endl;
    (mConnections == (uint64_t)~0 ? ss : ss << mConnections) << endl
            << mNetworkHandle[0].toString() << endl
            << mNetworkHandle[1].toString() << endl
            << mNetworkHandle[2].toString() << endl
            << mNetworkHandle[3].toString() << endl
            << mNetworkHandle[4].toString() << endl
            << mNetworkHandle[5].toString() << endl
            << mNetworkHandle[6].toString() << endl
            << mNetworkHandle[7].toString() << endl
            << mNetworkHandle[8].toString() << endl
            << mNetworkHandle[MAX_NETWORK_HANDLES-1].toString() << endl
            << mTac << endl << mMccmnc << endl << mIsConnectivityStatusKnown;

    string s = ss.str();
    return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}

void XtraSystemStatusObserver::startDgnssSource(const StartDgnssNtripParams& params) {
    stringstream ss;
    const GnssNtripConnectionParams* ntripParams = &(params.ntripParams);

    ss <<  "startDgnssSource" << endl;
    ss << ntripParams->useSSL << endl;
    ss << ntripParams->hostNameOrIp.data() << endl;
    ss << ntripParams->port << endl;
    ss << ntripParams->mountPoint.data() << endl;
    ss << ntripParams->username.data() << endl;
    ss << ntripParams->password.data() << endl;
    if (ntripParams->requiresNmeaLocation && !params.nmea.empty()) {
        ss << params.nmea.data() << endl;
    }
    string s = ss.str();

    LOC_LOGd("%s", s.data());
    LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size());
    // make a local copy of the string for SSR
    mNtripParamsString.assign(std::move(s));
}

void XtraSystemStatusObserver::restartDgnssSource() {
    if (!mNtripParamsString.empty()) {
        LocIpc::send(*mSender,
            (const uint8_t*)mNtripParamsString.data(), mNtripParamsString.size());
        LOC_LOGv("Xtra SSR %s", mNtripParamsString.data());
    }
}

void XtraSystemStatusObserver::stopDgnssSource() {
    LOC_LOGv();
    mNtripParamsString.clear();

    const char s[] = "stopDgnssSource";
    LocIpc::send(*mSender, (const uint8_t*)s, strlen(s));
}

void XtraSystemStatusObserver::updateNmeaToDgnssServer(const string& nmea)
{
    stringstream ss;
    ss <<  "updateDgnssServerNmea" << endl;
    ss << nmea.data() << endl;

    string s = ss.str();
    LOC_LOGd("%s", s.data());
    LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size());
}

void XtraSystemStatusObserver::subscribe(bool yes)
{
    // Subscription data list
    list<DataItemId> subItemIdList;
    subItemIdList.push_back(NETWORKINFO_DATA_ITEM_ID);
    subItemIdList.push_back(MCCMNC_DATA_ITEM_ID);

    if (yes) {
        mSystemStatusObsrvr->subscribe(subItemIdList, this);

        list<DataItemId> reqItemIdList;
        reqItemIdList.push_back(TAC_DATA_ITEM_ID);

        mSystemStatusObsrvr->requestData(reqItemIdList, this);

    } else {
        mSystemStatusObsrvr->unsubscribe(subItemIdList, this);
    }
}

// IDataItemObserver overrides
void XtraSystemStatusObserver::getName(string& name)
{
    name = "XtraSystemStatusObserver";
}

void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist)
{
    struct HandleOsObserverUpdateMsg : public LocMsg {
        XtraSystemStatusObserver* mXtraSysStatObj;
        list <IDataItemCore*> mDataItemList;

        inline HandleOsObserverUpdateMsg(XtraSystemStatusObserver* xtraSysStatObs,
                const list<IDataItemCore*>& dataItemList) :
                mXtraSysStatObj(xtraSysStatObs) {
            for (auto eachItem : dataItemList) {
                IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(
                        eachItem->getId());
                if (NULL == dataitem) {
                    break;
                }
                // Copy the contents of the data item
                dataitem->copy(eachItem);

                mDataItemList.push_back(dataitem);
            }
        }

        inline ~HandleOsObserverUpdateMsg() {
            for (auto itor = mDataItemList.begin(); itor != mDataItemList.end(); ++itor) {
                if (*itor != nullptr) {
                    delete *itor;
                    *itor = nullptr;
                }
            }
        }

        inline void proc() const {
            for (auto each : mDataItemList) {
                switch (each->getId())
                {
                    case NETWORKINFO_DATA_ITEM_ID:
                    {
                        NetworkInfoDataItemBase* networkInfo =
                                static_cast<NetworkInfoDataItemBase*>(each);
                        NetworkInfoType* networkHandleInfo =
                                static_cast<NetworkInfoType*>(networkInfo->getNetworkHandle());
                        mXtraSysStatObj->updateConnections(networkInfo->getAllTypes(),
                                networkHandleInfo);
                    }
                    break;

                    case TAC_DATA_ITEM_ID:
                    {
                        TacDataItemBase* tac =
                                 static_cast<TacDataItemBase*>(each);
                        mXtraSysStatObj->updateTac(tac->mValue);
                    }
                    break;

                    case MCCMNC_DATA_ITEM_ID:
                    {
                        MccmncDataItemBase* mccmnc =
                                static_cast<MccmncDataItemBase*>(each);
                        mXtraSysStatObj->updateMccMnc(mccmnc->mValue);
                    }
                    break;

                    default:
                    break;
                }
            }
        }
    };
    mMsgTask->sendMsg(new (nothrow) HandleOsObserverUpdateMsg(this, dlist));
}


code:
/* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#ifndef XTRA_SYSTEM_STATUS_OBS_H
#define XTRA_SYSTEM_STATUS_OBS_H

#include <cinttypes>
#include <MsgTask.h>
#include <LocIpc.h>
#include <LocTimer.h>
#include <stdlib.h>

using namespace std;
using namespace loc_util;
using loc_core::IOsObserver;
using loc_core::IDataItemObserver;
using loc_core::IDataItemCore;

struct StartDgnssNtripParams {
    GnssNtripConnectionParams ntripParams;
    string                    nmea;

    void clear() {
        ntripParams.hostNameOrIp.clear();
        ntripParams.mountPoint.clear();
        ntripParams.username.clear();
        ntripParams.password.clear();
        ntripParams.port = 0;
        ntripParams.useSSL = false;
        ntripParams.requiresNmeaLocation = false;
        nmea.clear();
    }
};

class XtraSystemStatusObserver : public IDataItemObserver {
public :
    // constructor & destructor
    XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask);
    inline virtual ~XtraSystemStatusObserver() {
        subscribe(false);
        mIpc.stopNonBlockingListening();
    }

    // IDataItemObserver overrides
    inline virtual void getName(string& name);
    virtual void notify(const list<IDataItemCore*>& dlist);

    bool updateLockStatus(GnssConfigGpsLock lock);
    bool updateConnections(uint64_t allConnections,
            loc_core::NetworkInfoType* networkHandleInfo);
    bool updateTac(const string& tac);
    bool updateMccMnc(const string& mccmnc);
    bool updateXtraThrottle(const bool enabled);
    inline const MsgTask* getMsgTask() { return mMsgTask; }
    void subscribe(bool yes);
    bool onStatusRequested(int32_t xtraStatusUpdated);
    void startDgnssSource(const StartDgnssNtripParams& params);
    void restartDgnssSource();
    void stopDgnssSource();
    void updateNmeaToDgnssServer(const string& nmea);

private:
    IOsObserver*    mSystemStatusObsrvr;
    const MsgTask* mMsgTask;
    GnssConfigGpsLock mGpsLock;
    LocIpc mIpc;
    uint64_t mConnections;
    loc_core::NetworkInfoType mNetworkHandle[MAX_NETWORK_HANDLES];
    string mTac;
    string mMccmnc;
    bool mXtraThrottle;
    bool mReqStatusReceived;
    bool mIsConnectivityStatusKnown;
    shared_ptr<LocIpcSender> mSender;
    string mNtripParamsString;

    class DelayLocTimer : public LocTimer {
        LocIpcSender& mSender;
    public:
        DelayLocTimer(LocIpcSender& sender) : mSender(sender) {}
        void timeOutCallback() override {
            LocIpc::send(mSender, (const uint8_t*)"halinit", sizeof("halinit"));
        }
    } mDelayLocTimer;
};

#endif


code:
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "GnssAdapter.h"
#include "location_interface.h"

static GnssAdapter* gGnssAdapter = NULL;

static void initialize();
static void deinitialize();

static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb);
static void requestCapabilities(LocationAPI* client);

static uint32_t startTracking(LocationAPI* client, TrackingOptions&);
static void updateTrackingOptions(LocationAPI* client, uint32_t id, TrackingOptions&);
static void stopTracking(LocationAPI* client, uint32_t id);

static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse response);
static uint32_t gnssDeleteAidingData(GnssAidingData& data);
static void gnssUpdateXtraThrottle(const bool enabled);

static void setControlCallbacks(LocationControlCallbacks& controlCallbacks);
static uint32_t enable(LocationTechnologyType techType);
static void disable(uint32_t id);
static uint32_t* gnssUpdateConfig(const GnssConfig& config);
static uint32_t* gnssGetConfig(GnssConfigFlagsMask mask);

static void gnssUpdateSvTypeConfig(GnssSvTypeConfig& config);
static void gnssGetSvTypeConfig(GnssSvTypeConfigCallback& callback);
static void gnssResetSvTypeConfig();

static void injectLocation(double latitude, double longitude, float accuracy);
static void injectLocationExt(const GnssLocationInfoNotification &locationInfo);
static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty);

static void agpsInit(const AgpsCbInfo& cbInfo);
static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnLen, int ipType);
static void agpsDataConnClosed(AGpsExtType agpsType);
static void agpsDataConnFailed(AGpsExtType agpsType);
static void getDebugReport(GnssDebugReport& report);
static void updateConnectionStatus(bool connected, int8_t type, bool roaming,
                                   NetworkHandle networkHandle, string& apn);
static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb);
static void enableNfwLocationAccess(bool enable);
static void nfwInit(const NfwCbInfo& cbInfo);
static void getPowerStateChanges(std::function<void(bool)> powerStateCb);

static void odcpiInit(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority);
static void odcpiInject(const Location& location);

static void blockCPI(double latitude, double longitude, float accuracy,
                     int blockDurationMsec, double latLonDiffThreshold);
static void updateBatteryStatus(bool charging);
static void updateSystemPowerState(PowerStateType systemPowerState);
static uint32_t setConstrainedTunc (bool enable, float tuncConstraint,
                                    uint32_t energyBudget);
static uint32_t setPositionAssistedClockEstimator(bool enable);
static uint32_t gnssUpdateSvConfig(const GnssSvTypeConfig& constellationEnablementConfig,
                                   const GnssSvIdConfig& blacklistSvConfig);
static uint32_t gnssResetSvConfig();
static uint32_t configLeverArm(const LeverArmConfigInfo& configInfo);
static uint32_t configRobustLocation(bool enable, bool enableForE911);
static uint32_t configMinGpsWeek(uint16_t minGpsWeek);
static uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig);
static uint32_t gnssUpdateSecondaryBandConfig(const GnssSvTypeConfig& secondaryBandConfig);
static uint32_t gnssGetSecondaryBandConfig();
static void resetNetworkInfo();

static void updateNTRIPGGAConsent(bool consentAccepted);
static void enablePPENtripStream(const GnssNtripConnectionParams& params, bool enableRTKEngine);
static void disablePPENtripStream();

static bool measCorrInit(const measCorrSetCapabilitiesCb setCapabilitiesCb);
static bool measCorrSetCorrections(const GnssMeasurementCorrections gnssMeasCorr);
static void measCorrClose();
static uint32_t antennaInfoInit(const antennaInfoCb antennaInfoCallback);
static void antennaInfoClose();
static uint32_t configEngineRunState(PositioningEngineMask engType, LocEngineRunState engState);

static const GnssInterface gGnssInterface = {
    sizeof(GnssInterface),
    initialize,
    deinitialize,
    addClient,
    removeClient,
    requestCapabilities,
    startTracking,
    updateTrackingOptions,
    stopTracking,
    gnssNiResponse,
    setControlCallbacks,
    enable,
    disable,
    gnssUpdateConfig,
    gnssGetConfig,
    gnssUpdateSvTypeConfig,
    gnssGetSvTypeConfig,
    gnssResetSvTypeConfig,
    gnssDeleteAidingData,
    gnssUpdateXtraThrottle,
    injectLocation,
    injectTime,
    agpsInit,
    agpsDataConnOpen,
    agpsDataConnClosed,
    agpsDataConnFailed,
    getDebugReport,
    updateConnectionStatus,
    odcpiInit,
    odcpiInject,
    blockCPI,
    getGnssEnergyConsumed,
    enableNfwLocationAccess,
    nfwInit,
    getPowerStateChanges,
    injectLocationExt,
    updateBatteryStatus,
    updateSystemPowerState,
    setConstrainedTunc,
    setPositionAssistedClockEstimator,
    gnssUpdateSvConfig,
    configLeverArm,
    measCorrInit,
    measCorrSetCorrections,
    measCorrClose,
    antennaInfoInit,
    antennaInfoClose,
    configRobustLocation,
    configMinGpsWeek,
    configDeadReckoningEngineParams,
    updateNTRIPGGAConsent,
    enablePPENtripStream,
    disablePPENtripStream,
    gnssUpdateSecondaryBandConfig,
    gnssGetSecondaryBandConfig,
    resetNetworkInfo,
    configEngineRunState
};

#ifndef DEBUG_X86
extern "C" const GnssInterface* getGnssInterface()
#else
const GnssInterface* getGnssInterface()
#endif // DEBUG_X86
{
   gGnssInterface.initialize();
   return &gGnssInterface;
}

static void initialize()
{
    if (NULL == gGnssAdapter) {
        gGnssAdapter = new GnssAdapter();
    }
}

static void deinitialize()
{
    if (NULL != gGnssAdapter) {
        delete gGnssAdapter;
        gGnssAdapter = NULL;
    }
}

static void addClient(LocationAPI* client, const LocationCallbacks& callbacks)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->addClientCommand(client, callbacks);
    }
}

static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->removeClientCommand(client, rmClientCb);
    }
}

static void requestCapabilities(LocationAPI* client)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->requestCapabilitiesCommand(client);
    }
}

static uint32_t startTracking(
        LocationAPI* client, TrackingOptions& trackingOptions)
{
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->startTrackingCommand(client, trackingOptions);
    } else {
        return 0;
    }
}

static void updateTrackingOptions(
        LocationAPI* client, uint32_t id, TrackingOptions& trackingOptions)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->updateTrackingOptionsCommand(
                client, id, trackingOptions);
    }
}

static void stopTracking(LocationAPI* client, uint32_t id)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->stopTrackingCommand(client, id);
    }
}

static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse response)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->gnssNiResponseCommand(client, id, response);
    }
}

static void setControlCallbacks(LocationControlCallbacks& controlCallbacks)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->setControlCallbacksCommand(controlCallbacks);
    }
}

static uint32_t enable(LocationTechnologyType techType)
{
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->enableCommand(techType);
    } else {
        return 0;
    }
}

static void disable(uint32_t id)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->disableCommand(id);
    }
}

static uint32_t* gnssUpdateConfig(const GnssConfig& config)
{
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->gnssUpdateConfigCommand(config);
    } else {
        return NULL;
    }
}

static uint32_t* gnssGetConfig(GnssConfigFlagsMask mask)
{
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->gnssGetConfigCommand(mask);
    } else {
        return NULL;
    }
}

static void gnssUpdateSvTypeConfig(GnssSvTypeConfig& config)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->gnssUpdateSvTypeConfigCommand(config);
    }
}

static void gnssGetSvTypeConfig(GnssSvTypeConfigCallback& callback)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->gnssGetSvTypeConfigCommand(callback);
    }
}

static void gnssResetSvTypeConfig()
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->gnssResetSvTypeConfigCommand();
    }
}

static uint32_t gnssDeleteAidingData(GnssAidingData& data)
{
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->gnssDeleteAidingDataCommand(data);
    } else {
        return 0;
    }
}

static void gnssUpdateXtraThrottle(const bool enabled)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->gnssUpdateXtraThrottleCommand(enabled);
    }
}

static void injectLocation(double latitude, double longitude, float accuracy)
{
   if (NULL != gGnssAdapter) {
       gGnssAdapter->injectLocationCommand(latitude, longitude, accuracy);
   }
}

static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty)
{
   if (NULL != gGnssAdapter) {
       gGnssAdapter->injectTimeCommand(time, timeReference, uncertainty);
   }
}

static void agpsInit(const AgpsCbInfo& cbInfo) {

    if (NULL != gGnssAdapter) {
        gGnssAdapter->initAgpsCommand(cbInfo);
    }
}
static void agpsDataConnOpen(
        AGpsExtType agpsType, const char* apnName, int apnLen, int ipType) {

    if (NULL != gGnssAdapter) {
        gGnssAdapter->dataConnOpenCommand(
                agpsType, apnName, apnLen, (AGpsBearerType)ipType);
    }
}
static void agpsDataConnClosed(AGpsExtType agpsType) {

    if (NULL != gGnssAdapter) {
        gGnssAdapter->dataConnClosedCommand(agpsType);
    }
}
static void agpsDataConnFailed(AGpsExtType agpsType) {

    if (NULL != gGnssAdapter) {
        gGnssAdapter->dataConnFailedCommand(agpsType);
    }
}

static void getDebugReport(GnssDebugReport& report) {

    if (NULL != gGnssAdapter) {
        gGnssAdapter->getDebugReport(report);
    }
}

static void updateConnectionStatus(bool connected, int8_t type,
                                   bool roaming, NetworkHandle networkHandle,
                                   string& apn) {
    if (NULL != gGnssAdapter) {
        gGnssAdapter->getSystemStatus()->eventConnectionStatus(
                connected, type, roaming, networkHandle, apn);
    }
}

static void odcpiInit(const OdcpiRequestCallback& callback, OdcpiPrioritytype priority)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->initOdcpiCommand(callback, priority);
    }
}

static void odcpiInject(const Location& location)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->injectOdcpiCommand(location);
    }
}

static void blockCPI(double latitude, double longitude, float accuracy,
                     int blockDurationMsec, double latLonDiffThreshold) {
    if (NULL != gGnssAdapter) {
        gGnssAdapter->blockCPICommand(latitude, longitude, accuracy,
                                      blockDurationMsec, latLonDiffThreshold);
    }
}

static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb) {
    if (NULL != gGnssAdapter) {
        gGnssAdapter->getGnssEnergyConsumedCommand(energyConsumedCb);
    }
}

static void enableNfwLocationAccess(bool enable) {
    if (NULL != gGnssAdapter) {
        gGnssAdapter->nfwControlCommand(enable);
    }
}

static void nfwInit(const NfwCbInfo& cbInfo) {
    if (NULL != gGnssAdapter) {
        gGnssAdapter->initNfwCommand(cbInfo);
    }
}

static void getPowerStateChanges(std::function<void(bool)> powerStateCb)
{
    if (NULL != gGnssAdapter) {
        gGnssAdapter->getPowerStateChangesCommand(powerStateCb);
    }
}

static void injectLocationExt(const GnssLocationInfoNotification &locationInfo)
{
   if (NULL != gGnssAdapter) {
       gGnssAdapter->injectLocationExtCommand(locationInfo);
   }
}

static void updateBatteryStatus(bool charging) {
    if (NULL != gGnssAdapter) {
        gGnssAdapter->getSystemStatus()->updatePowerConnectState(charging);
    }
}

static void resetNetworkInfo() {
    if (NULL != gGnssAdapter) {
        gGnssAdapter->getSystemStatus()->resetNetworkInfo();
    }
}

static void updateSystemPowerState(PowerStateType systemPowerState) {
   if (NULL != gGnssAdapter) {
       gGnssAdapter->updateSystemPowerStateCommand(systemPowerState);
   }
}

static uint32_t setConstrainedTunc (bool enable, float tuncConstraint, uint32_t energyBudget) {
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->setConstrainedTuncCommand(enable, tuncConstraint, energyBudget);
    } else {
        return 0;
    }
}

static uint32_t setPositionAssistedClockEstimator(bool enable) {
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->setPositionAssistedClockEstimatorCommand(enable);
    } else {
        return 0;
    }
}

static uint32_t gnssUpdateSvConfig(
        const GnssSvTypeConfig& constellationEnablementConfig,
        const GnssSvIdConfig&   blacklistSvConfig) {
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->gnssUpdateSvConfigCommand(
                constellationEnablementConfig, blacklistSvConfig);
    } else {
        return 0;
    }
}

static uint32_t configLeverArm(const LeverArmConfigInfo& configInfo){
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->configLeverArmCommand(configInfo);
    } else {
        return 0;
    }
}

static bool measCorrInit(const measCorrSetCapabilitiesCb setCapabilitiesCb) {
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->openMeasCorrCommand(setCapabilitiesCb);
    } else {
        return false;
    }
}

static bool measCorrSetCorrections(const GnssMeasurementCorrections gnssMeasCorr) {
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->measCorrSetCorrectionsCommand(gnssMeasCorr);
    } else {
        return false;
    }
}

static void measCorrClose() {
    if (NULL != gGnssAdapter) {
        gGnssAdapter->closeMeasCorrCommand();
    }
}

static uint32_t antennaInfoInit(const antennaInfoCb antennaInfoCallback) {
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->antennaInfoInitCommand(antennaInfoCallback);
    } else {
        return ANTENNA_INFO_ERROR_GENERIC;
    }
}

static void antennaInfoClose() {
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->antennaInfoCloseCommand();
    }
}

static uint32_t configRobustLocation(bool enable, bool enableForE911){
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->configRobustLocationCommand(enable, enableForE911);
    } else {
        return 0;
    }
}

static uint32_t configMinGpsWeek(uint16_t minGpsWeek){
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->configMinGpsWeekCommand(minGpsWeek);
    } else {
        return 0;
    }
}

static uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig){
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->configDeadReckoningEngineParamsCommand(dreConfig);
    } else {
        return 0;
    }
}

static uint32_t gnssUpdateSecondaryBandConfig(
        const GnssSvTypeConfig& secondaryBandConfig) {
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->gnssUpdateSecondaryBandConfigCommand(secondaryBandConfig);
    } else {
        return 0;
    }
}

static uint32_t gnssGetSecondaryBandConfig(){
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->gnssGetSecondaryBandConfigCommand();
    } else {
        return 0;
    }
}

static void updateNTRIPGGAConsent(bool consentAccepted){
    if (NULL != gGnssAdapter) {
        // Call will be enabled once GnssAdapter impl. is ready.
        gGnssAdapter->updateNTRIPGGAConsentCommand(consentAccepted);
    }
}

static void enablePPENtripStream(const GnssNtripConnectionParams& params, bool enableRTKEngine){
    if (NULL != gGnssAdapter) {
        // Call will be enabled once GnssAdapter impl. is ready.
        gGnssAdapter->enablePPENtripStreamCommand(params, enableRTKEngine);
    }
}

static void disablePPENtripStream(){
    if (NULL != gGnssAdapter) {
        // Call will be enabled once GnssAdapter impl. is ready.
        gGnssAdapter->disablePPENtripStreamCommand();
    }
}

static uint32_t configEngineRunState(PositioningEngineMask engType, LocEngineRunState engState) {
    if (NULL != gGnssAdapter) {
        return gGnssAdapter->configEngineRunStateCommand(engType, engState);
    } else {
        return 0;
    }
}


code:
# Flags from BoardConfigVendor.mk
ifneq ($(TARGET_USES_QMAA),true)
BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE := default
else ifneq ($(TARGET_USES_QMAA_OVERRIDE_GPS),false)
BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE := default
endif


code:
# HAL packages
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)

# GPS-HIDL
LOC_BOARD_PLATFORM_LIST += msm8937
LOC_BOARD_PLATFORM_LIST += msm8953
LOC_BOARD_PLATFORM_LIST += msm8998
LOC_BOARD_PLATFORM_LIST += apq8098_latv
LOC_BOARD_PLATFORM_LIST += sdm710
LOC_BOARD_PLATFORM_LIST += qcs605
LOC_BOARD_PLATFORM_LIST += sdm845
LOC_BOARD_PLATFORM_LIST += sdm660
LOC_BOARD_PLATFORM_LIST += msmnile
LOC_BOARD_PLATFORM_LIST += sdmshrike
LOC_BOARD_PLATFORM_LIST += $(MSMSTEPPE)
LOC_BOARD_PLATFORM_LIST += $(TRINKET)
LOC_BOARD_PLATFORM_LIST += kona
LOC_BOARD_PLATFORM_LIST += atoll
LOC_BOARD_PLATFORM_LIST += lito
LOC_BOARD_PLATFORM_LIST += bengal
LOC_BOARD_PLATFORM_LIST += lahaina
LOC_BOARD_PLATFORM_LIST += holi

# Add product packages
ifneq (,$(filter $(LOC_BOARD_PLATFORM_LIST),$(TARGET_BOARD_PLATFORM)))

PRODUCT_PACKAGES += gps.conf
PRODUCT_PACKAGES += flp.conf
PRODUCT_PACKAGES += gnss_antenna_info.conf
PRODUCT_PACKAGES += gnss@2.0-base.policy
PRODUCT_PACKAGES += gnss@2.0-xtra-daemon.policy
PRODUCT_PACKAGES += gnss@2.0-xtwifi-client.policy
PRODUCT_PACKAGES += gnss@2.0-xtwifi-inet-agent.policy
PRODUCT_PACKAGES += libloc_pla_headers
PRODUCT_PACKAGES += liblocation_api_headers
PRODUCT_PACKAGES += libgps.utils_headers
PRODUCT_PACKAGES += liblocation_api
PRODUCT_PACKAGES += libgps.utils
PRODUCT_PACKAGES += libbatching
PRODUCT_PACKAGES += libgeofencing
PRODUCT_PACKAGES += libloc_core
PRODUCT_PACKAGES += libgnss

PRODUCT_PACKAGES += android.hardware.gnss@2.1-impl-qti
PRODUCT_PACKAGES += android.hardware.gnss@2.1-service-qti

endif # ifneq (,$(filter $(LOC_BOARD_PLATFORM_LIST),$(TARGET_BOARD_PLATFORM)))
endif # ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)


code:
cc_library_shared {

    name: "liblocation_api",
    vendor: true,

    shared_libs: [
        "libutils",
        "libcutils",
        "libgps.utils",
        "libdl",
        "liblog",
    ],

    srcs: [
        "LocationAPI.cpp",
        "LocationAPIClientBase.cpp",
    ],

    cflags: ["-fno-short-enums"] + GNSS_CFLAGS,

    header_libs: [
        "libloc_pla_headers",
        "libgps.utils_headers",
    ],

}

cc_library_headers {

    name: "liblocation_api_headers",
    export_include_dirs: ["."],
    vendor: true,
}


code:
/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef ILOCATIONAPI_H
#define ILOCATIONAPI_H

#include "LocationDataTypes.h"

class ILocationAPI
{
public:
    virtual ~ILocationAPI(){};

    /** @brief Updates/changes the callbacks that will be called.
        mandatory callbacks must be present for callbacks to be successfully updated
        no return value */
    virtual void updateCallbacks(LocationCallbacks&) = 0;

    /* ================================== TRACKING ================================== */

    /** @brief Starts a tracking session, which returns a session id that will be
       used by the other tracking APIs and also in the responseCallback to match command
       with response. locations are reported on the registered trackingCallback
       periodically according to LocationOptions.
       @return session id
        responseCallback returns:
                LOCATION_ERROR_SUCCESS if session was successfully started
                LOCATION_ERROR_ALREADY_STARTED if a startTracking session is already in progress
                LOCATION_ERROR_CALLBACK_MISSING if no trackingCallback was passed
                LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameter is invalid */
    virtual uint32_t startTracking(TrackingOptions&) = 0;

    /** @brief Stops a tracking session associated with id parameter.
        responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
    virtual void stopTracking(uint32_t id) = 0;

    /** @brief Changes the LocationOptions of a tracking session associated with id.
        responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid
                LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
    virtual void updateTrackingOptions(uint32_t id, TrackingOptions&) = 0;

    /* ================================== BATCHING ================================== */

    /** @brief starts a batching session, which returns a session id that will be
       used by the other batching APIs and also in the responseCallback to match command
       with response. locations are reported on the batchingCallback passed in createInstance
       periodically according to LocationOptions. A batching session starts tracking on
       the low power processor and delivers them in batches by the batchingCallback when
       the batch is full or when getBatchedLocations is called. This allows for the processor
       that calls this API to sleep when the low power processor can batch locations in the
       backgroup and wake up the processor calling the API only when the batch is full, thus
       saving power.
       @return session id
        responseCallback returns:
                LOCATION_ERROR_SUCCESS if session was successful
                LOCATION_ERROR_ALREADY_STARTED if a startBatching session is already in progress
                LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback
                LOCATION_ERROR_INVALID_PARAMETER if a parameter is invalid
                LOCATION_ERROR_NOT_SUPPORTED if batching is not supported */
    virtual uint32_t startBatching(BatchingOptions&) = 0;

    /** @brief Stops a batching session associated with id parameter.
        responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_ID_UNKNOWN if id is not associated with batching session */
    virtual void stopBatching(uint32_t id) = 0;

    /** @brief Changes the LocationOptions of a batching session associated with id.
        responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid
                LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
    virtual void updateBatchingOptions(uint32_t id, BatchingOptions&) = 0;

    /** @brief Gets a number of locations that are currently stored/batched
       on the low power processor, delivered by the batchingCallback passed in createInstance.
       Location are then deleted from the batch stored on the low power processor.
        responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful, will be followed by batchingCallback call
                LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback
                LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
    virtual void getBatchedLocations(uint32_t id, size_t count) = 0;

    /* ================================== GEOFENCE ================================== */

    /** @brief Adds any number of geofences and returns an array of geofence ids that
       will be used by the other geofence APIs and also in the collectiveResponseCallback to
       match command with response. The geofenceBreachCallback will deliver the status of each
       geofence according to the GeofenceOption for each. The geofence id array returned will
       be valid until the collectiveResponseCallback is called and has returned.
       @return id array
        collectiveResponseCallback returns:
                LOCATION_ERROR_SUCCESS if session was successful
                LOCATION_ERROR_CALLBACK_MISSING if no geofenceBreachCallback
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
                LOCATION_ERROR_NOT_SUPPORTED if geofence is not supported */
    virtual uint32_t* addGeofences(size_t count, GeofenceOption*, GeofenceInfo*) = 0;

    /** @brief Removes any number of geofences. Caller should delete ids array after
       removeGeofences returneds.
        collectiveResponseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
    virtual void removeGeofences(size_t count, uint32_t* ids) = 0;

    /** @brief Modifies any number of geofences. Caller should delete ids array after
       modifyGeofences returns.
        collectiveResponseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid */
    virtual void modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options) = 0;

    /** @brief Pauses any number of geofences, which is similar to removeGeofences,
       only that they can be resumed at any time. Caller should delete ids array after
       pauseGeofences returns.
        collectiveResponseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
    virtual void pauseGeofences(size_t count, uint32_t* ids) = 0;

    /** @brief Resumes any number of geofences that are currently paused. Caller should
       delete ids array after resumeGeofences returns.
        collectiveResponseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
    virtual void resumeGeofences(size_t count, uint32_t* ids) = 0;

    /* ================================== GNSS ====================================== */

     /** @brief gnssNiResponse is called in response to a gnssNiCallback.
        responseCallback returns:
                LOCATION_ERROR_SUCCESS if session was successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters in GnssNiResponse are invalid
                LOCATION_ERROR_ID_UNKNOWN if id does not match a gnssNiCallback */
    virtual void gnssNiResponse(uint32_t id, GnssNiResponse response) = 0;
};

class ILocationControlAPI
{
public:
    virtual ~ILocationControlAPI(){};

    /** @brief Updates the gnss specific configuration, which returns a session id array
       with an id for each of the bits set in GnssConfig.flags, order from low bits to high bits.
       The response for each config that is set will be returned in collectiveResponseCallback.
       The session id array returned will be valid until the collectiveResponseCallback is called
       and has returned. This effect is global for all clients of ILocationAPI.
        collectiveResponseCallback returns:
                LOCATION_ERROR_SUCCESS if session was successful
                LOCATION_ERROR_INVALID_PARAMETER if any other parameters are invalid
                LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
    virtual uint32_t* gnssUpdateConfig(const GnssConfig& config) = 0;

    /** @brief Delete specific gnss aiding data for testing, which returns a session id
       that will be returned in responseCallback to match command with response.
       Only allowed in userdebug builds. This effect is global for all clients of ILocationAPI.
        responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
                LOCATION_ERROR_NOT_SUPPORTED if build is not userdebug */
    virtual uint32_t gnssDeleteAidingData(GnssAidingData& data) = 0;

    /** @brief
        Configure the constellation and SVs to be used by the GNSS engine on
        modem.

        @param
        constellationEnablementConfig: configuration to enable/disable SV
        constellation to be used by SPE engine. When size in
        constellationEnablementConfig is set to 0, this indicates to reset SV
        constellation configuration to modem NV default.

        blacklistSvConfig: configuration to blacklist or unblacklist SVs
        used by SPE engine

        @return
        A session id that will be returned in responseCallback to
        match command with response. This effect is global for all
        clients of LocationAPI responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
    */
    virtual uint32_t configConstellations(
            const GnssSvTypeConfig& constellationEnablementConfig,
            const GnssSvIdConfig&   blacklistSvConfig) = 0;

    /** @brief
        Configure the secondary band of constellations to be used by
        the GNSS engine on modem.

        @param
        secondaryBandConfig: configuration the secondary band usage
        for SPE engine

        @return
        A session id that will be returned in responseCallback to
        match command with response. This effect is global for all
        clients of LocationAPI responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
    */
    virtual uint32_t configConstellationSecondaryBand(
            const GnssSvTypeConfig& secondaryBandConfig) = 0;

    /** @brief
        Enable or disable the constrained time uncertainty feature.

        @param
        enable: true to enable the constrained time uncertainty
        feature and false to disable the constrainted time
        uncertainty feature.

        @param
        tuncThreshold: this specifies the time uncertainty threshold
        that gps engine need to maintain, in units of milli-seconds.
        Default is 0.0 meaning that modem default value of time
        uncertainty threshold will be used. This parameter is
        ignored when requesting to disable this feature.

        @param
        energyBudget: this specifies the power budget that gps
        engine is allowed to spend to maintain the time uncertainty.
        Default is 0 meaning that GPS engine is not constained by
        power budget and can spend as much power as needed. The
        parameter need to be specified in units of 0.1 milli watt
        second. This parameter is ignored requesting to disable this
        feature.

        @return
        A session id that will be returned in responseCallback to
        match command with response. This effect is global for all
        clients of LocationAPI responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters
                are invalid
    */
    virtual uint32_t configConstrainedTimeUncertainty(
            bool enable, float tuncThreshold = 0.0,
            uint32_t energyBudget = 0) = 0;

    /** @brief
        Enable or disable position assisted clock estimator feature.

        @param
        enable: true to enable position assisted clock estimator and
        false to disable the position assisted clock estimator
        feature.

        @return
        A session id that will be returned in responseCallback to
        match command with response. This effect is global for all
        clients of LocationAPI responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
    */
    virtual uint32_t configPositionAssistedClockEstimator(bool enable) = 0;

    /** @brief
        Sets the lever arm parameters for the vehicle.

        @param
        configInfo: lever arm configuration info regarding below two
        types of lever arm info:
        a: GNSS Antenna w.r.t the origin at the IMU e.g.: inertial
        measurement unit.
        b: lever arm parameters regarding the OPF (output frame)
        w.r.t the origin (at the GPS Antenna). Vehicle manufacturers
        prefer the position output to be tied to a specific point in
        the vehicle rather than where the antenna is placed
        (midpoint of the rear axle is typical).

        Caller can choose types of lever arm info to configure via the
        leverMarkTypeMask.

        @return
        A session id that will be returned in responseCallback to
        match command with response. This effect is global for all
        clients of LocationAPI responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
    */
    virtual uint32_t configLeverArm(const LeverArmConfigInfo& configInfo) = 0;

    /** @brief
        Configure the robust location setting.

        @param
        enable: true to enable robust location and false to disable
        robust location.

        @param
        enableForE911: true to enable robust location when device is on
        E911 session and false to disable on E911 session.
        This parameter is only valid if robust location is enabled.

        @return
        A session id that will be returned in responseCallback to
        match command with response. This effect is global for all
        clients of LocationAPI responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
    */
    virtual uint32_t configRobustLocation(bool enable, bool enableForE911) = 0;

    /** @brief
        Config the minimum GPS week used by modem GNSS engine.

        @param
        minGpsWeek: minimum GPS week to be used by modem GNSS engine.

        @return
        A session id that will be returned in responseCallback to
        match command with response. This effect is global for all
        clients of LocationAPI responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
    */
    virtual uint32_t configMinGpsWeek(uint16_t minGpsWeek) = 0;

    /** @brief
        Configure the vehicle body-to-Sensor mount parameters and
        other parameters for dead reckoning position engine.

        @param
        dreConfig: vehicle body-to-Sensor mount angles and other
        parameters.

        @return
        A session id that will be returned in responseCallback to
        match command with response. This effect is global for all
        clients of LocationAPI responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
    */
    virtual uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig)=0;

    /** @brief
        This API is used to instruct the specified engine to be in
        the pause/resume state.

        When the engine is placed in paused state, the engine will
        stop. If there is an on-going session, engine will no longer
        produce fixes. In the paused state, calling API to delete
        aiding data from the paused engine may not have effect.
        Request to delete Aiding data shall be issued after
        engine resume.

        Currently, only DRE engine will support pause/resume
        request. responseCb() will return not supported when request
        is made to pause/resume none-DRE engine.

        Request to pause/resume DRE engine can be made with or
        without an on-going session. With QDR engine, on resume,
        GNSS position & heading re-acquisition is needed for DR
        engine to engage. If DR engine is already in the requested
        state, the request will be no-op.

        @param
        engType: the engine that is instructed to change its run
        state.

        engState: the new engine run state that the engine is
        instructed to be in.

        @return
        A session id that will be returned in responseCallback to
        match command with response. This effect is global for all
        clients of LocationAPI responseCallback returns:
                LOCATION_ERROR_SUCCESS if successful
                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
    */
    virtual uint32_t configEngineRunState(PositioningEngineMask engType,
                                          LocEngineRunState engState) = 0;
};

#endif /* ILOCATIONAPI_H */